Blame view
drivers/scsi/bfa/bfa_fcbuild.c
37.9 KB
7725ccfda
|
1 |
/* |
a36c61f90
|
2 |
* Copyright (c) 2005-2010 Brocade Communications Systems, Inc. |
7725ccfda
|
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
* All rights reserved * www.brocade.com * * Linux driver for Brocade Fibre Channel Host Bus Adapter. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License (GPL) Version 2 as * published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ /* * fcbuild.c - FC link service frame building and parsing routines */ |
f16a17507
|
20 |
#include "bfad_drv.h" |
a36c61f90
|
21 |
#include "bfa_fcbuild.h" |
7725ccfda
|
22 23 24 25 |
/* * static build functions */ |
a36c61f90
|
26 |
static void fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, |
50444a340
|
27 |
__be16 ox_id); |
a36c61f90
|
28 |
static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, |
50444a340
|
29 |
__be16 ox_id); |
a36c61f90
|
30 31 32 33 |
static struct fchs_s fc_els_req_tmpl; static struct fchs_s fc_els_rsp_tmpl; static struct fchs_s fc_bls_req_tmpl; static struct fchs_s fc_bls_rsp_tmpl; |
7725ccfda
|
34 35 36 37 |
static struct fc_ba_acc_s ba_acc_tmpl; static struct fc_logi_s plogi_tmpl; static struct fc_prli_s prli_tmpl; static struct fc_rrq_s rrq_tmpl; |
a36c61f90
|
38 |
static struct fchs_s fcp_fchs_tmpl; |
7725ccfda
|
39 40 41 42 43 44 45 46 47 48 49 |
void fcbuild_init(void) { /* * fc_els_req_tmpl */ fc_els_req_tmpl.routing = FC_RTG_EXT_LINK; fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST; fc_els_req_tmpl.type = FC_TYPE_ELS; fc_els_req_tmpl.f_ctl = |
f16a17507
|
50 |
bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ | |
7725ccfda
|
51 52 53 54 55 56 57 58 59 60 |
FCTL_SI_XFER); fc_els_req_tmpl.rx_id = FC_RXID_ANY; /* * fc_els_rsp_tmpl */ fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK; fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY; fc_els_rsp_tmpl.type = FC_TYPE_ELS; fc_els_rsp_tmpl.f_ctl = |
f16a17507
|
61 |
bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | |
7725ccfda
|
62 63 64 65 66 67 68 69 |
FCTL_END_SEQ | FCTL_SI_XFER); fc_els_rsp_tmpl.rx_id = FC_RXID_ANY; /* * fc_bls_req_tmpl */ fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK; fc_bls_req_tmpl.type = FC_TYPE_BLS; |
f16a17507
|
70 |
fc_bls_req_tmpl.f_ctl = bfa_hton3b(FCTL_END_SEQ | FCTL_SI_XFER); |
7725ccfda
|
71 72 73 74 75 76 77 78 79 |
fc_bls_req_tmpl.rx_id = FC_RXID_ANY; /* * fc_bls_rsp_tmpl */ fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK; fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC; fc_bls_rsp_tmpl.type = FC_TYPE_BLS; fc_bls_rsp_tmpl.f_ctl = |
f16a17507
|
80 |
bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | |
7725ccfda
|
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
FCTL_END_SEQ | FCTL_SI_XFER); fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY; /* * ba_acc_tmpl */ ba_acc_tmpl.seq_id_valid = 0; ba_acc_tmpl.low_seq_cnt = 0; ba_acc_tmpl.high_seq_cnt = 0xFFFF; /* * plogi_tmpl */ plogi_tmpl.csp.verhi = FC_PH_VER_PH_3; plogi_tmpl.csp.verlo = FC_PH_VER_4_3; |
7725ccfda
|
96 97 98 |
plogi_tmpl.csp.ciro = 0x1; plogi_tmpl.csp.cisc = 0x0; plogi_tmpl.csp.altbbcred = 0x0; |
ba816ea8e
|
99 100 101 |
plogi_tmpl.csp.conseq = cpu_to_be16(0x00FF); plogi_tmpl.csp.ro_bitmap = cpu_to_be16(0x0002); plogi_tmpl.csp.e_d_tov = cpu_to_be32(2000); |
7725ccfda
|
102 103 104 105 106 107 108 109 110 111 112 |
plogi_tmpl.class3.class_valid = 1; plogi_tmpl.class3.sequential = 1; plogi_tmpl.class3.conseq = 0xFF; plogi_tmpl.class3.ospx = 1; /* * prli_tmpl */ prli_tmpl.command = FC_ELS_PRLI; prli_tmpl.pglen = 0x10; |
ba816ea8e
|
113 |
prli_tmpl.pagebytes = cpu_to_be16(0x0014); |
7725ccfda
|
114 115 116 117 118 119 120 121 122 123 |
prli_tmpl.parampage.type = FC_TYPE_FCP; prli_tmpl.parampage.imagepair = 1; prli_tmpl.parampage.servparams.rxrdisab = 1; /* * rrq_tmpl */ rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ; /* |
a36c61f90
|
124 |
* fcp_struct fchs_s mpl |
7725ccfda
|
125 126 127 128 129 |
*/ fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA; fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD; fcp_fchs_tmpl.type = FC_TYPE_FCP; fcp_fchs_tmpl.f_ctl = |
f16a17507
|
130 |
bfa_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER); |
7725ccfda
|
131 132 133 134 135 |
fcp_fchs_tmpl.seq_id = 1; fcp_fchs_tmpl.rx_id = FC_RXID_ANY; } static void |
a36c61f90
|
136 |
fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id) |
7725ccfda
|
137 |
{ |
6a18b1675
|
138 |
memset(fchs, 0, sizeof(struct fchs_s)); |
7725ccfda
|
139 140 141 142 143 |
fchs->routing = FC_RTG_FC4_DEV_DATA; fchs->cat_info = FC_CAT_UNSOLICIT_CTRL; fchs->type = FC_TYPE_SERVICES; fchs->f_ctl = |
f16a17507
|
144 |
bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ | |
7725ccfda
|
145 146 147 148 |
FCTL_SI_XFER); fchs->rx_id = FC_RXID_ANY; fchs->d_id = (d_id); fchs->s_id = (s_id); |
ba816ea8e
|
149 |
fchs->ox_id = cpu_to_be16(ox_id); |
7725ccfda
|
150 |
|
5fbe25c7a
|
151 |
/* |
7725ccfda
|
152 153 154 155 |
* @todo no need to set ox_id for request * no need to set rx_id for response */ } |
d7be54cc5
|
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
static void fc_gsresp_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) { memset(fchs, 0, sizeof(struct fchs_s)); fchs->routing = FC_RTG_FC4_DEV_DATA; fchs->cat_info = FC_CAT_SOLICIT_CTRL; fchs->type = FC_TYPE_SERVICES; fchs->f_ctl = bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER); fchs->d_id = d_id; fchs->s_id = s_id; fchs->ox_id = ox_id; } |
7725ccfda
|
171 |
void |
50444a340
|
172 |
fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) |
7725ccfda
|
173 |
{ |
6a18b1675
|
174 |
memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s)); |
7725ccfda
|
175 176 |
fchs->d_id = (d_id); fchs->s_id = (s_id); |
ba816ea8e
|
177 |
fchs->ox_id = cpu_to_be16(ox_id); |
7725ccfda
|
178 179 180 |
} static void |
50444a340
|
181 |
fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) |
7725ccfda
|
182 |
{ |
6a18b1675
|
183 |
memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s)); |
7725ccfda
|
184 185 186 187 188 189 190 191 |
fchs->d_id = d_id; fchs->s_id = s_id; fchs->ox_id = ox_id; } enum fc_parse_status fc_els_rsp_parse(struct fchs_s *fchs, int len) { |
a36c61f90
|
192 193 |
struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); struct fc_ls_rjt_s *ls_rjt = (struct fc_ls_rjt_s *) els_cmd; |
7725ccfda
|
194 195 196 197 198 199 |
len = len; switch (els_cmd->els_code) { case FC_ELS_LS_RJT: if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) |
f8ceafde6
|
200 |
return FC_PARSE_BUSY; |
7725ccfda
|
201 |
else |
f8ceafde6
|
202 |
return FC_PARSE_FAILURE; |
7725ccfda
|
203 204 |
case FC_ELS_ACC: |
f8ceafde6
|
205 |
return FC_PARSE_OK; |
7725ccfda
|
206 |
} |
f8ceafde6
|
207 |
return FC_PARSE_OK; |
7725ccfda
|
208 209 210 |
} static void |
50444a340
|
211 |
fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id) |
7725ccfda
|
212 |
{ |
6a18b1675
|
213 |
memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s)); |
7725ccfda
|
214 215 216 217 218 219 220 |
fchs->d_id = d_id; fchs->s_id = s_id; fchs->ox_id = ox_id; } static u16 fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, |
50444a340
|
221 |
__be16 ox_id, wwn_t port_name, wwn_t node_name, |
be540a991
|
222 |
u16 pdu_size, u16 bb_cr, u8 els_code) |
7725ccfda
|
223 |
{ |
a36c61f90
|
224 |
struct fc_logi_s *plogi = (struct fc_logi_s *) (pld); |
7725ccfda
|
225 |
|
6a18b1675
|
226 |
memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s)); |
7725ccfda
|
227 |
|
bc0e2c2a9
|
228 229 230 |
/* For FC AL bb_cr is 0 and altbbcred is 1 */ if (!bb_cr) plogi->csp.altbbcred = 1; |
7725ccfda
|
231 232 233 234 235 |
plogi->els_cmd.els_code = els_code; if (els_code == FC_ELS_PLOGI) fc_els_req_build(fchs, d_id, s_id, ox_id); else fc_els_rsp_build(fchs, d_id, s_id, ox_id); |
ba816ea8e
|
236 |
plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size); |
be540a991
|
237 |
plogi->csp.bbcred = cpu_to_be16(bb_cr); |
7725ccfda
|
238 |
|
6a18b1675
|
239 240 |
memcpy(&plogi->port_name, &port_name, sizeof(wwn_t)); memcpy(&plogi->node_name, &node_name, sizeof(wwn_t)); |
7725ccfda
|
241 |
|
f8ceafde6
|
242 |
return sizeof(struct fc_logi_s); |
7725ccfda
|
243 244 245 246 |
} u16 fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, |
a36c61f90
|
247 248 |
u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size, u8 set_npiv, u8 set_auth, u16 local_bb_credits) |
7725ccfda
|
249 |
{ |
f16a17507
|
250 |
u32 d_id = bfa_hton3b(FC_FABRIC_PORT); |
50444a340
|
251 |
__be32 *vvl_info; |
7725ccfda
|
252 |
|
6a18b1675
|
253 |
memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); |
7725ccfda
|
254 255 256 |
flogi->els_cmd.els_code = FC_ELS_FLOGI; fc_els_req_build(fchs, d_id, s_id, ox_id); |
ba816ea8e
|
257 |
flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size); |
7725ccfda
|
258 259 260 261 262 263 264 265 266 267 268 |
flogi->port_name = port_name; flogi->node_name = node_name; /* * Set the NPIV Capability Bit ( word 1, bit 31) of Common * Service Parameters. */ flogi->csp.ciro = set_npiv; /* set AUTH capability */ flogi->csp.security = set_auth; |
ba816ea8e
|
269 |
flogi->csp.bbcred = cpu_to_be16(local_bb_credits); |
7725ccfda
|
270 271 272 273 274 275 |
/* Set brcd token in VVL */ vvl_info = (u32 *)&flogi->vvl[0]; /* set the flag to indicate the presence of VVL */ flogi->csp.npiv_supp = 1; /* @todo. field name is not correct */ |
ba816ea8e
|
276 |
vvl_info[0] = cpu_to_be32(FLOGI_VVL_BRCD); |
7725ccfda
|
277 |
|
f8ceafde6
|
278 |
return sizeof(struct fc_logi_s); |
7725ccfda
|
279 280 281 282 |
} u16 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, |
50444a340
|
283 |
__be16 ox_id, wwn_t port_name, wwn_t node_name, |
be540a991
|
284 |
u16 pdu_size, u16 local_bb_credits, u8 bb_scn) |
7725ccfda
|
285 286 |
{ u32 d_id = 0; |
be540a991
|
287 |
u16 bbscn_rxsz = (bb_scn << 12) | pdu_size; |
7725ccfda
|
288 |
|
6a18b1675
|
289 |
memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); |
7725ccfda
|
290 291 292 |
fc_els_rsp_build(fchs, d_id, s_id, ox_id); flogi->els_cmd.els_code = FC_ELS_ACC; |
be540a991
|
293 294 |
flogi->class3.rxsz = cpu_to_be16(pdu_size); flogi->csp.rxsz = cpu_to_be16(bbscn_rxsz); /* bb_scn/rxsz */ |
7725ccfda
|
295 296 |
flogi->port_name = port_name; flogi->node_name = node_name; |
ba816ea8e
|
297 |
flogi->csp.bbcred = cpu_to_be16(local_bb_credits); |
7725ccfda
|
298 |
|
f8ceafde6
|
299 |
return sizeof(struct fc_logi_s); |
7725ccfda
|
300 301 302 303 |
} u16 fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, |
a36c61f90
|
304 |
u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size) |
7725ccfda
|
305 |
{ |
f16a17507
|
306 |
u32 d_id = bfa_hton3b(FC_FABRIC_PORT); |
7725ccfda
|
307 |
|
6a18b1675
|
308 |
memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); |
7725ccfda
|
309 310 311 |
flogi->els_cmd.els_code = FC_ELS_FDISC; fc_els_req_build(fchs, d_id, s_id, ox_id); |
ba816ea8e
|
312 |
flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size); |
7725ccfda
|
313 314 |
flogi->port_name = port_name; flogi->node_name = node_name; |
f8ceafde6
|
315 |
return sizeof(struct fc_logi_s); |
7725ccfda
|
316 317 318 319 320 |
} u16 fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, u16 ox_id, wwn_t port_name, wwn_t node_name, |
be540a991
|
321 |
u16 pdu_size, u16 bb_cr) |
7725ccfda
|
322 323 |
{ return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name, |
be540a991
|
324 |
node_name, pdu_size, bb_cr, FC_ELS_PLOGI); |
7725ccfda
|
325 326 327 328 329 |
} u16 fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, u16 ox_id, wwn_t port_name, wwn_t node_name, |
be540a991
|
330 |
u16 pdu_size, u16 bb_cr) |
7725ccfda
|
331 332 |
{ return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name, |
be540a991
|
333 |
node_name, pdu_size, bb_cr, FC_ELS_ACC); |
7725ccfda
|
334 335 336 337 338 |
} enum fc_parse_status fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) { |
a36c61f90
|
339 340 341 |
struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); struct fc_logi_s *plogi; struct fc_ls_rjt_s *ls_rjt; |
7725ccfda
|
342 343 344 345 346 |
switch (els_cmd->els_code) { case FC_ELS_LS_RJT: ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1); if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) |
f8ceafde6
|
347 |
return FC_PARSE_BUSY; |
7725ccfda
|
348 |
else |
f8ceafde6
|
349 |
return FC_PARSE_FAILURE; |
7725ccfda
|
350 351 352 |
case FC_ELS_ACC: plogi = (struct fc_logi_s *) (fchs + 1); if (len < sizeof(struct fc_logi_s)) |
f8ceafde6
|
353 |
return FC_PARSE_FAILURE; |
7725ccfda
|
354 355 |
if (!wwn_is_equal(plogi->port_name, port_name)) |
f8ceafde6
|
356 |
return FC_PARSE_FAILURE; |
7725ccfda
|
357 358 |
if (!plogi->class3.class_valid) |
f8ceafde6
|
359 |
return FC_PARSE_FAILURE; |
7725ccfda
|
360 |
|
ba816ea8e
|
361 |
if (be16_to_cpu(plogi->class3.rxsz) < (FC_MIN_PDUSZ)) |
f8ceafde6
|
362 |
return FC_PARSE_FAILURE; |
7725ccfda
|
363 |
|
f8ceafde6
|
364 |
return FC_PARSE_OK; |
7725ccfda
|
365 |
default: |
f8ceafde6
|
366 |
return FC_PARSE_FAILURE; |
7725ccfda
|
367 368 369 370 371 372 |
} } enum fc_parse_status fc_plogi_parse(struct fchs_s *fchs) { |
a36c61f90
|
373 |
struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1); |
7725ccfda
|
374 375 376 |
if (plogi->class3.class_valid != 1) return FC_PARSE_FAILURE; |
ba816ea8e
|
377 378 |
if ((be16_to_cpu(plogi->class3.rxsz) < FC_MIN_PDUSZ) || (be16_to_cpu(plogi->class3.rxsz) > FC_MAX_PDUSZ) |
7725ccfda
|
379 |
|| (plogi->class3.rxsz == 0)) |
f8ceafde6
|
380 |
return FC_PARSE_FAILURE; |
7725ccfda
|
381 382 383 384 385 386 387 388 |
return FC_PARSE_OK; } u16 fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, u16 ox_id) { |
a36c61f90
|
389 |
struct fc_prli_s *prli = (struct fc_prli_s *) (pld); |
7725ccfda
|
390 391 |
fc_els_req_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
392 |
memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); |
7725ccfda
|
393 394 395 396 397 398 399 |
prli->command = FC_ELS_PRLI; prli->parampage.servparams.initiator = 1; prli->parampage.servparams.retry = 1; prli->parampage.servparams.rec_support = 1; prli->parampage.servparams.task_retry_id = 0; prli->parampage.servparams.confirm = 1; |
f8ceafde6
|
400 |
return sizeof(struct fc_prli_s); |
7725ccfda
|
401 402 403 404 |
} u16 fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, |
50444a340
|
405 |
__be16 ox_id, enum bfa_lport_role role) |
7725ccfda
|
406 |
{ |
a36c61f90
|
407 |
struct fc_prli_s *prli = (struct fc_prli_s *) (pld); |
7725ccfda
|
408 409 |
fc_els_rsp_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
410 |
memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); |
7725ccfda
|
411 412 |
prli->command = FC_ELS_ACC; |
a36c61f90
|
413 |
prli->parampage.servparams.initiator = 1; |
7725ccfda
|
414 415 |
prli->parampage.rspcode = FC_PRLI_ACC_XQTD; |
f8ceafde6
|
416 |
return sizeof(struct fc_prli_s); |
7725ccfda
|
417 418 419 420 421 422 |
} enum fc_parse_status fc_prli_rsp_parse(struct fc_prli_s *prli, int len) { if (len < sizeof(struct fc_prli_s)) |
f8ceafde6
|
423 |
return FC_PARSE_FAILURE; |
7725ccfda
|
424 425 |
if (prli->command != FC_ELS_ACC) |
f8ceafde6
|
426 |
return FC_PARSE_FAILURE; |
7725ccfda
|
427 428 429 |
if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD) && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG)) |
f8ceafde6
|
430 |
return FC_PARSE_FAILURE; |
7725ccfda
|
431 432 |
if (prli->parampage.servparams.target != 1) |
f8ceafde6
|
433 |
return FC_PARSE_FAILURE; |
7725ccfda
|
434 |
|
f8ceafde6
|
435 |
return FC_PARSE_OK; |
7725ccfda
|
436 437 438 439 440 441 |
} enum fc_parse_status fc_prli_parse(struct fc_prli_s *prli) { if (prli->parampage.type != FC_TYPE_FCP) |
f8ceafde6
|
442 |
return FC_PARSE_FAILURE; |
7725ccfda
|
443 444 |
if (!prli->parampage.imagepair) |
f8ceafde6
|
445 |
return FC_PARSE_FAILURE; |
7725ccfda
|
446 447 |
if (!prli->parampage.servparams.initiator) |
f8ceafde6
|
448 |
return FC_PARSE_FAILURE; |
7725ccfda
|
449 |
|
f8ceafde6
|
450 |
return FC_PARSE_OK; |
7725ccfda
|
451 452 453 |
} u16 |
a36c61f90
|
454 455 |
fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id, u16 ox_id, wwn_t port_name) |
7725ccfda
|
456 457 |
{ fc_els_req_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
458 |
memset(logo, '\0', sizeof(struct fc_logo_s)); |
7725ccfda
|
459 460 461 |
logo->els_cmd.els_code = FC_ELS_LOGO; logo->nport_id = (s_id); logo->orig_port_name = port_name; |
f8ceafde6
|
462 |
return sizeof(struct fc_logo_s); |
7725ccfda
|
463 |
} |
da99dcc98
|
464 |
static u16 |
7725ccfda
|
465 |
fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, |
50444a340
|
466 |
u32 s_id, __be16 ox_id, wwn_t port_name, |
7725ccfda
|
467 468 |
wwn_t node_name, u8 els_code) { |
6a18b1675
|
469 |
memset(adisc, '\0', sizeof(struct fc_adisc_s)); |
7725ccfda
|
470 471 472 473 474 475 476 477 478 479 480 481 |
adisc->els_cmd.els_code = els_code; if (els_code == FC_ELS_ADISC) fc_els_req_build(fchs, d_id, s_id, ox_id); else fc_els_rsp_build(fchs, d_id, s_id, ox_id); adisc->orig_HA = 0; adisc->orig_port_name = port_name; adisc->orig_node_name = node_name; adisc->nport_id = (s_id); |
f8ceafde6
|
482 |
return sizeof(struct fc_adisc_s); |
7725ccfda
|
483 484 485 486 |
} u16 fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, |
50444a340
|
487 |
u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name) |
7725ccfda
|
488 489 490 491 492 493 494 |
{ return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name, node_name, FC_ELS_ADISC); } u16 fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, |
50444a340
|
495 |
u32 s_id, __be16 ox_id, wwn_t port_name, |
7725ccfda
|
496 497 498 499 500 501 502 503 504 505 506 507 |
wwn_t node_name) { return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name, node_name, FC_ELS_ACC); } enum fc_parse_status fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name, wwn_t node_name) { if (len < sizeof(struct fc_adisc_s)) |
f8ceafde6
|
508 |
return FC_PARSE_FAILURE; |
7725ccfda
|
509 510 |
if (adisc->els_cmd.els_code != FC_ELS_ACC) |
f8ceafde6
|
511 |
return FC_PARSE_FAILURE; |
7725ccfda
|
512 513 |
if (!wwn_is_equal(adisc->orig_port_name, port_name)) |
f8ceafde6
|
514 |
return FC_PARSE_FAILURE; |
7725ccfda
|
515 |
|
f8ceafde6
|
516 |
return FC_PARSE_OK; |
7725ccfda
|
517 518 519 |
} enum fc_parse_status |
a36c61f90
|
520 521 |
fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, wwn_t node_name, wwn_t port_name) |
7725ccfda
|
522 |
{ |
a36c61f90
|
523 |
struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld; |
7725ccfda
|
524 525 |
if (adisc->els_cmd.els_code != FC_ELS_ACC) |
f8ceafde6
|
526 |
return FC_PARSE_FAILURE; |
7725ccfda
|
527 528 529 530 |
if ((adisc->nport_id == (host_dap)) && wwn_is_equal(adisc->orig_port_name, port_name) && wwn_is_equal(adisc->orig_node_name, node_name)) |
f8ceafde6
|
531 |
return FC_PARSE_OK; |
7725ccfda
|
532 |
|
f8ceafde6
|
533 |
return FC_PARSE_FAILURE; |
7725ccfda
|
534 535 536 537 538 |
} enum fc_parse_status fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name) { |
a36c61f90
|
539 |
struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); |
7725ccfda
|
540 541 542 |
if (pdisc->class3.class_valid != 1) return FC_PARSE_FAILURE; |
ba816ea8e
|
543 |
if ((be16_to_cpu(pdisc->class3.rxsz) < |
a36c61f90
|
544 |
(FC_MIN_PDUSZ - sizeof(struct fchs_s))) |
7725ccfda
|
545 |
|| (pdisc->class3.rxsz == 0)) |
f8ceafde6
|
546 |
return FC_PARSE_FAILURE; |
7725ccfda
|
547 548 |
if (!wwn_is_equal(pdisc->port_name, port_name)) |
f8ceafde6
|
549 |
return FC_PARSE_FAILURE; |
7725ccfda
|
550 551 |
if (!wwn_is_equal(pdisc->node_name, node_name)) |
f8ceafde6
|
552 |
return FC_PARSE_FAILURE; |
7725ccfda
|
553 554 555 556 557 558 559 |
return FC_PARSE_OK; } u16 fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) { |
6a18b1675
|
560 |
memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s)); |
7725ccfda
|
561 562 563 |
fchs->cat_info = FC_CAT_ABTS; fchs->d_id = (d_id); fchs->s_id = (s_id); |
ba816ea8e
|
564 |
fchs->ox_id = cpu_to_be16(ox_id); |
7725ccfda
|
565 |
|
f8ceafde6
|
566 |
return sizeof(struct fchs_s); |
7725ccfda
|
567 568 569 570 571 572 573 |
} enum fc_parse_status fc_abts_rsp_parse(struct fchs_s *fchs, int len) { if ((fchs->cat_info == FC_CAT_BA_ACC) || (fchs->cat_info == FC_CAT_BA_RJT)) |
f8ceafde6
|
574 |
return FC_PARSE_OK; |
7725ccfda
|
575 |
|
f8ceafde6
|
576 |
return FC_PARSE_FAILURE; |
7725ccfda
|
577 578 579 |
} u16 |
a36c61f90
|
580 581 |
fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id, u16 ox_id, u16 rrq_oxid) |
7725ccfda
|
582 583 584 585 586 587 |
{ fc_els_req_build(fchs, d_id, s_id, ox_id); /* * build rrq payload */ |
6a18b1675
|
588 |
memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s)); |
7725ccfda
|
589 |
rrq->s_id = (s_id); |
ba816ea8e
|
590 |
rrq->ox_id = cpu_to_be16(rrq_oxid); |
7725ccfda
|
591 |
rrq->rx_id = FC_RXID_ANY; |
f8ceafde6
|
592 |
return sizeof(struct fc_rrq_s); |
7725ccfda
|
593 594 595 596 |
} u16 fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, |
50444a340
|
597 |
__be16 ox_id) |
7725ccfda
|
598 |
{ |
a36c61f90
|
599 |
struct fc_els_cmd_s *acc = pld; |
7725ccfda
|
600 601 |
fc_els_rsp_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
602 |
memset(acc, 0, sizeof(struct fc_els_cmd_s)); |
7725ccfda
|
603 |
acc->els_code = FC_ELS_ACC; |
f8ceafde6
|
604 |
return sizeof(struct fc_els_cmd_s); |
7725ccfda
|
605 606 607 608 |
} u16 fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id, |
50444a340
|
609 |
u32 s_id, __be16 ox_id, u8 reason_code, |
7725ccfda
|
610 611 612 |
u8 reason_code_expl) { fc_els_rsp_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
613 |
memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s)); |
7725ccfda
|
614 615 616 617 618 |
ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT; ls_rjt->reason_code = reason_code; ls_rjt->reason_code_expl = reason_code_expl; ls_rjt->vendor_unique = 0x00; |
f8ceafde6
|
619 |
return sizeof(struct fc_ls_rjt_s); |
7725ccfda
|
620 621 622 623 |
} u16 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id, |
50444a340
|
624 |
u32 s_id, __be16 ox_id, u16 rx_id) |
7725ccfda
|
625 626 |
{ fc_bls_rsp_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
627 |
memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s)); |
7725ccfda
|
628 629 630 631 632 |
fchs->rx_id = rx_id; ba_acc->ox_id = fchs->ox_id; ba_acc->rx_id = fchs->rx_id; |
f8ceafde6
|
633 |
return sizeof(struct fc_ba_acc_s); |
7725ccfda
|
634 635 636 |
} u16 |
a36c61f90
|
637 |
fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id, |
50444a340
|
638 |
u32 s_id, __be16 ox_id) |
7725ccfda
|
639 640 |
{ fc_els_rsp_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
641 |
memset(els_cmd, 0, sizeof(struct fc_els_cmd_s)); |
7725ccfda
|
642 |
els_cmd->els_code = FC_ELS_ACC; |
f8ceafde6
|
643 |
return sizeof(struct fc_els_cmd_s); |
7725ccfda
|
644 645 646 647 648 649 |
} int fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code) { int num_pages = 0; |
a36c61f90
|
650 651 |
struct fc_prlo_s *prlo; struct fc_tprlo_s *tprlo; |
7725ccfda
|
652 653 654 |
if (els_code == FC_ELS_PRLO) { prlo = (struct fc_prlo_s *) (fc_frame + 1); |
ba816ea8e
|
655 |
num_pages = (be16_to_cpu(prlo->payload_len) - 4) / 16; |
7725ccfda
|
656 657 |
} else { tprlo = (struct fc_tprlo_s *) (fc_frame + 1); |
ba816ea8e
|
658 |
num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16; |
7725ccfda
|
659 660 661 662 663 664 |
} return num_pages; } u16 fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc, |
50444a340
|
665 |
u32 d_id, u32 s_id, __be16 ox_id, int num_pages) |
7725ccfda
|
666 667 668 669 |
{ int page; fc_els_rsp_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
670 |
memset(tprlo_acc, 0, (num_pages * 16) + 4); |
7725ccfda
|
671 672 673 |
tprlo_acc->command = FC_ELS_ACC; tprlo_acc->page_len = 0x10; |
ba816ea8e
|
674 |
tprlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4); |
7725ccfda
|
675 676 677 678 679 680 681 682 |
for (page = 0; page < num_pages; page++) { tprlo_acc->tprlo_acc_params[page].opa_valid = 0; tprlo_acc->tprlo_acc_params[page].rpa_valid = 0; tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0; tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0; } |
ba816ea8e
|
683 |
return be16_to_cpu(tprlo_acc->payload_len); |
7725ccfda
|
684 685 686 |
} u16 |
a36c61f90
|
687 |
fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id, |
50444a340
|
688 |
u32 s_id, __be16 ox_id, int num_pages) |
7725ccfda
|
689 690 691 692 |
{ int page; fc_els_rsp_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
693 |
memset(prlo_acc, 0, (num_pages * 16) + 4); |
7725ccfda
|
694 695 |
prlo_acc->command = FC_ELS_ACC; prlo_acc->page_len = 0x10; |
ba816ea8e
|
696 |
prlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4); |
7725ccfda
|
697 698 699 700 701 702 703 704 |
for (page = 0; page < num_pages; page++) { prlo_acc->prlo_acc_params[page].opa_valid = 0; prlo_acc->prlo_acc_params[page].rpa_valid = 0; prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; prlo_acc->prlo_acc_params[page].orig_process_assc = 0; prlo_acc->prlo_acc_params[page].resp_process_assc = 0; } |
ba816ea8e
|
705 |
return be16_to_cpu(prlo_acc->payload_len); |
7725ccfda
|
706 707 708 709 |
} u16 fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id, |
a36c61f90
|
710 |
u32 s_id, u16 ox_id, u32 data_format) |
7725ccfda
|
711 712 |
{ fc_els_req_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
713 |
memset(rnid, 0, sizeof(struct fc_rnid_cmd_s)); |
7725ccfda
|
714 715 716 |
rnid->els_cmd.els_code = FC_ELS_RNID; rnid->node_id_data_format = data_format; |
f8ceafde6
|
717 |
return sizeof(struct fc_rnid_cmd_s); |
7725ccfda
|
718 719 720 |
} u16 |
a36c61f90
|
721 |
fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id, |
50444a340
|
722 |
u32 s_id, __be16 ox_id, u32 data_format, |
a36c61f90
|
723 724 |
struct fc_rnid_common_id_data_s *common_id_data, struct fc_rnid_general_topology_data_s *gen_topo_data) |
7725ccfda
|
725 |
{ |
6a18b1675
|
726 |
memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s)); |
7725ccfda
|
727 728 729 730 731 732 733 734 735 736 737 738 |
fc_els_rsp_build(fchs, d_id, s_id, ox_id); rnid_acc->els_cmd.els_code = FC_ELS_ACC; rnid_acc->node_id_data_format = data_format; rnid_acc->common_id_data_length = sizeof(struct fc_rnid_common_id_data_s); rnid_acc->common_id_data = *common_id_data; if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { rnid_acc->specific_id_data_length = sizeof(struct fc_rnid_general_topology_data_s); |
6a18b1675
|
739 |
rnid_acc->gen_topology_data = *gen_topo_data; |
f8ceafde6
|
740 |
return sizeof(struct fc_rnid_acc_s); |
7725ccfda
|
741 |
} else { |
f8ceafde6
|
742 743 |
return sizeof(struct fc_rnid_acc_s) - sizeof(struct fc_rnid_general_topology_data_s); |
7725ccfda
|
744 745 746 747 748 749 |
} } u16 fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id, |
a36c61f90
|
750 |
u32 s_id, u16 ox_id) |
7725ccfda
|
751 752 |
{ fc_els_req_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
753 |
memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s)); |
7725ccfda
|
754 755 |
rpsc->els_cmd.els_code = FC_ELS_RPSC; |
f8ceafde6
|
756 |
return sizeof(struct fc_rpsc_cmd_s); |
7725ccfda
|
757 758 759 |
} u16 |
a36c61f90
|
760 761 |
fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id, u32 s_id, u32 *pid_list, u16 npids) |
7725ccfda
|
762 |
{ |
f16a17507
|
763 |
u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id)); |
7725ccfda
|
764 |
int i = 0; |
f16a17507
|
765 |
fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0); |
7725ccfda
|
766 |
|
6a18b1675
|
767 |
memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s)); |
7725ccfda
|
768 769 |
rpsc2->els_cmd.els_code = FC_ELS_RPSC; |
ba816ea8e
|
770 771 |
rpsc2->token = cpu_to_be32(FC_BRCD_TOKEN); rpsc2->num_pids = cpu_to_be16(npids); |
7725ccfda
|
772 773 |
for (i = 0; i < npids; i++) rpsc2->pid_list[i].pid = pid_list[i]; |
a36c61f90
|
774 |
return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * (sizeof(u32))); |
7725ccfda
|
775 776 777 778 |
} u16 fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc, |
50444a340
|
779 |
u32 d_id, u32 s_id, __be16 ox_id, |
a36c61f90
|
780 |
struct fc_rpsc_speed_info_s *oper_speed) |
7725ccfda
|
781 |
{ |
6a18b1675
|
782 |
memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s)); |
7725ccfda
|
783 784 785 786 |
fc_els_rsp_build(fchs, d_id, s_id, ox_id); rpsc_acc->command = FC_ELS_ACC; |
ba816ea8e
|
787 |
rpsc_acc->num_entries = cpu_to_be16(1); |
7725ccfda
|
788 789 |
rpsc_acc->speed_info[0].port_speed_cap = |
ba816ea8e
|
790 |
cpu_to_be16(oper_speed->port_speed_cap); |
7725ccfda
|
791 792 |
rpsc_acc->speed_info[0].port_op_speed = |
ba816ea8e
|
793 |
cpu_to_be16(oper_speed->port_op_speed); |
7725ccfda
|
794 |
|
f8ceafde6
|
795 |
return sizeof(struct fc_rpsc_acc_s); |
7725ccfda
|
796 |
} |
7725ccfda
|
797 798 799 |
u16 fc_logo_rsp_parse(struct fchs_s *fchs, int len) { |
a36c61f90
|
800 |
struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); |
7725ccfda
|
801 802 803 804 805 806 807 808 809 |
len = len; if (els_cmd->els_code != FC_ELS_ACC) return FC_PARSE_FAILURE; return FC_PARSE_OK; } u16 |
a36c61f90
|
810 811 |
fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size) |
7725ccfda
|
812 |
{ |
a36c61f90
|
813 |
struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); |
7725ccfda
|
814 |
|
6a18b1675
|
815 |
memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s)); |
7725ccfda
|
816 817 818 |
pdisc->els_cmd.els_code = FC_ELS_PDISC; fc_els_req_build(fchs, d_id, s_id, ox_id); |
ba816ea8e
|
819 |
pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size); |
7725ccfda
|
820 821 |
pdisc->port_name = port_name; pdisc->node_name = node_name; |
f8ceafde6
|
822 |
return sizeof(struct fc_logi_s); |
7725ccfda
|
823 824 825 826 827 |
} u16 fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) { |
a36c61f90
|
828 |
struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); |
7725ccfda
|
829 830 |
if (len < sizeof(struct fc_logi_s)) |
f8ceafde6
|
831 |
return FC_PARSE_LEN_INVAL; |
7725ccfda
|
832 833 |
if (pdisc->els_cmd.els_code != FC_ELS_ACC) |
f8ceafde6
|
834 |
return FC_PARSE_ACC_INVAL; |
7725ccfda
|
835 836 |
if (!wwn_is_equal(pdisc->port_name, port_name)) |
f8ceafde6
|
837 |
return FC_PARSE_PWWN_NOT_EQUAL; |
7725ccfda
|
838 839 |
if (!pdisc->class3.class_valid) |
f8ceafde6
|
840 |
return FC_PARSE_NWWN_NOT_EQUAL; |
7725ccfda
|
841 |
|
ba816ea8e
|
842 |
if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ)) |
f8ceafde6
|
843 |
return FC_PARSE_RXSZ_INVAL; |
7725ccfda
|
844 |
|
f8ceafde6
|
845 |
return FC_PARSE_OK; |
7725ccfda
|
846 847 848 849 850 851 |
} u16 fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, int num_pages) { |
a36c61f90
|
852 |
struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1); |
7725ccfda
|
853 854 855 |
int page; fc_els_req_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
856 |
memset(prlo, 0, (num_pages * 16) + 4); |
7725ccfda
|
857 858 |
prlo->command = FC_ELS_PRLO; prlo->page_len = 0x10; |
ba816ea8e
|
859 |
prlo->payload_len = cpu_to_be16((num_pages * 16) + 4); |
7725ccfda
|
860 861 862 863 864 865 866 867 |
for (page = 0; page < num_pages; page++) { prlo->prlo_params[page].type = FC_TYPE_FCP; prlo->prlo_params[page].opa_valid = 0; prlo->prlo_params[page].rpa_valid = 0; prlo->prlo_params[page].orig_process_assc = 0; prlo->prlo_params[page].resp_process_assc = 0; } |
ba816ea8e
|
868 |
return be16_to_cpu(prlo->payload_len); |
7725ccfda
|
869 870 871 872 873 |
} u16 fc_prlo_rsp_parse(struct fchs_s *fchs, int len) { |
a36c61f90
|
874 |
struct fc_prlo_acc_s *prlo = (struct fc_prlo_acc_s *) (fchs + 1); |
7725ccfda
|
875 876 877 878 879 880 |
int num_pages = 0; int page = 0; len = len; if (prlo->command != FC_ELS_ACC) |
f8ceafde6
|
881 |
return FC_PARSE_FAILURE; |
7725ccfda
|
882 |
|
ba816ea8e
|
883 |
num_pages = ((be16_to_cpu(prlo->payload_len)) - 4) / 16; |
7725ccfda
|
884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 |
for (page = 0; page < num_pages; page++) { if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP) return FC_PARSE_FAILURE; if (prlo->prlo_acc_params[page].opa_valid != 0) return FC_PARSE_FAILURE; if (prlo->prlo_acc_params[page].rpa_valid != 0) return FC_PARSE_FAILURE; if (prlo->prlo_acc_params[page].orig_process_assc != 0) return FC_PARSE_FAILURE; if (prlo->prlo_acc_params[page].resp_process_assc != 0) return FC_PARSE_FAILURE; } |
f8ceafde6
|
901 |
return FC_PARSE_OK; |
7725ccfda
|
902 903 904 905 |
} u16 |
a36c61f90
|
906 907 |
fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id) |
7725ccfda
|
908 |
{ |
a36c61f90
|
909 |
struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1); |
7725ccfda
|
910 911 912 |
int page; fc_els_req_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
913 |
memset(tprlo, 0, (num_pages * 16) + 4); |
7725ccfda
|
914 915 |
tprlo->command = FC_ELS_TPRLO; tprlo->page_len = 0x10; |
ba816ea8e
|
916 |
tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4); |
7725ccfda
|
917 918 919 920 921 922 923 924 925 926 927 928 929 930 |
for (page = 0; page < num_pages; page++) { tprlo->tprlo_params[page].type = FC_TYPE_FCP; tprlo->tprlo_params[page].opa_valid = 0; tprlo->tprlo_params[page].rpa_valid = 0; tprlo->tprlo_params[page].orig_process_assc = 0; tprlo->tprlo_params[page].resp_process_assc = 0; if (tprlo_type == FC_GLOBAL_LOGO) { tprlo->tprlo_params[page].global_process_logout = 1; } else if (tprlo_type == FC_TPR_LOGO) { tprlo->tprlo_params[page].tpo_nport_valid = 1; tprlo->tprlo_params[page].tpo_nport_id = (tpr_id); } } |
ba816ea8e
|
931 |
return be16_to_cpu(tprlo->payload_len); |
7725ccfda
|
932 933 934 935 936 937 938 939 940 941 942 943 |
} u16 fc_tprlo_rsp_parse(struct fchs_s *fchs, int len) { struct fc_tprlo_acc_s *tprlo = (struct fc_tprlo_acc_s *) (fchs + 1); int num_pages = 0; int page = 0; len = len; if (tprlo->command != FC_ELS_ACC) |
f8ceafde6
|
944 |
return FC_PARSE_ACC_INVAL; |
7725ccfda
|
945 |
|
ba816ea8e
|
946 |
num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16; |
7725ccfda
|
947 948 949 |
for (page = 0; page < num_pages; page++) { if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP) |
f8ceafde6
|
950 |
return FC_PARSE_NOT_FCP; |
7725ccfda
|
951 |
if (tprlo->tprlo_acc_params[page].opa_valid != 0) |
f8ceafde6
|
952 |
return FC_PARSE_OPAFLAG_INVAL; |
7725ccfda
|
953 |
if (tprlo->tprlo_acc_params[page].rpa_valid != 0) |
f8ceafde6
|
954 |
return FC_PARSE_RPAFLAG_INVAL; |
7725ccfda
|
955 |
if (tprlo->tprlo_acc_params[page].orig_process_assc != 0) |
f8ceafde6
|
956 |
return FC_PARSE_OPA_INVAL; |
7725ccfda
|
957 |
if (tprlo->tprlo_acc_params[page].resp_process_assc != 0) |
f8ceafde6
|
958 |
return FC_PARSE_RPA_INVAL; |
7725ccfda
|
959 |
} |
f8ceafde6
|
960 |
return FC_PARSE_OK; |
7725ccfda
|
961 962 963 964 965 |
} enum fc_parse_status fc_rrq_rsp_parse(struct fchs_s *fchs, int len) { |
a36c61f90
|
966 |
struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); |
7725ccfda
|
967 968 969 970 971 972 973 974 975 |
len = len; if (els_cmd->els_code != FC_ELS_ACC) return FC_PARSE_FAILURE; return FC_PARSE_OK; } u16 |
50444a340
|
976 |
fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id, |
a36c61f90
|
977 |
u32 reason_code, u32 reason_expl) |
7725ccfda
|
978 |
{ |
a36c61f90
|
979 |
struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1); |
7725ccfda
|
980 981 982 983 984 985 |
fc_bls_rsp_build(fchs, d_id, s_id, ox_id); fchs->cat_info = FC_CAT_BA_RJT; ba_rjt->reason_code = reason_code; ba_rjt->reason_expl = reason_expl; |
f8ceafde6
|
986 |
return sizeof(struct fc_ba_rjt_s); |
7725ccfda
|
987 988 989 990 991 |
} static void fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code) { |
6a18b1675
|
992 |
memset(cthdr, 0, sizeof(struct ct_hdr_s)); |
7725ccfda
|
993 994 995 |
cthdr->rev_id = CT_GS3_REVISION; cthdr->gs_type = CT_GSTYPE_DIRSERVICE; cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER; |
ba816ea8e
|
996 |
cthdr->cmd_rsp_code = cpu_to_be16(cmd_code); |
7725ccfda
|
997 998 999 1000 1001 |
} static void fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code) { |
6a18b1675
|
1002 |
memset(cthdr, 0, sizeof(struct ct_hdr_s)); |
7725ccfda
|
1003 1004 1005 |
cthdr->rev_id = CT_GS3_REVISION; cthdr->gs_type = CT_GSTYPE_MGMTSERVICE; cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER; |
ba816ea8e
|
1006 |
cthdr->cmd_rsp_code = cpu_to_be16(cmd_code); |
7725ccfda
|
1007 1008 1009 1010 1011 1012 |
} static void fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code, u8 sub_type) { |
6a18b1675
|
1013 |
memset(cthdr, 0, sizeof(struct ct_hdr_s)); |
7725ccfda
|
1014 1015 1016 |
cthdr->rev_id = CT_GS3_REVISION; cthdr->gs_type = CT_GSTYPE_MGMTSERVICE; cthdr->gs_sub_type = sub_type; |
ba816ea8e
|
1017 |
cthdr->cmd_rsp_code = cpu_to_be16(cmd_code); |
7725ccfda
|
1018 1019 1020 1021 1022 1023 |
} u16 fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, wwn_t port_name) { |
a36c61f90
|
1024 1025 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1); |
f16a17507
|
1026 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1027 1028 1029 |
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN); |
6a18b1675
|
1030 |
memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s)); |
7725ccfda
|
1031 |
gidpn->port_name = port_name; |
f8ceafde6
|
1032 |
return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1033 1034 1035 1036 1037 1038 |
} u16 fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, u32 port_id) { |
a36c61f90
|
1039 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; |
7725ccfda
|
1040 |
fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1); |
f16a17507
|
1041 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1042 1043 1044 |
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID); |
6a18b1675
|
1045 |
memset(gpnid, 0, sizeof(fcgs_gpnid_req_t)); |
7725ccfda
|
1046 |
gpnid->dap = port_id; |
f8ceafde6
|
1047 |
return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1048 1049 1050 1051 1052 1053 |
} u16 fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, u32 port_id) { |
a36c61f90
|
1054 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; |
7725ccfda
|
1055 |
fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1); |
f16a17507
|
1056 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1057 1058 1059 |
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID); |
6a18b1675
|
1060 |
memset(gnnid, 0, sizeof(fcgs_gnnid_req_t)); |
7725ccfda
|
1061 |
gnnid->dap = port_id; |
f8ceafde6
|
1062 |
return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1063 1064 1065 1066 1067 |
} u16 fc_ct_rsp_parse(struct ct_hdr_s *cthdr) { |
ba816ea8e
|
1068 |
if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) { |
7725ccfda
|
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 |
if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY) return FC_PARSE_BUSY; else return FC_PARSE_FAILURE; } return FC_PARSE_OK; } u16 |
d7be54cc5
|
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 |
fc_gs_rjt_build(struct fchs_s *fchs, struct ct_hdr_s *cthdr, u32 d_id, u32 s_id, u16 ox_id, u8 reason_code, u8 reason_code_expl) { fc_gsresp_fchdr_build(fchs, d_id, s_id, ox_id); cthdr->cmd_rsp_code = cpu_to_be16(CT_RSP_REJECT); cthdr->rev_id = CT_GS3_REVISION; cthdr->reason_code = reason_code; cthdr->exp_code = reason_code_expl; return sizeof(struct ct_hdr_s); } u16 |
a36c61f90
|
1094 1095 |
fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, u8 set_br_reg, u32 s_id, u16 ox_id) |
7725ccfda
|
1096 |
{ |
f16a17507
|
1097 |
u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER); |
7725ccfda
|
1098 1099 |
fc_els_req_build(fchs, d_id, s_id, ox_id); |
6a18b1675
|
1100 |
memset(scr, 0, sizeof(struct fc_scr_s)); |
7725ccfda
|
1101 1102 1103 1104 |
scr->command = FC_ELS_SCR; scr->reg_func = FC_SCR_REG_FUNC_FULL; if (set_br_reg) scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE; |
f8ceafde6
|
1105 |
return sizeof(struct fc_scr_s); |
7725ccfda
|
1106 1107 1108 |
} u16 |
a36c61f90
|
1109 1110 |
fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn, u32 s_id, u16 ox_id) |
7725ccfda
|
1111 |
{ |
f16a17507
|
1112 |
u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER); |
7725ccfda
|
1113 1114 1115 1116 1117 1118 1119 |
u16 payldlen; fc_els_req_build(fchs, d_id, s_id, ox_id); rscn->command = FC_ELS_RSCN; rscn->pagelen = sizeof(rscn->event[0]); payldlen = sizeof(u32) + rscn->pagelen; |
ba816ea8e
|
1120 |
rscn->payldlen = cpu_to_be16(payldlen); |
7725ccfda
|
1121 1122 1123 |
rscn->event[0].format = FC_RSCN_FORMAT_PORTID; rscn->event[0].portid = s_id; |
f8ceafde6
|
1124 |
return sizeof(struct fc_rscn_pl_s); |
7725ccfda
|
1125 1126 1127 1128 |
} u16 fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, |
a36c61f90
|
1129 |
enum bfa_lport_role roles) |
7725ccfda
|
1130 |
{ |
a36c61f90
|
1131 1132 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1); |
f16a17507
|
1133 |
u32 type_value, d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1134 1135 1136 1137 |
u8 index; fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID); |
6a18b1675
|
1138 |
memset(rftid, 0, sizeof(struct fcgs_rftid_req_s)); |
7725ccfda
|
1139 1140 1141 1142 1143 1144 |
rftid->dap = s_id; /* By default, FCP FC4 Type is registered */ index = FC_TYPE_FCP >> 5; type_value = 1 << (FC_TYPE_FCP % 32); |
ba816ea8e
|
1145 |
rftid->fc4_type[index] = cpu_to_be32(type_value); |
7725ccfda
|
1146 |
|
f8ceafde6
|
1147 |
return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1148 1149 1150 |
} u16 |
a36c61f90
|
1151 1152 |
fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, u8 *fc4_bitmap, u32 bitmap_size) |
7725ccfda
|
1153 |
{ |
a36c61f90
|
1154 1155 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1); |
f16a17507
|
1156 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1157 1158 1159 |
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID); |
6a18b1675
|
1160 |
memset(rftid, 0, sizeof(struct fcgs_rftid_req_s)); |
7725ccfda
|
1161 1162 |
rftid->dap = s_id; |
6a18b1675
|
1163 |
memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap, |
a36c61f90
|
1164 |
(bitmap_size < 32 ? bitmap_size : 32)); |
7725ccfda
|
1165 |
|
f8ceafde6
|
1166 |
return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1167 1168 1169 1170 1171 1172 |
} u16 fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, u8 fc4_type, u8 fc4_ftrs) { |
a36c61f90
|
1173 1174 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; struct fcgs_rffid_req_s *rffid = (struct fcgs_rffid_req_s *)(cthdr + 1); |
f16a17507
|
1175 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1176 1177 1178 |
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID); |
6a18b1675
|
1179 |
memset(rffid, 0, sizeof(struct fcgs_rffid_req_s)); |
7725ccfda
|
1180 |
|
a36c61f90
|
1181 |
rffid->dap = s_id; |
7725ccfda
|
1182 |
rffid->fc4ftr_bits = fc4_ftrs; |
a36c61f90
|
1183 |
rffid->fc4_type = fc4_type; |
7725ccfda
|
1184 |
|
f8ceafde6
|
1185 |
return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1186 1187 1188 1189 1190 1191 |
} u16 fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, u8 *name) { |
a36c61f90
|
1192 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; |
7725ccfda
|
1193 |
struct fcgs_rspnid_req_s *rspnid = |
a36c61f90
|
1194 |
(struct fcgs_rspnid_req_s *)(cthdr + 1); |
f16a17507
|
1195 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1196 1197 1198 |
fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID); |
6a18b1675
|
1199 |
memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s)); |
7725ccfda
|
1200 1201 1202 1203 |
rspnid->dap = s_id; rspnid->spn_len = (u8) strlen((char *)name); strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len); |
f8ceafde6
|
1204 |
return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1205 1206 1207 |
} u16 |
ce7242b80
|
1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 |
fc_rsnn_nn_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t node_name, u8 *name) { struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; struct fcgs_rsnn_nn_req_s *rsnn_nn = (struct fcgs_rsnn_nn_req_s *) (cthdr + 1); u32 d_id = bfa_hton3b(FC_NAME_SERVER); fc_gs_fchdr_build(fchs, d_id, s_id, 0); fc_gs_cthdr_build(cthdr, s_id, GS_RSNN_NN); memset(rsnn_nn, 0, sizeof(struct fcgs_rsnn_nn_req_s)); rsnn_nn->node_name = node_name; rsnn_nn->snn_len = (u8) strlen((char *)name); strncpy((char *)rsnn_nn->snn, (char *)name, rsnn_nn->snn_len); return sizeof(struct fcgs_rsnn_nn_req_s) + sizeof(struct ct_hdr_s); } u16 |
a36c61f90
|
1229 |
fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type) |
7725ccfda
|
1230 |
{ |
a36c61f90
|
1231 1232 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; struct fcgs_gidft_req_s *gidft = (struct fcgs_gidft_req_s *)(cthdr + 1); |
f16a17507
|
1233 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1234 1235 1236 1237 |
fc_gs_fchdr_build(fchs, d_id, s_id, 0); fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT); |
6a18b1675
|
1238 |
memset(gidft, 0, sizeof(struct fcgs_gidft_req_s)); |
7725ccfda
|
1239 1240 1241 |
gidft->fc4_type = fc4_type; gidft->domain_id = 0; gidft->area_id = 0; |
f8ceafde6
|
1242 |
return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1243 1244 1245 1246 1247 1248 |
} u16 fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, wwn_t port_name) { |
a36c61f90
|
1249 1250 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; struct fcgs_rpnid_req_s *rpnid = (struct fcgs_rpnid_req_s *)(cthdr + 1); |
f16a17507
|
1251 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1252 1253 1254 |
fc_gs_fchdr_build(fchs, d_id, s_id, 0); fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID); |
6a18b1675
|
1255 |
memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s)); |
7725ccfda
|
1256 1257 |
rpnid->port_id = port_id; rpnid->port_name = port_name; |
f8ceafde6
|
1258 |
return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1259 1260 1261 1262 1263 1264 |
} u16 fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, wwn_t node_name) { |
a36c61f90
|
1265 1266 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; struct fcgs_rnnid_req_s *rnnid = (struct fcgs_rnnid_req_s *)(cthdr + 1); |
f16a17507
|
1267 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1268 1269 1270 |
fc_gs_fchdr_build(fchs, d_id, s_id, 0); fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID); |
6a18b1675
|
1271 |
memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s)); |
7725ccfda
|
1272 1273 |
rnnid->port_id = port_id; rnnid->node_name = node_name; |
f8ceafde6
|
1274 |
return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1275 1276 1277 1278 1279 1280 |
} u16 fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, u32 cos) { |
a36c61f90
|
1281 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; |
7725ccfda
|
1282 1283 |
struct fcgs_rcsid_req_s *rcsid = (struct fcgs_rcsid_req_s *) (cthdr + 1); |
f16a17507
|
1284 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1285 1286 1287 |
fc_gs_fchdr_build(fchs, d_id, s_id, 0); fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID); |
6a18b1675
|
1288 |
memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s)); |
7725ccfda
|
1289 1290 |
rcsid->port_id = port_id; rcsid->cos = cos; |
f8ceafde6
|
1291 |
return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1292 1293 1294 1295 1296 1297 |
} u16 fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, u8 port_type) { |
a36c61f90
|
1298 1299 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; struct fcgs_rptid_req_s *rptid = (struct fcgs_rptid_req_s *)(cthdr + 1); |
f16a17507
|
1300 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1301 1302 1303 |
fc_gs_fchdr_build(fchs, d_id, s_id, 0); fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID); |
6a18b1675
|
1304 |
memset(rptid, 0, sizeof(struct fcgs_rptid_req_s)); |
7725ccfda
|
1305 1306 |
rptid->port_id = port_id; rptid->port_type = port_type; |
f8ceafde6
|
1307 |
return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s); |
7725ccfda
|
1308 1309 1310 1311 1312 |
} u16 fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id) { |
a36c61f90
|
1313 1314 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; struct fcgs_ganxt_req_s *ganxt = (struct fcgs_ganxt_req_s *)(cthdr + 1); |
f16a17507
|
1315 |
u32 d_id = bfa_hton3b(FC_NAME_SERVER); |
7725ccfda
|
1316 1317 1318 |
fc_gs_fchdr_build(fchs, d_id, s_id, 0); fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT); |
6a18b1675
|
1319 |
memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s)); |
7725ccfda
|
1320 |
ganxt->port_id = port_id; |
f8ceafde6
|
1321 |
return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s); |
7725ccfda
|
1322 1323 1324 1325 1326 1327 1328 1329 1330 |
} /* * Builds fc hdr and ct hdr for FDMI requests. */ u16 fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 cmd_code) { |
a36c61f90
|
1331 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; |
f16a17507
|
1332 |
u32 d_id = bfa_hton3b(FC_MGMT_SERVER); |
7725ccfda
|
1333 1334 1335 |
fc_gs_fchdr_build(fchs, d_id, s_id, 0); fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code); |
f8ceafde6
|
1336 |
return sizeof(struct ct_hdr_s); |
7725ccfda
|
1337 1338 1339 1340 1341 1342 1343 1344 1345 |
} /* * Given a FC4 Type, this function returns a fc4 type bitmask */ void fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask) { u8 index; |
50444a340
|
1346 |
__be32 *ptr = (__be32 *) bit_mask; |
7725ccfda
|
1347 1348 1349 1350 1351 1352 1353 1354 |
u32 type_value; /* * @todo : Check for bitmask size */ index = fc4_type >> 5; type_value = 1 << (fc4_type % 32); |
ba816ea8e
|
1355 |
ptr[index] = cpu_to_be32(type_value); |
7725ccfda
|
1356 1357 1358 1359 |
} /* |
a36c61f90
|
1360 |
* GMAL Request |
7725ccfda
|
1361 1362 1363 1364 |
*/ u16 fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn) { |
a36c61f90
|
1365 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; |
7725ccfda
|
1366 |
fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1); |
f16a17507
|
1367 |
u32 d_id = bfa_hton3b(FC_MGMT_SERVER); |
7725ccfda
|
1368 1369 1370 1371 |
fc_gs_fchdr_build(fchs, d_id, s_id, 0); fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD, CT_GSSUBTYPE_CFGSERVER); |
6a18b1675
|
1372 |
memset(gmal, 0, sizeof(fcgs_gmal_req_t)); |
7725ccfda
|
1373 |
gmal->wwn = wwn; |
f8ceafde6
|
1374 |
return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t); |
7725ccfda
|
1375 1376 1377 1378 1379 1380 1381 1382 |
} /* * GFN (Get Fabric Name) Request */ u16 fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn) { |
a36c61f90
|
1383 |
struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; |
7725ccfda
|
1384 |
fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1); |
f16a17507
|
1385 |
u32 d_id = bfa_hton3b(FC_MGMT_SERVER); |
7725ccfda
|
1386 1387 1388 1389 |
fc_gs_fchdr_build(fchs, d_id, s_id, 0); fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD, CT_GSSUBTYPE_CFGSERVER); |
6a18b1675
|
1390 |
memset(gfn, 0, sizeof(fcgs_gfn_req_t)); |
7725ccfda
|
1391 |
gfn->wwn = wwn; |
f8ceafde6
|
1392 |
return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t); |
7725ccfda
|
1393 |
} |