ms.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  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_assert(0);
  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_assert(0);
  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_assert(0);
  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_assert(0);
  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. /*
  207. * now invoke MS related sub-modules
  208. */
  209. bfa_fcs_port_fdmi_offline(ms);
  210. break;
  211. case MSSM_EVENT_PORT_FABRIC_RSCN:
  212. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
  213. ms->retry_cnt = 0;
  214. bfa_fcs_port_ms_send_gfn(ms, NULL);
  215. break;
  216. default:
  217. bfa_assert(0);
  218. }
  219. }
  220. static void
  221. bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
  222. enum port_ms_event event)
  223. {
  224. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  225. bfa_trc(ms->port->fcs, event);
  226. switch (event) {
  227. case MSSM_EVENT_FCXP_SENT:
  228. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal);
  229. break;
  230. case MSSM_EVENT_PORT_OFFLINE:
  231. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  232. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
  233. &ms->fcxp_wqe);
  234. break;
  235. default:
  236. bfa_assert(0);
  237. }
  238. }
  239. static void
  240. bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
  241. {
  242. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  243. bfa_trc(ms->port->fcs, event);
  244. switch (event) {
  245. case MSSM_EVENT_RSP_ERROR:
  246. /*
  247. * Start timer for a delayed retry
  248. */
  249. if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
  250. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_retry);
  251. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
  252. &ms->timer, bfa_fcs_port_ms_timeout, ms,
  253. BFA_FCS_RETRY_TIMEOUT);
  254. } else {
  255. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
  256. bfa_fcs_port_ms_send_gfn(ms, NULL);
  257. ms->retry_cnt = 0;
  258. }
  259. break;
  260. case MSSM_EVENT_RSP_OK:
  261. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
  262. bfa_fcs_port_ms_send_gfn(ms, NULL);
  263. break;
  264. case MSSM_EVENT_PORT_OFFLINE:
  265. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  266. bfa_fcxp_discard(ms->fcxp);
  267. break;
  268. default:
  269. bfa_assert(0);
  270. }
  271. }
  272. static void
  273. bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
  274. enum port_ms_event event)
  275. {
  276. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  277. bfa_trc(ms->port->fcs, event);
  278. switch (event) {
  279. case MSSM_EVENT_TIMEOUT:
  280. /*
  281. * Retry Timer Expired. Re-send
  282. */
  283. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending);
  284. bfa_fcs_port_ms_send_gmal(ms, NULL);
  285. break;
  286. case MSSM_EVENT_PORT_OFFLINE:
  287. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  288. bfa_timer_stop(&ms->timer);
  289. break;
  290. default:
  291. bfa_assert(0);
  292. }
  293. }
  294. /**
  295. * ms_pvt MS local functions
  296. */
  297. static void
  298. bfa_fcs_port_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  299. {
  300. struct bfa_fcs_port_ms_s *ms = ms_cbarg;
  301. struct bfa_fcs_port_s *port = ms->port;
  302. struct fchs_s fchs;
  303. int len;
  304. struct bfa_fcxp_s *fcxp;
  305. bfa_trc(port->fcs, port->pid);
  306. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  307. if (!fcxp) {
  308. bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
  309. bfa_fcs_port_ms_send_gmal, ms);
  310. return;
  311. }
  312. ms->fcxp = fcxp;
  313. len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  314. bfa_fcs_port_get_fcid(port),
  315. bfa_lps_get_peer_nwwn(port->fabric->lps));
  316. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  317. FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gmal_response,
  318. (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
  319. bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
  320. }
  321. static void
  322. bfa_fcs_port_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  323. void *cbarg, bfa_status_t req_status,
  324. u32 rsp_len, u32 resid_len,
  325. struct fchs_s *rsp_fchs)
  326. {
  327. struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
  328. struct bfa_fcs_port_s *port = ms->port;
  329. struct ct_hdr_s *cthdr = NULL;
  330. struct fcgs_gmal_resp_s *gmal_resp;
  331. struct fc_gmal_entry_s *gmal_entry;
  332. u32 num_entries;
  333. u8 *rsp_str;
  334. bfa_trc(port->fcs, req_status);
  335. bfa_trc(port->fcs, port->port_cfg.pwwn);
  336. /*
  337. * Sanity Checks
  338. */
  339. if (req_status != BFA_STATUS_OK) {
  340. bfa_trc(port->fcs, req_status);
  341. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  342. return;
  343. }
  344. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  345. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  346. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  347. gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
  348. num_entries = bfa_os_ntohl(gmal_resp->ms_len);
  349. if (num_entries == 0) {
  350. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  351. return;
  352. }
  353. /*
  354. * The response could contain multiple Entries.
  355. * Entries for SNMP interface, etc.
  356. * We look for the entry with a telnet prefix.
  357. * First "http://" entry refers to IP addr
  358. */
  359. gmal_entry = (struct fc_gmal_entry_s *)gmal_resp->ms_ma;
  360. while (num_entries > 0) {
  361. if (strncmp
  362. (gmal_entry->prefix, CT_GMAL_RESP_PREFIX_HTTP,
  363. sizeof(gmal_entry->prefix)) == 0) {
  364. /*
  365. * if the IP address is terminating with a '/',
  366. * remove it. *Byte 0 consists of the length
  367. * of the string.
  368. */
  369. rsp_str = &(gmal_entry->prefix[0]);
  370. if (rsp_str[gmal_entry->len - 1] == '/')
  371. rsp_str[gmal_entry->len - 1] = 0;
  372. /*
  373. * copy IP Address to fabric
  374. */
  375. strncpy(bfa_fcs_port_get_fabric_ipaddr(port),
  376. gmal_entry->ip_addr,
  377. BFA_FCS_FABRIC_IPADDR_SZ);
  378. break;
  379. } else {
  380. --num_entries;
  381. ++gmal_entry;
  382. }
  383. }
  384. bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
  385. return;
  386. }
  387. bfa_trc(port->fcs, cthdr->reason_code);
  388. bfa_trc(port->fcs, cthdr->exp_code);
  389. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  390. }
  391. static void
  392. bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
  393. enum port_ms_event event)
  394. {
  395. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  396. bfa_trc(ms->port->fcs, event);
  397. switch (event) {
  398. case MSSM_EVENT_FCXP_SENT:
  399. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn);
  400. break;
  401. case MSSM_EVENT_PORT_OFFLINE:
  402. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  403. bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
  404. &ms->fcxp_wqe);
  405. break;
  406. default:
  407. bfa_assert(0);
  408. }
  409. }
  410. static void
  411. bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
  412. {
  413. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  414. bfa_trc(ms->port->fcs, event);
  415. switch (event) {
  416. case MSSM_EVENT_RSP_ERROR:
  417. /*
  418. * Start timer for a delayed retry
  419. */
  420. if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
  421. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_retry);
  422. bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
  423. &ms->timer, bfa_fcs_port_ms_timeout, ms,
  424. BFA_FCS_RETRY_TIMEOUT);
  425. } else {
  426. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
  427. ms->retry_cnt = 0;
  428. }
  429. break;
  430. case MSSM_EVENT_RSP_OK:
  431. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
  432. break;
  433. case MSSM_EVENT_PORT_OFFLINE:
  434. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  435. bfa_fcxp_discard(ms->fcxp);
  436. break;
  437. default:
  438. bfa_assert(0);
  439. }
  440. }
  441. static void
  442. bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
  443. enum port_ms_event event)
  444. {
  445. bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
  446. bfa_trc(ms->port->fcs, event);
  447. switch (event) {
  448. case MSSM_EVENT_TIMEOUT:
  449. /*
  450. * Retry Timer Expired. Re-send
  451. */
  452. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
  453. bfa_fcs_port_ms_send_gfn(ms, NULL);
  454. break;
  455. case MSSM_EVENT_PORT_OFFLINE:
  456. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  457. bfa_timer_stop(&ms->timer);
  458. break;
  459. default:
  460. bfa_assert(0);
  461. }
  462. }
  463. /**
  464. * ms_pvt MS local functions
  465. */
  466. static void
  467. bfa_fcs_port_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  468. {
  469. struct bfa_fcs_port_ms_s *ms = ms_cbarg;
  470. struct bfa_fcs_port_s *port = ms->port;
  471. struct fchs_s fchs;
  472. int len;
  473. struct bfa_fcxp_s *fcxp;
  474. bfa_trc(port->fcs, port->pid);
  475. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  476. if (!fcxp) {
  477. bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
  478. bfa_fcs_port_ms_send_gfn, ms);
  479. return;
  480. }
  481. ms->fcxp = fcxp;
  482. len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  483. bfa_fcs_port_get_fcid(port),
  484. bfa_lps_get_peer_nwwn(port->fabric->lps));
  485. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  486. FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gfn_response,
  487. (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
  488. bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
  489. }
  490. static void
  491. bfa_fcs_port_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
  492. bfa_status_t req_status, u32 rsp_len,
  493. u32 resid_len, struct fchs_s *rsp_fchs)
  494. {
  495. struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
  496. struct bfa_fcs_port_s *port = ms->port;
  497. struct ct_hdr_s *cthdr = NULL;
  498. wwn_t *gfn_resp;
  499. bfa_trc(port->fcs, req_status);
  500. bfa_trc(port->fcs, port->port_cfg.pwwn);
  501. /*
  502. * Sanity Checks
  503. */
  504. if (req_status != BFA_STATUS_OK) {
  505. bfa_trc(port->fcs, req_status);
  506. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  507. return;
  508. }
  509. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  510. cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
  511. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  512. gfn_resp = (wwn_t *) (cthdr + 1);
  513. /*
  514. * check if it has actually changed
  515. */
  516. if ((memcmp
  517. ((void *)&bfa_fcs_port_get_fabric_name(port), gfn_resp,
  518. sizeof(wwn_t)) != 0))
  519. bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
  520. bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
  521. return;
  522. }
  523. bfa_trc(port->fcs, cthdr->reason_code);
  524. bfa_trc(port->fcs, cthdr->exp_code);
  525. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  526. }
  527. /**
  528. * ms_pvt MS local functions
  529. */
  530. static void
  531. bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  532. {
  533. struct bfa_fcs_port_ms_s *ms = ms_cbarg;
  534. struct bfa_fcs_port_s *port = ms->port;
  535. struct fchs_s fchs;
  536. int len;
  537. struct bfa_fcxp_s *fcxp;
  538. bfa_trc(port->fcs, port->pid);
  539. fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
  540. if (!fcxp) {
  541. port->stats.ms_plogi_alloc_wait++;
  542. bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
  543. bfa_fcs_port_ms_send_plogi, ms);
  544. return;
  545. }
  546. ms->fcxp = fcxp;
  547. len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  548. bfa_os_hton3b(FC_MGMT_SERVER),
  549. bfa_fcs_port_get_fcid(port), 0,
  550. port->port_cfg.pwwn, port->port_cfg.nwwn,
  551. bfa_pport_get_maxfrsize(port->fcs->bfa));
  552. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  553. FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response,
  554. (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
  555. port->stats.ms_plogi_sent++;
  556. bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
  557. }
  558. static void
  559. bfa_fcs_port_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
  560. void *cbarg, bfa_status_t req_status,
  561. u32 rsp_len, u32 resid_len,
  562. struct fchs_s *rsp_fchs)
  563. {
  564. struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
  565. struct bfa_fcs_port_s *port = ms->port;
  566. struct fc_els_cmd_s *els_cmd;
  567. struct fc_ls_rjt_s *ls_rjt;
  568. bfa_trc(port->fcs, req_status);
  569. bfa_trc(port->fcs, port->port_cfg.pwwn);
  570. /*
  571. * Sanity Checks
  572. */
  573. if (req_status != BFA_STATUS_OK) {
  574. port->stats.ms_plogi_rsp_err++;
  575. bfa_trc(port->fcs, req_status);
  576. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  577. return;
  578. }
  579. els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
  580. switch (els_cmd->els_code) {
  581. case FC_ELS_ACC:
  582. if (rsp_len < sizeof(struct fc_logi_s)) {
  583. bfa_trc(port->fcs, rsp_len);
  584. port->stats.ms_plogi_acc_err++;
  585. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  586. break;
  587. }
  588. port->stats.ms_plogi_accepts++;
  589. bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
  590. break;
  591. case FC_ELS_LS_RJT:
  592. ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
  593. bfa_trc(port->fcs, ls_rjt->reason_code);
  594. bfa_trc(port->fcs, ls_rjt->reason_code_expl);
  595. port->stats.ms_rejects++;
  596. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  597. break;
  598. default:
  599. port->stats.ms_plogi_unknown_rsp++;
  600. bfa_trc(port->fcs, els_cmd->els_code);
  601. bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
  602. }
  603. }
  604. static void
  605. bfa_fcs_port_ms_timeout(void *arg)
  606. {
  607. struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)arg;
  608. ms->port->stats.ms_timeouts++;
  609. bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
  610. }
  611. void
  612. bfa_fcs_port_ms_init(struct bfa_fcs_port_s *port)
  613. {
  614. struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
  615. ms->port = port;
  616. bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
  617. /*
  618. * Invoke init routines of sub modules.
  619. */
  620. bfa_fcs_port_fdmi_init(ms);
  621. }
  622. void
  623. bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port)
  624. {
  625. struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
  626. ms->port = port;
  627. bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
  628. }
  629. void
  630. bfa_fcs_port_ms_online(struct bfa_fcs_port_s *port)
  631. {
  632. struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
  633. ms->port = port;
  634. bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
  635. }
  636. void
  637. bfa_fcs_port_ms_fabric_rscn(struct bfa_fcs_port_s *port)
  638. {
  639. struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
  640. /*
  641. * @todo. Handle this only when in Online state
  642. */
  643. if (bfa_sm_cmp_state(ms, bfa_fcs_port_ms_sm_online))
  644. bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
  645. }