bfa_fcport.c 50 KB

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