bfa_fcbuild.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410
  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 "bfa_os_inc.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. u16 ox_id);
  27. static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
  28. u16 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_os_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_os_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_os_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_os_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_os_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_os_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, u16 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, u16 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, u16 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. u16 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_os_hton3b(FC_FABRIC_PORT);
  207. u32 *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. u16 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_os_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. u16 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, u16 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, u16 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, u16 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. u16 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, u16 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, u16 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, u16 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, u16 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, u16 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, u16 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_os_hton3b(d_id));
  624. int i = 0;
  625. fc_els_req_build(fchs, bfa_os_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, u16 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. /*
  650. * TBD -
  651. * . get rid of unnecessary memsets
  652. */
  653. u16
  654. fc_logo_rsp_parse(struct fchs_s *fchs, int len)
  655. {
  656. struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
  657. len = len;
  658. if (els_cmd->els_code != FC_ELS_ACC)
  659. return FC_PARSE_FAILURE;
  660. return FC_PARSE_OK;
  661. }
  662. u16
  663. fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
  664. wwn_t port_name, wwn_t node_name, u16 pdu_size)
  665. {
  666. struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
  667. memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
  668. pdisc->els_cmd.els_code = FC_ELS_PDISC;
  669. fc_els_req_build(fchs, d_id, s_id, ox_id);
  670. pdisc->csp.rxsz = pdisc->class3.rxsz = cpu_to_be16(pdu_size);
  671. pdisc->port_name = port_name;
  672. pdisc->node_name = node_name;
  673. return sizeof(struct fc_logi_s);
  674. }
  675. u16
  676. fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
  677. {
  678. struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
  679. if (len < sizeof(struct fc_logi_s))
  680. return FC_PARSE_LEN_INVAL;
  681. if (pdisc->els_cmd.els_code != FC_ELS_ACC)
  682. return FC_PARSE_ACC_INVAL;
  683. if (!wwn_is_equal(pdisc->port_name, port_name))
  684. return FC_PARSE_PWWN_NOT_EQUAL;
  685. if (!pdisc->class3.class_valid)
  686. return FC_PARSE_NWWN_NOT_EQUAL;
  687. if (be16_to_cpu(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
  688. return FC_PARSE_RXSZ_INVAL;
  689. return FC_PARSE_OK;
  690. }
  691. u16
  692. fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
  693. int num_pages)
  694. {
  695. struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1);
  696. int page;
  697. fc_els_req_build(fchs, d_id, s_id, ox_id);
  698. memset(prlo, 0, (num_pages * 16) + 4);
  699. prlo->command = FC_ELS_PRLO;
  700. prlo->page_len = 0x10;
  701. prlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
  702. for (page = 0; page < num_pages; page++) {
  703. prlo->prlo_params[page].type = FC_TYPE_FCP;
  704. prlo->prlo_params[page].opa_valid = 0;
  705. prlo->prlo_params[page].rpa_valid = 0;
  706. prlo->prlo_params[page].orig_process_assc = 0;
  707. prlo->prlo_params[page].resp_process_assc = 0;
  708. }
  709. return be16_to_cpu(prlo->payload_len);
  710. }
  711. u16
  712. fc_prlo_rsp_parse(struct fchs_s *fchs, int len)
  713. {
  714. struct fc_prlo_acc_s *prlo = (struct fc_prlo_acc_s *) (fchs + 1);
  715. int num_pages = 0;
  716. int page = 0;
  717. len = len;
  718. if (prlo->command != FC_ELS_ACC)
  719. return FC_PARSE_FAILURE;
  720. num_pages = ((be16_to_cpu(prlo->payload_len)) - 4) / 16;
  721. for (page = 0; page < num_pages; page++) {
  722. if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP)
  723. return FC_PARSE_FAILURE;
  724. if (prlo->prlo_acc_params[page].opa_valid != 0)
  725. return FC_PARSE_FAILURE;
  726. if (prlo->prlo_acc_params[page].rpa_valid != 0)
  727. return FC_PARSE_FAILURE;
  728. if (prlo->prlo_acc_params[page].orig_process_assc != 0)
  729. return FC_PARSE_FAILURE;
  730. if (prlo->prlo_acc_params[page].resp_process_assc != 0)
  731. return FC_PARSE_FAILURE;
  732. }
  733. return FC_PARSE_OK;
  734. }
  735. u16
  736. fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
  737. int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id)
  738. {
  739. struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1);
  740. int page;
  741. fc_els_req_build(fchs, d_id, s_id, ox_id);
  742. memset(tprlo, 0, (num_pages * 16) + 4);
  743. tprlo->command = FC_ELS_TPRLO;
  744. tprlo->page_len = 0x10;
  745. tprlo->payload_len = cpu_to_be16((num_pages * 16) + 4);
  746. for (page = 0; page < num_pages; page++) {
  747. tprlo->tprlo_params[page].type = FC_TYPE_FCP;
  748. tprlo->tprlo_params[page].opa_valid = 0;
  749. tprlo->tprlo_params[page].rpa_valid = 0;
  750. tprlo->tprlo_params[page].orig_process_assc = 0;
  751. tprlo->tprlo_params[page].resp_process_assc = 0;
  752. if (tprlo_type == FC_GLOBAL_LOGO) {
  753. tprlo->tprlo_params[page].global_process_logout = 1;
  754. } else if (tprlo_type == FC_TPR_LOGO) {
  755. tprlo->tprlo_params[page].tpo_nport_valid = 1;
  756. tprlo->tprlo_params[page].tpo_nport_id = (tpr_id);
  757. }
  758. }
  759. return be16_to_cpu(tprlo->payload_len);
  760. }
  761. u16
  762. fc_tprlo_rsp_parse(struct fchs_s *fchs, int len)
  763. {
  764. struct fc_tprlo_acc_s *tprlo = (struct fc_tprlo_acc_s *) (fchs + 1);
  765. int num_pages = 0;
  766. int page = 0;
  767. len = len;
  768. if (tprlo->command != FC_ELS_ACC)
  769. return FC_PARSE_ACC_INVAL;
  770. num_pages = (be16_to_cpu(tprlo->payload_len) - 4) / 16;
  771. for (page = 0; page < num_pages; page++) {
  772. if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP)
  773. return FC_PARSE_NOT_FCP;
  774. if (tprlo->tprlo_acc_params[page].opa_valid != 0)
  775. return FC_PARSE_OPAFLAG_INVAL;
  776. if (tprlo->tprlo_acc_params[page].rpa_valid != 0)
  777. return FC_PARSE_RPAFLAG_INVAL;
  778. if (tprlo->tprlo_acc_params[page].orig_process_assc != 0)
  779. return FC_PARSE_OPA_INVAL;
  780. if (tprlo->tprlo_acc_params[page].resp_process_assc != 0)
  781. return FC_PARSE_RPA_INVAL;
  782. }
  783. return FC_PARSE_OK;
  784. }
  785. enum fc_parse_status
  786. fc_rrq_rsp_parse(struct fchs_s *fchs, int len)
  787. {
  788. struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
  789. len = len;
  790. if (els_cmd->els_code != FC_ELS_ACC)
  791. return FC_PARSE_FAILURE;
  792. return FC_PARSE_OK;
  793. }
  794. u16
  795. fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
  796. u32 reason_code, u32 reason_expl)
  797. {
  798. struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
  799. fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
  800. fchs->cat_info = FC_CAT_BA_RJT;
  801. ba_rjt->reason_code = reason_code;
  802. ba_rjt->reason_expl = reason_expl;
  803. return sizeof(struct fc_ba_rjt_s);
  804. }
  805. static void
  806. fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
  807. {
  808. memset(cthdr, 0, sizeof(struct ct_hdr_s));
  809. cthdr->rev_id = CT_GS3_REVISION;
  810. cthdr->gs_type = CT_GSTYPE_DIRSERVICE;
  811. cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER;
  812. cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
  813. }
  814. static void
  815. fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
  816. {
  817. memset(cthdr, 0, sizeof(struct ct_hdr_s));
  818. cthdr->rev_id = CT_GS3_REVISION;
  819. cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
  820. cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER;
  821. cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
  822. }
  823. static void
  824. fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code,
  825. u8 sub_type)
  826. {
  827. memset(cthdr, 0, sizeof(struct ct_hdr_s));
  828. cthdr->rev_id = CT_GS3_REVISION;
  829. cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
  830. cthdr->gs_sub_type = sub_type;
  831. cthdr->cmd_rsp_code = cpu_to_be16(cmd_code);
  832. }
  833. u16
  834. fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  835. wwn_t port_name)
  836. {
  837. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  838. struct fcgs_gidpn_req_s *gidpn = (struct fcgs_gidpn_req_s *)(cthdr + 1);
  839. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  840. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  841. fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
  842. memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
  843. gidpn->port_name = port_name;
  844. return sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s);
  845. }
  846. u16
  847. fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  848. u32 port_id)
  849. {
  850. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  851. fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
  852. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  853. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  854. fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
  855. memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
  856. gpnid->dap = port_id;
  857. return sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s);
  858. }
  859. u16
  860. fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  861. u32 port_id)
  862. {
  863. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  864. fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
  865. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  866. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  867. fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
  868. memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
  869. gnnid->dap = port_id;
  870. return sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s);
  871. }
  872. u16
  873. fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
  874. {
  875. if (be16_to_cpu(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
  876. if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY)
  877. return FC_PARSE_BUSY;
  878. else
  879. return FC_PARSE_FAILURE;
  880. }
  881. return FC_PARSE_OK;
  882. }
  883. u16
  884. fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
  885. u8 set_br_reg, u32 s_id, u16 ox_id)
  886. {
  887. u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER);
  888. fc_els_req_build(fchs, d_id, s_id, ox_id);
  889. memset(scr, 0, sizeof(struct fc_scr_s));
  890. scr->command = FC_ELS_SCR;
  891. scr->reg_func = FC_SCR_REG_FUNC_FULL;
  892. if (set_br_reg)
  893. scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE;
  894. return sizeof(struct fc_scr_s);
  895. }
  896. u16
  897. fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
  898. u32 s_id, u16 ox_id)
  899. {
  900. u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER);
  901. u16 payldlen;
  902. fc_els_req_build(fchs, d_id, s_id, ox_id);
  903. rscn->command = FC_ELS_RSCN;
  904. rscn->pagelen = sizeof(rscn->event[0]);
  905. payldlen = sizeof(u32) + rscn->pagelen;
  906. rscn->payldlen = cpu_to_be16(payldlen);
  907. rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
  908. rscn->event[0].portid = s_id;
  909. return sizeof(struct fc_rscn_pl_s);
  910. }
  911. u16
  912. fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  913. enum bfa_lport_role roles)
  914. {
  915. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  916. struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
  917. u32 type_value, d_id = bfa_os_hton3b(FC_NAME_SERVER);
  918. u8 index;
  919. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  920. fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
  921. memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
  922. rftid->dap = s_id;
  923. /* By default, FCP FC4 Type is registered */
  924. index = FC_TYPE_FCP >> 5;
  925. type_value = 1 << (FC_TYPE_FCP % 32);
  926. rftid->fc4_type[index] = cpu_to_be32(type_value);
  927. return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
  928. }
  929. u16
  930. fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  931. u8 *fc4_bitmap, u32 bitmap_size)
  932. {
  933. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  934. struct fcgs_rftid_req_s *rftid = (struct fcgs_rftid_req_s *)(cthdr + 1);
  935. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  936. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  937. fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
  938. memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
  939. rftid->dap = s_id;
  940. memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
  941. (bitmap_size < 32 ? bitmap_size : 32));
  942. return sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s);
  943. }
  944. u16
  945. fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  946. u8 fc4_type, u8 fc4_ftrs)
  947. {
  948. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  949. struct fcgs_rffid_req_s *rffid = (struct fcgs_rffid_req_s *)(cthdr + 1);
  950. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  951. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  952. fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID);
  953. memset(rffid, 0, sizeof(struct fcgs_rffid_req_s));
  954. rffid->dap = s_id;
  955. rffid->fc4ftr_bits = fc4_ftrs;
  956. rffid->fc4_type = fc4_type;
  957. return sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s);
  958. }
  959. u16
  960. fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
  961. u8 *name)
  962. {
  963. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  964. struct fcgs_rspnid_req_s *rspnid =
  965. (struct fcgs_rspnid_req_s *)(cthdr + 1);
  966. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  967. fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
  968. fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID);
  969. memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s));
  970. rspnid->dap = s_id;
  971. rspnid->spn_len = (u8) strlen((char *)name);
  972. strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len);
  973. return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s);
  974. }
  975. u16
  976. fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, u8 fc4_type)
  977. {
  978. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  979. struct fcgs_gidft_req_s *gidft = (struct fcgs_gidft_req_s *)(cthdr + 1);
  980. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  981. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  982. fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT);
  983. memset(gidft, 0, sizeof(struct fcgs_gidft_req_s));
  984. gidft->fc4_type = fc4_type;
  985. gidft->domain_id = 0;
  986. gidft->area_id = 0;
  987. return sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s);
  988. }
  989. u16
  990. fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
  991. wwn_t port_name)
  992. {
  993. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  994. struct fcgs_rpnid_req_s *rpnid = (struct fcgs_rpnid_req_s *)(cthdr + 1);
  995. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  996. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  997. fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID);
  998. memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s));
  999. rpnid->port_id = port_id;
  1000. rpnid->port_name = port_name;
  1001. return sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s);
  1002. }
  1003. u16
  1004. fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
  1005. wwn_t node_name)
  1006. {
  1007. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1008. struct fcgs_rnnid_req_s *rnnid = (struct fcgs_rnnid_req_s *)(cthdr + 1);
  1009. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  1010. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1011. fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID);
  1012. memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s));
  1013. rnnid->port_id = port_id;
  1014. rnnid->node_name = node_name;
  1015. return sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s);
  1016. }
  1017. u16
  1018. fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
  1019. u32 cos)
  1020. {
  1021. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1022. struct fcgs_rcsid_req_s *rcsid =
  1023. (struct fcgs_rcsid_req_s *) (cthdr + 1);
  1024. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  1025. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1026. fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID);
  1027. memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s));
  1028. rcsid->port_id = port_id;
  1029. rcsid->cos = cos;
  1030. return sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s);
  1031. }
  1032. u16
  1033. fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
  1034. u8 port_type)
  1035. {
  1036. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1037. struct fcgs_rptid_req_s *rptid = (struct fcgs_rptid_req_s *)(cthdr + 1);
  1038. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  1039. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1040. fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID);
  1041. memset(rptid, 0, sizeof(struct fcgs_rptid_req_s));
  1042. rptid->port_id = port_id;
  1043. rptid->port_type = port_type;
  1044. return sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s);
  1045. }
  1046. u16
  1047. fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id)
  1048. {
  1049. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1050. struct fcgs_ganxt_req_s *ganxt = (struct fcgs_ganxt_req_s *)(cthdr + 1);
  1051. u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
  1052. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1053. fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT);
  1054. memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
  1055. ganxt->port_id = port_id;
  1056. return sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s);
  1057. }
  1058. /*
  1059. * Builds fc hdr and ct hdr for FDMI requests.
  1060. */
  1061. u16
  1062. fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
  1063. u16 cmd_code)
  1064. {
  1065. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1066. u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
  1067. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1068. fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
  1069. return sizeof(struct ct_hdr_s);
  1070. }
  1071. /*
  1072. * Given a FC4 Type, this function returns a fc4 type bitmask
  1073. */
  1074. void
  1075. fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask)
  1076. {
  1077. u8 index;
  1078. u32 *ptr = (u32 *) bit_mask;
  1079. u32 type_value;
  1080. /*
  1081. * @todo : Check for bitmask size
  1082. */
  1083. index = fc4_type >> 5;
  1084. type_value = 1 << (fc4_type % 32);
  1085. ptr[index] = cpu_to_be32(type_value);
  1086. }
  1087. /*
  1088. * GMAL Request
  1089. */
  1090. u16
  1091. fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
  1092. {
  1093. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1094. fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1);
  1095. u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
  1096. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1097. fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD,
  1098. CT_GSSUBTYPE_CFGSERVER);
  1099. memset(gmal, 0, sizeof(fcgs_gmal_req_t));
  1100. gmal->wwn = wwn;
  1101. return sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t);
  1102. }
  1103. /*
  1104. * GFN (Get Fabric Name) Request
  1105. */
  1106. u16
  1107. fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
  1108. {
  1109. struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
  1110. fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1);
  1111. u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
  1112. fc_gs_fchdr_build(fchs, d_id, s_id, 0);
  1113. fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,
  1114. CT_GSSUBTYPE_CFGSERVER);
  1115. memset(gfn, 0, sizeof(fcgs_gfn_req_t));
  1116. gfn->wwn = wwn;
  1117. return sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t);
  1118. }