bfa_fcport.c 50 KB

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