bfa_fcs_rport.c 77 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028
  1. /*
  2. * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
  3. * All rights reserved
  4. * www.brocade.com
  5. *
  6. * Linux driver for Brocade Fibre Channel Host Bus Adapter.
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License (GPL) Version 2 as
  10. * published by the Free Software Foundation
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. */
  17. /*
  18. * rport.c Remote port implementation.
  19. */
  20. #include "bfad_drv.h"
  21. #include "bfad_im.h"
  22. #include "bfa_fcs.h"
  23. #include "bfa_fcbuild.h"
  24. BFA_TRC_FILE(FCS, RPORT);
  25. static u32
  26. bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
  27. /* In millisecs */
  28. /*
  29. * forward declarations
  30. */
  31. static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(
  32. struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid);
  33. static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
  34. static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
  35. static void bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport);
  36. static void bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport);
  37. static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
  38. struct fc_logi_s *plogi);
  39. static void bfa_fcs_rport_timeout(void *arg);
  40. static void bfa_fcs_rport_send_plogi(void *rport_cbarg,
  41. struct bfa_fcxp_s *fcxp_alloced);
  42. static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
  43. struct bfa_fcxp_s *fcxp_alloced);
  44. static void bfa_fcs_rport_plogi_response(void *fcsarg,
  45. struct bfa_fcxp_s *fcxp, void *cbarg,
  46. bfa_status_t req_status, u32 rsp_len,
  47. u32 resid_len, struct fchs_s *rsp_fchs);
  48. static void bfa_fcs_rport_send_adisc(void *rport_cbarg,
  49. struct bfa_fcxp_s *fcxp_alloced);
  50. static void bfa_fcs_rport_adisc_response(void *fcsarg,
  51. struct bfa_fcxp_s *fcxp, void *cbarg,
  52. bfa_status_t req_status, u32 rsp_len,
  53. u32 resid_len, struct fchs_s *rsp_fchs);
  54. static void bfa_fcs_rport_send_nsdisc(void *rport_cbarg,
  55. struct bfa_fcxp_s *fcxp_alloced);
  56. static void bfa_fcs_rport_gidpn_response(void *fcsarg,
  57. struct bfa_fcxp_s *fcxp, void *cbarg,
  58. bfa_status_t req_status, u32 rsp_len,
  59. u32 resid_len, struct fchs_s *rsp_fchs);
  60. static void bfa_fcs_rport_gpnid_response(void *fcsarg,
  61. struct bfa_fcxp_s *fcxp, void *cbarg,
  62. bfa_status_t req_status, u32 rsp_len,
  63. u32 resid_len, struct fchs_s *rsp_fchs);
  64. static void bfa_fcs_rport_send_logo(void *rport_cbarg,
  65. struct bfa_fcxp_s *fcxp_alloced);
  66. static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
  67. static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
  68. struct fchs_s *rx_fchs, u16 len);
  69. static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
  70. struct fchs_s *rx_fchs, u8 reason_code,
  71. u8 reason_code_expl);
  72. static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
  73. struct fchs_s *rx_fchs, u16 len);
  74. static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
  75. static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
  76. enum rport_event event);
  77. static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
  78. enum rport_event event);
  79. static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
  80. enum rport_event event);
  81. static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
  82. enum rport_event event);
  83. static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
  84. enum rport_event event);
  85. static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
  86. enum rport_event event);
  87. static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
  88. enum rport_event event);
  89. static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
  90. enum rport_event event);
  91. static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
  92. enum rport_event event);
  93. static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
  94. enum rport_event event);
  95. static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport,
  96. enum rport_event event);
  97. static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
  98. enum rport_event event);
  99. static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
  100. enum rport_event event);
  101. static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
  102. enum rport_event event);
  103. static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
  104. enum rport_event event);
  105. static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
  106. enum rport_event event);
  107. static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
  108. enum rport_event event);
  109. static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
  110. enum rport_event event);
  111. static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
  112. enum rport_event event);
  113. static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
  114. enum rport_event event);
  115. static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
  116. enum rport_event event);
  117. static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
  118. enum rport_event event);
  119. static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
  120. enum rport_event event);
  121. static struct bfa_sm_table_s rport_sm_table[] = {
  122. {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
  123. {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
  124. {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
  125. {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
  126. {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
  127. {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
  128. {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
  129. {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
  130. {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
  131. {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC},
  132. {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC},
  133. {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
  134. {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
  135. {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
  136. {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
  137. {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
  138. {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
  139. {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
  140. {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
  141. {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
  142. {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
  143. {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
  144. };
  145. /*
  146. * Beginning state.
  147. */
  148. static void
  149. bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
  150. {
  151. bfa_trc(rport->fcs, rport->pwwn);
  152. bfa_trc(rport->fcs, rport->pid);
  153. bfa_trc(rport->fcs, event);
  154. switch (event) {
  155. case RPSM_EVENT_PLOGI_SEND:
  156. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
  157. rport->plogi_retries = 0;
  158. bfa_fcs_rport_send_plogi(rport, NULL);
  159. break;
  160. case RPSM_EVENT_PLOGI_RCVD:
  161. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
  162. bfa_fcs_rport_send_plogiacc(rport, NULL);
  163. break;
  164. case RPSM_EVENT_PLOGI_COMP:
  165. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
  166. bfa_fcs_rport_hal_online(rport);
  167. break;
  168. case RPSM_EVENT_ADDRESS_CHANGE:
  169. case RPSM_EVENT_ADDRESS_DISC:
  170. bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
  171. rport->ns_retries = 0;
  172. bfa_fcs_rport_send_nsdisc(rport, NULL);
  173. break;
  174. default:
  175. bfa_sm_fault(rport->fcs, event);
  176. }
  177. }
  178. /*
  179. * PLOGI is being sent.
  180. */
  181. static void
  182. bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
  183. enum rport_event event)
  184. {
  185. bfa_trc(rport->fcs, rport->pwwn);
  186. bfa_trc(rport->fcs, rport->pid);
  187. bfa_trc(rport->fcs, event);
  188. switch (event) {
  189. case RPSM_EVENT_FCXP_SENT:
  190. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
  191. break;
  192. case RPSM_EVENT_DELETE:
  193. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  194. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  195. bfa_fcs_rport_free(rport);
  196. break;
  197. case RPSM_EVENT_PLOGI_RCVD:
  198. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
  199. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  200. bfa_fcs_rport_send_plogiacc(rport, NULL);
  201. break;
  202. case RPSM_EVENT_ADDRESS_CHANGE:
  203. case RPSM_EVENT_SCN:
  204. /* query the NS */
  205. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  206. bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
  207. rport->ns_retries = 0;
  208. bfa_fcs_rport_send_nsdisc(rport, NULL);
  209. break;
  210. case RPSM_EVENT_LOGO_IMP:
  211. rport->pid = 0;
  212. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  213. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  214. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  215. bfa_fcs_rport_timeout, rport,
  216. bfa_fcs_rport_del_timeout);
  217. break;
  218. default:
  219. bfa_sm_fault(rport->fcs, event);
  220. }
  221. }
  222. /*
  223. * PLOGI is being sent.
  224. */
  225. static void
  226. bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
  227. enum rport_event event)
  228. {
  229. bfa_trc(rport->fcs, rport->pwwn);
  230. bfa_trc(rport->fcs, rport->pid);
  231. bfa_trc(rport->fcs, event);
  232. switch (event) {
  233. case RPSM_EVENT_FCXP_SENT:
  234. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
  235. bfa_fcs_rport_hal_online(rport);
  236. break;
  237. case RPSM_EVENT_DELETE:
  238. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  239. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  240. bfa_fcs_rport_free(rport);
  241. break;
  242. case RPSM_EVENT_PLOGI_RCVD:
  243. case RPSM_EVENT_PLOGI_COMP:
  244. case RPSM_EVENT_SCN:
  245. /*
  246. * Ignore, SCN is possibly online notification.
  247. */
  248. break;
  249. case RPSM_EVENT_ADDRESS_CHANGE:
  250. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  251. bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
  252. rport->ns_retries = 0;
  253. bfa_fcs_rport_send_nsdisc(rport, NULL);
  254. break;
  255. case RPSM_EVENT_LOGO_IMP:
  256. rport->pid = 0;
  257. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  258. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  259. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  260. bfa_fcs_rport_timeout, rport,
  261. bfa_fcs_rport_del_timeout);
  262. break;
  263. case RPSM_EVENT_HCB_OFFLINE:
  264. /*
  265. * Ignore BFA callback, on a PLOGI receive we call bfa offline.
  266. */
  267. break;
  268. default:
  269. bfa_sm_fault(rport->fcs, event);
  270. }
  271. }
  272. /*
  273. * PLOGI is sent.
  274. */
  275. static void
  276. bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
  277. enum rport_event event)
  278. {
  279. bfa_trc(rport->fcs, rport->pwwn);
  280. bfa_trc(rport->fcs, rport->pid);
  281. bfa_trc(rport->fcs, event);
  282. switch (event) {
  283. case RPSM_EVENT_TIMEOUT:
  284. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
  285. bfa_fcs_rport_send_plogi(rport, NULL);
  286. break;
  287. case RPSM_EVENT_DELETE:
  288. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  289. bfa_timer_stop(&rport->timer);
  290. bfa_fcs_rport_free(rport);
  291. break;
  292. case RPSM_EVENT_PRLO_RCVD:
  293. case RPSM_EVENT_LOGO_RCVD:
  294. break;
  295. case RPSM_EVENT_PLOGI_RCVD:
  296. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
  297. bfa_timer_stop(&rport->timer);
  298. bfa_fcs_rport_send_plogiacc(rport, NULL);
  299. break;
  300. case RPSM_EVENT_ADDRESS_CHANGE:
  301. case RPSM_EVENT_SCN:
  302. bfa_timer_stop(&rport->timer);
  303. bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
  304. rport->ns_retries = 0;
  305. bfa_fcs_rport_send_nsdisc(rport, NULL);
  306. break;
  307. case RPSM_EVENT_LOGO_IMP:
  308. rport->pid = 0;
  309. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  310. bfa_timer_stop(&rport->timer);
  311. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  312. bfa_fcs_rport_timeout, rport,
  313. bfa_fcs_rport_del_timeout);
  314. break;
  315. case RPSM_EVENT_PLOGI_COMP:
  316. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
  317. bfa_timer_stop(&rport->timer);
  318. bfa_fcs_rport_hal_online(rport);
  319. break;
  320. default:
  321. bfa_sm_fault(rport->fcs, event);
  322. }
  323. }
  324. /*
  325. * PLOGI is sent.
  326. */
  327. static void
  328. bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
  329. {
  330. bfa_trc(rport->fcs, rport->pwwn);
  331. bfa_trc(rport->fcs, rport->pid);
  332. bfa_trc(rport->fcs, event);
  333. switch (event) {
  334. case RPSM_EVENT_ACCEPTED:
  335. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
  336. rport->plogi_retries = 0;
  337. bfa_fcs_rport_hal_online(rport);
  338. break;
  339. case RPSM_EVENT_LOGO_RCVD:
  340. bfa_fcs_rport_send_logo_acc(rport);
  341. /*
  342. * !! fall through !!
  343. */
  344. case RPSM_EVENT_PRLO_RCVD:
  345. if (rport->prlo == BFA_TRUE)
  346. bfa_fcs_rport_send_prlo_acc(rport);
  347. bfa_fcxp_discard(rport->fcxp);
  348. /*
  349. * !! fall through !!
  350. */
  351. case RPSM_EVENT_FAILED:
  352. if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
  353. rport->plogi_retries++;
  354. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
  355. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  356. bfa_fcs_rport_timeout, rport,
  357. BFA_FCS_RETRY_TIMEOUT);
  358. } else {
  359. bfa_stats(rport->port, rport_del_max_plogi_retry);
  360. rport->old_pid = rport->pid;
  361. rport->pid = 0;
  362. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  363. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  364. bfa_fcs_rport_timeout, rport,
  365. bfa_fcs_rport_del_timeout);
  366. }
  367. break;
  368. case RPSM_EVENT_PLOGI_RETRY:
  369. rport->plogi_retries = 0;
  370. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
  371. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  372. bfa_fcs_rport_timeout, rport,
  373. (FC_RA_TOV * 1000));
  374. break;
  375. case RPSM_EVENT_LOGO_IMP:
  376. rport->pid = 0;
  377. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  378. bfa_fcxp_discard(rport->fcxp);
  379. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  380. bfa_fcs_rport_timeout, rport,
  381. bfa_fcs_rport_del_timeout);
  382. break;
  383. case RPSM_EVENT_ADDRESS_CHANGE:
  384. case RPSM_EVENT_SCN:
  385. bfa_fcxp_discard(rport->fcxp);
  386. bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
  387. rport->ns_retries = 0;
  388. bfa_fcs_rport_send_nsdisc(rport, NULL);
  389. break;
  390. case RPSM_EVENT_PLOGI_RCVD:
  391. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
  392. bfa_fcxp_discard(rport->fcxp);
  393. bfa_fcs_rport_send_plogiacc(rport, NULL);
  394. break;
  395. case RPSM_EVENT_DELETE:
  396. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  397. bfa_fcxp_discard(rport->fcxp);
  398. bfa_fcs_rport_free(rport);
  399. break;
  400. case RPSM_EVENT_PLOGI_COMP:
  401. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
  402. bfa_fcxp_discard(rport->fcxp);
  403. bfa_fcs_rport_hal_online(rport);
  404. break;
  405. default:
  406. bfa_sm_fault(rport->fcs, event);
  407. }
  408. }
  409. /*
  410. * PLOGI is complete. Awaiting BFA rport online callback. FC-4s
  411. * are offline.
  412. */
  413. static void
  414. bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
  415. enum rport_event event)
  416. {
  417. bfa_trc(rport->fcs, rport->pwwn);
  418. bfa_trc(rport->fcs, rport->pid);
  419. bfa_trc(rport->fcs, event);
  420. switch (event) {
  421. case RPSM_EVENT_HCB_ONLINE:
  422. bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
  423. bfa_fcs_rport_online_action(rport);
  424. break;
  425. case RPSM_EVENT_PRLO_RCVD:
  426. case RPSM_EVENT_PLOGI_COMP:
  427. break;
  428. case RPSM_EVENT_LOGO_RCVD:
  429. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
  430. bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
  431. break;
  432. case RPSM_EVENT_LOGO_IMP:
  433. case RPSM_EVENT_ADDRESS_CHANGE:
  434. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
  435. bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
  436. break;
  437. case RPSM_EVENT_PLOGI_RCVD:
  438. rport->plogi_pending = BFA_TRUE;
  439. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
  440. bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
  441. break;
  442. case RPSM_EVENT_DELETE:
  443. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
  444. bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
  445. break;
  446. case RPSM_EVENT_SCN:
  447. /*
  448. * @todo
  449. * Ignore SCN - PLOGI just completed, FC-4 login should detect
  450. * device failures.
  451. */
  452. break;
  453. default:
  454. bfa_sm_fault(rport->fcs, event);
  455. }
  456. }
  457. /*
  458. * Rport is ONLINE. FC-4s active.
  459. */
  460. static void
  461. bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
  462. {
  463. bfa_trc(rport->fcs, rport->pwwn);
  464. bfa_trc(rport->fcs, rport->pid);
  465. bfa_trc(rport->fcs, event);
  466. switch (event) {
  467. case RPSM_EVENT_SCN:
  468. if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
  469. bfa_sm_set_state(rport,
  470. bfa_fcs_rport_sm_nsquery_sending);
  471. rport->ns_retries = 0;
  472. bfa_fcs_rport_send_nsdisc(rport, NULL);
  473. } else {
  474. bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
  475. bfa_fcs_rport_send_adisc(rport, NULL);
  476. }
  477. break;
  478. case RPSM_EVENT_PLOGI_RCVD:
  479. case RPSM_EVENT_LOGO_IMP:
  480. case RPSM_EVENT_ADDRESS_CHANGE:
  481. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
  482. bfa_fcs_rport_offline_action(rport);
  483. break;
  484. case RPSM_EVENT_DELETE:
  485. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
  486. bfa_fcs_rport_offline_action(rport);
  487. break;
  488. case RPSM_EVENT_LOGO_RCVD:
  489. case RPSM_EVENT_PRLO_RCVD:
  490. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
  491. bfa_fcs_rport_offline_action(rport);
  492. break;
  493. case RPSM_EVENT_PLOGI_COMP:
  494. break;
  495. default:
  496. bfa_sm_fault(rport->fcs, event);
  497. }
  498. }
  499. /*
  500. * An SCN event is received in ONLINE state. NS query is being sent
  501. * prior to ADISC authentication with rport. FC-4s are paused.
  502. */
  503. static void
  504. bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
  505. enum rport_event event)
  506. {
  507. bfa_trc(rport->fcs, rport->pwwn);
  508. bfa_trc(rport->fcs, rport->pid);
  509. bfa_trc(rport->fcs, event);
  510. switch (event) {
  511. case RPSM_EVENT_FCXP_SENT:
  512. bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
  513. break;
  514. case RPSM_EVENT_DELETE:
  515. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
  516. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  517. bfa_fcs_rport_offline_action(rport);
  518. break;
  519. case RPSM_EVENT_SCN:
  520. /*
  521. * ignore SCN, wait for response to query itself
  522. */
  523. break;
  524. case RPSM_EVENT_LOGO_RCVD:
  525. case RPSM_EVENT_PRLO_RCVD:
  526. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
  527. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  528. bfa_fcs_rport_offline_action(rport);
  529. break;
  530. case RPSM_EVENT_LOGO_IMP:
  531. rport->pid = 0;
  532. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  533. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  534. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  535. bfa_fcs_rport_timeout, rport,
  536. bfa_fcs_rport_del_timeout);
  537. break;
  538. case RPSM_EVENT_PLOGI_RCVD:
  539. case RPSM_EVENT_ADDRESS_CHANGE:
  540. case RPSM_EVENT_PLOGI_COMP:
  541. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
  542. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  543. bfa_fcs_rport_offline_action(rport);
  544. break;
  545. default:
  546. bfa_sm_fault(rport->fcs, event);
  547. }
  548. }
  549. /*
  550. * An SCN event is received in ONLINE state. NS query is sent to rport.
  551. * FC-4s are paused.
  552. */
  553. static void
  554. bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
  555. {
  556. bfa_trc(rport->fcs, rport->pwwn);
  557. bfa_trc(rport->fcs, rport->pid);
  558. bfa_trc(rport->fcs, event);
  559. switch (event) {
  560. case RPSM_EVENT_ACCEPTED:
  561. bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
  562. bfa_fcs_rport_send_adisc(rport, NULL);
  563. break;
  564. case RPSM_EVENT_FAILED:
  565. rport->ns_retries++;
  566. if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
  567. bfa_sm_set_state(rport,
  568. bfa_fcs_rport_sm_nsquery_sending);
  569. bfa_fcs_rport_send_nsdisc(rport, NULL);
  570. } else {
  571. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
  572. bfa_fcs_rport_offline_action(rport);
  573. }
  574. break;
  575. case RPSM_EVENT_DELETE:
  576. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
  577. bfa_fcxp_discard(rport->fcxp);
  578. bfa_fcs_rport_offline_action(rport);
  579. break;
  580. case RPSM_EVENT_SCN:
  581. break;
  582. case RPSM_EVENT_LOGO_RCVD:
  583. case RPSM_EVENT_PRLO_RCVD:
  584. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
  585. bfa_fcxp_discard(rport->fcxp);
  586. bfa_fcs_rport_offline_action(rport);
  587. break;
  588. case RPSM_EVENT_PLOGI_COMP:
  589. case RPSM_EVENT_ADDRESS_CHANGE:
  590. case RPSM_EVENT_PLOGI_RCVD:
  591. case RPSM_EVENT_LOGO_IMP:
  592. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
  593. bfa_fcxp_discard(rport->fcxp);
  594. bfa_fcs_rport_offline_action(rport);
  595. break;
  596. default:
  597. bfa_sm_fault(rport->fcs, event);
  598. }
  599. }
  600. /*
  601. * An SCN event is received in ONLINE state. ADISC is being sent for
  602. * authenticating with rport. FC-4s are paused.
  603. */
  604. static void
  605. bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
  606. enum rport_event event)
  607. {
  608. bfa_trc(rport->fcs, rport->pwwn);
  609. bfa_trc(rport->fcs, rport->pid);
  610. bfa_trc(rport->fcs, event);
  611. switch (event) {
  612. case RPSM_EVENT_FCXP_SENT:
  613. bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc);
  614. break;
  615. case RPSM_EVENT_DELETE:
  616. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
  617. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  618. bfa_fcs_rport_offline_action(rport);
  619. break;
  620. case RPSM_EVENT_LOGO_IMP:
  621. case RPSM_EVENT_ADDRESS_CHANGE:
  622. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
  623. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  624. bfa_fcs_rport_offline_action(rport);
  625. break;
  626. case RPSM_EVENT_LOGO_RCVD:
  627. case RPSM_EVENT_PRLO_RCVD:
  628. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
  629. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  630. bfa_fcs_rport_offline_action(rport);
  631. break;
  632. case RPSM_EVENT_SCN:
  633. break;
  634. case RPSM_EVENT_PLOGI_RCVD:
  635. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
  636. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  637. bfa_fcs_rport_offline_action(rport);
  638. break;
  639. default:
  640. bfa_sm_fault(rport->fcs, event);
  641. }
  642. }
  643. /*
  644. * An SCN event is received in ONLINE state. ADISC is to rport.
  645. * FC-4s are paused.
  646. */
  647. static void
  648. bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
  649. {
  650. bfa_trc(rport->fcs, rport->pwwn);
  651. bfa_trc(rport->fcs, rport->pid);
  652. bfa_trc(rport->fcs, event);
  653. switch (event) {
  654. case RPSM_EVENT_ACCEPTED:
  655. bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
  656. break;
  657. case RPSM_EVENT_PLOGI_RCVD:
  658. /*
  659. * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
  660. * At least go offline when a PLOGI is received.
  661. */
  662. bfa_fcxp_discard(rport->fcxp);
  663. /*
  664. * !!! fall through !!!
  665. */
  666. case RPSM_EVENT_FAILED:
  667. case RPSM_EVENT_ADDRESS_CHANGE:
  668. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
  669. bfa_fcs_rport_offline_action(rport);
  670. break;
  671. case RPSM_EVENT_DELETE:
  672. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
  673. bfa_fcxp_discard(rport->fcxp);
  674. bfa_fcs_rport_offline_action(rport);
  675. break;
  676. case RPSM_EVENT_SCN:
  677. /*
  678. * already processing RSCN
  679. */
  680. break;
  681. case RPSM_EVENT_LOGO_IMP:
  682. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
  683. bfa_fcxp_discard(rport->fcxp);
  684. bfa_fcs_rport_offline_action(rport);
  685. break;
  686. case RPSM_EVENT_LOGO_RCVD:
  687. case RPSM_EVENT_PRLO_RCVD:
  688. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
  689. bfa_fcxp_discard(rport->fcxp);
  690. bfa_fcs_rport_offline_action(rport);
  691. break;
  692. default:
  693. bfa_sm_fault(rport->fcs, event);
  694. }
  695. }
  696. /*
  697. * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
  698. */
  699. static void
  700. bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
  701. enum rport_event event)
  702. {
  703. bfa_trc(rport->fcs, rport->pwwn);
  704. bfa_trc(rport->fcs, rport->pid);
  705. bfa_trc(rport->fcs, event);
  706. switch (event) {
  707. case RPSM_EVENT_FC4_OFFLINE:
  708. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
  709. bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
  710. break;
  711. case RPSM_EVENT_DELETE:
  712. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
  713. break;
  714. case RPSM_EVENT_LOGO_RCVD:
  715. case RPSM_EVENT_PRLO_RCVD:
  716. case RPSM_EVENT_ADDRESS_CHANGE:
  717. break;
  718. default:
  719. bfa_sm_fault(rport->fcs, event);
  720. }
  721. }
  722. /*
  723. * LOGO needs to be sent to rport. Awaiting FC-4 offline completion
  724. * callback.
  725. */
  726. static void
  727. bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
  728. enum rport_event event)
  729. {
  730. bfa_trc(rport->fcs, rport->pwwn);
  731. bfa_trc(rport->fcs, rport->pid);
  732. bfa_trc(rport->fcs, event);
  733. switch (event) {
  734. case RPSM_EVENT_FC4_OFFLINE:
  735. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
  736. bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
  737. break;
  738. default:
  739. bfa_sm_fault(rport->fcs, event);
  740. }
  741. }
  742. /*
  743. * Rport is going offline. Awaiting FC-4 offline completion callback.
  744. */
  745. static void
  746. bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
  747. enum rport_event event)
  748. {
  749. bfa_trc(rport->fcs, rport->pwwn);
  750. bfa_trc(rport->fcs, rport->pid);
  751. bfa_trc(rport->fcs, event);
  752. switch (event) {
  753. case RPSM_EVENT_FC4_OFFLINE:
  754. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
  755. bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
  756. break;
  757. case RPSM_EVENT_SCN:
  758. case RPSM_EVENT_LOGO_IMP:
  759. case RPSM_EVENT_LOGO_RCVD:
  760. case RPSM_EVENT_PRLO_RCVD:
  761. case RPSM_EVENT_ADDRESS_CHANGE:
  762. /*
  763. * rport is already going offline.
  764. * SCN - ignore and wait till transitioning to offline state
  765. */
  766. break;
  767. case RPSM_EVENT_DELETE:
  768. bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
  769. break;
  770. default:
  771. bfa_sm_fault(rport->fcs, event);
  772. }
  773. }
  774. /*
  775. * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
  776. * callback.
  777. */
  778. static void
  779. bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
  780. enum rport_event event)
  781. {
  782. bfa_trc(rport->fcs, rport->pwwn);
  783. bfa_trc(rport->fcs, rport->pid);
  784. bfa_trc(rport->fcs, event);
  785. switch (event) {
  786. case RPSM_EVENT_HCB_OFFLINE:
  787. if (bfa_fcs_lport_is_online(rport->port) &&
  788. (rport->plogi_pending)) {
  789. rport->plogi_pending = BFA_FALSE;
  790. bfa_sm_set_state(rport,
  791. bfa_fcs_rport_sm_plogiacc_sending);
  792. bfa_fcs_rport_send_plogiacc(rport, NULL);
  793. break;
  794. }
  795. /*
  796. * !! fall through !!
  797. */
  798. case RPSM_EVENT_ADDRESS_CHANGE:
  799. if (bfa_fcs_lport_is_online(rport->port)) {
  800. if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
  801. bfa_sm_set_state(rport,
  802. bfa_fcs_rport_sm_nsdisc_sending);
  803. rport->ns_retries = 0;
  804. bfa_fcs_rport_send_nsdisc(rport, NULL);
  805. } else {
  806. bfa_sm_set_state(rport,
  807. bfa_fcs_rport_sm_plogi_sending);
  808. rport->plogi_retries = 0;
  809. bfa_fcs_rport_send_plogi(rport, NULL);
  810. }
  811. } else {
  812. rport->pid = 0;
  813. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  814. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  815. bfa_fcs_rport_timeout, rport,
  816. bfa_fcs_rport_del_timeout);
  817. }
  818. break;
  819. case RPSM_EVENT_DELETE:
  820. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  821. bfa_fcs_rport_free(rport);
  822. break;
  823. case RPSM_EVENT_SCN:
  824. case RPSM_EVENT_LOGO_RCVD:
  825. case RPSM_EVENT_PRLO_RCVD:
  826. case RPSM_EVENT_PLOGI_RCVD:
  827. case RPSM_EVENT_LOGO_IMP:
  828. /*
  829. * Ignore, already offline.
  830. */
  831. break;
  832. default:
  833. bfa_sm_fault(rport->fcs, event);
  834. }
  835. }
  836. /*
  837. * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
  838. * callback to send LOGO accept.
  839. */
  840. static void
  841. bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
  842. enum rport_event event)
  843. {
  844. bfa_trc(rport->fcs, rport->pwwn);
  845. bfa_trc(rport->fcs, rport->pid);
  846. bfa_trc(rport->fcs, event);
  847. switch (event) {
  848. case RPSM_EVENT_HCB_OFFLINE:
  849. case RPSM_EVENT_ADDRESS_CHANGE:
  850. if (rport->pid && (rport->prlo == BFA_TRUE))
  851. bfa_fcs_rport_send_prlo_acc(rport);
  852. if (rport->pid && (rport->prlo == BFA_FALSE))
  853. bfa_fcs_rport_send_logo_acc(rport);
  854. /*
  855. * If the lport is online and if the rport is not a well
  856. * known address port,
  857. * we try to re-discover the r-port.
  858. */
  859. if (bfa_fcs_lport_is_online(rport->port) &&
  860. (!BFA_FCS_PID_IS_WKA(rport->pid))) {
  861. if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
  862. bfa_sm_set_state(rport,
  863. bfa_fcs_rport_sm_nsdisc_sending);
  864. rport->ns_retries = 0;
  865. bfa_fcs_rport_send_nsdisc(rport, NULL);
  866. } else {
  867. /* For N2N Direct Attach, try to re-login */
  868. bfa_sm_set_state(rport,
  869. bfa_fcs_rport_sm_plogi_sending);
  870. rport->plogi_retries = 0;
  871. bfa_fcs_rport_send_plogi(rport, NULL);
  872. }
  873. } else {
  874. /*
  875. * if it is not a well known address, reset the
  876. * pid to 0.
  877. */
  878. if (!BFA_FCS_PID_IS_WKA(rport->pid))
  879. rport->pid = 0;
  880. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  881. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  882. bfa_fcs_rport_timeout, rport,
  883. bfa_fcs_rport_del_timeout);
  884. }
  885. break;
  886. case RPSM_EVENT_DELETE:
  887. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
  888. break;
  889. case RPSM_EVENT_LOGO_IMP:
  890. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
  891. break;
  892. case RPSM_EVENT_LOGO_RCVD:
  893. case RPSM_EVENT_PRLO_RCVD:
  894. /*
  895. * Ignore - already processing a LOGO.
  896. */
  897. break;
  898. default:
  899. bfa_sm_fault(rport->fcs, event);
  900. }
  901. }
  902. /*
  903. * Rport is being deleted. FC-4s are offline.
  904. * Awaiting BFA rport offline
  905. * callback to send LOGO.
  906. */
  907. static void
  908. bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
  909. enum rport_event event)
  910. {
  911. bfa_trc(rport->fcs, rport->pwwn);
  912. bfa_trc(rport->fcs, rport->pid);
  913. bfa_trc(rport->fcs, event);
  914. switch (event) {
  915. case RPSM_EVENT_HCB_OFFLINE:
  916. bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
  917. bfa_fcs_rport_send_logo(rport, NULL);
  918. break;
  919. case RPSM_EVENT_LOGO_RCVD:
  920. case RPSM_EVENT_PRLO_RCVD:
  921. case RPSM_EVENT_ADDRESS_CHANGE:
  922. break;
  923. default:
  924. bfa_sm_fault(rport->fcs, event);
  925. }
  926. }
  927. /*
  928. * Rport is being deleted. FC-4s are offline. LOGO is being sent.
  929. */
  930. static void
  931. bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
  932. enum rport_event event)
  933. {
  934. bfa_trc(rport->fcs, rport->pwwn);
  935. bfa_trc(rport->fcs, rport->pid);
  936. bfa_trc(rport->fcs, event);
  937. switch (event) {
  938. case RPSM_EVENT_FCXP_SENT:
  939. /* Once LOGO is sent, we donot wait for the response */
  940. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  941. bfa_fcs_rport_free(rport);
  942. break;
  943. case RPSM_EVENT_SCN:
  944. case RPSM_EVENT_ADDRESS_CHANGE:
  945. break;
  946. case RPSM_EVENT_LOGO_RCVD:
  947. case RPSM_EVENT_PRLO_RCVD:
  948. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  949. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  950. bfa_fcs_rport_free(rport);
  951. break;
  952. default:
  953. bfa_sm_fault(rport->fcs, event);
  954. }
  955. }
  956. /*
  957. * Rport is offline. FC-4s are offline. BFA rport is offline.
  958. * Timer active to delete stale rport.
  959. */
  960. static void
  961. bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
  962. {
  963. bfa_trc(rport->fcs, rport->pwwn);
  964. bfa_trc(rport->fcs, rport->pid);
  965. bfa_trc(rport->fcs, event);
  966. switch (event) {
  967. case RPSM_EVENT_TIMEOUT:
  968. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  969. bfa_fcs_rport_free(rport);
  970. break;
  971. case RPSM_EVENT_SCN:
  972. case RPSM_EVENT_ADDRESS_CHANGE:
  973. bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
  974. bfa_timer_stop(&rport->timer);
  975. rport->ns_retries = 0;
  976. bfa_fcs_rport_send_nsdisc(rport, NULL);
  977. break;
  978. case RPSM_EVENT_DELETE:
  979. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  980. bfa_timer_stop(&rport->timer);
  981. bfa_fcs_rport_free(rport);
  982. break;
  983. case RPSM_EVENT_PLOGI_RCVD:
  984. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
  985. bfa_timer_stop(&rport->timer);
  986. bfa_fcs_rport_send_plogiacc(rport, NULL);
  987. break;
  988. case RPSM_EVENT_LOGO_RCVD:
  989. case RPSM_EVENT_PRLO_RCVD:
  990. case RPSM_EVENT_LOGO_IMP:
  991. break;
  992. case RPSM_EVENT_PLOGI_COMP:
  993. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
  994. bfa_timer_stop(&rport->timer);
  995. bfa_fcs_rport_hal_online(rport);
  996. break;
  997. case RPSM_EVENT_PLOGI_SEND:
  998. bfa_timer_stop(&rport->timer);
  999. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
  1000. rport->plogi_retries = 0;
  1001. bfa_fcs_rport_send_plogi(rport, NULL);
  1002. break;
  1003. default:
  1004. bfa_sm_fault(rport->fcs, event);
  1005. }
  1006. }
  1007. /*
  1008. * Rport address has changed. Nameserver discovery request is being sent.
  1009. */
  1010. static void
  1011. bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
  1012. enum rport_event event)
  1013. {
  1014. bfa_trc(rport->fcs, rport->pwwn);
  1015. bfa_trc(rport->fcs, rport->pid);
  1016. bfa_trc(rport->fcs, event);
  1017. switch (event) {
  1018. case RPSM_EVENT_FCXP_SENT:
  1019. bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent);
  1020. break;
  1021. case RPSM_EVENT_DELETE:
  1022. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  1023. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  1024. bfa_fcs_rport_free(rport);
  1025. break;
  1026. case RPSM_EVENT_PLOGI_RCVD:
  1027. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
  1028. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  1029. bfa_fcs_rport_send_plogiacc(rport, NULL);
  1030. break;
  1031. case RPSM_EVENT_SCN:
  1032. case RPSM_EVENT_LOGO_RCVD:
  1033. case RPSM_EVENT_PRLO_RCVD:
  1034. case RPSM_EVENT_PLOGI_SEND:
  1035. break;
  1036. case RPSM_EVENT_ADDRESS_CHANGE:
  1037. rport->ns_retries = 0; /* reset the retry count */
  1038. break;
  1039. case RPSM_EVENT_LOGO_IMP:
  1040. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  1041. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  1042. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  1043. bfa_fcs_rport_timeout, rport,
  1044. bfa_fcs_rport_del_timeout);
  1045. break;
  1046. case RPSM_EVENT_PLOGI_COMP:
  1047. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
  1048. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
  1049. bfa_fcs_rport_hal_online(rport);
  1050. break;
  1051. default:
  1052. bfa_sm_fault(rport->fcs, event);
  1053. }
  1054. }
  1055. /*
  1056. * Nameserver discovery failed. Waiting for timeout to retry.
  1057. */
  1058. static void
  1059. bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
  1060. enum rport_event event)
  1061. {
  1062. bfa_trc(rport->fcs, rport->pwwn);
  1063. bfa_trc(rport->fcs, rport->pid);
  1064. bfa_trc(rport->fcs, event);
  1065. switch (event) {
  1066. case RPSM_EVENT_TIMEOUT:
  1067. bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
  1068. bfa_fcs_rport_send_nsdisc(rport, NULL);
  1069. break;
  1070. case RPSM_EVENT_SCN:
  1071. case RPSM_EVENT_ADDRESS_CHANGE:
  1072. bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
  1073. bfa_timer_stop(&rport->timer);
  1074. rport->ns_retries = 0;
  1075. bfa_fcs_rport_send_nsdisc(rport, NULL);
  1076. break;
  1077. case RPSM_EVENT_DELETE:
  1078. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  1079. bfa_timer_stop(&rport->timer);
  1080. bfa_fcs_rport_free(rport);
  1081. break;
  1082. case RPSM_EVENT_PLOGI_RCVD:
  1083. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
  1084. bfa_timer_stop(&rport->timer);
  1085. bfa_fcs_rport_send_plogiacc(rport, NULL);
  1086. break;
  1087. case RPSM_EVENT_LOGO_IMP:
  1088. rport->pid = 0;
  1089. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  1090. bfa_timer_stop(&rport->timer);
  1091. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  1092. bfa_fcs_rport_timeout, rport,
  1093. bfa_fcs_rport_del_timeout);
  1094. break;
  1095. case RPSM_EVENT_LOGO_RCVD:
  1096. bfa_fcs_rport_send_logo_acc(rport);
  1097. break;
  1098. case RPSM_EVENT_PRLO_RCVD:
  1099. bfa_fcs_rport_send_prlo_acc(rport);
  1100. break;
  1101. case RPSM_EVENT_PLOGI_COMP:
  1102. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
  1103. bfa_timer_stop(&rport->timer);
  1104. bfa_fcs_rport_hal_online(rport);
  1105. break;
  1106. default:
  1107. bfa_sm_fault(rport->fcs, event);
  1108. }
  1109. }
  1110. /*
  1111. * Rport address has changed. Nameserver discovery request is sent.
  1112. */
  1113. static void
  1114. bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
  1115. enum rport_event event)
  1116. {
  1117. bfa_trc(rport->fcs, rport->pwwn);
  1118. bfa_trc(rport->fcs, rport->pid);
  1119. bfa_trc(rport->fcs, event);
  1120. switch (event) {
  1121. case RPSM_EVENT_ACCEPTED:
  1122. case RPSM_EVENT_ADDRESS_CHANGE:
  1123. if (rport->pid) {
  1124. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
  1125. bfa_fcs_rport_send_plogi(rport, NULL);
  1126. } else {
  1127. bfa_sm_set_state(rport,
  1128. bfa_fcs_rport_sm_nsdisc_sending);
  1129. rport->ns_retries = 0;
  1130. bfa_fcs_rport_send_nsdisc(rport, NULL);
  1131. }
  1132. break;
  1133. case RPSM_EVENT_FAILED:
  1134. rport->ns_retries++;
  1135. if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
  1136. bfa_sm_set_state(rport,
  1137. bfa_fcs_rport_sm_nsdisc_sending);
  1138. bfa_fcs_rport_send_nsdisc(rport, NULL);
  1139. } else {
  1140. rport->old_pid = rport->pid;
  1141. rport->pid = 0;
  1142. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  1143. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  1144. bfa_fcs_rport_timeout, rport,
  1145. bfa_fcs_rport_del_timeout);
  1146. };
  1147. break;
  1148. case RPSM_EVENT_DELETE:
  1149. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  1150. bfa_fcxp_discard(rport->fcxp);
  1151. bfa_fcs_rport_free(rport);
  1152. break;
  1153. case RPSM_EVENT_PLOGI_RCVD:
  1154. bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
  1155. bfa_fcxp_discard(rport->fcxp);
  1156. bfa_fcs_rport_send_plogiacc(rport, NULL);
  1157. break;
  1158. case RPSM_EVENT_LOGO_IMP:
  1159. rport->pid = 0;
  1160. bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
  1161. bfa_fcxp_discard(rport->fcxp);
  1162. bfa_timer_start(rport->fcs->bfa, &rport->timer,
  1163. bfa_fcs_rport_timeout, rport,
  1164. bfa_fcs_rport_del_timeout);
  1165. break;
  1166. case RPSM_EVENT_PRLO_RCVD:
  1167. bfa_fcs_rport_send_prlo_acc(rport);
  1168. break;
  1169. case RPSM_EVENT_SCN:
  1170. /*
  1171. * ignore, wait for NS query response
  1172. */
  1173. break;
  1174. case RPSM_EVENT_LOGO_RCVD:
  1175. /*
  1176. * Not logged-in yet. Accept LOGO.
  1177. */
  1178. bfa_fcs_rport_send_logo_acc(rport);
  1179. break;
  1180. case RPSM_EVENT_PLOGI_COMP:
  1181. bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
  1182. bfa_fcxp_discard(rport->fcxp);
  1183. bfa_fcs_rport_hal_online(rport);
  1184. break;
  1185. default:
  1186. bfa_sm_fault(rport->fcs, event);
  1187. }
  1188. }
  1189. /*
  1190. * fcs_rport_private FCS RPORT provate functions
  1191. */
  1192. static void
  1193. bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  1194. {
  1195. struct bfa_fcs_rport_s *rport = rport_cbarg;
  1196. struct bfa_fcs_lport_s *port = rport->port;
  1197. struct fchs_s fchs;
  1198. int len;
  1199. struct bfa_fcxp_s *fcxp;
  1200. bfa_trc(rport->fcs, rport->pwwn);
  1201. fcxp = fcxp_alloced ? fcxp_alloced :
  1202. bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
  1203. if (!fcxp) {
  1204. bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
  1205. bfa_fcs_rport_send_plogi, rport, BFA_TRUE);
  1206. return;
  1207. }
  1208. rport->fcxp = fcxp;
  1209. len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
  1210. bfa_fcs_lport_get_fcid(port), 0,
  1211. port->port_cfg.pwwn, port->port_cfg.nwwn,
  1212. bfa_fcport_get_maxfrsize(port->fcs->bfa),
  1213. bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
  1214. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  1215. FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
  1216. (void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV);
  1217. rport->stats.plogis++;
  1218. bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
  1219. }
  1220. static void
  1221. bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
  1222. bfa_status_t req_status, u32 rsp_len,
  1223. u32 resid_len, struct fchs_s *rsp_fchs)
  1224. {
  1225. struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
  1226. struct fc_logi_s *plogi_rsp;
  1227. struct fc_ls_rjt_s *ls_rjt;
  1228. struct bfa_fcs_rport_s *twin;
  1229. struct list_head *qe;
  1230. bfa_trc(rport->fcs, rport->pwwn);
  1231. /*
  1232. * Sanity Checks
  1233. */
  1234. if (req_status != BFA_STATUS_OK) {
  1235. bfa_trc(rport->fcs, req_status);
  1236. rport->stats.plogi_failed++;
  1237. bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
  1238. return;
  1239. }
  1240. plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
  1241. /*
  1242. * Check for failure first.
  1243. */
  1244. if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
  1245. ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
  1246. bfa_trc(rport->fcs, ls_rjt->reason_code);
  1247. bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
  1248. if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) &&
  1249. (ls_rjt->reason_code_expl == FC_LS_RJT_EXP_INSUFF_RES)) {
  1250. rport->stats.rjt_insuff_res++;
  1251. bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RETRY);
  1252. return;
  1253. }
  1254. rport->stats.plogi_rejects++;
  1255. bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
  1256. return;
  1257. }
  1258. /*
  1259. * PLOGI is complete. Make sure this device is not one of the known
  1260. * device with a new FC port address.
  1261. */
  1262. list_for_each(qe, &rport->port->rport_q) {
  1263. twin = (struct bfa_fcs_rport_s *) qe;
  1264. if (twin == rport)
  1265. continue;
  1266. if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
  1267. bfa_trc(rport->fcs, twin->pid);
  1268. bfa_trc(rport->fcs, rport->pid);
  1269. /* Update plogi stats in twin */
  1270. twin->stats.plogis += rport->stats.plogis;
  1271. twin->stats.plogi_rejects +=
  1272. rport->stats.plogi_rejects;
  1273. twin->stats.plogi_timeouts +=
  1274. rport->stats.plogi_timeouts;
  1275. twin->stats.plogi_failed +=
  1276. rport->stats.plogi_failed;
  1277. twin->stats.plogi_rcvd += rport->stats.plogi_rcvd;
  1278. twin->stats.plogi_accs++;
  1279. bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
  1280. bfa_fcs_rport_update(twin, plogi_rsp);
  1281. twin->pid = rsp_fchs->s_id;
  1282. bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP);
  1283. return;
  1284. }
  1285. }
  1286. /*
  1287. * Normal login path -- no evil twins.
  1288. */
  1289. rport->stats.plogi_accs++;
  1290. bfa_fcs_rport_update(rport, plogi_rsp);
  1291. bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
  1292. }
  1293. static void
  1294. bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  1295. {
  1296. struct bfa_fcs_rport_s *rport = rport_cbarg;
  1297. struct bfa_fcs_lport_s *port = rport->port;
  1298. struct fchs_s fchs;
  1299. int len;
  1300. struct bfa_fcxp_s *fcxp;
  1301. bfa_trc(rport->fcs, rport->pwwn);
  1302. bfa_trc(rport->fcs, rport->reply_oxid);
  1303. fcxp = fcxp_alloced ? fcxp_alloced :
  1304. bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
  1305. if (!fcxp) {
  1306. bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
  1307. bfa_fcs_rport_send_plogiacc, rport, BFA_FALSE);
  1308. return;
  1309. }
  1310. rport->fcxp = fcxp;
  1311. len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  1312. rport->pid, bfa_fcs_lport_get_fcid(port),
  1313. rport->reply_oxid, port->port_cfg.pwwn,
  1314. port->port_cfg.nwwn,
  1315. bfa_fcport_get_maxfrsize(port->fcs->bfa),
  1316. bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
  1317. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  1318. FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
  1319. bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
  1320. }
  1321. static void
  1322. bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  1323. {
  1324. struct bfa_fcs_rport_s *rport = rport_cbarg;
  1325. struct bfa_fcs_lport_s *port = rport->port;
  1326. struct fchs_s fchs;
  1327. int len;
  1328. struct bfa_fcxp_s *fcxp;
  1329. bfa_trc(rport->fcs, rport->pwwn);
  1330. fcxp = fcxp_alloced ? fcxp_alloced :
  1331. bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
  1332. if (!fcxp) {
  1333. bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
  1334. bfa_fcs_rport_send_adisc, rport, BFA_TRUE);
  1335. return;
  1336. }
  1337. rport->fcxp = fcxp;
  1338. len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
  1339. bfa_fcs_lport_get_fcid(port), 0,
  1340. port->port_cfg.pwwn, port->port_cfg.nwwn);
  1341. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  1342. FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
  1343. rport, FC_MAX_PDUSZ, FC_ELS_TOV);
  1344. rport->stats.adisc_sent++;
  1345. bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
  1346. }
  1347. static void
  1348. bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
  1349. bfa_status_t req_status, u32 rsp_len,
  1350. u32 resid_len, struct fchs_s *rsp_fchs)
  1351. {
  1352. struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
  1353. void *pld = bfa_fcxp_get_rspbuf(fcxp);
  1354. struct fc_ls_rjt_s *ls_rjt;
  1355. if (req_status != BFA_STATUS_OK) {
  1356. bfa_trc(rport->fcs, req_status);
  1357. rport->stats.adisc_failed++;
  1358. bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
  1359. return;
  1360. }
  1361. if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
  1362. rport->nwwn) == FC_PARSE_OK) {
  1363. rport->stats.adisc_accs++;
  1364. bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
  1365. return;
  1366. }
  1367. rport->stats.adisc_rejects++;
  1368. ls_rjt = pld;
  1369. bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
  1370. bfa_trc(rport->fcs, ls_rjt->reason_code);
  1371. bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
  1372. bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
  1373. }
  1374. static void
  1375. bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  1376. {
  1377. struct bfa_fcs_rport_s *rport = rport_cbarg;
  1378. struct bfa_fcs_lport_s *port = rport->port;
  1379. struct fchs_s fchs;
  1380. struct bfa_fcxp_s *fcxp;
  1381. int len;
  1382. bfa_cb_fcxp_send_t cbfn;
  1383. bfa_trc(rport->fcs, rport->pid);
  1384. fcxp = fcxp_alloced ? fcxp_alloced :
  1385. bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
  1386. if (!fcxp) {
  1387. bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
  1388. bfa_fcs_rport_send_nsdisc, rport, BFA_TRUE);
  1389. return;
  1390. }
  1391. rport->fcxp = fcxp;
  1392. if (rport->pwwn) {
  1393. len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  1394. bfa_fcs_lport_get_fcid(port), 0, rport->pwwn);
  1395. cbfn = bfa_fcs_rport_gidpn_response;
  1396. } else {
  1397. len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  1398. bfa_fcs_lport_get_fcid(port), 0, rport->pid);
  1399. cbfn = bfa_fcs_rport_gpnid_response;
  1400. }
  1401. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  1402. FC_CLASS_3, len, &fchs, cbfn,
  1403. (void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV);
  1404. bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
  1405. }
  1406. static void
  1407. bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
  1408. bfa_status_t req_status, u32 rsp_len,
  1409. u32 resid_len, struct fchs_s *rsp_fchs)
  1410. {
  1411. struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
  1412. struct ct_hdr_s *cthdr;
  1413. struct fcgs_gidpn_resp_s *gidpn_rsp;
  1414. struct bfa_fcs_rport_s *twin;
  1415. struct list_head *qe;
  1416. bfa_trc(rport->fcs, rport->pwwn);
  1417. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  1418. cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
  1419. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  1420. /* Check if the pid is the same as before. */
  1421. gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
  1422. if (gidpn_rsp->dap == rport->pid) {
  1423. /* Device is online */
  1424. bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
  1425. } else {
  1426. /*
  1427. * Device's PID has changed. We need to cleanup
  1428. * and re-login. If there is another device with
  1429. * the the newly discovered pid, send an scn notice
  1430. * so that its new pid can be discovered.
  1431. */
  1432. list_for_each(qe, &rport->port->rport_q) {
  1433. twin = (struct bfa_fcs_rport_s *) qe;
  1434. if (twin == rport)
  1435. continue;
  1436. if (gidpn_rsp->dap == twin->pid) {
  1437. bfa_trc(rport->fcs, twin->pid);
  1438. bfa_trc(rport->fcs, rport->pid);
  1439. twin->pid = 0;
  1440. bfa_sm_send_event(twin,
  1441. RPSM_EVENT_ADDRESS_CHANGE);
  1442. }
  1443. }
  1444. rport->pid = gidpn_rsp->dap;
  1445. bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE);
  1446. }
  1447. return;
  1448. }
  1449. /*
  1450. * Reject Response
  1451. */
  1452. switch (cthdr->reason_code) {
  1453. case CT_RSN_LOGICAL_BUSY:
  1454. /*
  1455. * Need to retry
  1456. */
  1457. bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
  1458. break;
  1459. case CT_RSN_UNABLE_TO_PERF:
  1460. /*
  1461. * device doesn't exist : Start timer to cleanup this later.
  1462. */
  1463. bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
  1464. break;
  1465. default:
  1466. bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
  1467. break;
  1468. }
  1469. }
  1470. static void
  1471. bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
  1472. bfa_status_t req_status, u32 rsp_len,
  1473. u32 resid_len, struct fchs_s *rsp_fchs)
  1474. {
  1475. struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
  1476. struct ct_hdr_s *cthdr;
  1477. bfa_trc(rport->fcs, rport->pwwn);
  1478. cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
  1479. cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
  1480. if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
  1481. bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
  1482. return;
  1483. }
  1484. /*
  1485. * Reject Response
  1486. */
  1487. switch (cthdr->reason_code) {
  1488. case CT_RSN_LOGICAL_BUSY:
  1489. /*
  1490. * Need to retry
  1491. */
  1492. bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
  1493. break;
  1494. case CT_RSN_UNABLE_TO_PERF:
  1495. /*
  1496. * device doesn't exist : Start timer to cleanup this later.
  1497. */
  1498. bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
  1499. break;
  1500. default:
  1501. bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
  1502. break;
  1503. }
  1504. }
  1505. /*
  1506. * Called to send a logout to the rport.
  1507. */
  1508. static void
  1509. bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  1510. {
  1511. struct bfa_fcs_rport_s *rport = rport_cbarg;
  1512. struct bfa_fcs_lport_s *port;
  1513. struct fchs_s fchs;
  1514. struct bfa_fcxp_s *fcxp;
  1515. u16 len;
  1516. bfa_trc(rport->fcs, rport->pid);
  1517. port = rport->port;
  1518. fcxp = fcxp_alloced ? fcxp_alloced :
  1519. bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
  1520. if (!fcxp) {
  1521. bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
  1522. bfa_fcs_rport_send_logo, rport, BFA_FALSE);
  1523. return;
  1524. }
  1525. rport->fcxp = fcxp;
  1526. len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
  1527. bfa_fcs_lport_get_fcid(port), 0,
  1528. bfa_fcs_lport_get_pwwn(port));
  1529. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  1530. FC_CLASS_3, len, &fchs, NULL,
  1531. rport, FC_MAX_PDUSZ, FC_ELS_TOV);
  1532. rport->stats.logos++;
  1533. bfa_fcxp_discard(rport->fcxp);
  1534. bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
  1535. }
  1536. /*
  1537. * Send ACC for a LOGO received.
  1538. */
  1539. static void
  1540. bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
  1541. {
  1542. struct bfa_fcs_rport_s *rport = rport_cbarg;
  1543. struct bfa_fcs_lport_s *port;
  1544. struct fchs_s fchs;
  1545. struct bfa_fcxp_s *fcxp;
  1546. u16 len;
  1547. bfa_trc(rport->fcs, rport->pid);
  1548. port = rport->port;
  1549. fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
  1550. if (!fcxp)
  1551. return;
  1552. rport->stats.logo_rcvd++;
  1553. len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  1554. rport->pid, bfa_fcs_lport_get_fcid(port),
  1555. rport->reply_oxid);
  1556. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  1557. FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
  1558. }
  1559. /*
  1560. * brief
  1561. * This routine will be called by bfa_timer on timer timeouts.
  1562. *
  1563. * param[in] rport - pointer to bfa_fcs_lport_ns_t.
  1564. * param[out] rport_status - pointer to return vport status in
  1565. *
  1566. * return
  1567. * void
  1568. *
  1569. * Special Considerations:
  1570. *
  1571. * note
  1572. */
  1573. static void
  1574. bfa_fcs_rport_timeout(void *arg)
  1575. {
  1576. struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg;
  1577. rport->stats.plogi_timeouts++;
  1578. bfa_stats(rport->port, rport_plogi_timeouts);
  1579. bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
  1580. }
  1581. static void
  1582. bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
  1583. struct fchs_s *rx_fchs, u16 len)
  1584. {
  1585. struct bfa_fcxp_s *fcxp;
  1586. struct fchs_s fchs;
  1587. struct bfa_fcs_lport_s *port = rport->port;
  1588. struct fc_prli_s *prli;
  1589. bfa_trc(port->fcs, rx_fchs->s_id);
  1590. bfa_trc(port->fcs, rx_fchs->d_id);
  1591. rport->stats.prli_rcvd++;
  1592. /*
  1593. * We are in Initiator Mode
  1594. */
  1595. prli = (struct fc_prli_s *) (rx_fchs + 1);
  1596. if (prli->parampage.servparams.target) {
  1597. /*
  1598. * PRLI from a target ?
  1599. * Send the Acc.
  1600. * PRLI sent by us will be used to transition the IT nexus,
  1601. * once the response is received from the target.
  1602. */
  1603. bfa_trc(port->fcs, rx_fchs->s_id);
  1604. rport->scsi_function = BFA_RPORT_TARGET;
  1605. } else {
  1606. bfa_trc(rport->fcs, prli->parampage.type);
  1607. rport->scsi_function = BFA_RPORT_INITIATOR;
  1608. bfa_fcs_itnim_is_initiator(rport->itnim);
  1609. }
  1610. fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
  1611. if (!fcxp)
  1612. return;
  1613. len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  1614. rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
  1615. rx_fchs->ox_id, port->port_cfg.roles);
  1616. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  1617. FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
  1618. }
  1619. static void
  1620. bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
  1621. struct fchs_s *rx_fchs, u16 len)
  1622. {
  1623. struct bfa_fcxp_s *fcxp;
  1624. struct fchs_s fchs;
  1625. struct bfa_fcs_lport_s *port = rport->port;
  1626. struct fc_rpsc_speed_info_s speeds;
  1627. struct bfa_port_attr_s pport_attr;
  1628. bfa_trc(port->fcs, rx_fchs->s_id);
  1629. bfa_trc(port->fcs, rx_fchs->d_id);
  1630. rport->stats.rpsc_rcvd++;
  1631. speeds.port_speed_cap =
  1632. RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G |
  1633. RPSC_SPEED_CAP_8G;
  1634. /*
  1635. * get curent speed from pport attributes from BFA
  1636. */
  1637. bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
  1638. speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
  1639. fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
  1640. if (!fcxp)
  1641. return;
  1642. len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  1643. rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
  1644. rx_fchs->ox_id, &speeds);
  1645. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  1646. FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
  1647. }
  1648. static void
  1649. bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
  1650. struct fchs_s *rx_fchs, u16 len)
  1651. {
  1652. struct bfa_fcxp_s *fcxp;
  1653. struct fchs_s fchs;
  1654. struct bfa_fcs_lport_s *port = rport->port;
  1655. struct fc_adisc_s *adisc;
  1656. bfa_trc(port->fcs, rx_fchs->s_id);
  1657. bfa_trc(port->fcs, rx_fchs->d_id);
  1658. rport->stats.adisc_rcvd++;
  1659. adisc = (struct fc_adisc_s *) (rx_fchs + 1);
  1660. /*
  1661. * Accept if the itnim for this rport is online.
  1662. * Else reject the ADISC.
  1663. */
  1664. if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
  1665. fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
  1666. if (!fcxp)
  1667. return;
  1668. len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  1669. rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
  1670. rx_fchs->ox_id, port->port_cfg.pwwn,
  1671. port->port_cfg.nwwn);
  1672. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
  1673. BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
  1674. FC_MAX_PDUSZ, 0);
  1675. } else {
  1676. rport->stats.adisc_rejected++;
  1677. bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
  1678. FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
  1679. FC_LS_RJT_EXP_LOGIN_REQUIRED);
  1680. }
  1681. }
  1682. static void
  1683. bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
  1684. {
  1685. struct bfa_fcs_lport_s *port = rport->port;
  1686. struct bfa_rport_info_s rport_info;
  1687. rport_info.pid = rport->pid;
  1688. rport_info.local_pid = port->pid;
  1689. rport_info.lp_tag = port->lp_tag;
  1690. rport_info.vf_id = port->fabric->vf_id;
  1691. rport_info.vf_en = port->fabric->is_vf;
  1692. rport_info.fc_class = rport->fc_cos;
  1693. rport_info.cisc = rport->cisc;
  1694. rport_info.max_frmsz = rport->maxfrsize;
  1695. bfa_rport_online(rport->bfa_rport, &rport_info);
  1696. }
  1697. static struct bfa_fcs_rport_s *
  1698. bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
  1699. {
  1700. struct bfa_fcs_s *fcs = port->fcs;
  1701. struct bfa_fcs_rport_s *rport;
  1702. struct bfad_rport_s *rport_drv;
  1703. /*
  1704. * allocate rport
  1705. */
  1706. if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
  1707. != BFA_STATUS_OK) {
  1708. bfa_trc(fcs, rpid);
  1709. return NULL;
  1710. }
  1711. /*
  1712. * Initialize r-port
  1713. */
  1714. rport->port = port;
  1715. rport->fcs = fcs;
  1716. rport->rp_drv = rport_drv;
  1717. rport->pid = rpid;
  1718. rport->pwwn = pwwn;
  1719. rport->old_pid = 0;
  1720. /*
  1721. * allocate BFA rport
  1722. */
  1723. rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport);
  1724. if (!rport->bfa_rport) {
  1725. bfa_trc(fcs, rpid);
  1726. kfree(rport_drv);
  1727. return NULL;
  1728. }
  1729. /*
  1730. * allocate FC-4s
  1731. */
  1732. WARN_ON(!bfa_fcs_lport_is_initiator(port));
  1733. if (bfa_fcs_lport_is_initiator(port)) {
  1734. rport->itnim = bfa_fcs_itnim_create(rport);
  1735. if (!rport->itnim) {
  1736. bfa_trc(fcs, rpid);
  1737. bfa_sm_send_event(rport->bfa_rport,
  1738. BFA_RPORT_SM_DELETE);
  1739. kfree(rport_drv);
  1740. return NULL;
  1741. }
  1742. }
  1743. bfa_fcs_lport_add_rport(port, rport);
  1744. bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
  1745. /* Initialize the Rport Features(RPF) Sub Module */
  1746. if (!BFA_FCS_PID_IS_WKA(rport->pid))
  1747. bfa_fcs_rpf_init(rport);
  1748. return rport;
  1749. }
  1750. static void
  1751. bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
  1752. {
  1753. struct bfa_fcs_lport_s *port = rport->port;
  1754. /*
  1755. * - delete FC-4s
  1756. * - delete BFA rport
  1757. * - remove from queue of rports
  1758. */
  1759. if (bfa_fcs_lport_is_initiator(port)) {
  1760. bfa_fcs_itnim_delete(rport->itnim);
  1761. if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid))
  1762. bfa_fcs_rpf_rport_offline(rport);
  1763. }
  1764. bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE);
  1765. bfa_fcs_lport_del_rport(port, rport);
  1766. kfree(rport->rp_drv);
  1767. }
  1768. static void
  1769. bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
  1770. enum bfa_rport_aen_event event,
  1771. struct bfa_rport_aen_data_s *data)
  1772. {
  1773. struct bfa_fcs_lport_s *port = rport->port;
  1774. struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
  1775. struct bfa_aen_entry_s *aen_entry;
  1776. bfad_get_aen_entry(bfad, aen_entry);
  1777. if (!aen_entry)
  1778. return;
  1779. if (event == BFA_RPORT_AEN_QOS_PRIO)
  1780. aen_entry->aen_data.rport.priv.qos = data->priv.qos;
  1781. else if (event == BFA_RPORT_AEN_QOS_FLOWID)
  1782. aen_entry->aen_data.rport.priv.qos = data->priv.qos;
  1783. aen_entry->aen_data.rport.vf_id = rport->port->fabric->vf_id;
  1784. aen_entry->aen_data.rport.ppwwn = bfa_fcs_lport_get_pwwn(
  1785. bfa_fcs_get_base_port(rport->fcs));
  1786. aen_entry->aen_data.rport.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
  1787. aen_entry->aen_data.rport.rpwwn = rport->pwwn;
  1788. /* Send the AEN notification */
  1789. bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
  1790. BFA_AEN_CAT_RPORT, event);
  1791. }
  1792. static void
  1793. bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
  1794. {
  1795. struct bfa_fcs_lport_s *port = rport->port;
  1796. struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
  1797. char lpwwn_buf[BFA_STRING_32];
  1798. char rpwwn_buf[BFA_STRING_32];
  1799. rport->stats.onlines++;
  1800. if ((!rport->pid) || (!rport->pwwn)) {
  1801. bfa_trc(rport->fcs, rport->pid);
  1802. bfa_sm_fault(rport->fcs, rport->pid);
  1803. }
  1804. if (bfa_fcs_lport_is_initiator(port)) {
  1805. bfa_fcs_itnim_rport_online(rport->itnim);
  1806. if (!BFA_FCS_PID_IS_WKA(rport->pid))
  1807. bfa_fcs_rpf_rport_online(rport);
  1808. };
  1809. wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
  1810. wwn2str(rpwwn_buf, rport->pwwn);
  1811. if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
  1812. BFA_LOG(KERN_INFO, bfad, bfa_log_level,
  1813. "Remote port (WWN = %s) online for logical port (WWN = %s)\n",
  1814. rpwwn_buf, lpwwn_buf);
  1815. bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
  1816. }
  1817. }
  1818. static void
  1819. bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
  1820. {
  1821. struct bfa_fcs_lport_s *port = rport->port;
  1822. struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
  1823. char lpwwn_buf[BFA_STRING_32];
  1824. char rpwwn_buf[BFA_STRING_32];
  1825. rport->stats.offlines++;
  1826. rport->plogi_pending = BFA_FALSE;
  1827. wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
  1828. wwn2str(rpwwn_buf, rport->pwwn);
  1829. if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
  1830. if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) {
  1831. BFA_LOG(KERN_ERR, bfad, bfa_log_level,
  1832. "Remote port (WWN = %s) connectivity lost for "
  1833. "logical port (WWN = %s)\n",
  1834. rpwwn_buf, lpwwn_buf);
  1835. bfa_fcs_rport_aen_post(rport,
  1836. BFA_RPORT_AEN_DISCONNECT, NULL);
  1837. } else {
  1838. BFA_LOG(KERN_INFO, bfad, bfa_log_level,
  1839. "Remote port (WWN = %s) offlined by "
  1840. "logical port (WWN = %s)\n",
  1841. rpwwn_buf, lpwwn_buf);
  1842. bfa_fcs_rport_aen_post(rport,
  1843. BFA_RPORT_AEN_OFFLINE, NULL);
  1844. }
  1845. }
  1846. if (bfa_fcs_lport_is_initiator(port)) {
  1847. bfa_fcs_itnim_rport_offline(rport->itnim);
  1848. if (!BFA_FCS_PID_IS_WKA(rport->pid))
  1849. bfa_fcs_rpf_rport_offline(rport);
  1850. }
  1851. }
  1852. /*
  1853. * Update rport parameters from PLOGI or PLOGI accept.
  1854. */
  1855. static void
  1856. bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
  1857. {
  1858. bfa_fcs_lport_t *port = rport->port;
  1859. /*
  1860. * - port name
  1861. * - node name
  1862. */
  1863. rport->pwwn = plogi->port_name;
  1864. rport->nwwn = plogi->node_name;
  1865. /*
  1866. * - class of service
  1867. */
  1868. rport->fc_cos = 0;
  1869. if (plogi->class3.class_valid)
  1870. rport->fc_cos = FC_CLASS_3;
  1871. if (plogi->class2.class_valid)
  1872. rport->fc_cos |= FC_CLASS_2;
  1873. /*
  1874. * - CISC
  1875. * - MAX receive frame size
  1876. */
  1877. rport->cisc = plogi->csp.cisc;
  1878. if (be16_to_cpu(plogi->class3.rxsz) < be16_to_cpu(plogi->csp.rxsz))
  1879. rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz);
  1880. else
  1881. rport->maxfrsize = be16_to_cpu(plogi->csp.rxsz);
  1882. bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
  1883. bfa_trc(port->fcs, port->fabric->bb_credit);
  1884. /*
  1885. * Direct Attach P2P mode :
  1886. * This is to handle a bug (233476) in IBM targets in Direct Attach
  1887. * Mode. Basically, in FLOGI Accept the target would have
  1888. * erroneously set the BB Credit to the value used in the FLOGI
  1889. * sent by the HBA. It uses the correct value (its own BB credit)
  1890. * in PLOGI.
  1891. */
  1892. if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
  1893. (be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
  1894. bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
  1895. bfa_trc(port->fcs, port->fabric->bb_credit);
  1896. port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
  1897. bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
  1898. port->fabric->bb_credit, 0);
  1899. }
  1900. }
  1901. /*
  1902. * Called to handle LOGO received from an existing remote port.
  1903. */
  1904. static void
  1905. bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
  1906. {
  1907. rport->reply_oxid = fchs->ox_id;
  1908. bfa_trc(rport->fcs, rport->reply_oxid);
  1909. rport->prlo = BFA_FALSE;
  1910. rport->stats.logo_rcvd++;
  1911. bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
  1912. }
  1913. /*
  1914. * fcs_rport_public FCS rport public interfaces
  1915. */
  1916. /*
  1917. * Called by bport/vport to create a remote port instance for a discovered
  1918. * remote device.
  1919. *
  1920. * @param[in] port - base port or vport
  1921. * @param[in] rpid - remote port ID
  1922. *
  1923. * @return None
  1924. */
  1925. struct bfa_fcs_rport_s *
  1926. bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid)
  1927. {
  1928. struct bfa_fcs_rport_s *rport;
  1929. bfa_trc(port->fcs, rpid);
  1930. rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
  1931. if (!rport)
  1932. return NULL;
  1933. bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
  1934. return rport;
  1935. }
  1936. /*
  1937. * Called to create a rport for which only the wwn is known.
  1938. *
  1939. * @param[in] port - base port
  1940. * @param[in] rpwwn - remote port wwn
  1941. *
  1942. * @return None
  1943. */
  1944. struct bfa_fcs_rport_s *
  1945. bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
  1946. {
  1947. struct bfa_fcs_rport_s *rport;
  1948. bfa_trc(port->fcs, rpwwn);
  1949. rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
  1950. if (!rport)
  1951. return NULL;
  1952. bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
  1953. return rport;
  1954. }
  1955. /*
  1956. * Called by bport in private loop topology to indicate that a
  1957. * rport has been discovered and plogi has been completed.
  1958. *
  1959. * @param[in] port - base port or vport
  1960. * @param[in] rpid - remote port ID
  1961. */
  1962. void
  1963. bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
  1964. struct fc_logi_s *plogi)
  1965. {
  1966. struct bfa_fcs_rport_s *rport;
  1967. rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
  1968. if (!rport)
  1969. return;
  1970. bfa_fcs_rport_update(rport, plogi);
  1971. bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
  1972. }
  1973. /*
  1974. * Called by bport/vport to handle PLOGI received from a new remote port.
  1975. * If an existing rport does a plogi, it will be handled separately.
  1976. */
  1977. void
  1978. bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
  1979. struct fc_logi_s *plogi)
  1980. {
  1981. struct bfa_fcs_rport_s *rport;
  1982. rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
  1983. if (!rport)
  1984. return;
  1985. bfa_fcs_rport_update(rport, plogi);
  1986. rport->reply_oxid = fchs->ox_id;
  1987. bfa_trc(rport->fcs, rport->reply_oxid);
  1988. rport->stats.plogi_rcvd++;
  1989. bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
  1990. }
  1991. /*
  1992. * Called by bport/vport to handle PLOGI received from an existing
  1993. * remote port.
  1994. */
  1995. void
  1996. bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
  1997. struct fc_logi_s *plogi)
  1998. {
  1999. /*
  2000. * @todo Handle P2P and initiator-initiator.
  2001. */
  2002. bfa_fcs_rport_update(rport, plogi);
  2003. rport->reply_oxid = rx_fchs->ox_id;
  2004. bfa_trc(rport->fcs, rport->reply_oxid);
  2005. rport->pid = rx_fchs->s_id;
  2006. bfa_trc(rport->fcs, rport->pid);
  2007. rport->stats.plogi_rcvd++;
  2008. bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
  2009. }
  2010. /*
  2011. * Called by bport/vport to notify SCN for the remote port
  2012. */
  2013. void
  2014. bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
  2015. {
  2016. rport->stats.rscns++;
  2017. bfa_sm_send_event(rport, RPSM_EVENT_SCN);
  2018. }
  2019. /*
  2020. * brief
  2021. * This routine BFA callback for bfa_rport_online() call.
  2022. *
  2023. * param[in] cb_arg - rport struct.
  2024. *
  2025. * return
  2026. * void
  2027. *
  2028. * Special Considerations:
  2029. *
  2030. * note
  2031. */
  2032. void
  2033. bfa_cb_rport_online(void *cbarg)
  2034. {
  2035. struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
  2036. bfa_trc(rport->fcs, rport->pwwn);
  2037. bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
  2038. }
  2039. /*
  2040. * brief
  2041. * This routine BFA callback for bfa_rport_offline() call.
  2042. *
  2043. * param[in] rport -
  2044. *
  2045. * return
  2046. * void
  2047. *
  2048. * Special Considerations:
  2049. *
  2050. * note
  2051. */
  2052. void
  2053. bfa_cb_rport_offline(void *cbarg)
  2054. {
  2055. struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
  2056. bfa_trc(rport->fcs, rport->pwwn);
  2057. bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
  2058. }
  2059. /*
  2060. * brief
  2061. * This routine is a static BFA callback when there is a QoS flow_id
  2062. * change notification
  2063. *
  2064. * param[in] rport -
  2065. *
  2066. * return
  2067. * void
  2068. *
  2069. * Special Considerations:
  2070. *
  2071. * note
  2072. */
  2073. void
  2074. bfa_cb_rport_qos_scn_flowid(void *cbarg,
  2075. struct bfa_rport_qos_attr_s old_qos_attr,
  2076. struct bfa_rport_qos_attr_s new_qos_attr)
  2077. {
  2078. struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
  2079. struct bfa_rport_aen_data_s aen_data;
  2080. bfa_trc(rport->fcs, rport->pwwn);
  2081. aen_data.priv.qos = new_qos_attr;
  2082. bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
  2083. }
  2084. /*
  2085. * brief
  2086. * This routine is a static BFA callback when there is a QoS priority
  2087. * change notification
  2088. *
  2089. * param[in] rport -
  2090. *
  2091. * return
  2092. * void
  2093. *
  2094. * Special Considerations:
  2095. *
  2096. * note
  2097. */
  2098. void
  2099. bfa_cb_rport_qos_scn_prio(void *cbarg,
  2100. struct bfa_rport_qos_attr_s old_qos_attr,
  2101. struct bfa_rport_qos_attr_s new_qos_attr)
  2102. {
  2103. struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
  2104. struct bfa_rport_aen_data_s aen_data;
  2105. bfa_trc(rport->fcs, rport->pwwn);
  2106. aen_data.priv.qos = new_qos_attr;
  2107. bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data);
  2108. }
  2109. /*
  2110. * Called to process any unsolicted frames from this remote port
  2111. */
  2112. void
  2113. bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
  2114. struct fchs_s *fchs, u16 len)
  2115. {
  2116. struct bfa_fcs_lport_s *port = rport->port;
  2117. struct fc_els_cmd_s *els_cmd;
  2118. bfa_trc(rport->fcs, fchs->s_id);
  2119. bfa_trc(rport->fcs, fchs->d_id);
  2120. bfa_trc(rport->fcs, fchs->type);
  2121. if (fchs->type != FC_TYPE_ELS)
  2122. return;
  2123. els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
  2124. bfa_trc(rport->fcs, els_cmd->els_code);
  2125. switch (els_cmd->els_code) {
  2126. case FC_ELS_LOGO:
  2127. bfa_stats(port, plogi_rcvd);
  2128. bfa_fcs_rport_process_logo(rport, fchs);
  2129. break;
  2130. case FC_ELS_ADISC:
  2131. bfa_stats(port, adisc_rcvd);
  2132. bfa_fcs_rport_process_adisc(rport, fchs, len);
  2133. break;
  2134. case FC_ELS_PRLO:
  2135. bfa_stats(port, prlo_rcvd);
  2136. if (bfa_fcs_lport_is_initiator(port))
  2137. bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
  2138. break;
  2139. case FC_ELS_PRLI:
  2140. bfa_stats(port, prli_rcvd);
  2141. bfa_fcs_rport_process_prli(rport, fchs, len);
  2142. break;
  2143. case FC_ELS_RPSC:
  2144. bfa_stats(port, rpsc_rcvd);
  2145. bfa_fcs_rport_process_rpsc(rport, fchs, len);
  2146. break;
  2147. default:
  2148. bfa_stats(port, un_handled_els_rcvd);
  2149. bfa_fcs_rport_send_ls_rjt(rport, fchs,
  2150. FC_LS_RJT_RSN_CMD_NOT_SUPP,
  2151. FC_LS_RJT_EXP_NO_ADDL_INFO);
  2152. break;
  2153. }
  2154. }
  2155. /* send best case acc to prlo */
  2156. static void
  2157. bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
  2158. {
  2159. struct bfa_fcs_lport_s *port = rport->port;
  2160. struct fchs_s fchs;
  2161. struct bfa_fcxp_s *fcxp;
  2162. int len;
  2163. bfa_trc(rport->fcs, rport->pid);
  2164. fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
  2165. if (!fcxp)
  2166. return;
  2167. len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  2168. rport->pid, bfa_fcs_lport_get_fcid(port),
  2169. rport->reply_oxid, 0);
  2170. bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id,
  2171. port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs,
  2172. NULL, NULL, FC_MAX_PDUSZ, 0);
  2173. }
  2174. /*
  2175. * Send a LS reject
  2176. */
  2177. static void
  2178. bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
  2179. u8 reason_code, u8 reason_code_expl)
  2180. {
  2181. struct bfa_fcs_lport_s *port = rport->port;
  2182. struct fchs_s fchs;
  2183. struct bfa_fcxp_s *fcxp;
  2184. int len;
  2185. bfa_trc(rport->fcs, rx_fchs->s_id);
  2186. fcxp = bfa_fcs_fcxp_alloc(rport->fcs, BFA_FALSE);
  2187. if (!fcxp)
  2188. return;
  2189. len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
  2190. rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
  2191. rx_fchs->ox_id, reason_code, reason_code_expl);
  2192. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
  2193. BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
  2194. FC_MAX_PDUSZ, 0);
  2195. }
  2196. /*
  2197. * Return state of rport.
  2198. */
  2199. int
  2200. bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
  2201. {
  2202. return bfa_sm_to_state(rport_sm_table, rport->sm);
  2203. }
  2204. /*
  2205. * brief
  2206. * Called by the Driver to set rport delete/ageout timeout
  2207. *
  2208. * param[in] rport timeout value in seconds.
  2209. *
  2210. * return None
  2211. */
  2212. void
  2213. bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
  2214. {
  2215. /* convert to Millisecs */
  2216. if (rport_tmo > 0)
  2217. bfa_fcs_rport_del_timeout = rport_tmo * 1000;
  2218. }
  2219. void
  2220. bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id)
  2221. {
  2222. bfa_trc(rport->fcs, rport->pid);
  2223. rport->prlo = BFA_TRUE;
  2224. rport->reply_oxid = ox_id;
  2225. bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD);
  2226. }
  2227. void
  2228. bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
  2229. struct bfa_rport_attr_s *rport_attr)
  2230. {
  2231. struct bfa_rport_qos_attr_s qos_attr;
  2232. struct bfa_fcs_lport_s *port = rport->port;
  2233. bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
  2234. memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
  2235. memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s));
  2236. rport_attr->pid = rport->pid;
  2237. rport_attr->pwwn = rport->pwwn;
  2238. rport_attr->nwwn = rport->nwwn;
  2239. rport_attr->cos_supported = rport->fc_cos;
  2240. rport_attr->df_sz = rport->maxfrsize;
  2241. rport_attr->state = bfa_fcs_rport_get_state(rport);
  2242. rport_attr->fc_cos = rport->fc_cos;
  2243. rport_attr->cisc = rport->cisc;
  2244. rport_attr->scsi_function = rport->scsi_function;
  2245. rport_attr->curr_speed = rport->rpf.rpsc_speed;
  2246. rport_attr->assigned_speed = rport->rpf.assigned_speed;
  2247. qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority;
  2248. qos_attr.qos_flow_id =
  2249. cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id);
  2250. rport_attr->qos_attr = qos_attr;
  2251. rport_attr->trl_enforced = BFA_FALSE;
  2252. if (bfa_fcport_is_ratelim(port->fcs->bfa) &&
  2253. (rport->scsi_function == BFA_RPORT_TARGET)) {
  2254. if (rport_speed == BFA_PORT_SPEED_UNKNOWN)
  2255. rport_speed =
  2256. bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
  2257. if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port))
  2258. rport_attr->trl_enforced = BFA_TRUE;
  2259. }
  2260. }
  2261. /*
  2262. * Remote port implementation.
  2263. */
  2264. /*
  2265. * fcs_rport_api FCS rport API.
  2266. */
  2267. struct bfa_fcs_rport_s *
  2268. bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
  2269. {
  2270. struct bfa_fcs_rport_s *rport;
  2271. rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
  2272. if (rport == NULL) {
  2273. /*
  2274. * TBD Error handling
  2275. */
  2276. }
  2277. return rport;
  2278. }
  2279. struct bfa_fcs_rport_s *
  2280. bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn)
  2281. {
  2282. struct bfa_fcs_rport_s *rport;
  2283. rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn);
  2284. if (rport == NULL) {
  2285. /*
  2286. * TBD Error handling
  2287. */
  2288. }
  2289. return rport;
  2290. }
  2291. /*
  2292. * Remote port features (RPF) implementation.
  2293. */
  2294. #define BFA_FCS_RPF_RETRIES (3)
  2295. #define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */
  2296. static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
  2297. struct bfa_fcxp_s *fcxp_alloced);
  2298. static void bfa_fcs_rpf_rpsc2_response(void *fcsarg,
  2299. struct bfa_fcxp_s *fcxp,
  2300. void *cbarg,
  2301. bfa_status_t req_status,
  2302. u32 rsp_len,
  2303. u32 resid_len,
  2304. struct fchs_s *rsp_fchs);
  2305. static void bfa_fcs_rpf_timeout(void *arg);
  2306. /*
  2307. * fcs_rport_ftrs_sm FCS rport state machine events
  2308. */
  2309. enum rpf_event {
  2310. RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */
  2311. RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */
  2312. RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */
  2313. RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */
  2314. RPFSM_EVENT_RPSC_COMP = 5,
  2315. RPFSM_EVENT_RPSC_FAIL = 6,
  2316. RPFSM_EVENT_RPSC_ERROR = 7,
  2317. };
  2318. static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
  2319. enum rpf_event event);
  2320. static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
  2321. enum rpf_event event);
  2322. static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
  2323. enum rpf_event event);
  2324. static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
  2325. enum rpf_event event);
  2326. static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
  2327. enum rpf_event event);
  2328. static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
  2329. enum rpf_event event);
  2330. static void
  2331. bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
  2332. {
  2333. struct bfa_fcs_rport_s *rport = rpf->rport;
  2334. struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric;
  2335. bfa_trc(rport->fcs, rport->pwwn);
  2336. bfa_trc(rport->fcs, rport->pid);
  2337. bfa_trc(rport->fcs, event);
  2338. switch (event) {
  2339. case RPFSM_EVENT_RPORT_ONLINE:
  2340. /* Send RPSC2 to a Brocade fabric only. */
  2341. if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
  2342. ((rport->port->fabric->lps->brcd_switch) ||
  2343. (bfa_fcs_fabric_get_switch_oui(fabric) ==
  2344. BFA_FCS_BRCD_SWITCH_OUI))) {
  2345. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
  2346. rpf->rpsc_retries = 0;
  2347. bfa_fcs_rpf_send_rpsc2(rpf, NULL);
  2348. }
  2349. break;
  2350. case RPFSM_EVENT_RPORT_OFFLINE:
  2351. break;
  2352. default:
  2353. bfa_sm_fault(rport->fcs, event);
  2354. }
  2355. }
  2356. static void
  2357. bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
  2358. {
  2359. struct bfa_fcs_rport_s *rport = rpf->rport;
  2360. bfa_trc(rport->fcs, event);
  2361. switch (event) {
  2362. case RPFSM_EVENT_FCXP_SENT:
  2363. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
  2364. break;
  2365. case RPFSM_EVENT_RPORT_OFFLINE:
  2366. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
  2367. bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
  2368. rpf->rpsc_retries = 0;
  2369. break;
  2370. default:
  2371. bfa_sm_fault(rport->fcs, event);
  2372. }
  2373. }
  2374. static void
  2375. bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
  2376. {
  2377. struct bfa_fcs_rport_s *rport = rpf->rport;
  2378. bfa_trc(rport->fcs, rport->pid);
  2379. bfa_trc(rport->fcs, event);
  2380. switch (event) {
  2381. case RPFSM_EVENT_RPSC_COMP:
  2382. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
  2383. /* Update speed info in f/w via BFA */
  2384. if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN)
  2385. bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
  2386. else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN)
  2387. bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
  2388. break;
  2389. case RPFSM_EVENT_RPSC_FAIL:
  2390. /* RPSC not supported by rport */
  2391. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
  2392. break;
  2393. case RPFSM_EVENT_RPSC_ERROR:
  2394. /* need to retry...delayed a bit. */
  2395. if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
  2396. bfa_timer_start(rport->fcs->bfa, &rpf->timer,
  2397. bfa_fcs_rpf_timeout, rpf,
  2398. BFA_FCS_RPF_RETRY_TIMEOUT);
  2399. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
  2400. } else {
  2401. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
  2402. }
  2403. break;
  2404. case RPFSM_EVENT_RPORT_OFFLINE:
  2405. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
  2406. bfa_fcxp_discard(rpf->fcxp);
  2407. rpf->rpsc_retries = 0;
  2408. break;
  2409. default:
  2410. bfa_sm_fault(rport->fcs, event);
  2411. }
  2412. }
  2413. static void
  2414. bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
  2415. {
  2416. struct bfa_fcs_rport_s *rport = rpf->rport;
  2417. bfa_trc(rport->fcs, rport->pid);
  2418. bfa_trc(rport->fcs, event);
  2419. switch (event) {
  2420. case RPFSM_EVENT_TIMEOUT:
  2421. /* re-send the RPSC */
  2422. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
  2423. bfa_fcs_rpf_send_rpsc2(rpf, NULL);
  2424. break;
  2425. case RPFSM_EVENT_RPORT_OFFLINE:
  2426. bfa_timer_stop(&rpf->timer);
  2427. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
  2428. rpf->rpsc_retries = 0;
  2429. break;
  2430. default:
  2431. bfa_sm_fault(rport->fcs, event);
  2432. }
  2433. }
  2434. static void
  2435. bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
  2436. {
  2437. struct bfa_fcs_rport_s *rport = rpf->rport;
  2438. bfa_trc(rport->fcs, rport->pwwn);
  2439. bfa_trc(rport->fcs, rport->pid);
  2440. bfa_trc(rport->fcs, event);
  2441. switch (event) {
  2442. case RPFSM_EVENT_RPORT_OFFLINE:
  2443. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
  2444. rpf->rpsc_retries = 0;
  2445. break;
  2446. default:
  2447. bfa_sm_fault(rport->fcs, event);
  2448. }
  2449. }
  2450. static void
  2451. bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
  2452. {
  2453. struct bfa_fcs_rport_s *rport = rpf->rport;
  2454. bfa_trc(rport->fcs, rport->pwwn);
  2455. bfa_trc(rport->fcs, rport->pid);
  2456. bfa_trc(rport->fcs, event);
  2457. switch (event) {
  2458. case RPFSM_EVENT_RPORT_ONLINE:
  2459. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
  2460. bfa_fcs_rpf_send_rpsc2(rpf, NULL);
  2461. break;
  2462. case RPFSM_EVENT_RPORT_OFFLINE:
  2463. break;
  2464. default:
  2465. bfa_sm_fault(rport->fcs, event);
  2466. }
  2467. }
  2468. /*
  2469. * Called when Rport is created.
  2470. */
  2471. void
  2472. bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
  2473. {
  2474. struct bfa_fcs_rpf_s *rpf = &rport->rpf;
  2475. bfa_trc(rport->fcs, rport->pid);
  2476. rpf->rport = rport;
  2477. bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
  2478. }
  2479. /*
  2480. * Called when Rport becomes online
  2481. */
  2482. void
  2483. bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
  2484. {
  2485. bfa_trc(rport->fcs, rport->pid);
  2486. if (__fcs_min_cfg(rport->port->fcs))
  2487. return;
  2488. if (bfa_fcs_fabric_is_switched(rport->port->fabric))
  2489. bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
  2490. }
  2491. /*
  2492. * Called when Rport becomes offline
  2493. */
  2494. void
  2495. bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
  2496. {
  2497. bfa_trc(rport->fcs, rport->pid);
  2498. if (__fcs_min_cfg(rport->port->fcs))
  2499. return;
  2500. rport->rpf.rpsc_speed = 0;
  2501. bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
  2502. }
  2503. static void
  2504. bfa_fcs_rpf_timeout(void *arg)
  2505. {
  2506. struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
  2507. struct bfa_fcs_rport_s *rport = rpf->rport;
  2508. bfa_trc(rport->fcs, rport->pid);
  2509. bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT);
  2510. }
  2511. static void
  2512. bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
  2513. {
  2514. struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
  2515. struct bfa_fcs_rport_s *rport = rpf->rport;
  2516. struct bfa_fcs_lport_s *port = rport->port;
  2517. struct fchs_s fchs;
  2518. int len;
  2519. struct bfa_fcxp_s *fcxp;
  2520. bfa_trc(rport->fcs, rport->pwwn);
  2521. fcxp = fcxp_alloced ? fcxp_alloced :
  2522. bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
  2523. if (!fcxp) {
  2524. bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
  2525. bfa_fcs_rpf_send_rpsc2, rpf, BFA_TRUE);
  2526. return;
  2527. }
  2528. rpf->fcxp = fcxp;
  2529. len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
  2530. bfa_fcs_lport_get_fcid(port), &rport->pid, 1);
  2531. bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
  2532. FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
  2533. rpf, FC_MAX_PDUSZ, FC_ELS_TOV);
  2534. rport->stats.rpsc_sent++;
  2535. bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
  2536. }
  2537. static void
  2538. bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
  2539. bfa_status_t req_status, u32 rsp_len,
  2540. u32 resid_len, struct fchs_s *rsp_fchs)
  2541. {
  2542. struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
  2543. struct bfa_fcs_rport_s *rport = rpf->rport;
  2544. struct fc_ls_rjt_s *ls_rjt;
  2545. struct fc_rpsc2_acc_s *rpsc2_acc;
  2546. u16 num_ents;
  2547. bfa_trc(rport->fcs, req_status);
  2548. if (req_status != BFA_STATUS_OK) {
  2549. bfa_trc(rport->fcs, req_status);
  2550. if (req_status == BFA_STATUS_ETIMER)
  2551. rport->stats.rpsc_failed++;
  2552. bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
  2553. return;
  2554. }
  2555. rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
  2556. if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
  2557. rport->stats.rpsc_accs++;
  2558. num_ents = be16_to_cpu(rpsc2_acc->num_pids);
  2559. bfa_trc(rport->fcs, num_ents);
  2560. if (num_ents > 0) {
  2561. WARN_ON(rpsc2_acc->port_info[0].pid == rport->pid);
  2562. bfa_trc(rport->fcs,
  2563. be16_to_cpu(rpsc2_acc->port_info[0].pid));
  2564. bfa_trc(rport->fcs,
  2565. be16_to_cpu(rpsc2_acc->port_info[0].speed));
  2566. bfa_trc(rport->fcs,
  2567. be16_to_cpu(rpsc2_acc->port_info[0].index));
  2568. bfa_trc(rport->fcs,
  2569. rpsc2_acc->port_info[0].type);
  2570. if (rpsc2_acc->port_info[0].speed == 0) {
  2571. bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
  2572. return;
  2573. }
  2574. rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
  2575. be16_to_cpu(rpsc2_acc->port_info[0].speed));
  2576. bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
  2577. }
  2578. } else {
  2579. ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
  2580. bfa_trc(rport->fcs, ls_rjt->reason_code);
  2581. bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
  2582. rport->stats.rpsc_rejects++;
  2583. if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
  2584. bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
  2585. else
  2586. bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
  2587. }
  2588. }