fcbuild.c 37 KB

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