bfa_fcbuild.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
  4. * Copyright (c) 2014- QLogic Corporation.
  5. * All rights reserved
  6. * www.qlogic.com
  7. *
  8. * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
  9. */
  10. /*
  11. * fcbuild.c - FC link service frame building and parsing routines
  12. */
  13. #include "bfad_drv.h"
  14. #include "bfa_fcbuild.h"
  15. /*
  16. * static build functions
  17. */
  18. static void fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
  19. __be16 ox_id);
  20. static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
  21. __be16 ox_id);
  22. static struct fchs_s fc_els_req_tmpl;
  23. static struct fchs_s fc_els_rsp_tmpl;
  24. static struct fchs_s fc_bls_req_tmpl;
  25. static struct fchs_s fc_bls_rsp_tmpl;
  26. static struct fc_ba_acc_s ba_acc_tmpl;
  27. static struct fc_logi_s plogi_tmpl;
  28. static struct fc_prli_s prli_tmpl;
  29. static struct fc_rrq_s rrq_tmpl;
  30. static struct fchs_s fcp_fchs_tmpl;
  31. void
  32. fcbuild_init(void)
  33. {
  34. /*
  35. * fc_els_req_tmpl
  36. */
  37. fc_els_req_tmpl.routing = FC_RTG_EXT_LINK;
  38. fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST;
  39. fc_els_req_tmpl.type = FC_TYPE_ELS;
  40. fc_els_req_tmpl.f_ctl =
  41. bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
  42. FCTL_SI_XFER);
  43. fc_els_req_tmpl.rx_id = FC_RXID_ANY;
  44. /*
  45. * fc_els_rsp_tmpl
  46. */
  47. fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK;
  48. fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY;
  49. fc_els_rsp_tmpl.type = FC_TYPE_ELS;
  50. fc_els_rsp_tmpl.f_ctl =
  51. bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
  52. FCTL_END_SEQ | FCTL_SI_XFER);
  53. fc_els_rsp_tmpl.rx_id = FC_RXID_ANY;
  54. /*
  55. * fc_bls_req_tmpl
  56. */
  57. fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK;
  58. fc_bls_req_tmpl.type = FC_TYPE_BLS;
  59. fc_bls_req_tmpl.f_ctl = bfa_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
  60. fc_bls_req_tmpl.rx_id = FC_RXID_ANY;
  61. /*
  62. * fc_bls_rsp_tmpl
  63. */
  64. fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK;
  65. fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC;
  66. fc_bls_rsp_tmpl.type = FC_TYPE_BLS;
  67. fc_bls_rsp_tmpl.f_ctl =
  68. bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
  69. FCTL_END_SEQ | FCTL_SI_XFER);
  70. fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY;
  71. /*
  72. * ba_acc_tmpl
  73. */
  74. ba_acc_tmpl.seq_id_valid = 0;
  75. ba_acc_tmpl.low_seq_cnt = 0;
  76. ba_acc_tmpl.high_seq_cnt = 0xFFFF;
  77. /*
  78. * plogi_tmpl
  79. */
  80. plogi_tmpl.csp.verhi = FC_PH_VER_PH_3;
  81. plogi_tmpl.csp.verlo = FC_PH_VER_4_3;
  82. plogi_tmpl.csp.ciro = 0x1;
  83. plogi_tmpl.csp.cisc = 0x0;
  84. plogi_tmpl.csp.altbbcred = 0x0;
  85. plogi_tmpl.csp.conseq = cpu_to_be16(0x00FF);
  86. plogi_tmpl.csp.ro_bitmap = cpu_to_be16(0x0002);
  87. plogi_tmpl.csp.e_d_tov = cpu_to_be32(2000);
  88. plogi_tmpl.class3.class_valid = 1;
  89. plogi_tmpl.class3.sequential = 1;
  90. plogi_tmpl.class3.conseq = 0xFF;
  91. plogi_tmpl.class3.ospx = 1;
  92. /*
  93. * prli_tmpl
  94. */
  95. prli_tmpl.command = FC_ELS_PRLI;
  96. prli_tmpl.pglen = 0x10;
  97. prli_tmpl.pagebytes = cpu_to_be16(0x0014);
  98. prli_tmpl.parampage.type = FC_TYPE_FCP;
  99. prli_tmpl.parampage.imagepair = 1;
  100. prli_tmpl.parampage.servparams.rxrdisab = 1;
  101. /*
  102. * rrq_tmpl
  103. */
  104. rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ;
  105. /*
  106. * fcp_struct fchs_s mpl
  107. */
  108. fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA;
  109. fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD;
  110. fcp_fchs_tmpl.type = FC_TYPE_FCP;
  111. fcp_fchs_tmpl.f_ctl =
  112. bfa_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
  113. fcp_fchs_tmpl.seq_id = 1;
  114. fcp_fchs_tmpl.rx_id = FC_RXID_ANY;
  115. }
  116. static void
  117. fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u32 ox_id)
  118. {
  119. memset(fchs, 0, sizeof(struct fchs_s));
  120. fchs->routing = FC_RTG_FC4_DEV_DATA;
  121. fchs->cat_info = FC_CAT_UNSOLICIT_CTRL;
  122. fchs->type = FC_TYPE_SERVICES;
  123. fchs->f_ctl =
  124. bfa_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
  125. FCTL_SI_XFER);
  126. fchs->rx_id = FC_RXID_ANY;
  127. fchs->d_id = (d_id);
  128. fchs->s_id = (s_id);
  129. fchs->ox_id = cpu_to_be16(ox_id);
  130. /*
  131. * @todo no need to set ox_id for request
  132. * no need to set rx_id for response
  133. */
  134. }
  135. static void
  136. fc_gsresp_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
  137. {
  138. memset(fchs, 0, sizeof(struct fchs_s));
  139. fchs->routing = FC_RTG_FC4_DEV_DATA;
  140. fchs->cat_info = FC_CAT_SOLICIT_CTRL;
  141. fchs->type = FC_TYPE_SERVICES;
  142. fchs->f_ctl =
  143. bfa_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
  144. FCTL_END_SEQ | FCTL_SI_XFER);
  145. fchs->d_id = d_id;
  146. fchs->s_id = s_id;
  147. fchs->ox_id = ox_id;
  148. }
  149. void
  150. fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
  151. {
  152. memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
  153. fchs->d_id = (d_id);
  154. fchs->s_id = (s_id);
  155. fchs->ox_id = cpu_to_be16(ox_id);
  156. }
  157. static void
  158. fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
  159. {
  160. memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
  161. fchs->d_id = d_id;
  162. fchs->s_id = s_id;
  163. fchs->ox_id = ox_id;
  164. }
  165. static void
  166. fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id)
  167. {
  168. memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
  169. fchs->d_id = d_id;
  170. fchs->s_id = s_id;
  171. fchs->ox_id = ox_id;
  172. }
  173. static u16
  174. fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
  175. __be16 ox_id, wwn_t port_name, wwn_t node_name,
  176. u16 pdu_size, u16 bb_cr, u8 els_code)
  177. {
  178. struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
  179. memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
  180. /* For FC AL bb_cr is 0 and altbbcred is 1 */
  181. if (!bb_cr)
  182. plogi->csp.altbbcred = 1;
  183. plogi->els_cmd.els_code = els_code;
  184. if (els_code == FC_ELS_PLOGI)
  185. fc_els_req_build(fchs, d_id, s_id, ox_id);
  186. else
  187. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  188. plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size);
  189. plogi->csp.bbcred = cpu_to_be16(bb_cr);
  190. memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
  191. memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
  192. return sizeof(struct fc_logi_s);
  193. }
  194. u16
  195. fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
  196. u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size,
  197. u8 set_npiv, u8 set_auth, u16 local_bb_credits)
  198. {
  199. u32 d_id = bfa_hton3b(FC_FABRIC_PORT);
  200. __be32 *vvl_info;
  201. memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
  202. flogi->els_cmd.els_code = FC_ELS_FLOGI;
  203. fc_els_req_build(fchs, d_id, s_id, ox_id);
  204. flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
  205. flogi->port_name = port_name;
  206. flogi->node_name = node_name;
  207. /*
  208. * Set the NPIV Capability Bit ( word 1, bit 31) of Common
  209. * Service Parameters.
  210. */
  211. flogi->csp.ciro = set_npiv;
  212. /* set AUTH capability */
  213. flogi->csp.security = set_auth;
  214. flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
  215. /* Set brcd token in VVL */
  216. vvl_info = (u32 *)&flogi->vvl[0];
  217. /* set the flag to indicate the presence of VVL */
  218. flogi->csp.npiv_supp = 1; /* @todo. field name is not correct */
  219. vvl_info[0] = cpu_to_be32(FLOGI_VVL_BRCD);
  220. return sizeof(struct fc_logi_s);
  221. }
  222. u16
  223. fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
  224. __be16 ox_id, wwn_t port_name, wwn_t node_name,
  225. u16 pdu_size, u16 local_bb_credits, u8 bb_scn)
  226. {
  227. u32 d_id = 0;
  228. u16 bbscn_rxsz = (bb_scn << 12) | pdu_size;
  229. memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
  230. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  231. flogi->els_cmd.els_code = FC_ELS_ACC;
  232. flogi->class3.rxsz = cpu_to_be16(pdu_size);
  233. flogi->csp.rxsz = cpu_to_be16(bbscn_rxsz); /* bb_scn/rxsz */
  234. flogi->port_name = port_name;
  235. flogi->node_name = node_name;
  236. flogi->csp.bbcred = cpu_to_be16(local_bb_credits);
  237. return sizeof(struct fc_logi_s);
  238. }
  239. u16
  240. fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
  241. u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size)
  242. {
  243. u32 d_id = bfa_hton3b(FC_FABRIC_PORT);
  244. memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
  245. flogi->els_cmd.els_code = FC_ELS_FDISC;
  246. fc_els_req_build(fchs, d_id, s_id, ox_id);
  247. flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
  248. flogi->port_name = port_name;
  249. flogi->node_name = node_name;
  250. return sizeof(struct fc_logi_s);
  251. }
  252. u16
  253. fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
  254. u16 ox_id, wwn_t port_name, wwn_t node_name,
  255. u16 pdu_size, u16 bb_cr)
  256. {
  257. return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
  258. node_name, pdu_size, bb_cr, FC_ELS_PLOGI);
  259. }
  260. u16
  261. fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
  262. u16 ox_id, wwn_t port_name, wwn_t node_name,
  263. u16 pdu_size, u16 bb_cr)
  264. {
  265. return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
  266. node_name, pdu_size, bb_cr, FC_ELS_ACC);
  267. }
  268. enum fc_parse_status
  269. fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
  270. {
  271. struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
  272. struct fc_logi_s *plogi;
  273. struct fc_ls_rjt_s *ls_rjt;
  274. switch (els_cmd->els_code) {
  275. case FC_ELS_LS_RJT:
  276. ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1);
  277. if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
  278. return FC_PARSE_BUSY;
  279. else
  280. return FC_PARSE_FAILURE;
  281. case FC_ELS_ACC:
  282. plogi = (struct fc_logi_s *) (fchs + 1);
  283. if (len < sizeof(struct fc_logi_s))
  284. return FC_PARSE_FAILURE;
  285. if (!wwn_is_equal(plogi->port_name, port_name))
  286. return FC_PARSE_FAILURE;
  287. if (!plogi->class3.class_valid)
  288. return FC_PARSE_FAILURE;
  289. if (be16_to_cpu(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
  290. return FC_PARSE_FAILURE;
  291. return FC_PARSE_OK;
  292. default:
  293. return FC_PARSE_FAILURE;
  294. }
  295. }
  296. enum fc_parse_status
  297. fc_plogi_parse(struct fchs_s *fchs)
  298. {
  299. struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1);
  300. if (plogi->class3.class_valid != 1)
  301. return FC_PARSE_FAILURE;
  302. if ((be16_to_cpu(plogi->class3.rxsz) < FC_MIN_PDUSZ)
  303. || (be16_to_cpu(plogi->class3.rxsz) > FC_MAX_PDUSZ)
  304. || (plogi->class3.rxsz == 0))
  305. return FC_PARSE_FAILURE;
  306. return FC_PARSE_OK;
  307. }
  308. u16
  309. fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
  310. u16 ox_id)
  311. {
  312. struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
  313. fc_els_req_build(fchs, d_id, s_id, ox_id);
  314. memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
  315. prli->command = FC_ELS_PRLI;
  316. prli->parampage.servparams.initiator = 1;
  317. prli->parampage.servparams.retry = 1;
  318. prli->parampage.servparams.rec_support = 1;
  319. prli->parampage.servparams.task_retry_id = 0;
  320. prli->parampage.servparams.confirm = 1;
  321. return sizeof(struct fc_prli_s);
  322. }
  323. u16
  324. fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
  325. __be16 ox_id, enum bfa_lport_role role)
  326. {
  327. struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
  328. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  329. memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
  330. prli->command = FC_ELS_ACC;
  331. prli->parampage.servparams.initiator = 1;
  332. prli->parampage.rspcode = FC_PRLI_ACC_XQTD;
  333. return sizeof(struct fc_prli_s);
  334. }
  335. enum fc_parse_status
  336. fc_prli_rsp_parse(struct fc_prli_s *prli, int len)
  337. {
  338. if (len < sizeof(struct fc_prli_s))
  339. return FC_PARSE_FAILURE;
  340. if (prli->command != FC_ELS_ACC)
  341. return FC_PARSE_FAILURE;
  342. if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD)
  343. && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG))
  344. return FC_PARSE_FAILURE;
  345. if (prli->parampage.servparams.target != 1)
  346. return FC_PARSE_FAILURE;
  347. return FC_PARSE_OK;
  348. }
  349. enum fc_parse_status
  350. fc_prli_parse(struct fc_prli_s *prli)
  351. {
  352. if (prli->parampage.type != FC_TYPE_FCP)
  353. return FC_PARSE_FAILURE;
  354. if (!prli->parampage.imagepair)
  355. return FC_PARSE_FAILURE;
  356. if (!prli->parampage.servparams.initiator)
  357. return FC_PARSE_FAILURE;
  358. return FC_PARSE_OK;
  359. }
  360. u16
  361. fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, u32 s_id,
  362. u16 ox_id, wwn_t port_name)
  363. {
  364. fc_els_req_build(fchs, d_id, s_id, ox_id);
  365. memset(logo, '\0', sizeof(struct fc_logo_s));
  366. logo->els_cmd.els_code = FC_ELS_LOGO;
  367. logo->nport_id = (s_id);
  368. logo->orig_port_name = port_name;
  369. return sizeof(struct fc_logo_s);
  370. }
  371. static u16
  372. fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
  373. u32 s_id, __be16 ox_id, wwn_t port_name,
  374. wwn_t node_name, u8 els_code)
  375. {
  376. memset(adisc, '\0', sizeof(struct fc_adisc_s));
  377. adisc->els_cmd.els_code = els_code;
  378. if (els_code == FC_ELS_ADISC)
  379. fc_els_req_build(fchs, d_id, s_id, ox_id);
  380. else
  381. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  382. adisc->orig_HA = 0;
  383. adisc->orig_port_name = port_name;
  384. adisc->orig_node_name = node_name;
  385. adisc->nport_id = (s_id);
  386. return sizeof(struct fc_adisc_s);
  387. }
  388. u16
  389. fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
  390. u32 s_id, __be16 ox_id, wwn_t port_name, wwn_t node_name)
  391. {
  392. return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
  393. node_name, FC_ELS_ADISC);
  394. }
  395. u16
  396. fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
  397. u32 s_id, __be16 ox_id, wwn_t port_name,
  398. wwn_t node_name)
  399. {
  400. return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
  401. node_name, FC_ELS_ACC);
  402. }
  403. enum fc_parse_status
  404. fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name,
  405. wwn_t node_name)
  406. {
  407. if (len < sizeof(struct fc_adisc_s))
  408. return FC_PARSE_FAILURE;
  409. if (adisc->els_cmd.els_code != FC_ELS_ACC)
  410. return FC_PARSE_FAILURE;
  411. if (!wwn_is_equal(adisc->orig_port_name, port_name))
  412. return FC_PARSE_FAILURE;
  413. return FC_PARSE_OK;
  414. }
  415. enum fc_parse_status
  416. fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, wwn_t node_name,
  417. wwn_t port_name)
  418. {
  419. struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld;
  420. if (adisc->els_cmd.els_code != FC_ELS_ACC)
  421. return FC_PARSE_FAILURE;
  422. if ((adisc->nport_id == (host_dap))
  423. && wwn_is_equal(adisc->orig_port_name, port_name)
  424. && wwn_is_equal(adisc->orig_node_name, node_name))
  425. return FC_PARSE_OK;
  426. return FC_PARSE_FAILURE;
  427. }
  428. enum fc_parse_status
  429. fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name)
  430. {
  431. struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
  432. if (pdisc->class3.class_valid != 1)
  433. return FC_PARSE_FAILURE;
  434. if ((be16_to_cpu(pdisc->class3.rxsz) <
  435. (FC_MIN_PDUSZ - sizeof(struct fchs_s)))
  436. || (pdisc->class3.rxsz == 0))
  437. return FC_PARSE_FAILURE;
  438. if (!wwn_is_equal(pdisc->port_name, port_name))
  439. return FC_PARSE_FAILURE;
  440. if (!wwn_is_equal(pdisc->node_name, node_name))
  441. return FC_PARSE_FAILURE;
  442. return FC_PARSE_OK;
  443. }
  444. u16
  445. fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
  446. {
  447. memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s));
  448. fchs->cat_info = FC_CAT_ABTS;
  449. fchs->d_id = (d_id);
  450. fchs->s_id = (s_id);
  451. fchs->ox_id = cpu_to_be16(ox_id);
  452. return sizeof(struct fchs_s);
  453. }
  454. enum fc_parse_status
  455. fc_abts_rsp_parse(struct fchs_s *fchs, int len)
  456. {
  457. if ((fchs->cat_info == FC_CAT_BA_ACC)
  458. || (fchs->cat_info == FC_CAT_BA_RJT))
  459. return FC_PARSE_OK;
  460. return FC_PARSE_FAILURE;
  461. }
  462. u16
  463. fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id,
  464. u16 ox_id, u16 rrq_oxid)
  465. {
  466. fc_els_req_build(fchs, d_id, s_id, ox_id);
  467. /*
  468. * build rrq payload
  469. */
  470. memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s));
  471. rrq->s_id = (s_id);
  472. rrq->ox_id = cpu_to_be16(rrq_oxid);
  473. rrq->rx_id = FC_RXID_ANY;
  474. return sizeof(struct fc_rrq_s);
  475. }
  476. u16
  477. fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
  478. __be16 ox_id)
  479. {
  480. struct fc_els_cmd_s *acc = pld;
  481. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  482. memset(acc, 0, sizeof(struct fc_els_cmd_s));
  483. acc->els_code = FC_ELS_ACC;
  484. return sizeof(struct fc_els_cmd_s);
  485. }
  486. u16
  487. fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
  488. u32 s_id, __be16 ox_id, u8 reason_code,
  489. u8 reason_code_expl)
  490. {
  491. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  492. memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s));
  493. ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT;
  494. ls_rjt->reason_code = reason_code;
  495. ls_rjt->reason_code_expl = reason_code_expl;
  496. ls_rjt->vendor_unique = 0x00;
  497. return sizeof(struct fc_ls_rjt_s);
  498. }
  499. u16
  500. fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
  501. u32 s_id, __be16 ox_id, u16 rx_id)
  502. {
  503. fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
  504. memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s));
  505. fchs->rx_id = rx_id;
  506. ba_acc->ox_id = fchs->ox_id;
  507. ba_acc->rx_id = fchs->rx_id;
  508. return sizeof(struct fc_ba_acc_s);
  509. }
  510. u16
  511. fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, u32 d_id,
  512. u32 s_id, __be16 ox_id)
  513. {
  514. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  515. memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
  516. els_cmd->els_code = FC_ELS_ACC;
  517. return sizeof(struct fc_els_cmd_s);
  518. }
  519. int
  520. fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
  521. {
  522. int num_pages = 0;
  523. struct fc_prlo_s *prlo;
  524. struct fc_tprlo_s *tprlo;
  525. if (els_code == FC_ELS_PRLO) {
  526. prlo = (struct fc_prlo_s *) (fc_frame + 1);
  527. num_pages = (be16_to_cpu(prlo->payload_len) - 4) / 16;
  528. } else {
  529. tprlo = (struct fc_tprlo_s *) (fc_frame + 1);
  530. num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16;
  531. }
  532. return num_pages;
  533. }
  534. u16
  535. fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
  536. u32 d_id, u32 s_id, __be16 ox_id, int num_pages)
  537. {
  538. int page;
  539. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  540. memset(tprlo_acc, 0, (num_pages * 16) + 4);
  541. tprlo_acc->command = FC_ELS_ACC;
  542. tprlo_acc->page_len = 0x10;
  543. tprlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
  544. for (page = 0; page < num_pages; page++) {
  545. tprlo_acc->tprlo_acc_params[page].opa_valid = 0;
  546. tprlo_acc->tprlo_acc_params[page].rpa_valid = 0;
  547. tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
  548. tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
  549. tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
  550. }
  551. return be16_to_cpu(tprlo_acc->payload_len);
  552. }
  553. u16
  554. fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id,
  555. u32 s_id, __be16 ox_id, int num_pages)
  556. {
  557. int page;
  558. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  559. memset(prlo_acc, 0, (num_pages * 16) + 4);
  560. prlo_acc->command = FC_ELS_ACC;
  561. prlo_acc->page_len = 0x10;
  562. prlo_acc->payload_len = cpu_to_be16((num_pages * 16) + 4);
  563. for (page = 0; page < num_pages; page++) {
  564. prlo_acc->prlo_acc_params[page].opa_valid = 0;
  565. prlo_acc->prlo_acc_params[page].rpa_valid = 0;
  566. prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
  567. prlo_acc->prlo_acc_params[page].orig_process_assc = 0;
  568. prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
  569. }
  570. return be16_to_cpu(prlo_acc->payload_len);
  571. }
  572. u16
  573. fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
  574. u32 s_id, u16 ox_id, u32 data_format)
  575. {
  576. fc_els_req_build(fchs, d_id, s_id, ox_id);
  577. memset(rnid, 0, sizeof(struct fc_rnid_cmd_s));
  578. rnid->els_cmd.els_code = FC_ELS_RNID;
  579. rnid->node_id_data_format = data_format;
  580. return sizeof(struct fc_rnid_cmd_s);
  581. }
  582. u16
  583. fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id,
  584. u32 s_id, __be16 ox_id, u32 data_format,
  585. struct fc_rnid_common_id_data_s *common_id_data,
  586. struct fc_rnid_general_topology_data_s *gen_topo_data)
  587. {
  588. memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s));
  589. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  590. rnid_acc->els_cmd.els_code = FC_ELS_ACC;
  591. rnid_acc->node_id_data_format = data_format;
  592. rnid_acc->common_id_data_length =
  593. sizeof(struct fc_rnid_common_id_data_s);
  594. rnid_acc->common_id_data = *common_id_data;
  595. if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
  596. rnid_acc->specific_id_data_length =
  597. sizeof(struct fc_rnid_general_topology_data_s);
  598. rnid_acc->gen_topology_data = *gen_topo_data;
  599. return sizeof(struct fc_rnid_acc_s);
  600. } else {
  601. return sizeof(struct fc_rnid_acc_s) -
  602. sizeof(struct fc_rnid_general_topology_data_s);
  603. }
  604. }
  605. u16
  606. fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id,
  607. u32 s_id, u16 ox_id)
  608. {
  609. fc_els_req_build(fchs, d_id, s_id, ox_id);
  610. memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
  611. rpsc->els_cmd.els_code = FC_ELS_RPSC;
  612. return sizeof(struct fc_rpsc_cmd_s);
  613. }
  614. u16
  615. fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, u32 d_id,
  616. u32 s_id, u32 *pid_list, u16 npids)
  617. {
  618. u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_hton3b(d_id));
  619. int i = 0;
  620. fc_els_req_build(fchs, bfa_hton3b(dctlr_id), s_id, 0);
  621. memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
  622. rpsc2->els_cmd.els_code = FC_ELS_RPSC;
  623. rpsc2->token = cpu_to_be32(FC_BRCD_TOKEN);
  624. rpsc2->num_pids = cpu_to_be16(npids);
  625. for (i = 0; i < npids; i++)
  626. rpsc2->pid_list[i].pid = pid_list[i];
  627. return sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * (sizeof(u32)));
  628. }
  629. u16
  630. fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
  631. u32 d_id, u32 s_id, __be16 ox_id,
  632. struct fc_rpsc_speed_info_s *oper_speed)
  633. {
  634. memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
  635. fc_els_rsp_build(fchs, d_id, s_id, ox_id);
  636. rpsc_acc->command = FC_ELS_ACC;
  637. rpsc_acc->num_entries = cpu_to_be16(1);
  638. rpsc_acc->speed_info[0].port_speed_cap =
  639. cpu_to_be16(oper_speed->port_speed_cap);
  640. rpsc_acc->speed_info[0].port_op_speed =
  641. cpu_to_be16(oper_speed->port_op_speed);
  642. return sizeof(struct fc_rpsc_acc_s);
  643. }
  644. u16
  645. fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
  646. wwn_t port_name, wwn_t node_name, u16 pdu_size)
  647. {
  648. struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
  649. memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
  650. pdisc->els_cmd.els_code = FC_ELS_PDISC;
  651. fc_els_req_build(fchs, d_id, s_id, ox_id);
  652. pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size);
  653. pdisc->port_name = port_name;
  654. pdisc->node_name = node_name;
  655. return sizeof(struct fc_logi_s);
  656. }
  657. u16
  658. fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
  659. {
  660. struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
  661. if (len < sizeof(struct fc_logi_s))
  662. return FC_PARSE_LEN_INVAL;
  663. if (pdisc->els_cmd.els_code != FC_ELS_ACC)
  664. return FC_PARSE_ACC_INVAL;
  665. if (!wwn_is_equal(pdisc->port_name, port_name))
  666. return FC_PARSE_PWWN_NOT_EQUAL;
  667. if (!pdisc->class3.class_valid)
  668. return FC_PARSE_NWWN_NOT_EQUAL;
  669. if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
  670. return FC_PARSE_RXSZ_INVAL;
  671. return FC_PARSE_OK;
  672. }
  673. u16
  674. fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
  675. int num_pages)
  676. {
  677. struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1);
  678. int page;
  679. fc_els_req_build(fchs, d_id, s_id, ox_id);
  680. memset(prlo, 0, (num_pages * 16) + 4);
  681. prlo->command = FC_ELS_PRLO;
  682. prlo->page_len = 0x10;
  683. prlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
  684. for (page = 0; page < num_pages; page++) {
  685. prlo->prlo_params[page].type = FC_TYPE_FCP;
  686. prlo->prlo_params[page].opa_valid = 0;
  687. prlo->prlo_params[page].rpa_valid = 0;
  688. prlo->prlo_params[page].orig_process_assc = 0;
  689. prlo->prlo_params[page].resp_process_assc = 0;
  690. }
  691. return be16_to_cpu(prlo->payload_len);
  692. }
  693. u16
  694. fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
  695. int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id)
  696. {
  697. struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1);
  698. int page;
  699. fc_els_req_build(fchs, d_id, s_id, ox_id);
  700. memset(tprlo, 0, (num_pages * 16) + 4);
  701. tprlo->command = FC_ELS_TPRLO;
  702. tprlo->page_len = 0x10;
  703. tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
  704. for (page = 0; page < num_pages; page++) {
  705. tprlo->tprlo_params[page].type = FC_TYPE_FCP;
  706. tprlo->tprlo_params[page].opa_valid = 0;
  707. tprlo->tprlo_params[page].rpa_valid = 0;
  708. tprlo->tprlo_params[page].orig_process_assc = 0;
  709. tprlo->tprlo_params[page].resp_process_assc = 0;
  710. if (tprlo_type == FC_GLOBAL_LOGO) {
  711. tprlo->tprlo_params[page].global_process_logout = 1;
  712. } else if (tprlo_type == FC_TPR_LOGO) {
  713. tprlo->tprlo_params[page].tpo_nport_valid = 1;
  714. tprlo->tprlo_params[page].tpo_nport_id = (tpr_id);
  715. }
  716. }
  717. return be16_to_cpu(tprlo->payload_len);
  718. }
  719. u16
  720. fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, __be16 ox_id,
  721. u32 reason_code, u32 reason_expl)
  722. {
  723. struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
  724. fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
  725. fchs->cat_info = FC_CAT_BA_RJT;
  726. ba_rjt->reason_code = reason_code;
  727. ba_rjt->reason_expl = reason_expl;
  728. return sizeof(struct fc_ba_rjt_s);
  729. }
  730. static void
  731. fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
  732. {
  733. memset(cthdr, 0, sizeof(struct ct_hdr_s));
  734. cthdr->rev_id = CT_GS3_REVISION;
  735. cthdr->gs_type = CT_GSTYPE_DIRSERVICE;
  736. cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER;
  737. cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
  738. }
  739. static void
  740. fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
  741. {
  742. memset(cthdr, 0, sizeof(struct ct_hdr_s));
  743. cthdr->rev_id = CT_GS3_REVISION;
  744. cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
  745. cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER;
  746. cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
  747. }
  748. static void
  749. fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code,
  750. u8 sub_type)
  751. {
  752. memset(cthdr, 0, sizeof(struct ct_hdr_s));
  753. cthdr->rev_id = CT_GS3_REVISION;
  754. cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
  755. cthdr->gs_sub_type = sub_type;
  756. cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
  757. }
  758. u16
  759. fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  760. wwn_t port_name)
  761. {
  762. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  763. struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1);
  764. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  765. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  766. fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
  767. memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
  768. gidpn->port_name = port_name;
  769. return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s);
  770. }
  771. u16
  772. fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  773. u32 port_id)
  774. {
  775. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  776. fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
  777. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  778. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  779. fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
  780. memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
  781. gpnid->dap = port_id;
  782. return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s);
  783. }
  784. u16
  785. fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  786. u32 port_id)
  787. {
  788. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  789. fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
  790. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  791. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  792. fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
  793. memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
  794. gnnid->dap = port_id;
  795. return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s);
  796. }
  797. u16
  798. fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
  799. {
  800. if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
  801. if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY)
  802. return FC_PARSE_BUSY;
  803. else
  804. return FC_PARSE_FAILURE;
  805. }
  806. return FC_PARSE_OK;
  807. }
  808. u16
  809. fc_gs_rjt_build(struct fchs_s *fchs, struct ct_hdr_s *cthdr,
  810. u32 d_id, u32 s_id, u16 ox_id, u8 reason_code,
  811. u8 reason_code_expl)
  812. {
  813. fc_gsresp_fchdr_build(fchs, d_id, s_id, ox_id);
  814. cthdr->cmd_rsp_code = cpu_to_be16(CT_RSP_REJECT);
  815. cthdr->rev_id = CT_GS3_REVISION;
  816. cthdr->reason_code = reason_code;
  817. cthdr->exp_code = reason_code_expl;
  818. return sizeof(struct ct_hdr_s);
  819. }
  820. u16
  821. fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
  822. u8 set_br_reg, u32 s_id, u16 ox_id)
  823. {
  824. u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
  825. fc_els_req_build(fchs, d_id, s_id, ox_id);
  826. memset(scr, 0, sizeof(struct fc_scr_s));
  827. scr->command = FC_ELS_SCR;
  828. scr->reg_func = FC_SCR_REG_FUNC_FULL;
  829. if (set_br_reg)
  830. scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE;
  831. return sizeof(struct fc_scr_s);
  832. }
  833. u16
  834. fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
  835. u32 s_id, u16 ox_id)
  836. {
  837. u32 d_id = bfa_hton3b(FC_FABRIC_CONTROLLER);
  838. u16 payldlen;
  839. fc_els_req_build(fchs, d_id, s_id, ox_id);
  840. rscn->command = FC_ELS_RSCN;
  841. rscn->pagelen = sizeof(rscn->event[0]);
  842. payldlen = sizeof(u32) + rscn->pagelen;
  843. rscn->payldlen = cpu_to_be16(payldlen);
  844. rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
  845. rscn->event[0].portid = s_id;
  846. return sizeof(struct fc_rscn_pl_s);
  847. }
  848. u16
  849. fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  850. enum bfa_lport_role roles)
  851. {
  852. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  853. struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
  854. u32 type_value, d_id = bfa_hton3b(FC_NAME_SERVER);
  855. u8 index;
  856. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  857. fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
  858. memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
  859. rftid->dap = s_id;
  860. /* By default, FCP FC4 Type is registered */
  861. index = FC_TYPE_FCP >> 5;
  862. type_value = 1 << (FC_TYPE_FCP % 32);
  863. rftid->fc4_type[index] = cpu_to_be32(type_value);
  864. return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
  865. }
  866. u16
  867. fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  868. u8 *fc4_bitmap, u32 bitmap_size)
  869. {
  870. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  871. struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
  872. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  873. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  874. fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
  875. memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
  876. rftid->dap = s_id;
  877. memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
  878. (bitmap_size < 32 ? bitmap_size : 32));
  879. return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
  880. }
  881. u16
  882. fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  883. u8 fc4_type, u8 fc4_ftrs)
  884. {
  885. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  886. struct fcgs_rffid_req_s *rffid = (struct fcgs_rffid_req_s *)(cthdr + 1);
  887. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  888. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  889. fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID);
  890. memset(rffid, 0, sizeof(struct fcgs_rffid_req_s));
  891. rffid->dap = s_id;
  892. rffid->fc4ftr_bits = fc4_ftrs;
  893. rffid->fc4_type = fc4_type;
  894. return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s);
  895. }
  896. u16
  897. fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  898. u8 *name)
  899. {
  900. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  901. struct fcgs_rspnid_req_s *rspnid =
  902. (struct fcgs_rspnid_req_s *)(cthdr + 1);
  903. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  904. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  905. fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID);
  906. memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s));
  907. rspnid->dap = s_id;
  908. strlcpy(rspnid->spn, name, sizeof(rspnid->spn));
  909. rspnid->spn_len = (u8) strlen(rspnid->spn);
  910. return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s);
  911. }
  912. u16
  913. fc_rsnn_nn_build(struct fchs_s *fchs, void *pyld, u32 s_id,
  914. wwn_t node_name, u8 *name)
  915. {
  916. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  917. struct fcgs_rsnn_nn_req_s *rsnn_nn =
  918. (struct fcgs_rsnn_nn_req_s *) (cthdr + 1);
  919. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  920. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  921. fc_gs_cthdr_build(cthdr, s_id, GS_RSNN_NN);
  922. memset(rsnn_nn, 0, sizeof(struct fcgs_rsnn_nn_req_s));
  923. rsnn_nn->node_name = node_name;
  924. strlcpy(rsnn_nn->snn, name, sizeof(rsnn_nn->snn));
  925. rsnn_nn->snn_len = (u8) strlen(rsnn_nn->snn);
  926. return sizeof(struct fcgs_rsnn_nn_req_s) + sizeof(struct ct_hdr_s);
  927. }
  928. u16
  929. fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type)
  930. {
  931. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  932. struct fcgs_gidft_req_s *gidft = (struct fcgs_gidft_req_s *)(cthdr + 1);
  933. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  934. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  935. fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT);
  936. memset(gidft, 0, sizeof(struct fcgs_gidft_req_s));
  937. gidft->fc4_type = fc4_type;
  938. gidft->domain_id = 0;
  939. gidft->area_id = 0;
  940. return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s);
  941. }
  942. u16
  943. fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
  944. wwn_t port_name)
  945. {
  946. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  947. struct fcgs_rpnid_req_s *rpnid = (struct fcgs_rpnid_req_s *)(cthdr + 1);
  948. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  949. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  950. fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID);
  951. memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s));
  952. rpnid->port_id = port_id;
  953. rpnid->port_name = port_name;
  954. return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s);
  955. }
  956. u16
  957. fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
  958. wwn_t node_name)
  959. {
  960. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  961. struct fcgs_rnnid_req_s *rnnid = (struct fcgs_rnnid_req_s *)(cthdr + 1);
  962. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  963. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  964. fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID);
  965. memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s));
  966. rnnid->port_id = port_id;
  967. rnnid->node_name = node_name;
  968. return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s);
  969. }
  970. u16
  971. fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
  972. u32 cos)
  973. {
  974. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  975. struct fcgs_rcsid_req_s *rcsid =
  976. (struct fcgs_rcsid_req_s *) (cthdr + 1);
  977. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  978. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  979. fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID);
  980. memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s));
  981. rcsid->port_id = port_id;
  982. rcsid->cos = cos;
  983. return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s);
  984. }
  985. u16
  986. fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
  987. u8 port_type)
  988. {
  989. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  990. struct fcgs_rptid_req_s *rptid = (struct fcgs_rptid_req_s *)(cthdr + 1);
  991. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  992. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  993. fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID);
  994. memset(rptid, 0, sizeof(struct fcgs_rptid_req_s));
  995. rptid->port_id = port_id;
  996. rptid->port_type = port_type;
  997. return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s);
  998. }
  999. u16
  1000. fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id)
  1001. {
  1002. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1003. struct fcgs_ganxt_req_s *ganxt = (struct fcgs_ganxt_req_s *)(cthdr + 1);
  1004. u32 d_id = bfa_hton3b(FC_NAME_SERVER);
  1005. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1006. fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT);
  1007. memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
  1008. ganxt->port_id = port_id;
  1009. return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s);
  1010. }
  1011. /*
  1012. * Builds fc hdr and ct hdr for FDMI requests.
  1013. */
  1014. u16
  1015. fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
  1016. u16 cmd_code)
  1017. {
  1018. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1019. u32 d_id = bfa_hton3b(FC_MGMT_SERVER);
  1020. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1021. fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
  1022. return sizeof(struct ct_hdr_s);
  1023. }
  1024. /*
  1025. * Given a FC4 Type, this function returns a fc4 type bitmask
  1026. */
  1027. void
  1028. fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask)
  1029. {
  1030. u8 index;
  1031. __be32 *ptr = (__be32 *) bit_mask;
  1032. u32 type_value;
  1033. /*
  1034. * @todo : Check for bitmask size
  1035. */
  1036. index = fc4_type >> 5;
  1037. type_value = 1 << (fc4_type % 32);
  1038. ptr[index] = cpu_to_be32(type_value);
  1039. }
  1040. /*
  1041. * GMAL Request
  1042. */
  1043. u16
  1044. fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
  1045. {
  1046. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1047. fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1);
  1048. u32 d_id = bfa_hton3b(FC_MGMT_SERVER);
  1049. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1050. fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD,
  1051. CT_GSSUBTYPE_CFGSERVER);
  1052. memset(gmal, 0, sizeof(fcgs_gmal_req_t));
  1053. gmal->wwn = wwn;
  1054. return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t);
  1055. }
  1056. /*
  1057. * GFN (Get Fabric Name) Request
  1058. */
  1059. u16
  1060. fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
  1061. {
  1062. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1063. fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1);
  1064. u32 d_id = bfa_hton3b(FC_MGMT_SERVER);
  1065. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1066. fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,
  1067. CT_GSSUBTYPE_CFGSERVER);
  1068. memset(gfn, 0, sizeof(fcgs_gfn_req_t));
  1069. gfn->wwn = wwn;
  1070. return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t);
  1071. }