bfa_rport.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  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 <cs/bfa_debug.h>
  20. #include <bfi/bfi_rport.h>
  21. #include "bfa_intr_priv.h"
  22. BFA_TRC_FILE(HAL, RPORT);
  23. BFA_MODULE(rport);
  24. #define bfa_rport_offline_cb(__rp) do { \
  25. if ((__rp)->bfa->fcs) \
  26. bfa_cb_rport_offline((__rp)->rport_drv); \
  27. else { \
  28. bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \
  29. __bfa_cb_rport_offline, (__rp)); \
  30. } \
  31. } while (0)
  32. #define bfa_rport_online_cb(__rp) do { \
  33. if ((__rp)->bfa->fcs) \
  34. bfa_cb_rport_online((__rp)->rport_drv); \
  35. else { \
  36. bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \
  37. __bfa_cb_rport_online, (__rp)); \
  38. } \
  39. } while (0)
  40. /*
  41. * forward declarations
  42. */
  43. static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod);
  44. static void bfa_rport_free(struct bfa_rport_s *rport);
  45. static bfa_boolean_t bfa_rport_send_fwcreate(struct bfa_rport_s *rp);
  46. static bfa_boolean_t bfa_rport_send_fwdelete(struct bfa_rport_s *rp);
  47. static bfa_boolean_t bfa_rport_send_fwspeed(struct bfa_rport_s *rp);
  48. static void __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete);
  49. static void __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete);
  50. /**
  51. * bfa_rport_sm BFA rport state machine
  52. */
  53. enum bfa_rport_event {
  54. BFA_RPORT_SM_CREATE = 1, /* rport create event */
  55. BFA_RPORT_SM_DELETE = 2, /* deleting an existing rport */
  56. BFA_RPORT_SM_ONLINE = 3, /* rport is online */
  57. BFA_RPORT_SM_OFFLINE = 4, /* rport is offline */
  58. BFA_RPORT_SM_FWRSP = 5, /* firmware response */
  59. BFA_RPORT_SM_HWFAIL = 6, /* IOC h/w failure */
  60. BFA_RPORT_SM_QOS_SCN = 7, /* QoS SCN from firmware */
  61. BFA_RPORT_SM_SET_SPEED = 8, /* Set Rport Speed */
  62. BFA_RPORT_SM_QRESUME = 9, /* space in requeue queue */
  63. };
  64. static void bfa_rport_sm_uninit(struct bfa_rport_s *rp,
  65. enum bfa_rport_event event);
  66. static void bfa_rport_sm_created(struct bfa_rport_s *rp,
  67. enum bfa_rport_event event);
  68. static void bfa_rport_sm_fwcreate(struct bfa_rport_s *rp,
  69. enum bfa_rport_event event);
  70. static void bfa_rport_sm_online(struct bfa_rport_s *rp,
  71. enum bfa_rport_event event);
  72. static void bfa_rport_sm_fwdelete(struct bfa_rport_s *rp,
  73. enum bfa_rport_event event);
  74. static void bfa_rport_sm_offline(struct bfa_rport_s *rp,
  75. enum bfa_rport_event event);
  76. static void bfa_rport_sm_deleting(struct bfa_rport_s *rp,
  77. enum bfa_rport_event event);
  78. static void bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
  79. enum bfa_rport_event event);
  80. static void bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
  81. enum bfa_rport_event event);
  82. static void bfa_rport_sm_iocdisable(struct bfa_rport_s *rp,
  83. enum bfa_rport_event event);
  84. static void bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp,
  85. enum bfa_rport_event event);
  86. static void bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp,
  87. enum bfa_rport_event event);
  88. static void bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp,
  89. enum bfa_rport_event event);
  90. /**
  91. * Beginning state, only online event expected.
  92. */
  93. static void
  94. bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event)
  95. {
  96. bfa_trc(rp->bfa, rp->rport_tag);
  97. bfa_trc(rp->bfa, event);
  98. switch (event) {
  99. case BFA_RPORT_SM_CREATE:
  100. bfa_stats(rp, sm_un_cr);
  101. bfa_sm_set_state(rp, bfa_rport_sm_created);
  102. break;
  103. default:
  104. bfa_stats(rp, sm_un_unexp);
  105. bfa_assert(0);
  106. }
  107. }
  108. static void
  109. bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
  110. {
  111. bfa_trc(rp->bfa, rp->rport_tag);
  112. bfa_trc(rp->bfa, event);
  113. switch (event) {
  114. case BFA_RPORT_SM_ONLINE:
  115. bfa_stats(rp, sm_cr_on);
  116. if (bfa_rport_send_fwcreate(rp))
  117. bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
  118. else
  119. bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
  120. break;
  121. case BFA_RPORT_SM_DELETE:
  122. bfa_stats(rp, sm_cr_del);
  123. bfa_sm_set_state(rp, bfa_rport_sm_uninit);
  124. bfa_rport_free(rp);
  125. break;
  126. case BFA_RPORT_SM_HWFAIL:
  127. bfa_stats(rp, sm_cr_hwf);
  128. bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
  129. break;
  130. default:
  131. bfa_stats(rp, sm_cr_unexp);
  132. bfa_assert(0);
  133. }
  134. }
  135. /**
  136. * Waiting for rport create response from firmware.
  137. */
  138. static void
  139. bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
  140. {
  141. bfa_trc(rp->bfa, rp->rport_tag);
  142. bfa_trc(rp->bfa, event);
  143. switch (event) {
  144. case BFA_RPORT_SM_FWRSP:
  145. bfa_stats(rp, sm_fwc_rsp);
  146. bfa_sm_set_state(rp, bfa_rport_sm_online);
  147. bfa_rport_online_cb(rp);
  148. break;
  149. case BFA_RPORT_SM_DELETE:
  150. bfa_stats(rp, sm_fwc_del);
  151. bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
  152. break;
  153. case BFA_RPORT_SM_OFFLINE:
  154. bfa_stats(rp, sm_fwc_off);
  155. bfa_sm_set_state(rp, bfa_rport_sm_offline_pending);
  156. break;
  157. case BFA_RPORT_SM_HWFAIL:
  158. bfa_stats(rp, sm_fwc_hwf);
  159. bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
  160. break;
  161. default:
  162. bfa_stats(rp, sm_fwc_unexp);
  163. bfa_assert(0);
  164. }
  165. }
  166. /**
  167. * Request queue is full, awaiting queue resume to send create request.
  168. */
  169. static void
  170. bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
  171. {
  172. bfa_trc(rp->bfa, rp->rport_tag);
  173. bfa_trc(rp->bfa, event);
  174. switch (event) {
  175. case BFA_RPORT_SM_QRESUME:
  176. bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
  177. bfa_rport_send_fwcreate(rp);
  178. break;
  179. case BFA_RPORT_SM_DELETE:
  180. bfa_stats(rp, sm_fwc_del);
  181. bfa_sm_set_state(rp, bfa_rport_sm_uninit);
  182. bfa_reqq_wcancel(&rp->reqq_wait);
  183. bfa_rport_free(rp);
  184. break;
  185. case BFA_RPORT_SM_OFFLINE:
  186. bfa_stats(rp, sm_fwc_off);
  187. bfa_sm_set_state(rp, bfa_rport_sm_offline);
  188. bfa_reqq_wcancel(&rp->reqq_wait);
  189. bfa_rport_offline_cb(rp);
  190. break;
  191. case BFA_RPORT_SM_HWFAIL:
  192. bfa_stats(rp, sm_fwc_hwf);
  193. bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
  194. bfa_reqq_wcancel(&rp->reqq_wait);
  195. break;
  196. default:
  197. bfa_stats(rp, sm_fwc_unexp);
  198. bfa_assert(0);
  199. }
  200. }
  201. /**
  202. * Online state - normal parking state.
  203. */
  204. static void
  205. bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
  206. {
  207. struct bfi_rport_qos_scn_s *qos_scn;
  208. bfa_trc(rp->bfa, rp->rport_tag);
  209. bfa_trc(rp->bfa, event);
  210. switch (event) {
  211. case BFA_RPORT_SM_OFFLINE:
  212. bfa_stats(rp, sm_on_off);
  213. if (bfa_rport_send_fwdelete(rp))
  214. bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
  215. else
  216. bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
  217. break;
  218. case BFA_RPORT_SM_DELETE:
  219. bfa_stats(rp, sm_on_del);
  220. if (bfa_rport_send_fwdelete(rp))
  221. bfa_sm_set_state(rp, bfa_rport_sm_deleting);
  222. else
  223. bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
  224. break;
  225. case BFA_RPORT_SM_HWFAIL:
  226. bfa_stats(rp, sm_on_hwf);
  227. bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
  228. break;
  229. case BFA_RPORT_SM_SET_SPEED:
  230. bfa_rport_send_fwspeed(rp);
  231. break;
  232. case BFA_RPORT_SM_QOS_SCN:
  233. qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg;
  234. rp->qos_attr = qos_scn->new_qos_attr;
  235. bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id);
  236. bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id);
  237. bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority);
  238. bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority);
  239. qos_scn->old_qos_attr.qos_flow_id =
  240. bfa_os_ntohl(qos_scn->old_qos_attr.qos_flow_id);
  241. qos_scn->new_qos_attr.qos_flow_id =
  242. bfa_os_ntohl(qos_scn->new_qos_attr.qos_flow_id);
  243. qos_scn->old_qos_attr.qos_priority =
  244. bfa_os_ntohl(qos_scn->old_qos_attr.qos_priority);
  245. qos_scn->new_qos_attr.qos_priority =
  246. bfa_os_ntohl(qos_scn->new_qos_attr.qos_priority);
  247. if (qos_scn->old_qos_attr.qos_flow_id !=
  248. qos_scn->new_qos_attr.qos_flow_id)
  249. bfa_cb_rport_qos_scn_flowid(rp->rport_drv,
  250. qos_scn->old_qos_attr,
  251. qos_scn->new_qos_attr);
  252. if (qos_scn->old_qos_attr.qos_priority !=
  253. qos_scn->new_qos_attr.qos_priority)
  254. bfa_cb_rport_qos_scn_prio(rp->rport_drv,
  255. qos_scn->old_qos_attr,
  256. qos_scn->new_qos_attr);
  257. break;
  258. default:
  259. bfa_stats(rp, sm_on_unexp);
  260. bfa_assert(0);
  261. }
  262. }
  263. /**
  264. * Firmware rport is being deleted - awaiting f/w response.
  265. */
  266. static void
  267. bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event)
  268. {
  269. bfa_trc(rp->bfa, rp->rport_tag);
  270. bfa_trc(rp->bfa, event);
  271. switch (event) {
  272. case BFA_RPORT_SM_FWRSP:
  273. bfa_stats(rp, sm_fwd_rsp);
  274. bfa_sm_set_state(rp, bfa_rport_sm_offline);
  275. bfa_rport_offline_cb(rp);
  276. break;
  277. case BFA_RPORT_SM_DELETE:
  278. bfa_stats(rp, sm_fwd_del);
  279. bfa_sm_set_state(rp, bfa_rport_sm_deleting);
  280. break;
  281. case BFA_RPORT_SM_HWFAIL:
  282. bfa_stats(rp, sm_fwd_hwf);
  283. bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
  284. bfa_rport_offline_cb(rp);
  285. break;
  286. default:
  287. bfa_stats(rp, sm_fwd_unexp);
  288. bfa_assert(0);
  289. }
  290. }
  291. static void
  292. bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
  293. {
  294. bfa_trc(rp->bfa, rp->rport_tag);
  295. bfa_trc(rp->bfa, event);
  296. switch (event) {
  297. case BFA_RPORT_SM_QRESUME:
  298. bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
  299. bfa_rport_send_fwdelete(rp);
  300. break;
  301. case BFA_RPORT_SM_DELETE:
  302. bfa_stats(rp, sm_fwd_del);
  303. bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
  304. break;
  305. case BFA_RPORT_SM_HWFAIL:
  306. bfa_stats(rp, sm_fwd_hwf);
  307. bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
  308. bfa_reqq_wcancel(&rp->reqq_wait);
  309. bfa_rport_offline_cb(rp);
  310. break;
  311. default:
  312. bfa_stats(rp, sm_fwd_unexp);
  313. bfa_assert(0);
  314. }
  315. }
  316. /**
  317. * Offline state.
  318. */
  319. static void
  320. bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
  321. {
  322. bfa_trc(rp->bfa, rp->rport_tag);
  323. bfa_trc(rp->bfa, event);
  324. switch (event) {
  325. case BFA_RPORT_SM_DELETE:
  326. bfa_stats(rp, sm_off_del);
  327. bfa_sm_set_state(rp, bfa_rport_sm_uninit);
  328. bfa_rport_free(rp);
  329. break;
  330. case BFA_RPORT_SM_ONLINE:
  331. bfa_stats(rp, sm_off_on);
  332. if (bfa_rport_send_fwcreate(rp))
  333. bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
  334. else
  335. bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
  336. break;
  337. case BFA_RPORT_SM_HWFAIL:
  338. bfa_stats(rp, sm_off_hwf);
  339. bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
  340. break;
  341. default:
  342. bfa_stats(rp, sm_off_unexp);
  343. bfa_assert(0);
  344. }
  345. }
  346. /**
  347. * Rport is deleted, waiting for firmware response to delete.
  348. */
  349. static void
  350. bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event)
  351. {
  352. bfa_trc(rp->bfa, rp->rport_tag);
  353. bfa_trc(rp->bfa, event);
  354. switch (event) {
  355. case BFA_RPORT_SM_FWRSP:
  356. bfa_stats(rp, sm_del_fwrsp);
  357. bfa_sm_set_state(rp, bfa_rport_sm_uninit);
  358. bfa_rport_free(rp);
  359. break;
  360. case BFA_RPORT_SM_HWFAIL:
  361. bfa_stats(rp, sm_del_hwf);
  362. bfa_sm_set_state(rp, bfa_rport_sm_uninit);
  363. bfa_rport_free(rp);
  364. break;
  365. default:
  366. bfa_assert(0);
  367. }
  368. }
  369. static void
  370. bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
  371. {
  372. bfa_trc(rp->bfa, rp->rport_tag);
  373. bfa_trc(rp->bfa, event);
  374. switch (event) {
  375. case BFA_RPORT_SM_QRESUME:
  376. bfa_stats(rp, sm_del_fwrsp);
  377. bfa_sm_set_state(rp, bfa_rport_sm_deleting);
  378. bfa_rport_send_fwdelete(rp);
  379. break;
  380. case BFA_RPORT_SM_HWFAIL:
  381. bfa_stats(rp, sm_del_hwf);
  382. bfa_sm_set_state(rp, bfa_rport_sm_uninit);
  383. bfa_reqq_wcancel(&rp->reqq_wait);
  384. bfa_rport_free(rp);
  385. break;
  386. default:
  387. bfa_assert(0);
  388. }
  389. }
  390. /**
  391. * Waiting for rport create response from firmware. A delete is pending.
  392. */
  393. static void
  394. bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
  395. enum bfa_rport_event event)
  396. {
  397. bfa_trc(rp->bfa, rp->rport_tag);
  398. bfa_trc(rp->bfa, event);
  399. switch (event) {
  400. case BFA_RPORT_SM_FWRSP:
  401. bfa_stats(rp, sm_delp_fwrsp);
  402. if (bfa_rport_send_fwdelete(rp))
  403. bfa_sm_set_state(rp, bfa_rport_sm_deleting);
  404. else
  405. bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
  406. break;
  407. case BFA_RPORT_SM_HWFAIL:
  408. bfa_stats(rp, sm_delp_hwf);
  409. bfa_sm_set_state(rp, bfa_rport_sm_uninit);
  410. bfa_rport_free(rp);
  411. break;
  412. default:
  413. bfa_stats(rp, sm_delp_unexp);
  414. bfa_assert(0);
  415. }
  416. }
  417. /**
  418. * Waiting for rport create response from firmware. Rport offline is pending.
  419. */
  420. static void
  421. bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
  422. enum bfa_rport_event event)
  423. {
  424. bfa_trc(rp->bfa, rp->rport_tag);
  425. bfa_trc(rp->bfa, event);
  426. switch (event) {
  427. case BFA_RPORT_SM_FWRSP:
  428. bfa_stats(rp, sm_offp_fwrsp);
  429. if (bfa_rport_send_fwdelete(rp))
  430. bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
  431. else
  432. bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
  433. break;
  434. case BFA_RPORT_SM_DELETE:
  435. bfa_stats(rp, sm_offp_del);
  436. bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
  437. break;
  438. case BFA_RPORT_SM_HWFAIL:
  439. bfa_stats(rp, sm_offp_hwf);
  440. bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
  441. break;
  442. default:
  443. bfa_stats(rp, sm_offp_unexp);
  444. bfa_assert(0);
  445. }
  446. }
  447. /**
  448. * IOC h/w failed.
  449. */
  450. static void
  451. bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
  452. {
  453. bfa_trc(rp->bfa, rp->rport_tag);
  454. bfa_trc(rp->bfa, event);
  455. switch (event) {
  456. case BFA_RPORT_SM_OFFLINE:
  457. bfa_stats(rp, sm_iocd_off);
  458. bfa_rport_offline_cb(rp);
  459. break;
  460. case BFA_RPORT_SM_DELETE:
  461. bfa_stats(rp, sm_iocd_del);
  462. bfa_sm_set_state(rp, bfa_rport_sm_uninit);
  463. bfa_rport_free(rp);
  464. break;
  465. case BFA_RPORT_SM_ONLINE:
  466. bfa_stats(rp, sm_iocd_on);
  467. if (bfa_rport_send_fwcreate(rp))
  468. bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
  469. else
  470. bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
  471. break;
  472. case BFA_RPORT_SM_HWFAIL:
  473. break;
  474. default:
  475. bfa_stats(rp, sm_iocd_unexp);
  476. bfa_assert(0);
  477. }
  478. }
  479. /**
  480. * bfa_rport_private BFA rport private functions
  481. */
  482. static void
  483. __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete)
  484. {
  485. struct bfa_rport_s *rp = cbarg;
  486. if (complete)
  487. bfa_cb_rport_online(rp->rport_drv);
  488. }
  489. static void
  490. __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete)
  491. {
  492. struct bfa_rport_s *rp = cbarg;
  493. if (complete)
  494. bfa_cb_rport_offline(rp->rport_drv);
  495. }
  496. static void
  497. bfa_rport_qresume(void *cbarg)
  498. {
  499. struct bfa_rport_s *rp = cbarg;
  500. bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME);
  501. }
  502. static void
  503. bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
  504. u32 *dm_len)
  505. {
  506. if (cfg->fwcfg.num_rports < BFA_RPORT_MIN)
  507. cfg->fwcfg.num_rports = BFA_RPORT_MIN;
  508. *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s);
  509. }
  510. static void
  511. bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
  512. struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
  513. {
  514. struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
  515. struct bfa_rport_s *rp;
  516. u16 i;
  517. INIT_LIST_HEAD(&mod->rp_free_q);
  518. INIT_LIST_HEAD(&mod->rp_active_q);
  519. rp = (struct bfa_rport_s *) bfa_meminfo_kva(meminfo);
  520. mod->rps_list = rp;
  521. mod->num_rports = cfg->fwcfg.num_rports;
  522. bfa_assert(mod->num_rports
  523. && !(mod->num_rports & (mod->num_rports - 1)));
  524. for (i = 0; i < mod->num_rports; i++, rp++) {
  525. bfa_os_memset(rp, 0, sizeof(struct bfa_rport_s));
  526. rp->bfa = bfa;
  527. rp->rport_tag = i;
  528. bfa_sm_set_state(rp, bfa_rport_sm_uninit);
  529. /**
  530. * - is unused
  531. */
  532. if (i)
  533. list_add_tail(&rp->qe, &mod->rp_free_q);
  534. bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp);
  535. }
  536. /**
  537. * consume memory
  538. */
  539. bfa_meminfo_kva(meminfo) = (u8 *) rp;
  540. }
  541. static void
  542. bfa_rport_initdone(struct bfa_s *bfa)
  543. {
  544. }
  545. static void
  546. bfa_rport_detach(struct bfa_s *bfa)
  547. {
  548. }
  549. static void
  550. bfa_rport_start(struct bfa_s *bfa)
  551. {
  552. }
  553. static void
  554. bfa_rport_stop(struct bfa_s *bfa)
  555. {
  556. }
  557. static void
  558. bfa_rport_iocdisable(struct bfa_s *bfa)
  559. {
  560. struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
  561. struct bfa_rport_s *rport;
  562. struct list_head *qe, *qen;
  563. list_for_each_safe(qe, qen, &mod->rp_active_q) {
  564. rport = (struct bfa_rport_s *) qe;
  565. bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL);
  566. }
  567. }
  568. static struct bfa_rport_s *
  569. bfa_rport_alloc(struct bfa_rport_mod_s *mod)
  570. {
  571. struct bfa_rport_s *rport;
  572. bfa_q_deq(&mod->rp_free_q, &rport);
  573. if (rport)
  574. list_add_tail(&rport->qe, &mod->rp_active_q);
  575. return rport;
  576. }
  577. static void
  578. bfa_rport_free(struct bfa_rport_s *rport)
  579. {
  580. struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa);
  581. bfa_assert(bfa_q_is_on_q(&mod->rp_active_q, rport));
  582. list_del(&rport->qe);
  583. list_add_tail(&rport->qe, &mod->rp_free_q);
  584. }
  585. static bfa_boolean_t
  586. bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
  587. {
  588. struct bfi_rport_create_req_s *m;
  589. /**
  590. * check for room in queue to send request now
  591. */
  592. m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
  593. if (!m) {
  594. bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
  595. return BFA_FALSE;
  596. }
  597. bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ,
  598. bfa_lpuid(rp->bfa));
  599. m->bfa_handle = rp->rport_tag;
  600. m->max_frmsz = bfa_os_htons(rp->rport_info.max_frmsz);
  601. m->pid = rp->rport_info.pid;
  602. m->lp_tag = rp->rport_info.lp_tag;
  603. m->local_pid = rp->rport_info.local_pid;
  604. m->fc_class = rp->rport_info.fc_class;
  605. m->vf_en = rp->rport_info.vf_en;
  606. m->vf_id = rp->rport_info.vf_id;
  607. m->cisc = rp->rport_info.cisc;
  608. /**
  609. * queue I/O message to firmware
  610. */
  611. bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
  612. return BFA_TRUE;
  613. }
  614. static bfa_boolean_t
  615. bfa_rport_send_fwdelete(struct bfa_rport_s *rp)
  616. {
  617. struct bfi_rport_delete_req_s *m;
  618. /**
  619. * check for room in queue to send request now
  620. */
  621. m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
  622. if (!m) {
  623. bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
  624. return BFA_FALSE;
  625. }
  626. bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ,
  627. bfa_lpuid(rp->bfa));
  628. m->fw_handle = rp->fw_handle;
  629. /**
  630. * queue I/O message to firmware
  631. */
  632. bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
  633. return BFA_TRUE;
  634. }
  635. static bfa_boolean_t
  636. bfa_rport_send_fwspeed(struct bfa_rport_s *rp)
  637. {
  638. struct bfa_rport_speed_req_s *m;
  639. /**
  640. * check for room in queue to send request now
  641. */
  642. m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
  643. if (!m) {
  644. bfa_trc(rp->bfa, rp->rport_info.speed);
  645. return BFA_FALSE;
  646. }
  647. bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ,
  648. bfa_lpuid(rp->bfa));
  649. m->fw_handle = rp->fw_handle;
  650. m->speed = (u8)rp->rport_info.speed;
  651. /**
  652. * queue I/O message to firmware
  653. */
  654. bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
  655. return BFA_TRUE;
  656. }
  657. /**
  658. * bfa_rport_public
  659. */
  660. /**
  661. * Rport interrupt processing.
  662. */
  663. void
  664. bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
  665. {
  666. union bfi_rport_i2h_msg_u msg;
  667. struct bfa_rport_s *rp;
  668. bfa_trc(bfa, m->mhdr.msg_id);
  669. msg.msg = m;
  670. switch (m->mhdr.msg_id) {
  671. case BFI_RPORT_I2H_CREATE_RSP:
  672. rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle);
  673. rp->fw_handle = msg.create_rsp->fw_handle;
  674. rp->qos_attr = msg.create_rsp->qos_attr;
  675. bfa_assert(msg.create_rsp->status == BFA_STATUS_OK);
  676. bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
  677. break;
  678. case BFI_RPORT_I2H_DELETE_RSP:
  679. rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle);
  680. bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK);
  681. bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
  682. break;
  683. case BFI_RPORT_I2H_QOS_SCN:
  684. rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle);
  685. rp->event_arg.fw_msg = msg.qos_scn_evt;
  686. bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN);
  687. break;
  688. default:
  689. bfa_trc(bfa, m->mhdr.msg_id);
  690. bfa_assert(0);
  691. }
  692. }
  693. /**
  694. * bfa_rport_api
  695. */
  696. struct bfa_rport_s *
  697. bfa_rport_create(struct bfa_s *bfa, void *rport_drv)
  698. {
  699. struct bfa_rport_s *rp;
  700. rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa));
  701. if (rp == NULL)
  702. return NULL;
  703. rp->bfa = bfa;
  704. rp->rport_drv = rport_drv;
  705. bfa_rport_clear_stats(rp);
  706. bfa_assert(bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
  707. bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE);
  708. return rp;
  709. }
  710. void
  711. bfa_rport_delete(struct bfa_rport_s *rport)
  712. {
  713. bfa_sm_send_event(rport, BFA_RPORT_SM_DELETE);
  714. }
  715. void
  716. bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
  717. {
  718. bfa_assert(rport_info->max_frmsz != 0);
  719. /**
  720. * Some JBODs are seen to be not setting PDU size correctly in PLOGI
  721. * responses. Default to minimum size.
  722. */
  723. if (rport_info->max_frmsz == 0) {
  724. bfa_trc(rport->bfa, rport->rport_tag);
  725. rport_info->max_frmsz = FC_MIN_PDUSZ;
  726. }
  727. bfa_os_assign(rport->rport_info, *rport_info);
  728. bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE);
  729. }
  730. void
  731. bfa_rport_offline(struct bfa_rport_s *rport)
  732. {
  733. bfa_sm_send_event(rport, BFA_RPORT_SM_OFFLINE);
  734. }
  735. void
  736. bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_pport_speed speed)
  737. {
  738. bfa_assert(speed != 0);
  739. bfa_assert(speed != BFA_PPORT_SPEED_AUTO);
  740. rport->rport_info.speed = speed;
  741. bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
  742. }
  743. void
  744. bfa_rport_get_stats(struct bfa_rport_s *rport,
  745. struct bfa_rport_hal_stats_s *stats)
  746. {
  747. *stats = rport->stats;
  748. }
  749. void
  750. bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
  751. struct bfa_rport_qos_attr_s *qos_attr)
  752. {
  753. qos_attr->qos_priority = bfa_os_ntohl(rport->qos_attr.qos_priority);
  754. qos_attr->qos_flow_id = bfa_os_ntohl(rport->qos_attr.qos_flow_id);
  755. }
  756. void
  757. bfa_rport_clear_stats(struct bfa_rport_s *rport)
  758. {
  759. bfa_os_memset(&rport->stats, 0, sizeof(rport->stats));
  760. }