bfa_fcbuild.c 36 KB

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