ms.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  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. #include <bfa.h>
  18. #include <bfa_svc.h>
  19. #include "fcs_lport.h"
  20. #include "fcs_rport.h"
  21. #include "fcs_trcmod.h"
  22. #include "fcs_fcxp.h"
  23. #include "lport_priv.h"
  24. BFA_TRC_FILE(FCS, MS);
  25. #define BFA_FCS_MS_CMD_MAX_RETRIES 2
  26. /*
  27. * forward declarations
  28. */
  29. static void bfa_fcs_port_ms_send_plogi(void *ms_cbarg,
  30. struct bfa_fcxp_s *fcxp_alloced);
  31. static void bfa_fcs_port_ms_timeout(void *arg);
  32. static void bfa_fcs_port_ms_plogi_response(void *fcsarg,
  33. struct bfa_fcxp_s *fcxp,
  34. void *cbarg,
  35. bfa_status_t req_status,
  36. u32 rsp_len,
  37. u32 resid_len,
  38. struct fchs_s *rsp_fchs);
  39. static void bfa_fcs_port_ms_send_gmal(void *ms_cbarg,
  40. struct bfa_fcxp_s *fcxp_alloced);
  41. static void bfa_fcs_port_ms_gmal_response(void *fcsarg,
  42. struct bfa_fcxp_s *fcxp,
  43. void *cbarg,
  44. bfa_status_t req_status,
  45. u32 rsp_len,
  46. u32 resid_len,
  47. struct fchs_s *rsp_fchs);
  48. static void bfa_fcs_port_ms_send_gfn(void *ms_cbarg,
  49. struct bfa_fcxp_s *fcxp_alloced);
  50. static void bfa_fcs_port_ms_gfn_response(void *fcsarg,
  51. struct bfa_fcxp_s *fcxp,
  52. void *cbarg,
  53. bfa_status_t req_status,
  54. u32 rsp_len,
  55. u32 resid_len,
  56. struct fchs_s *rsp_fchs);
  57. /**
  58. * fcs_ms_sm FCS MS state machine
  59. */
  60. /**
  61. * MS State Machine events
  62. */
  63. enum port_ms_event {
  64. MSSM_EVENT_PORT_ONLINE = 1,
  65. MSSM_EVENT_PORT_OFFLINE = 2,
  66. MSSM_EVENT_RSP_OK = 3,
  67. MSSM_EVENT_RSP_ERROR = 4,
  68. MSSM_EVENT_TIMEOUT = 5,
  69. MSSM_EVENT_FCXP_SENT = 6,
  70. MSSM_EVENT_PORT_FABRIC_RSCN = 7
  71. };
  72. static void bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
  73. enum port_ms_event event);
  74. static void bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
  75. enum port_ms_event event);
  76. static void bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms,
  77. enum port_ms_event event);
  78. static void bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
  79. enum port_ms_event event);
  80. static void bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
  81. enum port_ms_event event);
  82. static void bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms,
  83. enum port_ms_event event);
  84. static void bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
  85. enum port_ms_event event);
  86. static void bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
  87. enum port_ms_event event);
  88. static void bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms,
  89. enum port_ms_event event);
  90. static void bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
  91. enum port_ms_event event);
  92. static void bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
  93. enum port_ms_event event);
  94. /**
  95. * Start in offline state - awaiting NS to send start.
  96. */
  97. static void
  98. bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
  99. enum port_ms_event event)
  100. {
  101. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  102. bfa_trc(ms->port->fcs, event);
  103. switch (event) {
  104. case MSSM_EVENT_PORT_ONLINE:
  105. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_sending);
  106. bfa_fcs_port_ms_send_plogi(ms, NULL);
  107. break;
  108. case MSSM_EVENT_PORT_OFFLINE:
  109. break;
  110. default:
  111. bfa_sm_fault(ms->port->fcs, event);
  112. }
  113. }
  114. static void
  115. bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
  116. enum port_ms_event event)
  117. {
  118. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  119. bfa_trc(ms->port->fcs, event);
  120. switch (event) {
  121. case MSSM_EVENT_FCXP_SENT:
  122. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi);
  123. break;
  124. case MSSM_EVENT_PORT_OFFLINE:
  125. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  126. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
  127. &ms->fcxp_wqe);
  128. break;
  129. default:
  130. bfa_sm_fault(ms->port->fcs, event);
  131. }
  132. }
  133. static void
  134. bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
  135. {
  136. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  137. bfa_trc(ms->port->fcs, event);
  138. switch (event) {
  139. case MSSM_EVENT_RSP_ERROR:
  140. /*
  141. * Start timer for a delayed retry
  142. */
  143. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_retry);
  144. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), &ms->timer,
  145. bfa_fcs_port_ms_timeout, ms,
  146. BFA_FCS_RETRY_TIMEOUT);
  147. break;
  148. case MSSM_EVENT_RSP_OK:
  149. /*
  150. * since plogi is done, now invoke MS related sub-modules
  151. */
  152. bfa_fcs_port_fdmi_online(ms);
  153. /**
  154. * if this is a Vport, go to online state.
  155. */
  156. if (ms->port->vport) {
  157. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
  158. break;
  159. }
  160. /*
  161. * For a base port we need to get the
  162. * switch's IP address.
  163. */
  164. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending);
  165. bfa_fcs_port_ms_send_gmal(ms, NULL);
  166. break;
  167. case MSSM_EVENT_PORT_OFFLINE:
  168. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  169. bfa_fcxp_discard(ms->fcxp);
  170. break;
  171. default:
  172. bfa_sm_fault(ms->port->fcs, event);
  173. }
  174. }
  175. static void
  176. bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
  177. enum port_ms_event event)
  178. {
  179. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  180. bfa_trc(ms->port->fcs, event);
  181. switch (event) {
  182. case MSSM_EVENT_TIMEOUT:
  183. /*
  184. * Retry Timer Expired. Re-send
  185. */
  186. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_sending);
  187. bfa_fcs_port_ms_send_plogi(ms, NULL);
  188. break;
  189. case MSSM_EVENT_PORT_OFFLINE:
  190. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  191. bfa_timer_stop(&ms->timer);
  192. break;
  193. default:
  194. bfa_sm_fault(ms->port->fcs, event);
  195. }
  196. }
  197. static void
  198. bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
  199. enum port_ms_event event)
  200. {
  201. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  202. bfa_trc(ms->port->fcs, event);
  203. switch (event) {
  204. case MSSM_EVENT_PORT_OFFLINE:
  205. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  206. break;
  207. case MSSM_EVENT_PORT_FABRIC_RSCN:
  208. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
  209. ms->retry_cnt = 0;
  210. bfa_fcs_port_ms_send_gfn(ms, NULL);
  211. break;
  212. default:
  213. bfa_sm_fault(ms->port->fcs, event);
  214. }
  215. }
  216. static void
  217. bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
  218. enum port_ms_event event)
  219. {
  220. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  221. bfa_trc(ms->port->fcs, event);
  222. switch (event) {
  223. case MSSM_EVENT_FCXP_SENT:
  224. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal);
  225. break;
  226. case MSSM_EVENT_PORT_OFFLINE:
  227. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  228. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
  229. &ms->fcxp_wqe);
  230. break;
  231. default:
  232. bfa_sm_fault(ms->port->fcs, event);
  233. }
  234. }
  235. static void
  236. bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
  237. {
  238. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  239. bfa_trc(ms->port->fcs, event);
  240. switch (event) {
  241. case MSSM_EVENT_RSP_ERROR:
  242. /*
  243. * Start timer for a delayed retry
  244. */
  245. if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
  246. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_retry);
  247. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
  248. &ms->timer, bfa_fcs_port_ms_timeout, ms,
  249. BFA_FCS_RETRY_TIMEOUT);
  250. } else {
  251. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
  252. bfa_fcs_port_ms_send_gfn(ms, NULL);
  253. ms->retry_cnt = 0;
  254. }
  255. break;
  256. case MSSM_EVENT_RSP_OK:
  257. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
  258. bfa_fcs_port_ms_send_gfn(ms, NULL);
  259. break;
  260. case MSSM_EVENT_PORT_OFFLINE:
  261. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  262. bfa_fcxp_discard(ms->fcxp);
  263. break;
  264. default:
  265. bfa_sm_fault(ms->port->fcs, event);
  266. }
  267. }
  268. static void
  269. bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
  270. enum port_ms_event event)
  271. {
  272. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  273. bfa_trc(ms->port->fcs, event);
  274. switch (event) {
  275. case MSSM_EVENT_TIMEOUT:
  276. /*
  277. * Retry Timer Expired. Re-send
  278. */
  279. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending);
  280. bfa_fcs_port_ms_send_gmal(ms, NULL);
  281. break;
  282. case MSSM_EVENT_PORT_OFFLINE:
  283. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  284. bfa_timer_stop(&ms->timer);
  285. break;
  286. default:
  287. bfa_sm_fault(ms->port->fcs, event);
  288. }
  289. }
  290. /**
  291. * ms_pvt MS local functions
  292. */
  293. static void
  294. bfa_fcs_port_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  295. {
  296. struct bfa_fcs_port_ms_s *ms = ms_cbarg;
  297. struct bfa_fcs_port_s *port = ms->port;
  298. struct fchs_s fchs;
  299. int len;
  300. struct bfa_fcxp_s *fcxp;
  301. bfa_trc(port->fcs, port->pid);
  302. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  303. if (!fcxp) {
  304. bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
  305. bfa_fcs_port_ms_send_gmal, ms);
  306. return;
  307. }
  308. ms->fcxp = fcxp;
  309. len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  310. bfa_fcs_port_get_fcid(port),
  311. bfa_lps_get_peer_nwwn(port->fabric->lps));
  312. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  313. FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gmal_response,
  314. (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
  315. bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
  316. }
  317. static void
  318. bfa_fcs_port_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  319. void *cbarg, bfa_status_t req_status,
  320. u32 rsp_len, u32 resid_len,
  321. struct fchs_s *rsp_fchs)
  322. {
  323. struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
  324. struct bfa_fcs_port_s *port = ms->port;
  325. struct ct_hdr_s *cthdr = NULL;
  326. struct fcgs_gmal_resp_s *gmal_resp;
  327. struct fc_gmal_entry_s *gmal_entry;
  328. u32 num_entries;
  329. u8 *rsp_str;
  330. bfa_trc(port->fcs, req_status);
  331. bfa_trc(port->fcs, port->port_cfg.pwwn);
  332. /*
  333. * Sanity Checks
  334. */
  335. if (req_status != BFA_STATUS_OK) {
  336. bfa_trc(port->fcs, req_status);
  337. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  338. return;
  339. }
  340. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  341. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  342. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  343. gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
  344. num_entries = bfa_os_ntohl(gmal_resp->ms_len);
  345. if (num_entries == 0) {
  346. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  347. return;
  348. }
  349. /*
  350. * The response could contain multiple Entries.
  351. * Entries for SNMP interface, etc.
  352. * We look for the entry with a telnet prefix.
  353. * First "http://" entry refers to IP addr
  354. */
  355. gmal_entry = (struct fc_gmal_entry_s *)gmal_resp->ms_ma;
  356. while (num_entries > 0) {
  357. if (strncmp
  358. (gmal_entry->prefix, CT_GMAL_RESP_PREFIX_HTTP,
  359. sizeof(gmal_entry->prefix)) == 0) {
  360. /*
  361. * if the IP address is terminating with a '/',
  362. * remove it. *Byte 0 consists of the length
  363. * of the string.
  364. */
  365. rsp_str = &(gmal_entry->prefix[0]);
  366. if (rsp_str[gmal_entry->len - 1] == '/')
  367. rsp_str[gmal_entry->len - 1] = 0;
  368. /*
  369. * copy IP Address to fabric
  370. */
  371. strncpy(bfa_fcs_port_get_fabric_ipaddr(port),
  372. gmal_entry->ip_addr,
  373. BFA_FCS_FABRIC_IPADDR_SZ);
  374. break;
  375. } else {
  376. --num_entries;
  377. ++gmal_entry;
  378. }
  379. }
  380. bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
  381. return;
  382. }
  383. bfa_trc(port->fcs, cthdr->reason_code);
  384. bfa_trc(port->fcs, cthdr->exp_code);
  385. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  386. }
  387. static void
  388. bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
  389. enum port_ms_event event)
  390. {
  391. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  392. bfa_trc(ms->port->fcs, event);
  393. switch (event) {
  394. case MSSM_EVENT_FCXP_SENT:
  395. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn);
  396. break;
  397. case MSSM_EVENT_PORT_OFFLINE:
  398. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  399. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
  400. &ms->fcxp_wqe);
  401. break;
  402. default:
  403. bfa_sm_fault(ms->port->fcs, event);
  404. }
  405. }
  406. static void
  407. bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
  408. {
  409. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  410. bfa_trc(ms->port->fcs, event);
  411. switch (event) {
  412. case MSSM_EVENT_RSP_ERROR:
  413. /*
  414. * Start timer for a delayed retry
  415. */
  416. if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
  417. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_retry);
  418. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
  419. &ms->timer, bfa_fcs_port_ms_timeout, ms,
  420. BFA_FCS_RETRY_TIMEOUT);
  421. } else {
  422. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
  423. ms->retry_cnt = 0;
  424. }
  425. break;
  426. case MSSM_EVENT_RSP_OK:
  427. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
  428. break;
  429. case MSSM_EVENT_PORT_OFFLINE:
  430. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  431. bfa_fcxp_discard(ms->fcxp);
  432. break;
  433. default:
  434. bfa_sm_fault(ms->port->fcs, event);
  435. }
  436. }
  437. static void
  438. bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
  439. enum port_ms_event event)
  440. {
  441. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  442. bfa_trc(ms->port->fcs, event);
  443. switch (event) {
  444. case MSSM_EVENT_TIMEOUT:
  445. /*
  446. * Retry Timer Expired. Re-send
  447. */
  448. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
  449. bfa_fcs_port_ms_send_gfn(ms, NULL);
  450. break;
  451. case MSSM_EVENT_PORT_OFFLINE:
  452. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  453. bfa_timer_stop(&ms->timer);
  454. break;
  455. default:
  456. bfa_sm_fault(ms->port->fcs, event);
  457. }
  458. }
  459. /**
  460. * ms_pvt MS local functions
  461. */
  462. static void
  463. bfa_fcs_port_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  464. {
  465. struct bfa_fcs_port_ms_s *ms = ms_cbarg;
  466. struct bfa_fcs_port_s *port = ms->port;
  467. struct fchs_s fchs;
  468. int len;
  469. struct bfa_fcxp_s *fcxp;
  470. bfa_trc(port->fcs, port->pid);
  471. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  472. if (!fcxp) {
  473. bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
  474. bfa_fcs_port_ms_send_gfn, ms);
  475. return;
  476. }
  477. ms->fcxp = fcxp;
  478. len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  479. bfa_fcs_port_get_fcid(port),
  480. bfa_lps_get_peer_nwwn(port->fabric->lps));
  481. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  482. FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gfn_response,
  483. (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
  484. bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
  485. }
  486. static void
  487. bfa_fcs_port_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
  488. bfa_status_t req_status, u32 rsp_len,
  489. u32 resid_len, struct fchs_s *rsp_fchs)
  490. {
  491. struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
  492. struct bfa_fcs_port_s *port = ms->port;
  493. struct ct_hdr_s *cthdr = NULL;
  494. wwn_t *gfn_resp;
  495. bfa_trc(port->fcs, req_status);
  496. bfa_trc(port->fcs, port->port_cfg.pwwn);
  497. /*
  498. * Sanity Checks
  499. */
  500. if (req_status != BFA_STATUS_OK) {
  501. bfa_trc(port->fcs, req_status);
  502. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  503. return;
  504. }
  505. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  506. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  507. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  508. gfn_resp = (wwn_t *) (cthdr + 1);
  509. /*
  510. * check if it has actually changed
  511. */
  512. if ((memcmp
  513. ((void *)&bfa_fcs_port_get_fabric_name(port), gfn_resp,
  514. sizeof(wwn_t)) != 0))
  515. bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
  516. bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
  517. return;
  518. }
  519. bfa_trc(port->fcs, cthdr->reason_code);
  520. bfa_trc(port->fcs, cthdr->exp_code);
  521. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  522. }
  523. /**
  524. * ms_pvt MS local functions
  525. */
  526. static void
  527. bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  528. {
  529. struct bfa_fcs_port_ms_s *ms = ms_cbarg;
  530. struct bfa_fcs_port_s *port = ms->port;
  531. struct fchs_s fchs;
  532. int len;
  533. struct bfa_fcxp_s *fcxp;
  534. bfa_trc(port->fcs, port->pid);
  535. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  536. if (!fcxp) {
  537. port->stats.ms_plogi_alloc_wait++;
  538. bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
  539. bfa_fcs_port_ms_send_plogi, ms);
  540. return;
  541. }
  542. ms->fcxp = fcxp;
  543. len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  544. bfa_os_hton3b(FC_MGMT_SERVER),
  545. bfa_fcs_port_get_fcid(port), 0,
  546. port->port_cfg.pwwn, port->port_cfg.nwwn,
  547. bfa_fcport_get_maxfrsize(port->fcs->bfa));
  548. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  549. FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response,
  550. (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
  551. port->stats.ms_plogi_sent++;
  552. bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
  553. }
  554. static void
  555. bfa_fcs_port_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  556. void *cbarg, bfa_status_t req_status,
  557. u32 rsp_len, u32 resid_len,
  558. struct fchs_s *rsp_fchs)
  559. {
  560. struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
  561. struct bfa_fcs_port_s *port = ms->port;
  562. struct fc_els_cmd_s *els_cmd;
  563. struct fc_ls_rjt_s *ls_rjt;
  564. bfa_trc(port->fcs, req_status);
  565. bfa_trc(port->fcs, port->port_cfg.pwwn);
  566. /*
  567. * Sanity Checks
  568. */
  569. if (req_status != BFA_STATUS_OK) {
  570. port->stats.ms_plogi_rsp_err++;
  571. bfa_trc(port->fcs, req_status);
  572. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  573. return;
  574. }
  575. els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
  576. switch (els_cmd->els_code) {
  577. case FC_ELS_ACC:
  578. if (rsp_len < sizeof(struct fc_logi_s)) {
  579. bfa_trc(port->fcs, rsp_len);
  580. port->stats.ms_plogi_acc_err++;
  581. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  582. break;
  583. }
  584. port->stats.ms_plogi_accepts++;
  585. bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
  586. break;
  587. case FC_ELS_LS_RJT:
  588. ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
  589. bfa_trc(port->fcs, ls_rjt->reason_code);
  590. bfa_trc(port->fcs, ls_rjt->reason_code_expl);
  591. port->stats.ms_rejects++;
  592. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  593. break;
  594. default:
  595. port->stats.ms_plogi_unknown_rsp++;
  596. bfa_trc(port->fcs, els_cmd->els_code);
  597. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  598. }
  599. }
  600. static void
  601. bfa_fcs_port_ms_timeout(void *arg)
  602. {
  603. struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)arg;
  604. ms->port->stats.ms_timeouts++;
  605. bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
  606. }
  607. void
  608. bfa_fcs_port_ms_init(struct bfa_fcs_port_s *port)
  609. {
  610. struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
  611. ms->port = port;
  612. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  613. /*
  614. * Invoke init routines of sub modules.
  615. */
  616. bfa_fcs_port_fdmi_init(ms);
  617. }
  618. void
  619. bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port)
  620. {
  621. struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
  622. ms->port = port;
  623. bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
  624. bfa_fcs_port_fdmi_offline(ms);
  625. }
  626. void
  627. bfa_fcs_port_ms_online(struct bfa_fcs_port_s *port)
  628. {
  629. struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
  630. ms->port = port;
  631. bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
  632. }
  633. void
  634. bfa_fcs_port_ms_fabric_rscn(struct bfa_fcs_port_s *port)
  635. {
  636. struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
  637. /*
  638. * @todo. Handle this only when in Online state
  639. */
  640. if (bfa_sm_cmp_state(ms, bfa_fcs_port_ms_sm_online))
  641. bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
  642. }