ns.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  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. }
  807. len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  808. bfa_fcs_port_get_fcid(port), 0, FC_TYPE_FCP,
  809. fc4_ftrs);
  810. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  811. FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rff_id_response,
  812. (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
  813. port->stats.ns_rffid_sent++;
  814. bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
  815. }
  816. static void
  817. bfa_fcs_port_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  818. void *cbarg, bfa_status_t req_status,
  819. u32 rsp_len, u32 resid_len,
  820. struct fchs_s *rsp_fchs)
  821. {
  822. struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
  823. struct bfa_fcs_port_s *port = ns->port;
  824. struct ct_hdr_s *cthdr = NULL;
  825. bfa_trc(port->fcs, port->port_cfg.pwwn);
  826. /*
  827. * Sanity Checks
  828. */
  829. if (req_status != BFA_STATUS_OK) {
  830. bfa_trc(port->fcs, req_status);
  831. port->stats.ns_rffid_rsp_err++;
  832. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  833. return;
  834. }
  835. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  836. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  837. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  838. port->stats.ns_rffid_accepts++;
  839. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  840. return;
  841. }
  842. port->stats.ns_rffid_rejects++;
  843. bfa_trc(port->fcs, cthdr->reason_code);
  844. bfa_trc(port->fcs, cthdr->exp_code);
  845. if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
  846. /*
  847. * if this command is not supported, we don't retry
  848. */
  849. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  850. } else {
  851. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  852. }
  853. }
  854. /**
  855. * Query Fabric for FC4-Types Devices.
  856. *
  857. * TBD : Need to use a local (FCS private) response buffer, since the response
  858. * can be larger than 2K.
  859. */
  860. static void
  861. bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  862. {
  863. struct bfa_fcs_port_ns_s *ns = ns_cbarg;
  864. struct bfa_fcs_port_s *port = ns->port;
  865. struct fchs_s fchs;
  866. int len;
  867. struct bfa_fcxp_s *fcxp;
  868. bfa_trc(port->fcs, port->pid);
  869. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  870. if (!fcxp) {
  871. port->stats.ns_gidft_alloc_wait++;
  872. bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
  873. bfa_fcs_port_ns_send_gid_ft, ns);
  874. return;
  875. }
  876. ns->fcxp = fcxp;
  877. /*
  878. * This query is only initiated for FCP initiator mode.
  879. */
  880. len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ns->port->pid,
  881. FC_TYPE_FCP);
  882. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  883. FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_gid_ft_response,
  884. (void *)ns, bfa_fcxp_get_maxrsp(port->fcs->bfa),
  885. FC_RA_TOV);
  886. port->stats.ns_gidft_sent++;
  887. bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
  888. }
  889. static void
  890. bfa_fcs_port_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  891. void *cbarg, bfa_status_t req_status,
  892. u32 rsp_len, u32 resid_len,
  893. struct fchs_s *rsp_fchs)
  894. {
  895. struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
  896. struct bfa_fcs_port_s *port = ns->port;
  897. struct ct_hdr_s *cthdr = NULL;
  898. u32 n_pids;
  899. bfa_trc(port->fcs, port->port_cfg.pwwn);
  900. /*
  901. * Sanity Checks
  902. */
  903. if (req_status != BFA_STATUS_OK) {
  904. bfa_trc(port->fcs, req_status);
  905. port->stats.ns_gidft_rsp_err++;
  906. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  907. return;
  908. }
  909. if (resid_len != 0) {
  910. /*
  911. * TBD : we will need to allocate a larger buffer & retry the
  912. * command
  913. */
  914. bfa_trc(port->fcs, rsp_len);
  915. bfa_trc(port->fcs, resid_len);
  916. return;
  917. }
  918. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  919. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  920. switch (cthdr->cmd_rsp_code) {
  921. case CT_RSP_ACCEPT:
  922. port->stats.ns_gidft_accepts++;
  923. n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
  924. bfa_trc(port->fcs, n_pids);
  925. bfa_fcs_port_ns_process_gidft_pids(port,
  926. (u32 *) (cthdr + 1),
  927. n_pids);
  928. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  929. break;
  930. case CT_RSP_REJECT:
  931. /*
  932. * Check the reason code & explanation.
  933. * There may not have been any FC4 devices in the fabric
  934. */
  935. port->stats.ns_gidft_rejects++;
  936. bfa_trc(port->fcs, cthdr->reason_code);
  937. bfa_trc(port->fcs, cthdr->exp_code);
  938. if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
  939. && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
  940. bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
  941. } else {
  942. /*
  943. * for all other errors, retry
  944. */
  945. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  946. }
  947. break;
  948. default:
  949. port->stats.ns_gidft_unknown_rsp++;
  950. bfa_trc(port->fcs, cthdr->cmd_rsp_code);
  951. bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
  952. }
  953. }
  954. /**
  955. * This routine will be called by bfa_timer on timer timeouts.
  956. *
  957. * param[in] port - pointer to bfa_fcs_port_t.
  958. *
  959. * return
  960. * void
  961. *
  962. * Special Considerations:
  963. *
  964. * note
  965. */
  966. static void
  967. bfa_fcs_port_ns_timeout(void *arg)
  968. {
  969. struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)arg;
  970. ns->port->stats.ns_timeouts++;
  971. bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
  972. }
  973. /*
  974. * Process the PID list in GID_FT response
  975. */
  976. static void
  977. bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
  978. u32 *pid_buf, u32 n_pids)
  979. {
  980. struct fcgs_gidft_resp_s *gidft_entry;
  981. struct bfa_fcs_rport_s *rport;
  982. u32 ii;
  983. for (ii = 0; ii < n_pids; ii++) {
  984. gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
  985. if (gidft_entry->pid == port->pid)
  986. continue;
  987. /*
  988. * Check if this rport already exists
  989. */
  990. rport = bfa_fcs_port_get_rport_by_pid(port, gidft_entry->pid);
  991. if (rport == NULL) {
  992. /*
  993. * this is a new device. create rport
  994. */
  995. rport = bfa_fcs_rport_create(port, gidft_entry->pid);
  996. } else {
  997. /*
  998. * this rport already exists
  999. */
  1000. bfa_fcs_rport_scn(rport);
  1001. }
  1002. bfa_trc(port->fcs, gidft_entry->pid);
  1003. /*
  1004. * if the last entry bit is set, bail out.
  1005. */
  1006. if (gidft_entry->last)
  1007. return;
  1008. }
  1009. }
  1010. /**
  1011. * fcs_ns_public FCS nameserver public interfaces
  1012. */
  1013. /*
  1014. * Functions called by port/fab.
  1015. * These will send relevant Events to the ns state machine.
  1016. */
  1017. void
  1018. bfa_fcs_port_ns_init(struct bfa_fcs_port_s *port)
  1019. {
  1020. struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
  1021. ns->port = port;
  1022. bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
  1023. }
  1024. void
  1025. bfa_fcs_port_ns_offline(struct bfa_fcs_port_s *port)
  1026. {
  1027. struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
  1028. ns->port = port;
  1029. bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
  1030. }
  1031. void
  1032. bfa_fcs_port_ns_online(struct bfa_fcs_port_s *port)
  1033. {
  1034. struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
  1035. ns->port = port;
  1036. bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
  1037. }
  1038. void
  1039. bfa_fcs_port_ns_query(struct bfa_fcs_port_s *port)
  1040. {
  1041. struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
  1042. bfa_trc(port->fcs, port->pid);
  1043. bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
  1044. }
  1045. static void
  1046. bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port)
  1047. {
  1048. struct bfa_fcs_rport_s *rport;
  1049. u8 nwwns;
  1050. wwn_t *wwns;
  1051. int ii;
  1052. bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, &wwns);
  1053. for (ii = 0; ii < nwwns; ++ii) {
  1054. rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
  1055. bfa_assert(rport);
  1056. }
  1057. }