fabric.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323
  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. * fabric.c Fabric module implementation.
  19. */
  20. #include "fcs_fabric.h"
  21. #include "fcs_lport.h"
  22. #include "fcs_vport.h"
  23. #include "fcs_trcmod.h"
  24. #include "fcs_fcxp.h"
  25. #include "fcs_auth.h"
  26. #include "fcs.h"
  27. #include "fcbuild.h"
  28. #include <log/bfa_log_fcs.h>
  29. #include <aen/bfa_aen_port.h>
  30. #include <bfa_svc.h>
  31. BFA_TRC_FILE(FCS, FABRIC);
  32. #define BFA_FCS_FABRIC_RETRY_DELAY (2000) /* Milliseconds */
  33. #define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */
  34. #define bfa_fcs_fabric_set_opertype(__fabric) do { \
  35. if (bfa_fcport_get_topology((__fabric)->fcs->bfa) \
  36. == BFA_PPORT_TOPOLOGY_P2P) \
  37. (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \
  38. else \
  39. (__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT; \
  40. } while (0)
  41. /*
  42. * forward declarations
  43. */
  44. static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
  45. static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
  46. static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
  47. static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
  48. static void bfa_fcs_fabric_delay(void *cbarg);
  49. static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
  50. static void bfa_fcs_fabric_delete_comp(void *cbarg);
  51. static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
  52. struct fchs_s *fchs, u16 len);
  53. static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
  54. struct fchs_s *fchs, u16 len);
  55. static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
  56. static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
  57. struct bfa_fcxp_s *fcxp,
  58. void *cbarg, bfa_status_t status,
  59. u32 rsp_len,
  60. u32 resid_len,
  61. struct fchs_s *rspfchs);
  62. /**
  63. * fcs_fabric_sm fabric state machine functions
  64. */
  65. /**
  66. * Fabric state machine events
  67. */
  68. enum bfa_fcs_fabric_event {
  69. BFA_FCS_FABRIC_SM_CREATE = 1, /* fabric create from driver */
  70. BFA_FCS_FABRIC_SM_DELETE = 2, /* fabric delete from driver */
  71. BFA_FCS_FABRIC_SM_LINK_DOWN = 3, /* link down from port */
  72. BFA_FCS_FABRIC_SM_LINK_UP = 4, /* link up from port */
  73. BFA_FCS_FABRIC_SM_CONT_OP = 5, /* continue op from flogi/auth */
  74. BFA_FCS_FABRIC_SM_RETRY_OP = 6, /* continue op from flogi/auth */
  75. BFA_FCS_FABRIC_SM_NO_FABRIC = 7, /* no fabric from flogi/auth
  76. */
  77. BFA_FCS_FABRIC_SM_PERF_EVFP = 8, /* perform EVFP from
  78. *flogi/auth */
  79. BFA_FCS_FABRIC_SM_ISOLATE = 9, /* isolate from EVFP processing */
  80. BFA_FCS_FABRIC_SM_NO_TAGGING = 10,/* no VFT tagging from EVFP */
  81. BFA_FCS_FABRIC_SM_DELAYED = 11, /* timeout delay event */
  82. BFA_FCS_FABRIC_SM_AUTH_FAILED = 12, /* authentication failed */
  83. BFA_FCS_FABRIC_SM_AUTH_SUCCESS = 13, /* authentication successful
  84. */
  85. BFA_FCS_FABRIC_SM_DELCOMP = 14, /* all vports deleted event */
  86. BFA_FCS_FABRIC_SM_LOOPBACK = 15, /* Received our own FLOGI */
  87. BFA_FCS_FABRIC_SM_START = 16, /* fabric delete from driver */
  88. };
  89. static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
  90. enum bfa_fcs_fabric_event event);
  91. static void bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
  92. enum bfa_fcs_fabric_event event);
  93. static void bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
  94. enum bfa_fcs_fabric_event event);
  95. static void bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
  96. enum bfa_fcs_fabric_event event);
  97. static void bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
  98. enum bfa_fcs_fabric_event event);
  99. static void bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
  100. enum bfa_fcs_fabric_event event);
  101. static void bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
  102. enum bfa_fcs_fabric_event event);
  103. static void bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
  104. enum bfa_fcs_fabric_event event);
  105. static void bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
  106. enum bfa_fcs_fabric_event event);
  107. static void bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
  108. enum bfa_fcs_fabric_event event);
  109. static void bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
  110. enum bfa_fcs_fabric_event event);
  111. static void bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
  112. enum bfa_fcs_fabric_event event);
  113. static void bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
  114. enum bfa_fcs_fabric_event event);
  115. static void bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
  116. enum bfa_fcs_fabric_event event);
  117. /**
  118. * Beginning state before fabric creation.
  119. */
  120. static void
  121. bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
  122. enum bfa_fcs_fabric_event event)
  123. {
  124. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  125. bfa_trc(fabric->fcs, event);
  126. switch (event) {
  127. case BFA_FCS_FABRIC_SM_CREATE:
  128. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
  129. bfa_fcs_fabric_init(fabric);
  130. bfa_fcs_lport_init(&fabric->bport, &fabric->bport.port_cfg);
  131. break;
  132. case BFA_FCS_FABRIC_SM_LINK_UP:
  133. case BFA_FCS_FABRIC_SM_LINK_DOWN:
  134. break;
  135. default:
  136. bfa_sm_fault(fabric->fcs, event);
  137. }
  138. }
  139. /**
  140. * Beginning state before fabric creation.
  141. */
  142. static void
  143. bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
  144. enum bfa_fcs_fabric_event event)
  145. {
  146. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  147. bfa_trc(fabric->fcs, event);
  148. switch (event) {
  149. case BFA_FCS_FABRIC_SM_START:
  150. if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
  151. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
  152. bfa_fcs_fabric_login(fabric);
  153. } else
  154. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
  155. break;
  156. case BFA_FCS_FABRIC_SM_LINK_UP:
  157. case BFA_FCS_FABRIC_SM_LINK_DOWN:
  158. break;
  159. case BFA_FCS_FABRIC_SM_DELETE:
  160. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
  161. bfa_fcs_modexit_comp(fabric->fcs);
  162. break;
  163. default:
  164. bfa_sm_fault(fabric->fcs, event);
  165. }
  166. }
  167. /**
  168. * Link is down, awaiting LINK UP event from port. This is also the
  169. * first state at fabric creation.
  170. */
  171. static void
  172. bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
  173. enum bfa_fcs_fabric_event event)
  174. {
  175. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  176. bfa_trc(fabric->fcs, event);
  177. switch (event) {
  178. case BFA_FCS_FABRIC_SM_LINK_UP:
  179. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
  180. bfa_fcs_fabric_login(fabric);
  181. break;
  182. case BFA_FCS_FABRIC_SM_RETRY_OP:
  183. break;
  184. case BFA_FCS_FABRIC_SM_DELETE:
  185. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
  186. bfa_fcs_fabric_delete(fabric);
  187. break;
  188. default:
  189. bfa_sm_fault(fabric->fcs, event);
  190. }
  191. }
  192. /**
  193. * FLOGI is in progress, awaiting FLOGI reply.
  194. */
  195. static void
  196. bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
  197. enum bfa_fcs_fabric_event event)
  198. {
  199. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  200. bfa_trc(fabric->fcs, event);
  201. switch (event) {
  202. case BFA_FCS_FABRIC_SM_CONT_OP:
  203. bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
  204. fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
  205. if (fabric->auth_reqd && fabric->is_auth) {
  206. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth);
  207. bfa_trc(fabric->fcs, event);
  208. } else {
  209. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
  210. bfa_fcs_fabric_notify_online(fabric);
  211. }
  212. break;
  213. case BFA_FCS_FABRIC_SM_RETRY_OP:
  214. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry);
  215. bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer,
  216. bfa_fcs_fabric_delay, fabric,
  217. BFA_FCS_FABRIC_RETRY_DELAY);
  218. break;
  219. case BFA_FCS_FABRIC_SM_LOOPBACK:
  220. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
  221. bfa_lps_discard(fabric->lps);
  222. bfa_fcs_fabric_set_opertype(fabric);
  223. break;
  224. case BFA_FCS_FABRIC_SM_NO_FABRIC:
  225. fabric->fab_type = BFA_FCS_FABRIC_N2N;
  226. bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
  227. bfa_fcs_fabric_notify_online(fabric);
  228. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
  229. break;
  230. case BFA_FCS_FABRIC_SM_LINK_DOWN:
  231. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
  232. bfa_lps_discard(fabric->lps);
  233. break;
  234. case BFA_FCS_FABRIC_SM_DELETE:
  235. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
  236. bfa_lps_discard(fabric->lps);
  237. bfa_fcs_fabric_delete(fabric);
  238. break;
  239. default:
  240. bfa_sm_fault(fabric->fcs, event);
  241. }
  242. }
  243. static void
  244. bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
  245. enum bfa_fcs_fabric_event event)
  246. {
  247. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  248. bfa_trc(fabric->fcs, event);
  249. switch (event) {
  250. case BFA_FCS_FABRIC_SM_DELAYED:
  251. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
  252. bfa_fcs_fabric_login(fabric);
  253. break;
  254. case BFA_FCS_FABRIC_SM_LINK_DOWN:
  255. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
  256. bfa_timer_stop(&fabric->delay_timer);
  257. break;
  258. case BFA_FCS_FABRIC_SM_DELETE:
  259. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
  260. bfa_timer_stop(&fabric->delay_timer);
  261. bfa_fcs_fabric_delete(fabric);
  262. break;
  263. default:
  264. bfa_sm_fault(fabric->fcs, event);
  265. }
  266. }
  267. /**
  268. * Authentication is in progress, awaiting authentication results.
  269. */
  270. static void
  271. bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
  272. enum bfa_fcs_fabric_event event)
  273. {
  274. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  275. bfa_trc(fabric->fcs, event);
  276. switch (event) {
  277. case BFA_FCS_FABRIC_SM_AUTH_FAILED:
  278. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
  279. bfa_lps_discard(fabric->lps);
  280. break;
  281. case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
  282. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
  283. bfa_fcs_fabric_notify_online(fabric);
  284. break;
  285. case BFA_FCS_FABRIC_SM_PERF_EVFP:
  286. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp);
  287. break;
  288. case BFA_FCS_FABRIC_SM_LINK_DOWN:
  289. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
  290. bfa_lps_discard(fabric->lps);
  291. break;
  292. case BFA_FCS_FABRIC_SM_DELETE:
  293. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
  294. bfa_fcs_fabric_delete(fabric);
  295. break;
  296. default:
  297. bfa_sm_fault(fabric->fcs, event);
  298. }
  299. }
  300. /**
  301. * Authentication failed
  302. */
  303. static void
  304. bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
  305. enum bfa_fcs_fabric_event event)
  306. {
  307. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  308. bfa_trc(fabric->fcs, event);
  309. switch (event) {
  310. case BFA_FCS_FABRIC_SM_LINK_DOWN:
  311. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
  312. bfa_fcs_fabric_notify_offline(fabric);
  313. break;
  314. case BFA_FCS_FABRIC_SM_DELETE:
  315. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
  316. bfa_fcs_fabric_delete(fabric);
  317. break;
  318. default:
  319. bfa_sm_fault(fabric->fcs, event);
  320. }
  321. }
  322. /**
  323. * Port is in loopback mode.
  324. */
  325. static void
  326. bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
  327. enum bfa_fcs_fabric_event event)
  328. {
  329. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  330. bfa_trc(fabric->fcs, event);
  331. switch (event) {
  332. case BFA_FCS_FABRIC_SM_LINK_DOWN:
  333. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
  334. bfa_fcs_fabric_notify_offline(fabric);
  335. break;
  336. case BFA_FCS_FABRIC_SM_DELETE:
  337. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
  338. bfa_fcs_fabric_delete(fabric);
  339. break;
  340. default:
  341. bfa_sm_fault(fabric->fcs, event);
  342. }
  343. }
  344. /**
  345. * There is no attached fabric - private loop or NPort-to-NPort topology.
  346. */
  347. static void
  348. bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
  349. enum bfa_fcs_fabric_event event)
  350. {
  351. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  352. bfa_trc(fabric->fcs, event);
  353. switch (event) {
  354. case BFA_FCS_FABRIC_SM_LINK_DOWN:
  355. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
  356. bfa_lps_discard(fabric->lps);
  357. bfa_fcs_fabric_notify_offline(fabric);
  358. break;
  359. case BFA_FCS_FABRIC_SM_DELETE:
  360. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
  361. bfa_fcs_fabric_delete(fabric);
  362. break;
  363. case BFA_FCS_FABRIC_SM_NO_FABRIC:
  364. bfa_trc(fabric->fcs, fabric->bb_credit);
  365. bfa_fcport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
  366. break;
  367. default:
  368. bfa_sm_fault(fabric->fcs, event);
  369. }
  370. }
  371. /**
  372. * Fabric is online - normal operating state.
  373. */
  374. static void
  375. bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
  376. enum bfa_fcs_fabric_event event)
  377. {
  378. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  379. bfa_trc(fabric->fcs, event);
  380. switch (event) {
  381. case BFA_FCS_FABRIC_SM_LINK_DOWN:
  382. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
  383. bfa_lps_discard(fabric->lps);
  384. bfa_fcs_fabric_notify_offline(fabric);
  385. break;
  386. case BFA_FCS_FABRIC_SM_DELETE:
  387. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
  388. bfa_fcs_fabric_delete(fabric);
  389. break;
  390. case BFA_FCS_FABRIC_SM_AUTH_FAILED:
  391. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
  392. bfa_lps_discard(fabric->lps);
  393. break;
  394. case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
  395. break;
  396. default:
  397. bfa_sm_fault(fabric->fcs, event);
  398. }
  399. }
  400. /**
  401. * Exchanging virtual fabric parameters.
  402. */
  403. static void
  404. bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
  405. enum bfa_fcs_fabric_event event)
  406. {
  407. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  408. bfa_trc(fabric->fcs, event);
  409. switch (event) {
  410. case BFA_FCS_FABRIC_SM_CONT_OP:
  411. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done);
  412. break;
  413. case BFA_FCS_FABRIC_SM_ISOLATE:
  414. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated);
  415. break;
  416. default:
  417. bfa_sm_fault(fabric->fcs, event);
  418. }
  419. }
  420. /**
  421. * EVFP exchange complete and VFT tagging is enabled.
  422. */
  423. static void
  424. bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
  425. enum bfa_fcs_fabric_event event)
  426. {
  427. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  428. bfa_trc(fabric->fcs, event);
  429. }
  430. /**
  431. * Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
  432. */
  433. static void
  434. bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
  435. enum bfa_fcs_fabric_event event)
  436. {
  437. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  438. bfa_trc(fabric->fcs, event);
  439. bfa_log(fabric->fcs->logm, BFA_LOG_FCS_FABRIC_ISOLATED,
  440. fabric->bport.port_cfg.pwwn, fabric->fcs->port_vfid,
  441. fabric->event_arg.swp_vfid);
  442. }
  443. /**
  444. * Fabric is being deleted, awaiting vport delete completions.
  445. */
  446. static void
  447. bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
  448. enum bfa_fcs_fabric_event event)
  449. {
  450. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  451. bfa_trc(fabric->fcs, event);
  452. switch (event) {
  453. case BFA_FCS_FABRIC_SM_DELCOMP:
  454. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
  455. bfa_fcs_modexit_comp(fabric->fcs);
  456. break;
  457. case BFA_FCS_FABRIC_SM_LINK_UP:
  458. break;
  459. case BFA_FCS_FABRIC_SM_LINK_DOWN:
  460. bfa_fcs_fabric_notify_offline(fabric);
  461. break;
  462. default:
  463. bfa_sm_fault(fabric->fcs, event);
  464. }
  465. }
  466. /**
  467. * fcs_fabric_private fabric private functions
  468. */
  469. static void
  470. bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
  471. {
  472. struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
  473. port_cfg->roles = BFA_PORT_ROLE_FCP_IM;
  474. port_cfg->nwwn = bfa_ioc_get_nwwn(&fabric->fcs->bfa->ioc);
  475. port_cfg->pwwn = bfa_ioc_get_pwwn(&fabric->fcs->bfa->ioc);
  476. }
  477. /**
  478. * Port Symbolic Name Creation for base port.
  479. */
  480. void
  481. bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
  482. {
  483. struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
  484. char model[BFA_ADAPTER_MODEL_NAME_LEN] = {0};
  485. struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
  486. bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
  487. /*
  488. * Model name/number
  489. */
  490. strncpy((char *)&port_cfg->sym_name, model,
  491. BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
  492. strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
  493. sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
  494. /*
  495. * Driver Version
  496. */
  497. strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
  498. BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
  499. strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
  500. sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
  501. /*
  502. * Host machine name
  503. */
  504. strncat((char *)&port_cfg->sym_name,
  505. (char *)driver_info->host_machine_name,
  506. BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
  507. strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
  508. sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
  509. /*
  510. * Host OS Info :
  511. * If OS Patch Info is not there, do not truncate any bytes from the
  512. * OS name string and instead copy the entire OS info string (64 bytes).
  513. */
  514. if (driver_info->host_os_patch[0] == '\0') {
  515. strncat((char *)&port_cfg->sym_name,
  516. (char *)driver_info->host_os_name, BFA_FCS_OS_STR_LEN);
  517. strncat((char *)&port_cfg->sym_name,
  518. BFA_FCS_PORT_SYMBNAME_SEPARATOR,
  519. sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
  520. } else {
  521. strncat((char *)&port_cfg->sym_name,
  522. (char *)driver_info->host_os_name,
  523. BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
  524. strncat((char *)&port_cfg->sym_name,
  525. BFA_FCS_PORT_SYMBNAME_SEPARATOR,
  526. sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
  527. /*
  528. * Append host OS Patch Info
  529. */
  530. strncat((char *)&port_cfg->sym_name,
  531. (char *)driver_info->host_os_patch,
  532. BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
  533. }
  534. /*
  535. * null terminate
  536. */
  537. port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
  538. }
  539. /**
  540. * bfa lps login completion callback
  541. */
  542. void
  543. bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
  544. {
  545. struct bfa_fcs_fabric_s *fabric = uarg;
  546. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  547. bfa_trc(fabric->fcs, status);
  548. switch (status) {
  549. case BFA_STATUS_OK:
  550. fabric->stats.flogi_accepts++;
  551. break;
  552. case BFA_STATUS_INVALID_MAC:
  553. /*
  554. * Only for CNA
  555. */
  556. fabric->stats.flogi_acc_err++;
  557. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
  558. return;
  559. case BFA_STATUS_EPROTOCOL:
  560. switch (bfa_lps_get_extstatus(fabric->lps)) {
  561. case BFA_EPROTO_BAD_ACCEPT:
  562. fabric->stats.flogi_acc_err++;
  563. break;
  564. case BFA_EPROTO_UNKNOWN_RSP:
  565. fabric->stats.flogi_unknown_rsp++;
  566. break;
  567. default:
  568. break;
  569. }
  570. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
  571. return;
  572. case BFA_STATUS_FABRIC_RJT:
  573. fabric->stats.flogi_rejects++;
  574. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
  575. return;
  576. default:
  577. fabric->stats.flogi_rsp_err++;
  578. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
  579. return;
  580. }
  581. fabric->bb_credit = bfa_lps_get_peer_bbcredit(fabric->lps);
  582. bfa_trc(fabric->fcs, fabric->bb_credit);
  583. if (!bfa_lps_is_brcd_fabric(fabric->lps))
  584. fabric->fabric_name = bfa_lps_get_peer_nwwn(fabric->lps);
  585. /*
  586. * Check port type. It should be 1 = F-port.
  587. */
  588. if (bfa_lps_is_fport(fabric->lps)) {
  589. fabric->bport.pid = bfa_lps_get_pid(fabric->lps);
  590. fabric->is_npiv = bfa_lps_is_npiv_en(fabric->lps);
  591. fabric->is_auth = bfa_lps_is_authreq(fabric->lps);
  592. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
  593. } else {
  594. /*
  595. * Nport-2-Nport direct attached
  596. */
  597. fabric->bport.port_topo.pn2n.rem_port_wwn =
  598. bfa_lps_get_peer_pwwn(fabric->lps);
  599. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
  600. }
  601. bfa_trc(fabric->fcs, fabric->bport.pid);
  602. bfa_trc(fabric->fcs, fabric->is_npiv);
  603. bfa_trc(fabric->fcs, fabric->is_auth);
  604. }
  605. /**
  606. * Allocate and send FLOGI.
  607. */
  608. static void
  609. bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
  610. {
  611. struct bfa_s *bfa = fabric->fcs->bfa;
  612. struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
  613. u8 alpa = 0;
  614. if (bfa_fcport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
  615. alpa = bfa_fcport_get_myalpa(bfa);
  616. bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_fcport_get_maxfrsize(bfa),
  617. pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
  618. fabric->stats.flogi_sent++;
  619. }
  620. static void
  621. bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
  622. {
  623. struct bfa_fcs_vport_s *vport;
  624. struct list_head *qe, *qen;
  625. bfa_trc(fabric->fcs, fabric->fabric_name);
  626. bfa_fcs_fabric_set_opertype(fabric);
  627. fabric->stats.fabric_onlines++;
  628. /**
  629. * notify online event to base and then virtual ports
  630. */
  631. bfa_fcs_port_online(&fabric->bport);
  632. list_for_each_safe(qe, qen, &fabric->vport_q) {
  633. vport = (struct bfa_fcs_vport_s *)qe;
  634. bfa_fcs_vport_online(vport);
  635. }
  636. }
  637. static void
  638. bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
  639. {
  640. struct bfa_fcs_vport_s *vport;
  641. struct list_head *qe, *qen;
  642. bfa_trc(fabric->fcs, fabric->fabric_name);
  643. fabric->stats.fabric_offlines++;
  644. /**
  645. * notify offline event first to vports and then base port.
  646. */
  647. list_for_each_safe(qe, qen, &fabric->vport_q) {
  648. vport = (struct bfa_fcs_vport_s *)qe;
  649. bfa_fcs_vport_offline(vport);
  650. }
  651. bfa_fcs_port_offline(&fabric->bport);
  652. fabric->fabric_name = 0;
  653. fabric->fabric_ip_addr[0] = 0;
  654. }
  655. static void
  656. bfa_fcs_fabric_delay(void *cbarg)
  657. {
  658. struct bfa_fcs_fabric_s *fabric = cbarg;
  659. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
  660. }
  661. /**
  662. * Delete all vports and wait for vport delete completions.
  663. */
  664. static void
  665. bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
  666. {
  667. struct bfa_fcs_vport_s *vport;
  668. struct list_head *qe, *qen;
  669. list_for_each_safe(qe, qen, &fabric->vport_q) {
  670. vport = (struct bfa_fcs_vport_s *)qe;
  671. bfa_fcs_vport_fcs_delete(vport);
  672. }
  673. bfa_fcs_port_delete(&fabric->bport);
  674. bfa_wc_wait(&fabric->wc);
  675. }
  676. static void
  677. bfa_fcs_fabric_delete_comp(void *cbarg)
  678. {
  679. struct bfa_fcs_fabric_s *fabric = cbarg;
  680. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
  681. }
  682. /**
  683. * fcs_fabric_public fabric public functions
  684. */
  685. /**
  686. * Attach time initialization
  687. */
  688. void
  689. bfa_fcs_fabric_attach(struct bfa_fcs_s *fcs)
  690. {
  691. struct bfa_fcs_fabric_s *fabric;
  692. fabric = &fcs->fabric;
  693. bfa_os_memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
  694. /**
  695. * Initialize base fabric.
  696. */
  697. fabric->fcs = fcs;
  698. INIT_LIST_HEAD(&fabric->vport_q);
  699. INIT_LIST_HEAD(&fabric->vf_q);
  700. fabric->lps = bfa_lps_alloc(fcs->bfa);
  701. bfa_assert(fabric->lps);
  702. /**
  703. * Initialize fabric delete completion handler. Fabric deletion is complete
  704. * when the last vport delete is complete.
  705. */
  706. bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric);
  707. bfa_wc_up(&fabric->wc); /* For the base port */
  708. bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
  709. bfa_fcs_lport_attach(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, NULL);
  710. }
  711. void
  712. bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
  713. {
  714. bfa_sm_send_event(&fcs->fabric, BFA_FCS_FABRIC_SM_CREATE);
  715. bfa_trc(fcs, 0);
  716. }
  717. /**
  718. * Module cleanup
  719. */
  720. void
  721. bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
  722. {
  723. struct bfa_fcs_fabric_s *fabric;
  724. bfa_trc(fcs, 0);
  725. /**
  726. * Cleanup base fabric.
  727. */
  728. fabric = &fcs->fabric;
  729. bfa_lps_delete(fabric->lps);
  730. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE);
  731. }
  732. /**
  733. * Fabric module start -- kick starts FCS actions
  734. */
  735. void
  736. bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
  737. {
  738. struct bfa_fcs_fabric_s *fabric;
  739. bfa_trc(fcs, 0);
  740. fabric = &fcs->fabric;
  741. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
  742. }
  743. /**
  744. * Suspend fabric activity as part of driver suspend.
  745. */
  746. void
  747. bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs)
  748. {
  749. }
  750. bfa_boolean_t
  751. bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
  752. {
  753. return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback);
  754. }
  755. bfa_boolean_t
  756. bfa_fcs_fabric_is_auth_failed(struct bfa_fcs_fabric_s *fabric)
  757. {
  758. return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_auth_failed);
  759. }
  760. enum bfa_pport_type
  761. bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
  762. {
  763. return fabric->oper_type;
  764. }
  765. /**
  766. * Link up notification from BFA physical port module.
  767. */
  768. void
  769. bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
  770. {
  771. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  772. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
  773. }
  774. /**
  775. * Link down notification from BFA physical port module.
  776. */
  777. void
  778. bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
  779. {
  780. bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
  781. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
  782. }
  783. /**
  784. * A child vport is being created in the fabric.
  785. *
  786. * Call from vport module at vport creation. A list of base port and vports
  787. * belonging to a fabric is maintained to propagate link events.
  788. *
  789. * param[in] fabric - Fabric instance. This can be a base fabric or vf.
  790. * param[in] vport - Vport being created.
  791. *
  792. * @return None (always succeeds)
  793. */
  794. void
  795. bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
  796. struct bfa_fcs_vport_s *vport)
  797. {
  798. /**
  799. * - add vport to fabric's vport_q
  800. */
  801. bfa_trc(fabric->fcs, fabric->vf_id);
  802. list_add_tail(&vport->qe, &fabric->vport_q);
  803. fabric->num_vports++;
  804. bfa_wc_up(&fabric->wc);
  805. }
  806. /**
  807. * A child vport is being deleted from fabric.
  808. *
  809. * Vport is being deleted.
  810. */
  811. void
  812. bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
  813. struct bfa_fcs_vport_s *vport)
  814. {
  815. list_del(&vport->qe);
  816. fabric->num_vports--;
  817. bfa_wc_down(&fabric->wc);
  818. }
  819. /**
  820. * Base port is deleted.
  821. */
  822. void
  823. bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric)
  824. {
  825. bfa_wc_down(&fabric->wc);
  826. }
  827. /**
  828. * Check if fabric is online.
  829. *
  830. * param[in] fabric - Fabric instance. This can be a base fabric or vf.
  831. *
  832. * @return TRUE/FALSE
  833. */
  834. int
  835. bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric)
  836. {
  837. return bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online);
  838. }
  839. bfa_status_t
  840. bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf, struct bfa_fcs_s *fcs,
  841. struct bfa_port_cfg_s *port_cfg,
  842. struct bfad_vf_s *vf_drv)
  843. {
  844. bfa_sm_set_state(vf, bfa_fcs_fabric_sm_uninit);
  845. return BFA_STATUS_OK;
  846. }
  847. /**
  848. * Lookup for a vport withing a fabric given its pwwn
  849. */
  850. struct bfa_fcs_vport_s *
  851. bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
  852. {
  853. struct bfa_fcs_vport_s *vport;
  854. struct list_head *qe;
  855. list_for_each(qe, &fabric->vport_q) {
  856. vport = (struct bfa_fcs_vport_s *)qe;
  857. if (bfa_fcs_port_get_pwwn(&vport->lport) == pwwn)
  858. return vport;
  859. }
  860. return NULL;
  861. }
  862. /**
  863. * In a given fabric, return the number of lports.
  864. *
  865. * param[in] fabric - Fabric instance. This can be a base fabric or vf.
  866. *
  867. * @return : 1 or more.
  868. */
  869. u16
  870. bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric)
  871. {
  872. return fabric->num_vports;
  873. }
  874. /*
  875. * Get OUI of the attached switch.
  876. *
  877. * Note : Use of this function should be avoided as much as possible.
  878. * This function should be used only if there is any requirement
  879. * to check for FOS version below 6.3.
  880. * To check if the attached fabric is a brocade fabric, use
  881. * bfa_lps_is_brcd_fabric() which works for FOS versions 6.3
  882. * or above only.
  883. */
  884. u16
  885. bfa_fcs_fabric_get_switch_oui(struct bfa_fcs_fabric_s *fabric)
  886. {
  887. wwn_t fab_nwwn;
  888. u8 *tmp;
  889. u16 oui;
  890. fab_nwwn = bfa_lps_get_peer_nwwn(fabric->lps);
  891. tmp = (uint8_t *)&fab_nwwn;
  892. oui = (tmp[3] << 8) | tmp[4];
  893. return oui;
  894. }
  895. /**
  896. * Unsolicited frame receive handling.
  897. */
  898. void
  899. bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
  900. u16 len)
  901. {
  902. u32 pid = fchs->d_id;
  903. struct bfa_fcs_vport_s *vport;
  904. struct list_head *qe;
  905. struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
  906. struct fc_logi_s *flogi = (struct fc_logi_s *) els_cmd;
  907. bfa_trc(fabric->fcs, len);
  908. bfa_trc(fabric->fcs, pid);
  909. /**
  910. * Look for our own FLOGI frames being looped back. This means an
  911. * external loopback cable is in place. Our own FLOGI frames are
  912. * sometimes looped back when switch port gets temporarily bypassed.
  913. */
  914. if ((pid == bfa_os_ntoh3b(FC_FABRIC_PORT))
  915. && (els_cmd->els_code == FC_ELS_FLOGI)
  916. && (flogi->port_name == bfa_fcs_port_get_pwwn(&fabric->bport))) {
  917. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
  918. return;
  919. }
  920. /**
  921. * FLOGI/EVFP exchanges should be consumed by base fabric.
  922. */
  923. if (fchs->d_id == bfa_os_hton3b(FC_FABRIC_PORT)) {
  924. bfa_trc(fabric->fcs, pid);
  925. bfa_fcs_fabric_process_uf(fabric, fchs, len);
  926. return;
  927. }
  928. if (fabric->bport.pid == pid) {
  929. /**
  930. * All authentication frames should be routed to auth
  931. */
  932. bfa_trc(fabric->fcs, els_cmd->els_code);
  933. if (els_cmd->els_code == FC_ELS_AUTH) {
  934. bfa_trc(fabric->fcs, els_cmd->els_code);
  935. fabric->auth.response = (u8 *) els_cmd;
  936. return;
  937. }
  938. bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
  939. bfa_fcs_port_uf_recv(&fabric->bport, fchs, len);
  940. return;
  941. }
  942. /**
  943. * look for a matching local port ID
  944. */
  945. list_for_each(qe, &fabric->vport_q) {
  946. vport = (struct bfa_fcs_vport_s *)qe;
  947. if (vport->lport.pid == pid) {
  948. bfa_fcs_port_uf_recv(&vport->lport, fchs, len);
  949. return;
  950. }
  951. }
  952. bfa_trc(fabric->fcs, els_cmd->els_code);
  953. bfa_fcs_port_uf_recv(&fabric->bport, fchs, len);
  954. }
  955. /**
  956. * Unsolicited frames to be processed by fabric.
  957. */
  958. static void
  959. bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
  960. u16 len)
  961. {
  962. struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
  963. bfa_trc(fabric->fcs, els_cmd->els_code);
  964. switch (els_cmd->els_code) {
  965. case FC_ELS_FLOGI:
  966. bfa_fcs_fabric_process_flogi(fabric, fchs, len);
  967. break;
  968. default:
  969. /*
  970. * need to generate a LS_RJT
  971. */
  972. break;
  973. }
  974. }
  975. /**
  976. * Process incoming FLOGI
  977. */
  978. static void
  979. bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
  980. struct fchs_s *fchs, u16 len)
  981. {
  982. struct fc_logi_s *flogi = (struct fc_logi_s *) (fchs + 1);
  983. struct bfa_fcs_port_s *bport = &fabric->bport;
  984. bfa_trc(fabric->fcs, fchs->s_id);
  985. fabric->stats.flogi_rcvd++;
  986. /*
  987. * Check port type. It should be 0 = n-port.
  988. */
  989. if (flogi->csp.port_type) {
  990. /*
  991. * @todo: may need to send a LS_RJT
  992. */
  993. bfa_trc(fabric->fcs, flogi->port_name);
  994. fabric->stats.flogi_rejected++;
  995. return;
  996. }
  997. fabric->bb_credit = bfa_os_ntohs(flogi->csp.bbcred);
  998. bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
  999. bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
  1000. /*
  1001. * Send a Flogi Acc
  1002. */
  1003. bfa_fcs_fabric_send_flogi_acc(fabric);
  1004. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
  1005. }
  1006. static void
  1007. bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
  1008. {
  1009. struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
  1010. struct bfa_fcs_port_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
  1011. struct bfa_s *bfa = fabric->fcs->bfa;
  1012. struct bfa_fcxp_s *fcxp;
  1013. u16 reqlen;
  1014. struct fchs_s fchs;
  1015. fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
  1016. /**
  1017. * Do not expect this failure -- expect remote node to retry
  1018. */
  1019. if (!fcxp)
  1020. return;
  1021. reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  1022. bfa_os_hton3b(FC_FABRIC_PORT),
  1023. n2n_port->reply_oxid, pcfg->pwwn,
  1024. pcfg->nwwn, bfa_fcport_get_maxfrsize(bfa),
  1025. bfa_fcport_get_rx_bbcredit(bfa));
  1026. bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps),
  1027. BFA_FALSE, FC_CLASS_3, reqlen, &fchs,
  1028. bfa_fcs_fabric_flogiacc_comp, fabric,
  1029. FC_MAX_PDUSZ, 0); /* Timeout 0 indicates no
  1030. * response expected
  1031. */
  1032. }
  1033. /**
  1034. * Flogi Acc completion callback.
  1035. */
  1036. static void
  1037. bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
  1038. bfa_status_t status, u32 rsp_len,
  1039. u32 resid_len, struct fchs_s *rspfchs)
  1040. {
  1041. struct bfa_fcs_fabric_s *fabric = cbarg;
  1042. bfa_trc(fabric->fcs, status);
  1043. }
  1044. /*
  1045. *
  1046. * @param[in] fabric - fabric
  1047. * @param[in] result - 1
  1048. *
  1049. * @return - none
  1050. */
  1051. void
  1052. bfa_fcs_auth_finished(struct bfa_fcs_fabric_s *fabric, enum auth_status status)
  1053. {
  1054. bfa_trc(fabric->fcs, status);
  1055. if (status == FC_AUTH_STATE_SUCCESS)
  1056. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_SUCCESS);
  1057. else
  1058. bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_FAILED);
  1059. }
  1060. /**
  1061. * Send AEN notification
  1062. */
  1063. static void
  1064. bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port,
  1065. enum bfa_port_aen_event event)
  1066. {
  1067. union bfa_aen_data_u aen_data;
  1068. struct bfa_log_mod_s *logmod = port->fcs->logm;
  1069. wwn_t pwwn = bfa_fcs_port_get_pwwn(port);
  1070. wwn_t fwwn = bfa_fcs_port_get_fabric_name(port);
  1071. char pwwn_ptr[BFA_STRING_32];
  1072. char fwwn_ptr[BFA_STRING_32];
  1073. wwn2str(pwwn_ptr, pwwn);
  1074. wwn2str(fwwn_ptr, fwwn);
  1075. bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event),
  1076. pwwn_ptr, fwwn_ptr);
  1077. aen_data.port.pwwn = pwwn;
  1078. aen_data.port.fwwn = fwwn;
  1079. }
  1080. /*
  1081. *
  1082. * @param[in] fabric - fabric
  1083. * @param[in] wwn_t - new fabric name
  1084. *
  1085. * @return - none
  1086. */
  1087. void
  1088. bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
  1089. wwn_t fabric_name)
  1090. {
  1091. bfa_trc(fabric->fcs, fabric_name);
  1092. if (fabric->fabric_name == 0) {
  1093. /*
  1094. * With BRCD switches, we don't get Fabric Name in FLOGI.
  1095. * Don't generate a fabric name change event in this case.
  1096. */
  1097. fabric->fabric_name = fabric_name;
  1098. } else {
  1099. fabric->fabric_name = fabric_name;
  1100. /*
  1101. * Generate a Event
  1102. */
  1103. bfa_fcs_fabric_aen_post(&fabric->bport,
  1104. BFA_PORT_AEN_FABRIC_NAME_CHANGE);
  1105. }
  1106. }
  1107. /**
  1108. *
  1109. * @param[in] fabric - fabric
  1110. * @param[in] node_symname -
  1111. * Caller allocated buffer to receive the symbolic name
  1112. *
  1113. * @return - none
  1114. */
  1115. void
  1116. bfa_fcs_get_sym_name(const struct bfa_fcs_s *fcs, char *node_symname)
  1117. {
  1118. bfa_os_memcpy(node_symname,
  1119. fcs->fabric.bport.port_cfg.sym_name.symname,
  1120. BFA_SYMNAME_MAXLEN);
  1121. }
  1122. /**
  1123. * Not used by FCS.
  1124. */
  1125. void
  1126. bfa_cb_lps_flogo_comp(void *bfad, void *uarg)
  1127. {
  1128. }