bfa_fcport.c 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945
  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 <bfi/bfi_pport.h>
  20. #include <bfi/bfi_pbc.h>
  21. #include <cs/bfa_debug.h>
  22. #include <aen/bfa_aen.h>
  23. #include <cs/bfa_plog.h>
  24. #include <aen/bfa_aen_port.h>
  25. BFA_TRC_FILE(HAL, FCPORT);
  26. BFA_MODULE(fcport);
  27. /*
  28. * The port is considered disabled if corresponding physical port or IOC are
  29. * disabled explicitly
  30. */
  31. #define BFA_PORT_IS_DISABLED(bfa) \
  32. ((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
  33. (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
  34. /*
  35. * forward declarations
  36. */
  37. static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
  38. static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport);
  39. static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport);
  40. static void bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport);
  41. static void bfa_fcport_set_wwns(struct bfa_fcport_s *fcport);
  42. static void __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete);
  43. static void bfa_fcport_callback(struct bfa_fcport_s *fcport,
  44. enum bfa_pport_linkstate event);
  45. static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln,
  46. enum bfa_pport_linkstate event);
  47. static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete);
  48. static void bfa_fcport_stats_get_timeout(void *cbarg);
  49. static void bfa_fcport_stats_clr_timeout(void *cbarg);
  50. /**
  51. * bfa_pport_private
  52. */
  53. /**
  54. * BFA port state machine events
  55. */
  56. enum bfa_fcport_sm_event {
  57. BFA_FCPORT_SM_START = 1, /* start port state machine */
  58. BFA_FCPORT_SM_STOP = 2, /* stop port state machine */
  59. BFA_FCPORT_SM_ENABLE = 3, /* enable port */
  60. BFA_FCPORT_SM_DISABLE = 4, /* disable port state machine */
  61. BFA_FCPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */
  62. BFA_FCPORT_SM_LINKUP = 6, /* firmware linkup event */
  63. BFA_FCPORT_SM_LINKDOWN = 7, /* firmware linkup down */
  64. BFA_FCPORT_SM_QRESUME = 8, /* CQ space available */
  65. BFA_FCPORT_SM_HWFAIL = 9, /* IOC h/w failure */
  66. };
  67. /**
  68. * BFA port link notification state machine events
  69. */
  70. enum bfa_fcport_ln_sm_event {
  71. BFA_FCPORT_LN_SM_LINKUP = 1, /* linkup event */
  72. BFA_FCPORT_LN_SM_LINKDOWN = 2, /* linkdown event */
  73. BFA_FCPORT_LN_SM_NOTIFICATION = 3 /* done notification */
  74. };
  75. static void bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
  76. enum bfa_fcport_sm_event event);
  77. static void bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
  78. enum bfa_fcport_sm_event event);
  79. static void bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
  80. enum bfa_fcport_sm_event event);
  81. static void bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
  82. enum bfa_fcport_sm_event event);
  83. static void bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
  84. enum bfa_fcport_sm_event event);
  85. static void bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
  86. enum bfa_fcport_sm_event event);
  87. static void bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
  88. enum bfa_fcport_sm_event event);
  89. static void bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
  90. enum bfa_fcport_sm_event event);
  91. static void bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
  92. enum bfa_fcport_sm_event event);
  93. static void bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
  94. enum bfa_fcport_sm_event event);
  95. static void bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
  96. enum bfa_fcport_sm_event event);
  97. static void bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
  98. enum bfa_fcport_ln_sm_event event);
  99. static void bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
  100. enum bfa_fcport_ln_sm_event event);
  101. static void bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
  102. enum bfa_fcport_ln_sm_event event);
  103. static void bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
  104. enum bfa_fcport_ln_sm_event event);
  105. static void bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
  106. enum bfa_fcport_ln_sm_event event);
  107. static void bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
  108. enum bfa_fcport_ln_sm_event event);
  109. static void bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
  110. enum bfa_fcport_ln_sm_event event);
  111. static struct bfa_sm_table_s hal_pport_sm_table[] = {
  112. {BFA_SM(bfa_fcport_sm_uninit), BFA_PPORT_ST_UNINIT},
  113. {BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
  114. {BFA_SM(bfa_fcport_sm_enabling), BFA_PPORT_ST_ENABLING},
  115. {BFA_SM(bfa_fcport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
  116. {BFA_SM(bfa_fcport_sm_linkup), BFA_PPORT_ST_LINKUP},
  117. {BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PPORT_ST_DISABLING_QWAIT},
  118. {BFA_SM(bfa_fcport_sm_disabling), BFA_PPORT_ST_DISABLING},
  119. {BFA_SM(bfa_fcport_sm_disabled), BFA_PPORT_ST_DISABLED},
  120. {BFA_SM(bfa_fcport_sm_stopped), BFA_PPORT_ST_STOPPED},
  121. {BFA_SM(bfa_fcport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
  122. {BFA_SM(bfa_fcport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
  123. };
  124. static void
  125. bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
  126. {
  127. union bfa_aen_data_u aen_data;
  128. struct bfa_log_mod_s *logmod = fcport->bfa->logm;
  129. wwn_t pwwn = fcport->pwwn;
  130. char pwwn_ptr[BFA_STRING_32];
  131. memset(&aen_data, 0, sizeof(aen_data));
  132. wwn2str(pwwn_ptr, pwwn);
  133. bfa_log(logmod, BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, event), pwwn_ptr);
  134. aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
  135. aen_data.port.pwwn = pwwn;
  136. }
  137. static void
  138. bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
  139. enum bfa_fcport_sm_event event)
  140. {
  141. bfa_trc(fcport->bfa, event);
  142. switch (event) {
  143. case BFA_FCPORT_SM_START:
  144. /**
  145. * Start event after IOC is configured and BFA is started.
  146. */
  147. if (bfa_fcport_send_enable(fcport))
  148. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
  149. else
  150. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
  151. break;
  152. case BFA_FCPORT_SM_ENABLE:
  153. /**
  154. * Port is persistently configured to be in enabled state. Do
  155. * not change state. Port enabling is done when START event is
  156. * received.
  157. */
  158. break;
  159. case BFA_FCPORT_SM_DISABLE:
  160. /**
  161. * If a port is persistently configured to be disabled, the
  162. * first event will a port disable request.
  163. */
  164. bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
  165. break;
  166. case BFA_FCPORT_SM_HWFAIL:
  167. bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
  168. break;
  169. default:
  170. bfa_sm_fault(fcport->bfa, event);
  171. }
  172. }
  173. static void
  174. bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
  175. enum bfa_fcport_sm_event event)
  176. {
  177. bfa_trc(fcport->bfa, event);
  178. switch (event) {
  179. case BFA_FCPORT_SM_QRESUME:
  180. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
  181. bfa_fcport_send_enable(fcport);
  182. break;
  183. case BFA_FCPORT_SM_STOP:
  184. bfa_reqq_wcancel(&fcport->reqq_wait);
  185. bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
  186. break;
  187. case BFA_FCPORT_SM_ENABLE:
  188. /**
  189. * Already enable is in progress.
  190. */
  191. break;
  192. case BFA_FCPORT_SM_DISABLE:
  193. /**
  194. * Just send disable request to firmware when room becomes
  195. * available in request queue.
  196. */
  197. bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
  198. bfa_reqq_wcancel(&fcport->reqq_wait);
  199. bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
  200. BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
  201. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
  202. break;
  203. case BFA_FCPORT_SM_LINKUP:
  204. case BFA_FCPORT_SM_LINKDOWN:
  205. /**
  206. * Possible to get link events when doing back-to-back
  207. * enable/disables.
  208. */
  209. break;
  210. case BFA_FCPORT_SM_HWFAIL:
  211. bfa_reqq_wcancel(&fcport->reqq_wait);
  212. bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
  213. break;
  214. default:
  215. bfa_sm_fault(fcport->bfa, event);
  216. }
  217. }
  218. static void
  219. bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
  220. enum bfa_fcport_sm_event event)
  221. {
  222. bfa_trc(fcport->bfa, event);
  223. switch (event) {
  224. case BFA_FCPORT_SM_FWRSP:
  225. case BFA_FCPORT_SM_LINKDOWN:
  226. bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
  227. break;
  228. case BFA_FCPORT_SM_LINKUP:
  229. bfa_fcport_update_linkinfo(fcport);
  230. bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
  231. bfa_assert(fcport->event_cbfn);
  232. bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
  233. break;
  234. case BFA_FCPORT_SM_ENABLE:
  235. /**
  236. * Already being enabled.
  237. */
  238. break;
  239. case BFA_FCPORT_SM_DISABLE:
  240. if (bfa_fcport_send_disable(fcport))
  241. bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
  242. else
  243. bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
  244. bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
  245. BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
  246. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
  247. break;
  248. case BFA_FCPORT_SM_STOP:
  249. bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
  250. break;
  251. case BFA_FCPORT_SM_HWFAIL:
  252. bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
  253. break;
  254. default:
  255. bfa_sm_fault(fcport->bfa, event);
  256. }
  257. }
  258. static void
  259. bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
  260. enum bfa_fcport_sm_event event)
  261. {
  262. struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
  263. bfa_trc(fcport->bfa, event);
  264. switch (event) {
  265. case BFA_FCPORT_SM_LINKUP:
  266. bfa_fcport_update_linkinfo(fcport);
  267. bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
  268. bfa_assert(fcport->event_cbfn);
  269. bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
  270. BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
  271. if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
  272. bfa_trc(fcport->bfa, pevent->link_state.fcf.fipenabled);
  273. bfa_trc(fcport->bfa, pevent->link_state.fcf.fipfailed);
  274. if (pevent->link_state.fcf.fipfailed)
  275. bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
  276. BFA_PL_EID_FIP_FCF_DISC, 0,
  277. "FIP FCF Discovery Failed");
  278. else
  279. bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
  280. BFA_PL_EID_FIP_FCF_DISC, 0,
  281. "FIP FCF Discovered");
  282. }
  283. bfa_fcport_callback(fcport, BFA_PPORT_LINKUP);
  284. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
  285. /**
  286. * If QoS is enabled and it is not online,
  287. * Send a separate event.
  288. */
  289. if ((fcport->cfg.qos_enabled)
  290. && (bfa_os_ntohl(fcport->qos_attr.state) != BFA_QOS_ONLINE))
  291. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
  292. break;
  293. case BFA_FCPORT_SM_LINKDOWN:
  294. /**
  295. * Possible to get link down event.
  296. */
  297. break;
  298. case BFA_FCPORT_SM_ENABLE:
  299. /**
  300. * Already enabled.
  301. */
  302. break;
  303. case BFA_FCPORT_SM_DISABLE:
  304. if (bfa_fcport_send_disable(fcport))
  305. bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
  306. else
  307. bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
  308. bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
  309. BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
  310. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
  311. break;
  312. case BFA_FCPORT_SM_STOP:
  313. bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
  314. break;
  315. case BFA_FCPORT_SM_HWFAIL:
  316. bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
  317. break;
  318. default:
  319. bfa_sm_fault(fcport->bfa, event);
  320. }
  321. }
  322. static void
  323. bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
  324. enum bfa_fcport_sm_event event)
  325. {
  326. bfa_trc(fcport->bfa, event);
  327. switch (event) {
  328. case BFA_FCPORT_SM_ENABLE:
  329. /**
  330. * Already enabled.
  331. */
  332. break;
  333. case BFA_FCPORT_SM_DISABLE:
  334. if (bfa_fcport_send_disable(fcport))
  335. bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
  336. else
  337. bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
  338. bfa_fcport_reset_linkinfo(fcport);
  339. bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
  340. bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
  341. BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
  342. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
  343. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
  344. break;
  345. case BFA_FCPORT_SM_LINKDOWN:
  346. bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
  347. bfa_fcport_reset_linkinfo(fcport);
  348. bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
  349. bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
  350. BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
  351. if (BFA_PORT_IS_DISABLED(fcport->bfa))
  352. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
  353. else
  354. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
  355. break;
  356. case BFA_FCPORT_SM_STOP:
  357. bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
  358. bfa_fcport_reset_linkinfo(fcport);
  359. if (BFA_PORT_IS_DISABLED(fcport->bfa))
  360. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
  361. else
  362. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
  363. break;
  364. case BFA_FCPORT_SM_HWFAIL:
  365. bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
  366. bfa_fcport_reset_linkinfo(fcport);
  367. bfa_fcport_callback(fcport, BFA_PPORT_LINKDOWN);
  368. if (BFA_PORT_IS_DISABLED(fcport->bfa))
  369. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
  370. else
  371. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
  372. break;
  373. default:
  374. bfa_sm_fault(fcport->bfa, event);
  375. }
  376. }
  377. static void
  378. bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
  379. enum bfa_fcport_sm_event event)
  380. {
  381. bfa_trc(fcport->bfa, event);
  382. switch (event) {
  383. case BFA_FCPORT_SM_QRESUME:
  384. bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
  385. bfa_fcport_send_disable(fcport);
  386. break;
  387. case BFA_FCPORT_SM_STOP:
  388. bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
  389. bfa_reqq_wcancel(&fcport->reqq_wait);
  390. break;
  391. case BFA_FCPORT_SM_DISABLE:
  392. /**
  393. * Already being disabled.
  394. */
  395. break;
  396. case BFA_FCPORT_SM_LINKUP:
  397. case BFA_FCPORT_SM_LINKDOWN:
  398. /**
  399. * Possible to get link events when doing back-to-back
  400. * enable/disables.
  401. */
  402. break;
  403. case BFA_FCPORT_SM_HWFAIL:
  404. bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
  405. bfa_reqq_wcancel(&fcport->reqq_wait);
  406. break;
  407. default:
  408. bfa_sm_fault(fcport->bfa, event);
  409. }
  410. }
  411. static void
  412. bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
  413. enum bfa_fcport_sm_event event)
  414. {
  415. bfa_trc(fcport->bfa, event);
  416. switch (event) {
  417. case BFA_FCPORT_SM_FWRSP:
  418. bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
  419. break;
  420. case BFA_FCPORT_SM_DISABLE:
  421. /**
  422. * Already being disabled.
  423. */
  424. break;
  425. case BFA_FCPORT_SM_ENABLE:
  426. if (bfa_fcport_send_enable(fcport))
  427. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
  428. else
  429. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
  430. bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
  431. BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
  432. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
  433. break;
  434. case BFA_FCPORT_SM_STOP:
  435. bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
  436. break;
  437. case BFA_FCPORT_SM_LINKUP:
  438. case BFA_FCPORT_SM_LINKDOWN:
  439. /**
  440. * Possible to get link events when doing back-to-back
  441. * enable/disables.
  442. */
  443. break;
  444. case BFA_FCPORT_SM_HWFAIL:
  445. bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
  446. break;
  447. default:
  448. bfa_sm_fault(fcport->bfa, event);
  449. }
  450. }
  451. static void
  452. bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
  453. enum bfa_fcport_sm_event event)
  454. {
  455. bfa_trc(fcport->bfa, event);
  456. switch (event) {
  457. case BFA_FCPORT_SM_START:
  458. /**
  459. * Ignore start event for a port that is disabled.
  460. */
  461. break;
  462. case BFA_FCPORT_SM_STOP:
  463. bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
  464. break;
  465. case BFA_FCPORT_SM_ENABLE:
  466. if (bfa_fcport_send_enable(fcport))
  467. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
  468. else
  469. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
  470. bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
  471. BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
  472. bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
  473. break;
  474. case BFA_FCPORT_SM_DISABLE:
  475. /**
  476. * Already disabled.
  477. */
  478. break;
  479. case BFA_FCPORT_SM_HWFAIL:
  480. bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
  481. break;
  482. default:
  483. bfa_sm_fault(fcport->bfa, event);
  484. }
  485. }
  486. static void
  487. bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
  488. enum bfa_fcport_sm_event event)
  489. {
  490. bfa_trc(fcport->bfa, event);
  491. switch (event) {
  492. case BFA_FCPORT_SM_START:
  493. if (bfa_fcport_send_enable(fcport))
  494. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
  495. else
  496. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
  497. break;
  498. default:
  499. /**
  500. * Ignore all other events.
  501. */
  502. ;
  503. }
  504. }
  505. /**
  506. * Port is enabled. IOC is down/failed.
  507. */
  508. static void
  509. bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
  510. enum bfa_fcport_sm_event event)
  511. {
  512. bfa_trc(fcport->bfa, event);
  513. switch (event) {
  514. case BFA_FCPORT_SM_START:
  515. if (bfa_fcport_send_enable(fcport))
  516. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
  517. else
  518. bfa_sm_set_state(fcport, bfa_fcport_sm_enabling_qwait);
  519. break;
  520. default:
  521. /**
  522. * Ignore all events.
  523. */
  524. ;
  525. }
  526. }
  527. /**
  528. * Port is disabled. IOC is down/failed.
  529. */
  530. static void
  531. bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
  532. enum bfa_fcport_sm_event event)
  533. {
  534. bfa_trc(fcport->bfa, event);
  535. switch (event) {
  536. case BFA_FCPORT_SM_START:
  537. bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
  538. break;
  539. case BFA_FCPORT_SM_ENABLE:
  540. bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
  541. break;
  542. default:
  543. /**
  544. * Ignore all events.
  545. */
  546. ;
  547. }
  548. }
  549. /**
  550. * Link state is down
  551. */
  552. static void
  553. bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
  554. enum bfa_fcport_ln_sm_event event)
  555. {
  556. bfa_trc(ln->fcport->bfa, event);
  557. switch (event) {
  558. case BFA_FCPORT_LN_SM_LINKUP:
  559. bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
  560. bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
  561. break;
  562. default:
  563. bfa_sm_fault(ln->fcport->bfa, event);
  564. }
  565. }
  566. /**
  567. * Link state is waiting for down notification
  568. */
  569. static void
  570. bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
  571. enum bfa_fcport_ln_sm_event event)
  572. {
  573. bfa_trc(ln->fcport->bfa, event);
  574. switch (event) {
  575. case BFA_FCPORT_LN_SM_LINKUP:
  576. bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
  577. break;
  578. case BFA_FCPORT_LN_SM_NOTIFICATION:
  579. bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
  580. break;
  581. default:
  582. bfa_sm_fault(ln->fcport->bfa, event);
  583. }
  584. }
  585. /**
  586. * Link state is waiting for down notification and there is a pending up
  587. */
  588. static void
  589. bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
  590. enum bfa_fcport_ln_sm_event event)
  591. {
  592. bfa_trc(ln->fcport->bfa, event);
  593. switch (event) {
  594. case BFA_FCPORT_LN_SM_LINKDOWN:
  595. bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
  596. break;
  597. case BFA_FCPORT_LN_SM_NOTIFICATION:
  598. bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
  599. bfa_fcport_queue_cb(ln, BFA_PPORT_LINKUP);
  600. break;
  601. default:
  602. bfa_sm_fault(ln->fcport->bfa, event);
  603. }
  604. }
  605. /**
  606. * Link state is up
  607. */
  608. static void
  609. bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
  610. enum bfa_fcport_ln_sm_event event)
  611. {
  612. bfa_trc(ln->fcport->bfa, event);
  613. switch (event) {
  614. case BFA_FCPORT_LN_SM_LINKDOWN:
  615. bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
  616. bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
  617. break;
  618. default:
  619. bfa_sm_fault(ln->fcport->bfa, event);
  620. }
  621. }
  622. /**
  623. * Link state is waiting for up notification
  624. */
  625. static void
  626. bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
  627. enum bfa_fcport_ln_sm_event event)
  628. {
  629. bfa_trc(ln->fcport->bfa, event);
  630. switch (event) {
  631. case BFA_FCPORT_LN_SM_LINKDOWN:
  632. bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
  633. break;
  634. case BFA_FCPORT_LN_SM_NOTIFICATION:
  635. bfa_sm_set_state(ln, bfa_fcport_ln_sm_up);
  636. break;
  637. default:
  638. bfa_sm_fault(ln->fcport->bfa, event);
  639. }
  640. }
  641. /**
  642. * Link state is waiting for up notification and there is a pending down
  643. */
  644. static void
  645. bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
  646. enum bfa_fcport_ln_sm_event event)
  647. {
  648. bfa_trc(ln->fcport->bfa, event);
  649. switch (event) {
  650. case BFA_FCPORT_LN_SM_LINKUP:
  651. bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf);
  652. break;
  653. case BFA_FCPORT_LN_SM_NOTIFICATION:
  654. bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
  655. bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
  656. break;
  657. default:
  658. bfa_sm_fault(ln->fcport->bfa, event);
  659. }
  660. }
  661. /**
  662. * Link state is waiting for up notification and there are pending down and up
  663. */
  664. static void
  665. bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
  666. enum bfa_fcport_ln_sm_event event)
  667. {
  668. bfa_trc(ln->fcport->bfa, event);
  669. switch (event) {
  670. case BFA_FCPORT_LN_SM_LINKDOWN:
  671. bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
  672. break;
  673. case BFA_FCPORT_LN_SM_NOTIFICATION:
  674. bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
  675. bfa_fcport_queue_cb(ln, BFA_PPORT_LINKDOWN);
  676. break;
  677. default:
  678. bfa_sm_fault(ln->fcport->bfa, event);
  679. }
  680. }
  681. /**
  682. * bfa_pport_private
  683. */
  684. static void
  685. __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
  686. {
  687. struct bfa_fcport_ln_s *ln = cbarg;
  688. if (complete)
  689. ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event);
  690. else
  691. bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
  692. }
  693. static void
  694. bfa_fcport_callback(struct bfa_fcport_s *fcport, enum bfa_pport_linkstate event)
  695. {
  696. if (fcport->bfa->fcs) {
  697. fcport->event_cbfn(fcport->event_cbarg, event);
  698. return;
  699. }
  700. switch (event) {
  701. case BFA_PPORT_LINKUP:
  702. bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP);
  703. break;
  704. case BFA_PPORT_LINKDOWN:
  705. bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
  706. break;
  707. default:
  708. bfa_assert(0);
  709. }
  710. }
  711. static void
  712. bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_pport_linkstate event)
  713. {
  714. ln->ln_event = event;
  715. bfa_cb_queue(ln->fcport->bfa, &ln->ln_qe, __bfa_cb_fcport_event, ln);
  716. }
  717. #define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
  718. BFA_CACHELINE_SZ))
  719. static void
  720. bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
  721. u32 *dm_len)
  722. {
  723. *dm_len += FCPORT_STATS_DMA_SZ;
  724. }
  725. static void
  726. bfa_fcport_qresume(void *cbarg)
  727. {
  728. struct bfa_fcport_s *fcport = cbarg;
  729. bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME);
  730. }
  731. static void
  732. bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo)
  733. {
  734. u8 *dm_kva;
  735. u64 dm_pa;
  736. dm_kva = bfa_meminfo_dma_virt(meminfo);
  737. dm_pa = bfa_meminfo_dma_phys(meminfo);
  738. fcport->stats_kva = dm_kva;
  739. fcport->stats_pa = dm_pa;
  740. fcport->stats = (union bfa_fcport_stats_u *)dm_kva;
  741. dm_kva += FCPORT_STATS_DMA_SZ;
  742. dm_pa += FCPORT_STATS_DMA_SZ;
  743. bfa_meminfo_dma_virt(meminfo) = dm_kva;
  744. bfa_meminfo_dma_phys(meminfo) = dm_pa;
  745. }
  746. /**
  747. * Memory initialization.
  748. */
  749. static void
  750. bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
  751. struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
  752. {
  753. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  754. struct bfa_pport_cfg_s *port_cfg = &fcport->cfg;
  755. struct bfa_fcport_ln_s *ln = &fcport->ln;
  756. struct bfa_timeval_s tv;
  757. bfa_os_memset(fcport, 0, sizeof(struct bfa_fcport_s));
  758. fcport->bfa = bfa;
  759. ln->fcport = fcport;
  760. bfa_fcport_mem_claim(fcport, meminfo);
  761. bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
  762. bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
  763. /**
  764. * initialize time stamp for stats reset
  765. */
  766. bfa_os_gettimeofday(&tv);
  767. fcport->stats_reset_time = tv.tv_sec;
  768. /**
  769. * initialize and set default configuration
  770. */
  771. port_cfg->topology = BFA_PPORT_TOPOLOGY_P2P;
  772. port_cfg->speed = BFA_PPORT_SPEED_AUTO;
  773. port_cfg->trunked = BFA_FALSE;
  774. port_cfg->maxfrsize = 0;
  775. port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
  776. bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
  777. }
  778. static void
  779. bfa_fcport_detach(struct bfa_s *bfa)
  780. {
  781. }
  782. /**
  783. * Called when IOC is ready.
  784. */
  785. static void
  786. bfa_fcport_start(struct bfa_s *bfa)
  787. {
  788. bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
  789. }
  790. /**
  791. * Called before IOC is stopped.
  792. */
  793. static void
  794. bfa_fcport_stop(struct bfa_s *bfa)
  795. {
  796. bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP);
  797. }
  798. /**
  799. * Called when IOC failure is detected.
  800. */
  801. static void
  802. bfa_fcport_iocdisable(struct bfa_s *bfa)
  803. {
  804. bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_HWFAIL);
  805. }
  806. static void
  807. bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
  808. {
  809. struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
  810. fcport->speed = pevent->link_state.speed;
  811. fcport->topology = pevent->link_state.topology;
  812. if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP)
  813. fcport->myalpa =
  814. pevent->link_state.tl.loop_info.myalpa;
  815. /*
  816. * QoS Details
  817. */
  818. bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr);
  819. bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr);
  820. bfa_trc(fcport->bfa, fcport->speed);
  821. bfa_trc(fcport->bfa, fcport->topology);
  822. }
  823. static void
  824. bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
  825. {
  826. fcport->speed = BFA_PPORT_SPEED_UNKNOWN;
  827. fcport->topology = BFA_PPORT_TOPOLOGY_NONE;
  828. }
  829. /**
  830. * Send port enable message to firmware.
  831. */
  832. static bfa_boolean_t
  833. bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
  834. {
  835. struct bfi_fcport_enable_req_s *m;
  836. /**
  837. * Increment message tag before queue check, so that responses to old
  838. * requests are discarded.
  839. */
  840. fcport->msgtag++;
  841. /**
  842. * check for room in queue to send request now
  843. */
  844. m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
  845. if (!m) {
  846. bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
  847. &fcport->reqq_wait);
  848. return BFA_FALSE;
  849. }
  850. bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ,
  851. bfa_lpuid(fcport->bfa));
  852. m->nwwn = fcport->nwwn;
  853. m->pwwn = fcport->pwwn;
  854. m->port_cfg = fcport->cfg;
  855. m->msgtag = fcport->msgtag;
  856. m->port_cfg.maxfrsize = bfa_os_htons(fcport->cfg.maxfrsize);
  857. bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
  858. bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
  859. bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
  860. /**
  861. * queue I/O message to firmware
  862. */
  863. bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
  864. return BFA_TRUE;
  865. }
  866. /**
  867. * Send port disable message to firmware.
  868. */
  869. static bfa_boolean_t
  870. bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
  871. {
  872. struct bfi_fcport_req_s *m;
  873. /**
  874. * Increment message tag before queue check, so that responses to old
  875. * requests are discarded.
  876. */
  877. fcport->msgtag++;
  878. /**
  879. * check for room in queue to send request now
  880. */
  881. m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
  882. if (!m) {
  883. bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
  884. &fcport->reqq_wait);
  885. return BFA_FALSE;
  886. }
  887. bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ,
  888. bfa_lpuid(fcport->bfa));
  889. m->msgtag = fcport->msgtag;
  890. /**
  891. * queue I/O message to firmware
  892. */
  893. bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
  894. return BFA_TRUE;
  895. }
  896. static void
  897. bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
  898. {
  899. fcport->pwwn = bfa_ioc_get_pwwn(&fcport->bfa->ioc);
  900. fcport->nwwn = bfa_ioc_get_nwwn(&fcport->bfa->ioc);
  901. bfa_trc(fcport->bfa, fcport->pwwn);
  902. bfa_trc(fcport->bfa, fcport->nwwn);
  903. }
  904. static void
  905. bfa_fcport_send_txcredit(void *port_cbarg)
  906. {
  907. struct bfa_fcport_s *fcport = port_cbarg;
  908. struct bfi_fcport_set_svc_params_req_s *m;
  909. /**
  910. * check for room in queue to send request now
  911. */
  912. m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
  913. if (!m) {
  914. bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit);
  915. return;
  916. }
  917. bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
  918. bfa_lpuid(fcport->bfa));
  919. m->tx_bbcredit = bfa_os_htons((u16) fcport->cfg.tx_bbcredit);
  920. /**
  921. * queue I/O message to firmware
  922. */
  923. bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
  924. }
  925. static void
  926. bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
  927. struct bfa_qos_stats_s *s)
  928. {
  929. u32 *dip = (u32 *) d;
  930. u32 *sip = (u32 *) s;
  931. int i;
  932. /* Now swap the 32 bit fields */
  933. for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
  934. dip[i] = bfa_os_ntohl(sip[i]);
  935. }
  936. static void
  937. bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
  938. struct bfa_fcoe_stats_s *s)
  939. {
  940. u32 *dip = (u32 *) d;
  941. u32 *sip = (u32 *) s;
  942. int i;
  943. for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
  944. i = i + 2) {
  945. #ifdef __BIGENDIAN
  946. dip[i] = bfa_os_ntohl(sip[i]);
  947. dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
  948. #else
  949. dip[i] = bfa_os_ntohl(sip[i + 1]);
  950. dip[i + 1] = bfa_os_ntohl(sip[i]);
  951. #endif
  952. }
  953. }
  954. static void
  955. __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
  956. {
  957. struct bfa_fcport_s *fcport = cbarg;
  958. if (complete) {
  959. if (fcport->stats_status == BFA_STATUS_OK) {
  960. struct bfa_timeval_s tv;
  961. /* Swap FC QoS or FCoE stats */
  962. if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
  963. bfa_fcport_qos_stats_swap(
  964. &fcport->stats_ret->fcqos,
  965. &fcport->stats->fcqos);
  966. } else {
  967. bfa_fcport_fcoe_stats_swap(
  968. &fcport->stats_ret->fcoe,
  969. &fcport->stats->fcoe);
  970. bfa_os_gettimeofday(&tv);
  971. fcport->stats_ret->fcoe.secs_reset =
  972. tv.tv_sec - fcport->stats_reset_time;
  973. }
  974. }
  975. fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
  976. } else {
  977. fcport->stats_busy = BFA_FALSE;
  978. fcport->stats_status = BFA_STATUS_OK;
  979. }
  980. }
  981. static void
  982. bfa_fcport_stats_get_timeout(void *cbarg)
  983. {
  984. struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
  985. bfa_trc(fcport->bfa, fcport->stats_qfull);
  986. if (fcport->stats_qfull) {
  987. bfa_reqq_wcancel(&fcport->stats_reqq_wait);
  988. fcport->stats_qfull = BFA_FALSE;
  989. }
  990. fcport->stats_status = BFA_STATUS_ETIMER;
  991. bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get,
  992. fcport);
  993. }
  994. static void
  995. bfa_fcport_send_stats_get(void *cbarg)
  996. {
  997. struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
  998. struct bfi_fcport_req_s *msg;
  999. msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
  1000. if (!msg) {
  1001. fcport->stats_qfull = BFA_TRUE;
  1002. bfa_reqq_winit(&fcport->stats_reqq_wait,
  1003. bfa_fcport_send_stats_get, fcport);
  1004. bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
  1005. &fcport->stats_reqq_wait);
  1006. return;
  1007. }
  1008. fcport->stats_qfull = BFA_FALSE;
  1009. bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
  1010. bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
  1011. bfa_lpuid(fcport->bfa));
  1012. bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
  1013. }
  1014. static void
  1015. __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
  1016. {
  1017. struct bfa_fcport_s *fcport = cbarg;
  1018. if (complete) {
  1019. struct bfa_timeval_s tv;
  1020. /**
  1021. * re-initialize time stamp for stats reset
  1022. */
  1023. bfa_os_gettimeofday(&tv);
  1024. fcport->stats_reset_time = tv.tv_sec;
  1025. fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
  1026. } else {
  1027. fcport->stats_busy = BFA_FALSE;
  1028. fcport->stats_status = BFA_STATUS_OK;
  1029. }
  1030. }
  1031. static void
  1032. bfa_fcport_stats_clr_timeout(void *cbarg)
  1033. {
  1034. struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
  1035. bfa_trc(fcport->bfa, fcport->stats_qfull);
  1036. if (fcport->stats_qfull) {
  1037. bfa_reqq_wcancel(&fcport->stats_reqq_wait);
  1038. fcport->stats_qfull = BFA_FALSE;
  1039. }
  1040. fcport->stats_status = BFA_STATUS_ETIMER;
  1041. bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
  1042. __bfa_cb_fcport_stats_clr, fcport);
  1043. }
  1044. static void
  1045. bfa_fcport_send_stats_clear(void *cbarg)
  1046. {
  1047. struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
  1048. struct bfi_fcport_req_s *msg;
  1049. msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
  1050. if (!msg) {
  1051. fcport->stats_qfull = BFA_TRUE;
  1052. bfa_reqq_winit(&fcport->stats_reqq_wait,
  1053. bfa_fcport_send_stats_clear, fcport);
  1054. bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
  1055. &fcport->stats_reqq_wait);
  1056. return;
  1057. }
  1058. fcport->stats_qfull = BFA_FALSE;
  1059. bfa_os_memset(msg, 0, sizeof(struct bfi_fcport_req_s));
  1060. bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
  1061. bfa_lpuid(fcport->bfa));
  1062. bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
  1063. }
  1064. /**
  1065. * bfa_pport_public
  1066. */
  1067. /**
  1068. * Called to initialize port attributes
  1069. */
  1070. void
  1071. bfa_fcport_init(struct bfa_s *bfa)
  1072. {
  1073. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1074. /**
  1075. * Initialize port attributes from IOC hardware data.
  1076. */
  1077. bfa_fcport_set_wwns(fcport);
  1078. if (fcport->cfg.maxfrsize == 0)
  1079. fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
  1080. fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
  1081. fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
  1082. bfa_assert(fcport->cfg.maxfrsize);
  1083. bfa_assert(fcport->cfg.rx_bbcredit);
  1084. bfa_assert(fcport->speed_sup);
  1085. }
  1086. /**
  1087. * Firmware message handler.
  1088. */
  1089. void
  1090. bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
  1091. {
  1092. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1093. union bfi_fcport_i2h_msg_u i2hmsg;
  1094. i2hmsg.msg = msg;
  1095. fcport->event_arg.i2hmsg = i2hmsg;
  1096. switch (msg->mhdr.msg_id) {
  1097. case BFI_FCPORT_I2H_ENABLE_RSP:
  1098. if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
  1099. bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
  1100. break;
  1101. case BFI_FCPORT_I2H_DISABLE_RSP:
  1102. if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
  1103. bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
  1104. break;
  1105. case BFI_FCPORT_I2H_EVENT:
  1106. switch (i2hmsg.event->link_state.linkstate) {
  1107. case BFA_PPORT_LINKUP:
  1108. bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
  1109. break;
  1110. case BFA_PPORT_LINKDOWN:
  1111. bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
  1112. break;
  1113. case BFA_PPORT_TRUNK_LINKDOWN:
  1114. /** todo: event notification */
  1115. break;
  1116. }
  1117. break;
  1118. case BFI_FCPORT_I2H_STATS_GET_RSP:
  1119. /*
  1120. * check for timer pop before processing the rsp
  1121. */
  1122. if (fcport->stats_busy == BFA_FALSE ||
  1123. fcport->stats_status == BFA_STATUS_ETIMER)
  1124. break;
  1125. bfa_timer_stop(&fcport->timer);
  1126. fcport->stats_status = i2hmsg.pstatsget_rsp->status;
  1127. bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
  1128. __bfa_cb_fcport_stats_get, fcport);
  1129. break;
  1130. case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
  1131. /*
  1132. * check for timer pop before processing the rsp
  1133. */
  1134. if (fcport->stats_busy == BFA_FALSE ||
  1135. fcport->stats_status == BFA_STATUS_ETIMER)
  1136. break;
  1137. bfa_timer_stop(&fcport->timer);
  1138. fcport->stats_status = BFA_STATUS_OK;
  1139. bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
  1140. __bfa_cb_fcport_stats_clr, fcport);
  1141. break;
  1142. default:
  1143. bfa_assert(0);
  1144. break;
  1145. }
  1146. }
  1147. /**
  1148. * bfa_pport_api
  1149. */
  1150. /**
  1151. * Registered callback for port events.
  1152. */
  1153. void
  1154. bfa_fcport_event_register(struct bfa_s *bfa,
  1155. void (*cbfn) (void *cbarg, bfa_pport_event_t event),
  1156. void *cbarg)
  1157. {
  1158. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1159. fcport->event_cbfn = cbfn;
  1160. fcport->event_cbarg = cbarg;
  1161. }
  1162. bfa_status_t
  1163. bfa_fcport_enable(struct bfa_s *bfa)
  1164. {
  1165. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1166. struct bfa_iocfc_s *iocfc = &bfa->iocfc;
  1167. struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
  1168. /* if port is PBC disabled, return error */
  1169. if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
  1170. bfa_trc(bfa, fcport->pwwn);
  1171. return BFA_STATUS_PBC;
  1172. }
  1173. if (fcport->diag_busy)
  1174. return BFA_STATUS_DIAG_BUSY;
  1175. else if (bfa_sm_cmp_state
  1176. (BFA_FCPORT_MOD(bfa), bfa_fcport_sm_disabling_qwait))
  1177. return BFA_STATUS_DEVBUSY;
  1178. bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE);
  1179. return BFA_STATUS_OK;
  1180. }
  1181. bfa_status_t
  1182. bfa_fcport_disable(struct bfa_s *bfa)
  1183. {
  1184. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1185. struct bfa_iocfc_s *iocfc = &bfa->iocfc;
  1186. struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
  1187. /* if port is PBC disabled, return error */
  1188. if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
  1189. bfa_trc(bfa, fcport->pwwn);
  1190. return BFA_STATUS_PBC;
  1191. }
  1192. bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
  1193. return BFA_STATUS_OK;
  1194. }
  1195. /**
  1196. * Configure port speed.
  1197. */
  1198. bfa_status_t
  1199. bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
  1200. {
  1201. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1202. bfa_trc(bfa, speed);
  1203. if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
  1204. bfa_trc(bfa, fcport->speed_sup);
  1205. return BFA_STATUS_UNSUPP_SPEED;
  1206. }
  1207. fcport->cfg.speed = speed;
  1208. return BFA_STATUS_OK;
  1209. }
  1210. /**
  1211. * Get current speed.
  1212. */
  1213. enum bfa_pport_speed
  1214. bfa_fcport_get_speed(struct bfa_s *bfa)
  1215. {
  1216. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1217. return fcport->speed;
  1218. }
  1219. /**
  1220. * Configure port topology.
  1221. */
  1222. bfa_status_t
  1223. bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
  1224. {
  1225. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1226. bfa_trc(bfa, topology);
  1227. bfa_trc(bfa, fcport->cfg.topology);
  1228. switch (topology) {
  1229. case BFA_PPORT_TOPOLOGY_P2P:
  1230. case BFA_PPORT_TOPOLOGY_LOOP:
  1231. case BFA_PPORT_TOPOLOGY_AUTO:
  1232. break;
  1233. default:
  1234. return BFA_STATUS_EINVAL;
  1235. }
  1236. fcport->cfg.topology = topology;
  1237. return BFA_STATUS_OK;
  1238. }
  1239. /**
  1240. * Get current topology.
  1241. */
  1242. enum bfa_pport_topology
  1243. bfa_fcport_get_topology(struct bfa_s *bfa)
  1244. {
  1245. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1246. return fcport->topology;
  1247. }
  1248. bfa_status_t
  1249. bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
  1250. {
  1251. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1252. bfa_trc(bfa, alpa);
  1253. bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
  1254. bfa_trc(bfa, fcport->cfg.hardalpa);
  1255. fcport->cfg.cfg_hardalpa = BFA_TRUE;
  1256. fcport->cfg.hardalpa = alpa;
  1257. return BFA_STATUS_OK;
  1258. }
  1259. bfa_status_t
  1260. bfa_fcport_clr_hardalpa(struct bfa_s *bfa)
  1261. {
  1262. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1263. bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
  1264. bfa_trc(bfa, fcport->cfg.hardalpa);
  1265. fcport->cfg.cfg_hardalpa = BFA_FALSE;
  1266. return BFA_STATUS_OK;
  1267. }
  1268. bfa_boolean_t
  1269. bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
  1270. {
  1271. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1272. *alpa = fcport->cfg.hardalpa;
  1273. return fcport->cfg.cfg_hardalpa;
  1274. }
  1275. u8
  1276. bfa_fcport_get_myalpa(struct bfa_s *bfa)
  1277. {
  1278. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1279. return fcport->myalpa;
  1280. }
  1281. bfa_status_t
  1282. bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
  1283. {
  1284. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1285. bfa_trc(bfa, maxfrsize);
  1286. bfa_trc(bfa, fcport->cfg.maxfrsize);
  1287. /*
  1288. * with in range
  1289. */
  1290. if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ))
  1291. return BFA_STATUS_INVLD_DFSZ;
  1292. /*
  1293. * power of 2, if not the max frame size of 2112
  1294. */
  1295. if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
  1296. return BFA_STATUS_INVLD_DFSZ;
  1297. fcport->cfg.maxfrsize = maxfrsize;
  1298. return BFA_STATUS_OK;
  1299. }
  1300. u16
  1301. bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
  1302. {
  1303. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1304. return fcport->cfg.maxfrsize;
  1305. }
  1306. u32
  1307. bfa_fcport_mypid(struct bfa_s *bfa)
  1308. {
  1309. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1310. return fcport->mypid;
  1311. }
  1312. u8
  1313. bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
  1314. {
  1315. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1316. return fcport->cfg.rx_bbcredit;
  1317. }
  1318. void
  1319. bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
  1320. {
  1321. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1322. fcport->cfg.tx_bbcredit = (u8) tx_bbcredit;
  1323. bfa_fcport_send_txcredit(fcport);
  1324. }
  1325. /**
  1326. * Get port attributes.
  1327. */
  1328. wwn_t
  1329. bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
  1330. {
  1331. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1332. if (node)
  1333. return fcport->nwwn;
  1334. else
  1335. return fcport->pwwn;
  1336. }
  1337. void
  1338. bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
  1339. {
  1340. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1341. struct bfa_iocfc_s *iocfc = &bfa->iocfc;
  1342. struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
  1343. bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
  1344. attr->nwwn = fcport->nwwn;
  1345. attr->pwwn = fcport->pwwn;
  1346. attr->factorypwwn = bfa_ioc_get_mfg_pwwn(&bfa->ioc);
  1347. attr->factorynwwn = bfa_ioc_get_mfg_nwwn(&bfa->ioc);
  1348. bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg,
  1349. sizeof(struct bfa_pport_cfg_s));
  1350. /*
  1351. * speed attributes
  1352. */
  1353. attr->pport_cfg.speed = fcport->cfg.speed;
  1354. attr->speed_supported = fcport->speed_sup;
  1355. attr->speed = fcport->speed;
  1356. attr->cos_supported = FC_CLASS_3;
  1357. /*
  1358. * topology attributes
  1359. */
  1360. attr->pport_cfg.topology = fcport->cfg.topology;
  1361. attr->topology = fcport->topology;
  1362. /*
  1363. * beacon attributes
  1364. */
  1365. attr->beacon = fcport->beacon;
  1366. attr->link_e2e_beacon = fcport->link_e2e_beacon;
  1367. attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog);
  1368. attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
  1369. attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
  1370. /* PBC Disabled State */
  1371. if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED)
  1372. attr->port_state = BFA_PPORT_ST_PREBOOT_DISABLED;
  1373. else {
  1374. attr->port_state = bfa_sm_to_state(
  1375. hal_pport_sm_table, fcport->sm);
  1376. if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
  1377. attr->port_state = BFA_PPORT_ST_IOCDIS;
  1378. else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
  1379. attr->port_state = BFA_PPORT_ST_FWMISMATCH;
  1380. }
  1381. }
  1382. #define BFA_FCPORT_STATS_TOV 1000
  1383. /**
  1384. * Fetch port attributes (FCQoS or FCoE).
  1385. */
  1386. bfa_status_t
  1387. bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
  1388. bfa_cb_pport_t cbfn, void *cbarg)
  1389. {
  1390. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1391. if (fcport->stats_busy) {
  1392. bfa_trc(bfa, fcport->stats_busy);
  1393. return BFA_STATUS_DEVBUSY;
  1394. }
  1395. fcport->stats_busy = BFA_TRUE;
  1396. fcport->stats_ret = stats;
  1397. fcport->stats_cbfn = cbfn;
  1398. fcport->stats_cbarg = cbarg;
  1399. bfa_fcport_send_stats_get(fcport);
  1400. bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
  1401. fcport, BFA_FCPORT_STATS_TOV);
  1402. return BFA_STATUS_OK;
  1403. }
  1404. /**
  1405. * Reset port statistics (FCQoS or FCoE).
  1406. */
  1407. bfa_status_t
  1408. bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
  1409. {
  1410. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1411. if (fcport->stats_busy) {
  1412. bfa_trc(bfa, fcport->stats_busy);
  1413. return BFA_STATUS_DEVBUSY;
  1414. }
  1415. fcport->stats_busy = BFA_TRUE;
  1416. fcport->stats_cbfn = cbfn;
  1417. fcport->stats_cbarg = cbarg;
  1418. bfa_fcport_send_stats_clear(fcport);
  1419. bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
  1420. fcport, BFA_FCPORT_STATS_TOV);
  1421. return BFA_STATUS_OK;
  1422. }
  1423. /**
  1424. * Fetch FCQoS port statistics
  1425. */
  1426. bfa_status_t
  1427. bfa_fcport_get_qos_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
  1428. bfa_cb_pport_t cbfn, void *cbarg)
  1429. {
  1430. /* Meaningful only for FC mode */
  1431. bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
  1432. return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
  1433. }
  1434. /**
  1435. * Reset FCoE port statistics
  1436. */
  1437. bfa_status_t
  1438. bfa_fcport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
  1439. {
  1440. /* Meaningful only for FC mode */
  1441. bfa_assert(bfa_ioc_get_fcmode(&bfa->ioc));
  1442. return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
  1443. }
  1444. /**
  1445. * Fetch FCQoS port statistics
  1446. */
  1447. bfa_status_t
  1448. bfa_fcport_get_fcoe_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
  1449. bfa_cb_pport_t cbfn, void *cbarg)
  1450. {
  1451. /* Meaningful only for FCoE mode */
  1452. bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
  1453. return bfa_fcport_get_stats(bfa, stats, cbfn, cbarg);
  1454. }
  1455. /**
  1456. * Reset FCoE port statistics
  1457. */
  1458. bfa_status_t
  1459. bfa_fcport_clear_fcoe_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
  1460. {
  1461. /* Meaningful only for FCoE mode */
  1462. bfa_assert(!bfa_ioc_get_fcmode(&bfa->ioc));
  1463. return bfa_fcport_clear_stats(bfa, cbfn, cbarg);
  1464. }
  1465. bfa_status_t
  1466. bfa_fcport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
  1467. {
  1468. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1469. bfa_trc(bfa, bitmap);
  1470. bfa_trc(bfa, fcport->cfg.trunked);
  1471. bfa_trc(bfa, fcport->cfg.trunk_ports);
  1472. if (!bitmap || (bitmap & (bitmap - 1)))
  1473. return BFA_STATUS_EINVAL;
  1474. fcport->cfg.trunked = BFA_TRUE;
  1475. fcport->cfg.trunk_ports = bitmap;
  1476. return BFA_STATUS_OK;
  1477. }
  1478. void
  1479. bfa_fcport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
  1480. {
  1481. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1482. qos_attr->state = bfa_os_ntohl(fcport->qos_attr.state);
  1483. qos_attr->total_bb_cr = bfa_os_ntohl(fcport->qos_attr.total_bb_cr);
  1484. }
  1485. void
  1486. bfa_fcport_qos_get_vc_attr(struct bfa_s *bfa,
  1487. struct bfa_qos_vc_attr_s *qos_vc_attr)
  1488. {
  1489. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1490. struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr;
  1491. u32 i = 0;
  1492. qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
  1493. qos_vc_attr->shared_credit = bfa_os_ntohs(bfa_vc_attr->shared_credit);
  1494. qos_vc_attr->elp_opmode_flags =
  1495. bfa_os_ntohl(bfa_vc_attr->elp_opmode_flags);
  1496. /*
  1497. * Individual VC info
  1498. */
  1499. while (i < qos_vc_attr->total_vc_count) {
  1500. qos_vc_attr->vc_info[i].vc_credit =
  1501. bfa_vc_attr->vc_info[i].vc_credit;
  1502. qos_vc_attr->vc_info[i].borrow_credit =
  1503. bfa_vc_attr->vc_info[i].borrow_credit;
  1504. qos_vc_attr->vc_info[i].priority =
  1505. bfa_vc_attr->vc_info[i].priority;
  1506. ++i;
  1507. }
  1508. }
  1509. /**
  1510. * Fetch port attributes.
  1511. */
  1512. bfa_status_t
  1513. bfa_fcport_trunk_disable(struct bfa_s *bfa)
  1514. {
  1515. return BFA_STATUS_OK;
  1516. }
  1517. bfa_boolean_t
  1518. bfa_fcport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
  1519. {
  1520. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1521. *bitmap = fcport->cfg.trunk_ports;
  1522. return fcport->cfg.trunked;
  1523. }
  1524. bfa_boolean_t
  1525. bfa_fcport_is_disabled(struct bfa_s *bfa)
  1526. {
  1527. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1528. return bfa_sm_to_state(hal_pport_sm_table, fcport->sm) ==
  1529. BFA_PPORT_ST_DISABLED;
  1530. }
  1531. bfa_boolean_t
  1532. bfa_fcport_is_ratelim(struct bfa_s *bfa)
  1533. {
  1534. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1535. return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
  1536. }
  1537. void
  1538. bfa_fcport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
  1539. {
  1540. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1541. enum bfa_ioc_type_e ioc_type = bfa_get_type(bfa);
  1542. bfa_trc(bfa, on_off);
  1543. bfa_trc(bfa, fcport->cfg.qos_enabled);
  1544. bfa_trc(bfa, ioc_type);
  1545. if (ioc_type == BFA_IOC_TYPE_FC)
  1546. fcport->cfg.qos_enabled = on_off;
  1547. }
  1548. void
  1549. bfa_fcport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
  1550. {
  1551. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1552. bfa_trc(bfa, on_off);
  1553. bfa_trc(bfa, fcport->cfg.ratelimit);
  1554. fcport->cfg.ratelimit = on_off;
  1555. if (fcport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
  1556. fcport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
  1557. }
  1558. /**
  1559. * Configure default minimum ratelim speed
  1560. */
  1561. bfa_status_t
  1562. bfa_fcport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
  1563. {
  1564. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1565. bfa_trc(bfa, speed);
  1566. /*
  1567. * Auto and speeds greater than the supported speed, are invalid
  1568. */
  1569. if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > fcport->speed_sup)) {
  1570. bfa_trc(bfa, fcport->speed_sup);
  1571. return BFA_STATUS_UNSUPP_SPEED;
  1572. }
  1573. fcport->cfg.trl_def_speed = speed;
  1574. return BFA_STATUS_OK;
  1575. }
  1576. /**
  1577. * Get default minimum ratelim speed
  1578. */
  1579. enum bfa_pport_speed
  1580. bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
  1581. {
  1582. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1583. bfa_trc(bfa, fcport->cfg.trl_def_speed);
  1584. return fcport->cfg.trl_def_speed;
  1585. }
  1586. void
  1587. bfa_fcport_busy(struct bfa_s *bfa, bfa_boolean_t status)
  1588. {
  1589. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1590. bfa_trc(bfa, status);
  1591. bfa_trc(bfa, fcport->diag_busy);
  1592. fcport->diag_busy = status;
  1593. }
  1594. void
  1595. bfa_fcport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
  1596. bfa_boolean_t link_e2e_beacon)
  1597. {
  1598. struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
  1599. bfa_trc(bfa, beacon);
  1600. bfa_trc(bfa, link_e2e_beacon);
  1601. bfa_trc(bfa, fcport->beacon);
  1602. bfa_trc(bfa, fcport->link_e2e_beacon);
  1603. fcport->beacon = beacon;
  1604. fcport->link_e2e_beacon = link_e2e_beacon;
  1605. }
  1606. bfa_boolean_t
  1607. bfa_fcport_is_linkup(struct bfa_s *bfa)
  1608. {
  1609. return bfa_sm_cmp_state(BFA_FCPORT_MOD(bfa), bfa_fcport_sm_linkup);
  1610. }