ns.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242
  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. * @page ns_sm_info VPORT NS State Machine
  19. *
  20. * @section ns_sm_interactions VPORT NS State Machine Interactions
  21. *
  22. * @section ns_sm VPORT NS State Machine
  23. * img ns_sm.jpg
  24. */
  25. #include <bfa.h>
  26. #include <bfa_svc.h>
  27. #include <bfa_iocfc.h>
  28. #include "fcs_lport.h"
  29. #include "fcs_rport.h"
  30. #include "fcs_trcmod.h"
  31. #include "fcs_fcxp.h"
  32. #include "fcs.h"
  33. #include "lport_priv.h"
  34. BFA_TRC_FILE(FCS, NS);
  35. /*
  36. * forward declarations
  37. */
  38. static void bfa_fcs_port_ns_send_plogi(void *ns_cbarg,
  39. struct bfa_fcxp_s *fcxp_alloced);
  40. static void bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg,
  41. struct bfa_fcxp_s *fcxp_alloced);
  42. static void bfa_fcs_port_ns_send_rft_id(void *ns_cbarg,
  43. struct bfa_fcxp_s *fcxp_alloced);
  44. static void bfa_fcs_port_ns_send_rff_id(void *ns_cbarg,
  45. struct bfa_fcxp_s *fcxp_alloced);
  46. static void bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg,
  47. struct bfa_fcxp_s *fcxp_alloced);
  48. static void bfa_fcs_port_ns_timeout(void *arg);
  49. static void bfa_fcs_port_ns_plogi_response(void *fcsarg,
  50. struct bfa_fcxp_s *fcxp,
  51. void *cbarg,
  52. bfa_status_t req_status,
  53. u32 rsp_len,
  54. u32 resid_len,
  55. struct fchs_s *rsp_fchs);
  56. static void bfa_fcs_port_ns_rspn_id_response(void *fcsarg,
  57. struct bfa_fcxp_s *fcxp,
  58. void *cbarg,
  59. bfa_status_t req_status,
  60. u32 rsp_len,
  61. u32 resid_len,
  62. struct fchs_s *rsp_fchs);
  63. static void bfa_fcs_port_ns_rft_id_response(void *fcsarg,
  64. struct bfa_fcxp_s *fcxp,
  65. void *cbarg,
  66. bfa_status_t req_status,
  67. u32 rsp_len,
  68. u32 resid_len,
  69. struct fchs_s *rsp_fchs);
  70. static void bfa_fcs_port_ns_rff_id_response(void *fcsarg,
  71. struct bfa_fcxp_s *fcxp,
  72. void *cbarg,
  73. bfa_status_t req_status,
  74. u32 rsp_len,
  75. u32 resid_len,
  76. struct fchs_s *rsp_fchs);
  77. static void bfa_fcs_port_ns_gid_ft_response(void *fcsarg,
  78. struct bfa_fcxp_s *fcxp,
  79. void *cbarg,
  80. bfa_status_t req_status,
  81. u32 rsp_len,
  82. u32 resid_len,
  83. struct fchs_s *rsp_fchs);
  84. static void bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
  85. u32 *pid_buf,
  86. u32 n_pids);
  87. static void bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port);
  88. /**
  89. * fcs_ns_sm FCS nameserver interface state machine
  90. */
  91. /**
  92. * VPort NS State Machine events
  93. */
  94. enum vport_ns_event {
  95. NSSM_EVENT_PORT_ONLINE = 1,
  96. NSSM_EVENT_PORT_OFFLINE = 2,
  97. NSSM_EVENT_PLOGI_SENT = 3,
  98. NSSM_EVENT_RSP_OK = 4,
  99. NSSM_EVENT_RSP_ERROR = 5,
  100. NSSM_EVENT_TIMEOUT = 6,
  101. NSSM_EVENT_NS_QUERY = 7,
  102. NSSM_EVENT_RSPNID_SENT = 8,
  103. NSSM_EVENT_RFTID_SENT = 9,
  104. NSSM_EVENT_RFFID_SENT = 10,
  105. NSSM_EVENT_GIDFT_SENT = 11,
  106. };
  107. static void bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
  108. enum vport_ns_event event);
  109. static void bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
  110. enum vport_ns_event event);
  111. static void bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
  112. enum vport_ns_event event);
  113. static void bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
  114. enum vport_ns_event event);
  115. static void bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
  116. enum vport_ns_event event);
  117. static void bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
  118. enum vport_ns_event event);
  119. static void bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
  120. enum vport_ns_event event);
  121. static void bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
  122. enum vport_ns_event event);
  123. static void bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
  124. enum vport_ns_event event);
  125. static void bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
  126. enum vport_ns_event event);
  127. static void bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
  128. enum vport_ns_event event);
  129. static void bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
  130. enum vport_ns_event event);
  131. static void bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
  132. enum vport_ns_event event);
  133. static void bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
  134. enum vport_ns_event event);
  135. static void bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
  136. enum vport_ns_event event);
  137. static void bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
  138. enum vport_ns_event event);
  139. static void bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
  140. enum vport_ns_event event);
  141. /**
  142. * Start in offline state - awaiting linkup
  143. */
  144. static void
  145. bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
  146. enum vport_ns_event event)
  147. {
  148. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  149. bfa_trc(ns->port->fcs, event);
  150. switch (event) {
  151. case NSSM_EVENT_PORT_ONLINE:
  152. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending);
  153. bfa_fcs_port_ns_send_plogi(ns, NULL);
  154. break;
  155. case NSSM_EVENT_PORT_OFFLINE:
  156. break;
  157. default:
  158. bfa_assert(0);
  159. }
  160. }
  161. static void
  162. bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
  163. enum vport_ns_event event)
  164. {
  165. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  166. bfa_trc(ns->port->fcs, event);
  167. switch (event) {
  168. case NSSM_EVENT_PLOGI_SENT:
  169. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi);
  170. break;
  171. case NSSM_EVENT_PORT_OFFLINE:
  172. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  173. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
  174. &ns->fcxp_wqe);
  175. break;
  176. default:
  177. bfa_assert(0);
  178. }
  179. }
  180. static void
  181. bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
  182. enum vport_ns_event event)
  183. {
  184. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  185. bfa_trc(ns->port->fcs, event);
  186. switch (event) {
  187. case NSSM_EVENT_RSP_ERROR:
  188. /*
  189. * Start timer for a delayed retry
  190. */
  191. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_retry);
  192. ns->port->stats.ns_retries++;
  193. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
  194. bfa_fcs_port_ns_timeout, ns,
  195. BFA_FCS_RETRY_TIMEOUT);
  196. break;
  197. case NSSM_EVENT_RSP_OK:
  198. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id);
  199. bfa_fcs_port_ns_send_rspn_id(ns, NULL);
  200. break;
  201. case NSSM_EVENT_PORT_OFFLINE:
  202. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  203. bfa_fcxp_discard(ns->fcxp);
  204. break;
  205. default:
  206. bfa_assert(0);
  207. }
  208. }
  209. static void
  210. bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
  211. enum vport_ns_event event)
  212. {
  213. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  214. bfa_trc(ns->port->fcs, event);
  215. switch (event) {
  216. case NSSM_EVENT_TIMEOUT:
  217. /*
  218. * Retry Timer Expired. Re-send
  219. */
  220. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending);
  221. bfa_fcs_port_ns_send_plogi(ns, NULL);
  222. break;
  223. case NSSM_EVENT_PORT_OFFLINE:
  224. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  225. bfa_timer_stop(&ns->timer);
  226. break;
  227. default:
  228. bfa_assert(0);
  229. }
  230. }
  231. static void
  232. bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
  233. enum vport_ns_event event)
  234. {
  235. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  236. bfa_trc(ns->port->fcs, event);
  237. switch (event) {
  238. case NSSM_EVENT_RSPNID_SENT:
  239. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id);
  240. break;
  241. case NSSM_EVENT_PORT_OFFLINE:
  242. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  243. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
  244. &ns->fcxp_wqe);
  245. break;
  246. default:
  247. bfa_assert(0);
  248. }
  249. }
  250. static void
  251. bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
  252. enum vport_ns_event event)
  253. {
  254. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  255. bfa_trc(ns->port->fcs, event);
  256. switch (event) {
  257. case NSSM_EVENT_RSP_ERROR:
  258. /*
  259. * Start timer for a delayed retry
  260. */
  261. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id_retry);
  262. ns->port->stats.ns_retries++;
  263. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
  264. bfa_fcs_port_ns_timeout, ns,
  265. BFA_FCS_RETRY_TIMEOUT);
  266. break;
  267. case NSSM_EVENT_RSP_OK:
  268. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rft_id);
  269. bfa_fcs_port_ns_send_rft_id(ns, NULL);
  270. break;
  271. case NSSM_EVENT_PORT_OFFLINE:
  272. bfa_fcxp_discard(ns->fcxp);
  273. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  274. break;
  275. default:
  276. bfa_assert(0);
  277. }
  278. }
  279. static void
  280. bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
  281. enum vport_ns_event event)
  282. {
  283. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  284. bfa_trc(ns->port->fcs, event);
  285. switch (event) {
  286. case NSSM_EVENT_TIMEOUT:
  287. /*
  288. * Retry Timer Expired. Re-send
  289. */
  290. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id);
  291. bfa_fcs_port_ns_send_rspn_id(ns, NULL);
  292. break;
  293. case NSSM_EVENT_PORT_OFFLINE:
  294. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  295. bfa_timer_stop(&ns->timer);
  296. break;
  297. default:
  298. bfa_assert(0);
  299. }
  300. }
  301. static void
  302. bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
  303. enum vport_ns_event event)
  304. {
  305. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  306. bfa_trc(ns->port->fcs, event);
  307. switch (event) {
  308. case NSSM_EVENT_RFTID_SENT:
  309. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id);
  310. break;
  311. case NSSM_EVENT_PORT_OFFLINE:
  312. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  313. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
  314. &ns->fcxp_wqe);
  315. break;
  316. default:
  317. bfa_assert(0);
  318. }
  319. }
  320. static void
  321. bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
  322. enum vport_ns_event event)
  323. {
  324. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  325. bfa_trc(ns->port->fcs, event);
  326. switch (event) {
  327. case NSSM_EVENT_RSP_OK:
  328. /*
  329. * Now move to register FC4 Features
  330. */
  331. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id);
  332. bfa_fcs_port_ns_send_rff_id(ns, NULL);
  333. break;
  334. case NSSM_EVENT_RSP_ERROR:
  335. /*
  336. * Start timer for a delayed retry
  337. */
  338. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id_retry);
  339. ns->port->stats.ns_retries++;
  340. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
  341. bfa_fcs_port_ns_timeout, ns,
  342. BFA_FCS_RETRY_TIMEOUT);
  343. break;
  344. case NSSM_EVENT_PORT_OFFLINE:
  345. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  346. bfa_fcxp_discard(ns->fcxp);
  347. break;
  348. default:
  349. bfa_assert(0);
  350. }
  351. }
  352. static void
  353. bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
  354. enum vport_ns_event event)
  355. {
  356. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  357. bfa_trc(ns->port->fcs, event);
  358. switch (event) {
  359. case NSSM_EVENT_TIMEOUT:
  360. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rft_id);
  361. bfa_fcs_port_ns_send_rft_id(ns, NULL);
  362. break;
  363. case NSSM_EVENT_PORT_OFFLINE:
  364. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  365. bfa_timer_stop(&ns->timer);
  366. break;
  367. default:
  368. bfa_assert(0);
  369. }
  370. }
  371. static void
  372. bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
  373. enum vport_ns_event event)
  374. {
  375. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  376. bfa_trc(ns->port->fcs, event);
  377. switch (event) {
  378. case NSSM_EVENT_RFFID_SENT:
  379. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id);
  380. break;
  381. case NSSM_EVENT_PORT_OFFLINE:
  382. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  383. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
  384. &ns->fcxp_wqe);
  385. break;
  386. default:
  387. bfa_assert(0);
  388. }
  389. }
  390. static void
  391. bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
  392. enum vport_ns_event event)
  393. {
  394. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  395. bfa_trc(ns->port->fcs, event);
  396. switch (event) {
  397. case NSSM_EVENT_RSP_OK:
  398. /*
  399. * If min cfg mode is enabled, we donot initiate rport
  400. * discovery with the fabric. Instead, we will retrieve the
  401. * boot targets from HAL/FW.
  402. */
  403. if (__fcs_min_cfg(ns->port->fcs)) {
  404. bfa_fcs_port_ns_boot_target_disc(ns->port);
  405. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
  406. return;
  407. }
  408. /*
  409. * If the port role is Initiator Mode issue NS query.
  410. * If it is Target Mode, skip this and go to online.
  411. */
  412. if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
  413. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
  414. bfa_fcs_port_ns_send_gid_ft(ns, NULL);
  415. } else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) {
  416. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
  417. }
  418. /*
  419. * kick off mgmt srvr state machine
  420. */
  421. bfa_fcs_port_ms_online(ns->port);
  422. break;
  423. case NSSM_EVENT_RSP_ERROR:
  424. /*
  425. * Start timer for a delayed retry
  426. */
  427. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id_retry);
  428. ns->port->stats.ns_retries++;
  429. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
  430. bfa_fcs_port_ns_timeout, ns,
  431. BFA_FCS_RETRY_TIMEOUT);
  432. break;
  433. case NSSM_EVENT_PORT_OFFLINE:
  434. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  435. bfa_fcxp_discard(ns->fcxp);
  436. break;
  437. default:
  438. bfa_assert(0);
  439. }
  440. }
  441. static void
  442. bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
  443. enum vport_ns_event event)
  444. {
  445. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  446. bfa_trc(ns->port->fcs, event);
  447. switch (event) {
  448. case NSSM_EVENT_TIMEOUT:
  449. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id);
  450. bfa_fcs_port_ns_send_rff_id(ns, NULL);
  451. break;
  452. case NSSM_EVENT_PORT_OFFLINE:
  453. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  454. bfa_timer_stop(&ns->timer);
  455. break;
  456. default:
  457. bfa_assert(0);
  458. }
  459. }
  460. static void
  461. bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
  462. enum vport_ns_event event)
  463. {
  464. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  465. bfa_trc(ns->port->fcs, event);
  466. switch (event) {
  467. case NSSM_EVENT_GIDFT_SENT:
  468. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft);
  469. break;
  470. case NSSM_EVENT_PORT_OFFLINE:
  471. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  472. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
  473. &ns->fcxp_wqe);
  474. break;
  475. default:
  476. bfa_assert(0);
  477. }
  478. }
  479. static void
  480. bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
  481. enum vport_ns_event event)
  482. {
  483. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  484. bfa_trc(ns->port->fcs, event);
  485. switch (event) {
  486. case NSSM_EVENT_RSP_OK:
  487. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
  488. break;
  489. case NSSM_EVENT_RSP_ERROR:
  490. /*
  491. * TBD: for certain reject codes, we don't need to retry
  492. */
  493. /*
  494. * Start timer for a delayed retry
  495. */
  496. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft_retry);
  497. ns->port->stats.ns_retries++;
  498. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
  499. bfa_fcs_port_ns_timeout, ns,
  500. BFA_FCS_RETRY_TIMEOUT);
  501. break;
  502. case NSSM_EVENT_PORT_OFFLINE:
  503. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  504. bfa_fcxp_discard(ns->fcxp);
  505. break;
  506. default:
  507. bfa_assert(0);
  508. }
  509. }
  510. static void
  511. bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
  512. enum vport_ns_event event)
  513. {
  514. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  515. bfa_trc(ns->port->fcs, event);
  516. switch (event) {
  517. case NSSM_EVENT_TIMEOUT:
  518. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
  519. bfa_fcs_port_ns_send_gid_ft(ns, NULL);
  520. break;
  521. case NSSM_EVENT_PORT_OFFLINE:
  522. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  523. bfa_timer_stop(&ns->timer);
  524. break;
  525. default:
  526. bfa_assert(0);
  527. }
  528. }
  529. static void
  530. bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
  531. enum vport_ns_event event)
  532. {
  533. bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
  534. bfa_trc(ns->port->fcs, event);
  535. switch (event) {
  536. case NSSM_EVENT_PORT_OFFLINE:
  537. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  538. break;
  539. case NSSM_EVENT_NS_QUERY:
  540. /*
  541. * If the port role is Initiator Mode issue NS query.
  542. * If it is Target Mode, skip this and go to online.
  543. */
  544. if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
  545. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
  546. bfa_fcs_port_ns_send_gid_ft(ns, NULL);
  547. };
  548. break;
  549. default:
  550. bfa_assert(0);
  551. }
  552. }
  553. /**
  554. * ns_pvt Nameserver local functions
  555. */
  556. static void
  557. bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  558. {
  559. struct bfa_fcs_port_ns_s *ns = ns_cbarg;
  560. struct bfa_fcs_port_s *port = ns->port;
  561. struct fchs_s fchs;
  562. int len;
  563. struct bfa_fcxp_s *fcxp;
  564. bfa_trc(port->fcs, port->pid);
  565. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  566. if (!fcxp) {
  567. port->stats.ns_plogi_alloc_wait++;
  568. bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
  569. bfa_fcs_port_ns_send_plogi, ns);
  570. return;
  571. }
  572. ns->fcxp = fcxp;
  573. len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  574. bfa_os_hton3b(FC_NAME_SERVER),
  575. bfa_fcs_port_get_fcid(port), 0,
  576. port->port_cfg.pwwn, port->port_cfg.nwwn,
  577. bfa_pport_get_maxfrsize(port->fcs->bfa));
  578. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  579. FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response,
  580. (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
  581. port->stats.ns_plogi_sent++;
  582. bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
  583. }
  584. static void
  585. bfa_fcs_port_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  586. void *cbarg, bfa_status_t req_status,
  587. u32 rsp_len, u32 resid_len,
  588. struct fchs_s *rsp_fchs)
  589. {
  590. struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
  591. struct bfa_fcs_port_s *port = ns->port;
  592. /* struct fc_logi_s *plogi_resp; */
  593. struct fc_els_cmd_s *els_cmd;
  594. struct fc_ls_rjt_s *ls_rjt;
  595. bfa_trc(port->fcs, req_status);
  596. bfa_trc(port->fcs, port->port_cfg.pwwn);
  597. /*
  598. * Sanity Checks
  599. */
  600. if (req_status != BFA_STATUS_OK) {
  601. bfa_trc(port->fcs, req_status);
  602. port->stats.ns_plogi_rsp_err++;
  603. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  604. return;
  605. }
  606. els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
  607. switch (els_cmd->els_code) {
  608. case FC_ELS_ACC:
  609. if (rsp_len < sizeof(struct fc_logi_s)) {
  610. bfa_trc(port->fcs, rsp_len);
  611. port->stats.ns_plogi_acc_err++;
  612. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  613. break;
  614. }
  615. port->stats.ns_plogi_accepts++;
  616. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  617. break;
  618. case FC_ELS_LS_RJT:
  619. ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
  620. bfa_trc(port->fcs, ls_rjt->reason_code);
  621. bfa_trc(port->fcs, ls_rjt->reason_code_expl);
  622. port->stats.ns_rejects++;
  623. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  624. break;
  625. default:
  626. port->stats.ns_plogi_unknown_rsp++;
  627. bfa_trc(port->fcs, els_cmd->els_code);
  628. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  629. }
  630. }
  631. /**
  632. * Register the symbolic port name.
  633. */
  634. static void
  635. bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  636. {
  637. struct bfa_fcs_port_ns_s *ns = ns_cbarg;
  638. struct bfa_fcs_port_s *port = ns->port;
  639. struct fchs_s fchs;
  640. int len;
  641. struct bfa_fcxp_s *fcxp;
  642. u8 symbl[256];
  643. u8 *psymbl = &symbl[0];
  644. bfa_os_memset(symbl, 0, sizeof(symbl));
  645. bfa_trc(port->fcs, port->port_cfg.pwwn);
  646. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  647. if (!fcxp) {
  648. port->stats.ns_rspnid_alloc_wait++;
  649. bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
  650. bfa_fcs_port_ns_send_rspn_id, ns);
  651. return;
  652. }
  653. ns->fcxp = fcxp;
  654. /*
  655. * for V-Port, form a Port Symbolic Name
  656. */
  657. if (port->vport) {
  658. /**For Vports,
  659. * we append the vport's port symbolic name to that of the base port.
  660. */
  661. strncpy((char *)psymbl,
  662. (char *)
  663. &(bfa_fcs_port_get_psym_name
  664. (bfa_fcs_get_base_port(port->fcs))),
  665. strlen((char *)
  666. &bfa_fcs_port_get_psym_name(bfa_fcs_get_base_port
  667. (port->fcs))));
  668. /*
  669. * Ensure we have a null terminating string.
  670. */
  671. ((char *)
  672. psymbl)[strlen((char *)
  673. &bfa_fcs_port_get_psym_name
  674. (bfa_fcs_get_base_port(port->fcs)))] = 0;
  675. strncat((char *)psymbl,
  676. (char *)&(bfa_fcs_port_get_psym_name(port)),
  677. strlen((char *)&bfa_fcs_port_get_psym_name(port)));
  678. } else {
  679. psymbl = (u8 *) &(bfa_fcs_port_get_psym_name(port));
  680. }
  681. len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  682. bfa_fcs_port_get_fcid(port), 0, psymbl);
  683. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  684. FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rspn_id_response,
  685. (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
  686. port->stats.ns_rspnid_sent++;
  687. bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
  688. }
  689. static void
  690. bfa_fcs_port_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  691. void *cbarg, bfa_status_t req_status,
  692. u32 rsp_len, u32 resid_len,
  693. struct fchs_s *rsp_fchs)
  694. {
  695. struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
  696. struct bfa_fcs_port_s *port = ns->port;
  697. struct ct_hdr_s *cthdr = NULL;
  698. bfa_trc(port->fcs, port->port_cfg.pwwn);
  699. /*
  700. * Sanity Checks
  701. */
  702. if (req_status != BFA_STATUS_OK) {
  703. bfa_trc(port->fcs, req_status);
  704. port->stats.ns_rspnid_rsp_err++;
  705. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  706. return;
  707. }
  708. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  709. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  710. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  711. port->stats.ns_rspnid_accepts++;
  712. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  713. return;
  714. }
  715. port->stats.ns_rspnid_rejects++;
  716. bfa_trc(port->fcs, cthdr->reason_code);
  717. bfa_trc(port->fcs, cthdr->exp_code);
  718. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  719. }
  720. /**
  721. * Register FC4-Types
  722. * TBD, Need to retrieve this from the OS driver, in case IPFC is enabled ?
  723. */
  724. static void
  725. bfa_fcs_port_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  726. {
  727. struct bfa_fcs_port_ns_s *ns = ns_cbarg;
  728. struct bfa_fcs_port_s *port = ns->port;
  729. struct fchs_s fchs;
  730. int len;
  731. struct bfa_fcxp_s *fcxp;
  732. bfa_trc(port->fcs, port->port_cfg.pwwn);
  733. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  734. if (!fcxp) {
  735. port->stats.ns_rftid_alloc_wait++;
  736. bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
  737. bfa_fcs_port_ns_send_rft_id, ns);
  738. return;
  739. }
  740. ns->fcxp = fcxp;
  741. len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  742. bfa_fcs_port_get_fcid(port), 0,
  743. port->port_cfg.roles);
  744. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  745. FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rft_id_response,
  746. (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
  747. port->stats.ns_rftid_sent++;
  748. bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
  749. }
  750. static void
  751. bfa_fcs_port_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  752. void *cbarg, bfa_status_t req_status,
  753. u32 rsp_len, u32 resid_len,
  754. struct fchs_s *rsp_fchs)
  755. {
  756. struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
  757. struct bfa_fcs_port_s *port = ns->port;
  758. struct ct_hdr_s *cthdr = NULL;
  759. bfa_trc(port->fcs, port->port_cfg.pwwn);
  760. /*
  761. * Sanity Checks
  762. */
  763. if (req_status != BFA_STATUS_OK) {
  764. bfa_trc(port->fcs, req_status);
  765. port->stats.ns_rftid_rsp_err++;
  766. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  767. return;
  768. }
  769. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  770. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  771. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  772. port->stats.ns_rftid_accepts++;
  773. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  774. return;
  775. }
  776. port->stats.ns_rftid_rejects++;
  777. bfa_trc(port->fcs, cthdr->reason_code);
  778. bfa_trc(port->fcs, cthdr->exp_code);
  779. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  780. }
  781. /**
  782. * Register FC4-Features : Should be done after RFT_ID
  783. */
  784. static void
  785. bfa_fcs_port_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  786. {
  787. struct bfa_fcs_port_ns_s *ns = ns_cbarg;
  788. struct bfa_fcs_port_s *port = ns->port;
  789. struct fchs_s fchs;
  790. int len;
  791. struct bfa_fcxp_s *fcxp;
  792. u8 fc4_ftrs = 0;
  793. bfa_trc(port->fcs, port->port_cfg.pwwn);
  794. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  795. if (!fcxp) {
  796. port->stats.ns_rffid_alloc_wait++;
  797. bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
  798. bfa_fcs_port_ns_send_rff_id, ns);
  799. return;
  800. }
  801. ns->fcxp = fcxp;
  802. if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port))
  803. fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
  804. else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port))
  805. fc4_ftrs = FC_GS_FCP_FC4_FEATURE_TARGET;
  806. len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  807. bfa_fcs_port_get_fcid(port), 0, FC_TYPE_FCP,
  808. fc4_ftrs);
  809. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  810. FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rff_id_response,
  811. (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
  812. port->stats.ns_rffid_sent++;
  813. bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
  814. }
  815. static void
  816. bfa_fcs_port_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  817. void *cbarg, bfa_status_t req_status,
  818. u32 rsp_len, u32 resid_len,
  819. struct fchs_s *rsp_fchs)
  820. {
  821. struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
  822. struct bfa_fcs_port_s *port = ns->port;
  823. struct ct_hdr_s *cthdr = NULL;
  824. bfa_trc(port->fcs, port->port_cfg.pwwn);
  825. /*
  826. * Sanity Checks
  827. */
  828. if (req_status != BFA_STATUS_OK) {
  829. bfa_trc(port->fcs, req_status);
  830. port->stats.ns_rffid_rsp_err++;
  831. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  832. return;
  833. }
  834. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  835. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  836. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  837. port->stats.ns_rffid_accepts++;
  838. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  839. return;
  840. }
  841. port->stats.ns_rffid_rejects++;
  842. bfa_trc(port->fcs, cthdr->reason_code);
  843. bfa_trc(port->fcs, cthdr->exp_code);
  844. if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
  845. /*
  846. * if this command is not supported, we don't retry
  847. */
  848. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  849. } else {
  850. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  851. }
  852. }
  853. /**
  854. * Query Fabric for FC4-Types Devices.
  855. *
  856. * TBD : Need to use a local (FCS private) response buffer, since the response
  857. * can be larger than 2K.
  858. */
  859. static void
  860. bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  861. {
  862. struct bfa_fcs_port_ns_s *ns = ns_cbarg;
  863. struct bfa_fcs_port_s *port = ns->port;
  864. struct fchs_s fchs;
  865. int len;
  866. struct bfa_fcxp_s *fcxp;
  867. bfa_trc(port->fcs, port->pid);
  868. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  869. if (!fcxp) {
  870. port->stats.ns_gidft_alloc_wait++;
  871. bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
  872. bfa_fcs_port_ns_send_gid_ft, ns);
  873. return;
  874. }
  875. ns->fcxp = fcxp;
  876. /*
  877. * This query is only initiated for FCP initiator mode.
  878. */
  879. len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ns->port->pid,
  880. FC_TYPE_FCP);
  881. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  882. FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_gid_ft_response,
  883. (void *)ns, bfa_fcxp_get_maxrsp(port->fcs->bfa),
  884. FC_RA_TOV);
  885. port->stats.ns_gidft_sent++;
  886. bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
  887. }
  888. static void
  889. bfa_fcs_port_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  890. void *cbarg, bfa_status_t req_status,
  891. u32 rsp_len, u32 resid_len,
  892. struct fchs_s *rsp_fchs)
  893. {
  894. struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
  895. struct bfa_fcs_port_s *port = ns->port;
  896. struct ct_hdr_s *cthdr = NULL;
  897. u32 n_pids;
  898. bfa_trc(port->fcs, port->port_cfg.pwwn);
  899. /*
  900. * Sanity Checks
  901. */
  902. if (req_status != BFA_STATUS_OK) {
  903. bfa_trc(port->fcs, req_status);
  904. port->stats.ns_gidft_rsp_err++;
  905. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  906. return;
  907. }
  908. if (resid_len != 0) {
  909. /*
  910. * TBD : we will need to allocate a larger buffer & retry the
  911. * command
  912. */
  913. bfa_trc(port->fcs, rsp_len);
  914. bfa_trc(port->fcs, resid_len);
  915. return;
  916. }
  917. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  918. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  919. switch (cthdr->cmd_rsp_code) {
  920. case CT_RSP_ACCEPT:
  921. port->stats.ns_gidft_accepts++;
  922. n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
  923. bfa_trc(port->fcs, n_pids);
  924. bfa_fcs_port_ns_process_gidft_pids(port,
  925. (u32 *) (cthdr + 1),
  926. n_pids);
  927. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  928. break;
  929. case CT_RSP_REJECT:
  930. /*
  931. * Check the reason code & explanation.
  932. * There may not have been any FC4 devices in the fabric
  933. */
  934. port->stats.ns_gidft_rejects++;
  935. bfa_trc(port->fcs, cthdr->reason_code);
  936. bfa_trc(port->fcs, cthdr->exp_code);
  937. if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
  938. && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
  939. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  940. } else {
  941. /*
  942. * for all other errors, retry
  943. */
  944. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  945. }
  946. break;
  947. default:
  948. port->stats.ns_gidft_unknown_rsp++;
  949. bfa_trc(port->fcs, cthdr->cmd_rsp_code);
  950. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  951. }
  952. }
  953. /**
  954. * This routine will be called by bfa_timer on timer timeouts.
  955. *
  956. * param[in] port - pointer to bfa_fcs_port_t.
  957. *
  958. * return
  959. * void
  960. *
  961. * Special Considerations:
  962. *
  963. * note
  964. */
  965. static void
  966. bfa_fcs_port_ns_timeout(void *arg)
  967. {
  968. struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)arg;
  969. ns->port->stats.ns_timeouts++;
  970. bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
  971. }
  972. /*
  973. * Process the PID list in GID_FT response
  974. */
  975. static void
  976. bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
  977. u32 *pid_buf, u32 n_pids)
  978. {
  979. struct fcgs_gidft_resp_s *gidft_entry;
  980. struct bfa_fcs_rport_s *rport;
  981. u32 ii;
  982. for (ii = 0; ii < n_pids; ii++) {
  983. gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
  984. if (gidft_entry->pid == port->pid)
  985. continue;
  986. /*
  987. * Check if this rport already exists
  988. */
  989. rport = bfa_fcs_port_get_rport_by_pid(port, gidft_entry->pid);
  990. if (rport == NULL) {
  991. /*
  992. * this is a new device. create rport
  993. */
  994. rport = bfa_fcs_rport_create(port, gidft_entry->pid);
  995. } else {
  996. /*
  997. * this rport already exists
  998. */
  999. bfa_fcs_rport_scn(rport);
  1000. }
  1001. bfa_trc(port->fcs, gidft_entry->pid);
  1002. /*
  1003. * if the last entry bit is set, bail out.
  1004. */
  1005. if (gidft_entry->last)
  1006. return;
  1007. }
  1008. }
  1009. /**
  1010. * fcs_ns_public FCS nameserver public interfaces
  1011. */
  1012. /*
  1013. * Functions called by port/fab.
  1014. * These will send relevant Events to the ns state machine.
  1015. */
  1016. void
  1017. bfa_fcs_port_ns_init(struct bfa_fcs_port_s *port)
  1018. {
  1019. struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
  1020. ns->port = port;
  1021. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  1022. }
  1023. void
  1024. bfa_fcs_port_ns_offline(struct bfa_fcs_port_s *port)
  1025. {
  1026. struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
  1027. ns->port = port;
  1028. bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
  1029. }
  1030. void
  1031. bfa_fcs_port_ns_online(struct bfa_fcs_port_s *port)
  1032. {
  1033. struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
  1034. ns->port = port;
  1035. bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
  1036. }
  1037. void
  1038. bfa_fcs_port_ns_query(struct bfa_fcs_port_s *port)
  1039. {
  1040. struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
  1041. bfa_trc(port->fcs, port->pid);
  1042. bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
  1043. }
  1044. static void
  1045. bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port)
  1046. {
  1047. struct bfa_fcs_rport_s *rport;
  1048. u8 nwwns;
  1049. wwn_t *wwns;
  1050. int ii;
  1051. bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, &wwns);
  1052. for (ii = 0; ii < nwwns; ++ii) {
  1053. rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
  1054. bfa_assert(rport);
  1055. }
  1056. }