bfa_fcbuild.c 36 KB

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