qla_gs.c 121 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * QLogic Fibre Channel HBA Driver
  4. * Copyright (c) 2003-2014 QLogic Corporation
  5. */
  6. #include "qla_def.h"
  7. #include "qla_target.h"
  8. #include <linux/utsname.h>
  9. static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
  10. static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
  11. static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
  12. static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *);
  13. static int qla2x00_sns_rft_id(scsi_qla_host_t *);
  14. static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
  15. static int qla_async_rftid(scsi_qla_host_t *, port_id_t *);
  16. static int qla_async_rffid(scsi_qla_host_t *, port_id_t *, u8, u8);
  17. static int qla_async_rnnid(scsi_qla_host_t *, port_id_t *, u8*);
  18. static int qla_async_rsnn_nn(scsi_qla_host_t *);
  19. /**
  20. * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
  21. * @vha: HA context
  22. * @arg: CT arguments
  23. *
  24. * Returns a pointer to the @vha's ms_iocb.
  25. */
  26. void *
  27. qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
  28. {
  29. struct qla_hw_data *ha = vha->hw;
  30. ms_iocb_entry_t *ms_pkt;
  31. ms_pkt = (ms_iocb_entry_t *)arg->iocb;
  32. memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
  33. ms_pkt->entry_type = MS_IOCB_TYPE;
  34. ms_pkt->entry_count = 1;
  35. SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
  36. ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
  37. ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
  38. ms_pkt->cmd_dsd_count = cpu_to_le16(1);
  39. ms_pkt->total_dsd_count = cpu_to_le16(2);
  40. ms_pkt->rsp_bytecount = cpu_to_le32(arg->rsp_size);
  41. ms_pkt->req_bytecount = cpu_to_le32(arg->req_size);
  42. put_unaligned_le64(arg->req_dma, &ms_pkt->req_dsd.address);
  43. ms_pkt->req_dsd.length = ms_pkt->req_bytecount;
  44. put_unaligned_le64(arg->rsp_dma, &ms_pkt->rsp_dsd.address);
  45. ms_pkt->rsp_dsd.length = ms_pkt->rsp_bytecount;
  46. vha->qla_stats.control_requests++;
  47. return (ms_pkt);
  48. }
  49. /**
  50. * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
  51. * @vha: HA context
  52. * @arg: CT arguments
  53. *
  54. * Returns a pointer to the @ha's ms_iocb.
  55. */
  56. void *
  57. qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
  58. {
  59. struct qla_hw_data *ha = vha->hw;
  60. struct ct_entry_24xx *ct_pkt;
  61. ct_pkt = (struct ct_entry_24xx *)arg->iocb;
  62. memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
  63. ct_pkt->entry_type = CT_IOCB_TYPE;
  64. ct_pkt->entry_count = 1;
  65. ct_pkt->nport_handle = cpu_to_le16(arg->nport_handle);
  66. ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
  67. ct_pkt->cmd_dsd_count = cpu_to_le16(1);
  68. ct_pkt->rsp_dsd_count = cpu_to_le16(1);
  69. ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size);
  70. ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size);
  71. put_unaligned_le64(arg->req_dma, &ct_pkt->dsd[0].address);
  72. ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
  73. put_unaligned_le64(arg->rsp_dma, &ct_pkt->dsd[1].address);
  74. ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count;
  75. ct_pkt->vp_index = vha->vp_idx;
  76. vha->qla_stats.control_requests++;
  77. return (ct_pkt);
  78. }
  79. /**
  80. * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
  81. * @p: CT request buffer
  82. * @cmd: GS command
  83. * @rsp_size: response size in bytes
  84. *
  85. * Returns a pointer to the intitialized @ct_req.
  86. */
  87. static inline struct ct_sns_req *
  88. qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size)
  89. {
  90. memset(p, 0, sizeof(struct ct_sns_pkt));
  91. p->p.req.header.revision = 0x01;
  92. p->p.req.header.gs_type = 0xFC;
  93. p->p.req.header.gs_subtype = 0x02;
  94. p->p.req.command = cpu_to_be16(cmd);
  95. p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
  96. return &p->p.req;
  97. }
  98. int
  99. qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
  100. struct ct_sns_rsp *ct_rsp, const char *routine)
  101. {
  102. int rval;
  103. uint16_t comp_status;
  104. struct qla_hw_data *ha = vha->hw;
  105. bool lid_is_sns = false;
  106. rval = QLA_FUNCTION_FAILED;
  107. if (ms_pkt->entry_status != 0) {
  108. ql_dbg(ql_dbg_disc, vha, 0x2031,
  109. "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
  110. routine, ms_pkt->entry_status, vha->d_id.b.domain,
  111. vha->d_id.b.area, vha->d_id.b.al_pa);
  112. } else {
  113. if (IS_FWI2_CAPABLE(ha))
  114. comp_status = le16_to_cpu(
  115. ((struct ct_entry_24xx *)ms_pkt)->comp_status);
  116. else
  117. comp_status = le16_to_cpu(ms_pkt->status);
  118. switch (comp_status) {
  119. case CS_COMPLETE:
  120. case CS_DATA_UNDERRUN:
  121. case CS_DATA_OVERRUN: /* Overrun? */
  122. if (ct_rsp->header.response !=
  123. cpu_to_be16(CT_ACCEPT_RESPONSE)) {
  124. ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077,
  125. "%s failed rejected request on port_id: %02x%02x%02x Completion status 0x%x, response 0x%x\n",
  126. routine, vha->d_id.b.domain,
  127. vha->d_id.b.area, vha->d_id.b.al_pa,
  128. comp_status, ct_rsp->header.response);
  129. ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha,
  130. 0x2078, ct_rsp,
  131. offsetof(typeof(*ct_rsp), rsp));
  132. rval = QLA_INVALID_COMMAND;
  133. } else
  134. rval = QLA_SUCCESS;
  135. break;
  136. case CS_PORT_LOGGED_OUT:
  137. if (IS_FWI2_CAPABLE(ha)) {
  138. if (le16_to_cpu(ms_pkt->loop_id.extended) ==
  139. NPH_SNS)
  140. lid_is_sns = true;
  141. } else {
  142. if (le16_to_cpu(ms_pkt->loop_id.extended) ==
  143. SIMPLE_NAME_SERVER)
  144. lid_is_sns = true;
  145. }
  146. if (lid_is_sns) {
  147. ql_dbg(ql_dbg_async, vha, 0x502b,
  148. "%s failed, Name server has logged out",
  149. routine);
  150. rval = QLA_NOT_LOGGED_IN;
  151. set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  152. set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
  153. }
  154. break;
  155. case CS_TIMEOUT:
  156. rval = QLA_FUNCTION_TIMEOUT;
  157. fallthrough;
  158. default:
  159. ql_dbg(ql_dbg_disc, vha, 0x2033,
  160. "%s failed, completion status (%x) on port_id: "
  161. "%02x%02x%02x.\n", routine, comp_status,
  162. vha->d_id.b.domain, vha->d_id.b.area,
  163. vha->d_id.b.al_pa);
  164. break;
  165. }
  166. }
  167. return rval;
  168. }
  169. /**
  170. * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
  171. * @vha: HA context
  172. * @fcport: fcport entry to updated
  173. *
  174. * Returns 0 on success.
  175. */
  176. int
  177. qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
  178. {
  179. int rval;
  180. ms_iocb_entry_t *ms_pkt;
  181. struct ct_sns_req *ct_req;
  182. struct ct_sns_rsp *ct_rsp;
  183. struct qla_hw_data *ha = vha->hw;
  184. struct ct_arg arg;
  185. if (IS_QLA2100(ha) || IS_QLA2200(ha))
  186. return qla2x00_sns_ga_nxt(vha, fcport);
  187. arg.iocb = ha->ms_iocb;
  188. arg.req_dma = ha->ct_sns_dma;
  189. arg.rsp_dma = ha->ct_sns_dma;
  190. arg.req_size = GA_NXT_REQ_SIZE;
  191. arg.rsp_size = GA_NXT_RSP_SIZE;
  192. arg.nport_handle = NPH_SNS;
  193. /* Issue GA_NXT */
  194. /* Prepare common MS IOCB */
  195. ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
  196. /* Prepare CT request */
  197. ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD,
  198. GA_NXT_RSP_SIZE);
  199. ct_rsp = &ha->ct_sns->p.rsp;
  200. /* Prepare CT arguments -- port_id */
  201. ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
  202. /* Execute MS IOCB */
  203. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  204. sizeof(ms_iocb_entry_t));
  205. if (rval != QLA_SUCCESS) {
  206. /*EMPTY*/
  207. ql_dbg(ql_dbg_disc, vha, 0x2062,
  208. "GA_NXT issue IOCB failed (%d).\n", rval);
  209. } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") !=
  210. QLA_SUCCESS) {
  211. rval = QLA_FUNCTION_FAILED;
  212. } else {
  213. /* Populate fc_port_t entry. */
  214. fcport->d_id = be_to_port_id(ct_rsp->rsp.ga_nxt.port_id);
  215. memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
  216. WWN_SIZE);
  217. memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name,
  218. WWN_SIZE);
  219. fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
  220. FS_FC4TYPE_FCP : FC4_TYPE_OTHER;
  221. if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
  222. ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
  223. fcport->d_id.b.domain = 0xf0;
  224. ql_dbg(ql_dbg_disc, vha, 0x2063,
  225. "GA_NXT entry - nn %8phN pn %8phN "
  226. "port_id=%02x%02x%02x.\n",
  227. fcport->node_name, fcport->port_name,
  228. fcport->d_id.b.domain, fcport->d_id.b.area,
  229. fcport->d_id.b.al_pa);
  230. }
  231. return (rval);
  232. }
  233. static inline int
  234. qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
  235. {
  236. return vha->hw->max_fibre_devices * 4 + 16;
  237. }
  238. /**
  239. * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
  240. * @vha: HA context
  241. * @list: switch info entries to populate
  242. *
  243. * NOTE: Non-Nx_Ports are not requested.
  244. *
  245. * Returns 0 on success.
  246. */
  247. int
  248. qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
  249. {
  250. int rval;
  251. uint16_t i;
  252. ms_iocb_entry_t *ms_pkt;
  253. struct ct_sns_req *ct_req;
  254. struct ct_sns_rsp *ct_rsp;
  255. struct ct_sns_gid_pt_data *gid_data;
  256. struct qla_hw_data *ha = vha->hw;
  257. uint16_t gid_pt_rsp_size;
  258. struct ct_arg arg;
  259. if (IS_QLA2100(ha) || IS_QLA2200(ha))
  260. return qla2x00_sns_gid_pt(vha, list);
  261. gid_data = NULL;
  262. gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha);
  263. arg.iocb = ha->ms_iocb;
  264. arg.req_dma = ha->ct_sns_dma;
  265. arg.rsp_dma = ha->ct_sns_dma;
  266. arg.req_size = GID_PT_REQ_SIZE;
  267. arg.rsp_size = gid_pt_rsp_size;
  268. arg.nport_handle = NPH_SNS;
  269. /* Issue GID_PT */
  270. /* Prepare common MS IOCB */
  271. ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
  272. /* Prepare CT request */
  273. ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size);
  274. ct_rsp = &ha->ct_sns->p.rsp;
  275. /* Prepare CT arguments -- port_type */
  276. ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE;
  277. /* Execute MS IOCB */
  278. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  279. sizeof(ms_iocb_entry_t));
  280. if (rval != QLA_SUCCESS) {
  281. /*EMPTY*/
  282. ql_dbg(ql_dbg_disc, vha, 0x2055,
  283. "GID_PT issue IOCB failed (%d).\n", rval);
  284. } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") !=
  285. QLA_SUCCESS) {
  286. rval = QLA_FUNCTION_FAILED;
  287. } else {
  288. /* Set port IDs in switch info list. */
  289. for (i = 0; i < ha->max_fibre_devices; i++) {
  290. gid_data = &ct_rsp->rsp.gid_pt.entries[i];
  291. list[i].d_id = be_to_port_id(gid_data->port_id);
  292. memset(list[i].fabric_port_name, 0, WWN_SIZE);
  293. list[i].fp_speed = PORT_SPEED_UNKNOWN;
  294. /* Last one exit. */
  295. if (gid_data->control_byte & BIT_7) {
  296. list[i].d_id.b.rsvd_1 = gid_data->control_byte;
  297. break;
  298. }
  299. }
  300. /*
  301. * If we've used all available slots, then the switch is
  302. * reporting back more devices than we can handle with this
  303. * single call. Return a failed status, and let GA_NXT handle
  304. * the overload.
  305. */
  306. if (i == ha->max_fibre_devices)
  307. rval = QLA_FUNCTION_FAILED;
  308. }
  309. return (rval);
  310. }
  311. /**
  312. * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
  313. * @vha: HA context
  314. * @list: switch info entries to populate
  315. *
  316. * Returns 0 on success.
  317. */
  318. int
  319. qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
  320. {
  321. int rval = QLA_SUCCESS;
  322. uint16_t i;
  323. ms_iocb_entry_t *ms_pkt;
  324. struct ct_sns_req *ct_req;
  325. struct ct_sns_rsp *ct_rsp;
  326. struct qla_hw_data *ha = vha->hw;
  327. struct ct_arg arg;
  328. if (IS_QLA2100(ha) || IS_QLA2200(ha))
  329. return qla2x00_sns_gpn_id(vha, list);
  330. arg.iocb = ha->ms_iocb;
  331. arg.req_dma = ha->ct_sns_dma;
  332. arg.rsp_dma = ha->ct_sns_dma;
  333. arg.req_size = GPN_ID_REQ_SIZE;
  334. arg.rsp_size = GPN_ID_RSP_SIZE;
  335. arg.nport_handle = NPH_SNS;
  336. for (i = 0; i < ha->max_fibre_devices; i++) {
  337. /* Issue GPN_ID */
  338. /* Prepare common MS IOCB */
  339. ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
  340. /* Prepare CT request */
  341. ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD,
  342. GPN_ID_RSP_SIZE);
  343. ct_rsp = &ha->ct_sns->p.rsp;
  344. /* Prepare CT arguments -- port_id */
  345. ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
  346. /* Execute MS IOCB */
  347. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  348. sizeof(ms_iocb_entry_t));
  349. if (rval != QLA_SUCCESS) {
  350. /*EMPTY*/
  351. ql_dbg(ql_dbg_disc, vha, 0x2056,
  352. "GPN_ID issue IOCB failed (%d).\n", rval);
  353. break;
  354. } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
  355. "GPN_ID") != QLA_SUCCESS) {
  356. rval = QLA_FUNCTION_FAILED;
  357. break;
  358. } else {
  359. /* Save portname */
  360. memcpy(list[i].port_name,
  361. ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
  362. }
  363. /* Last device exit. */
  364. if (list[i].d_id.b.rsvd_1 != 0)
  365. break;
  366. }
  367. return (rval);
  368. }
  369. /**
  370. * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
  371. * @vha: HA context
  372. * @list: switch info entries to populate
  373. *
  374. * Returns 0 on success.
  375. */
  376. int
  377. qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
  378. {
  379. int rval = QLA_SUCCESS;
  380. uint16_t i;
  381. struct qla_hw_data *ha = vha->hw;
  382. ms_iocb_entry_t *ms_pkt;
  383. struct ct_sns_req *ct_req;
  384. struct ct_sns_rsp *ct_rsp;
  385. struct ct_arg arg;
  386. if (IS_QLA2100(ha) || IS_QLA2200(ha))
  387. return qla2x00_sns_gnn_id(vha, list);
  388. arg.iocb = ha->ms_iocb;
  389. arg.req_dma = ha->ct_sns_dma;
  390. arg.rsp_dma = ha->ct_sns_dma;
  391. arg.req_size = GNN_ID_REQ_SIZE;
  392. arg.rsp_size = GNN_ID_RSP_SIZE;
  393. arg.nport_handle = NPH_SNS;
  394. for (i = 0; i < ha->max_fibre_devices; i++) {
  395. /* Issue GNN_ID */
  396. /* Prepare common MS IOCB */
  397. ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
  398. /* Prepare CT request */
  399. ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD,
  400. GNN_ID_RSP_SIZE);
  401. ct_rsp = &ha->ct_sns->p.rsp;
  402. /* Prepare CT arguments -- port_id */
  403. ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
  404. /* Execute MS IOCB */
  405. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  406. sizeof(ms_iocb_entry_t));
  407. if (rval != QLA_SUCCESS) {
  408. /*EMPTY*/
  409. ql_dbg(ql_dbg_disc, vha, 0x2057,
  410. "GNN_ID issue IOCB failed (%d).\n", rval);
  411. break;
  412. } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
  413. "GNN_ID") != QLA_SUCCESS) {
  414. rval = QLA_FUNCTION_FAILED;
  415. break;
  416. } else {
  417. /* Save nodename */
  418. memcpy(list[i].node_name,
  419. ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
  420. ql_dbg(ql_dbg_disc, vha, 0x2058,
  421. "GID_PT entry - nn %8phN pn %8phN "
  422. "portid=%02x%02x%02x.\n",
  423. list[i].node_name, list[i].port_name,
  424. list[i].d_id.b.domain, list[i].d_id.b.area,
  425. list[i].d_id.b.al_pa);
  426. }
  427. /* Last device exit. */
  428. if (list[i].d_id.b.rsvd_1 != 0)
  429. break;
  430. }
  431. return (rval);
  432. }
  433. static void qla2x00_async_sns_sp_done(srb_t *sp, int rc)
  434. {
  435. struct scsi_qla_host *vha = sp->vha;
  436. struct ct_sns_pkt *ct_sns;
  437. struct qla_work_evt *e;
  438. sp->rc = rc;
  439. if (rc == QLA_SUCCESS) {
  440. ql_dbg(ql_dbg_disc, vha, 0x204f,
  441. "Async done-%s exiting normally.\n",
  442. sp->name);
  443. } else if (rc == QLA_FUNCTION_TIMEOUT) {
  444. ql_dbg(ql_dbg_disc, vha, 0x204f,
  445. "Async done-%s timeout\n", sp->name);
  446. } else {
  447. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
  448. memset(ct_sns, 0, sizeof(*ct_sns));
  449. sp->retry_count++;
  450. if (sp->retry_count > 3)
  451. goto err;
  452. ql_dbg(ql_dbg_disc, vha, 0x204f,
  453. "Async done-%s fail rc %x. Retry count %d\n",
  454. sp->name, rc, sp->retry_count);
  455. e = qla2x00_alloc_work(vha, QLA_EVT_SP_RETRY);
  456. if (!e)
  457. goto err2;
  458. e->u.iosb.sp = sp;
  459. qla2x00_post_work(vha, e);
  460. return;
  461. }
  462. err:
  463. e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
  464. err2:
  465. if (!e) {
  466. /* please ignore kernel warning. otherwise, we have mem leak. */
  467. if (sp->u.iocb_cmd.u.ctarg.req) {
  468. dma_free_coherent(&vha->hw->pdev->dev,
  469. sp->u.iocb_cmd.u.ctarg.req_allocated_size,
  470. sp->u.iocb_cmd.u.ctarg.req,
  471. sp->u.iocb_cmd.u.ctarg.req_dma);
  472. sp->u.iocb_cmd.u.ctarg.req = NULL;
  473. }
  474. if (sp->u.iocb_cmd.u.ctarg.rsp) {
  475. dma_free_coherent(&vha->hw->pdev->dev,
  476. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
  477. sp->u.iocb_cmd.u.ctarg.rsp,
  478. sp->u.iocb_cmd.u.ctarg.rsp_dma);
  479. sp->u.iocb_cmd.u.ctarg.rsp = NULL;
  480. }
  481. /* ref: INIT */
  482. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  483. return;
  484. }
  485. e->u.iosb.sp = sp;
  486. qla2x00_post_work(vha, e);
  487. }
  488. /**
  489. * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
  490. * @vha: HA context
  491. *
  492. * Returns 0 on success.
  493. */
  494. int
  495. qla2x00_rft_id(scsi_qla_host_t *vha)
  496. {
  497. struct qla_hw_data *ha = vha->hw;
  498. if (IS_QLA2100(ha) || IS_QLA2200(ha))
  499. return qla2x00_sns_rft_id(vha);
  500. return qla_async_rftid(vha, &vha->d_id);
  501. }
  502. static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id)
  503. {
  504. int rval = QLA_MEMORY_ALLOC_FAILED;
  505. struct ct_sns_req *ct_req;
  506. srb_t *sp;
  507. struct ct_sns_pkt *ct_sns;
  508. if (!vha->flags.online)
  509. goto done;
  510. /* ref: INIT */
  511. sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
  512. if (!sp)
  513. goto done;
  514. sp->type = SRB_CT_PTHRU_CMD;
  515. sp->name = "rft_id";
  516. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  517. qla2x00_async_sns_sp_done);
  518. sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
  519. sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
  520. GFP_KERNEL);
  521. sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
  522. if (!sp->u.iocb_cmd.u.ctarg.req) {
  523. ql_log(ql_log_warn, vha, 0xd041,
  524. "%s: Failed to allocate ct_sns request.\n",
  525. __func__);
  526. goto done_free_sp;
  527. }
  528. sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
  529. sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
  530. GFP_KERNEL);
  531. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
  532. if (!sp->u.iocb_cmd.u.ctarg.rsp) {
  533. ql_log(ql_log_warn, vha, 0xd042,
  534. "%s: Failed to allocate ct_sns request.\n",
  535. __func__);
  536. goto done_free_sp;
  537. }
  538. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
  539. memset(ct_sns, 0, sizeof(*ct_sns));
  540. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
  541. /* Prepare CT request */
  542. ct_req = qla2x00_prep_ct_req(ct_sns, RFT_ID_CMD, RFT_ID_RSP_SIZE);
  543. /* Prepare CT arguments -- port_id, FC-4 types */
  544. ct_req->req.rft_id.port_id = port_id_to_be_id(vha->d_id);
  545. ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */
  546. if (vha->flags.nvme_enabled && qla_ini_mode_enabled(vha))
  547. ct_req->req.rft_id.fc4_types[6] = 1; /* NVMe type 28h */
  548. sp->u.iocb_cmd.u.ctarg.req_size = RFT_ID_REQ_SIZE;
  549. sp->u.iocb_cmd.u.ctarg.rsp_size = RFT_ID_RSP_SIZE;
  550. sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
  551. ql_dbg(ql_dbg_disc, vha, 0xffff,
  552. "Async-%s - hdl=%x portid %06x.\n",
  553. sp->name, sp->handle, d_id->b24);
  554. rval = qla2x00_start_sp(sp);
  555. if (rval != QLA_SUCCESS) {
  556. ql_dbg(ql_dbg_disc, vha, 0x2043,
  557. "RFT_ID issue IOCB failed (%d).\n", rval);
  558. goto done_free_sp;
  559. }
  560. return rval;
  561. done_free_sp:
  562. /* ref: INIT */
  563. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  564. done:
  565. return rval;
  566. }
  567. /**
  568. * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
  569. * @vha: HA context
  570. * @type: not used
  571. *
  572. * Returns 0 on success.
  573. */
  574. int
  575. qla2x00_rff_id(scsi_qla_host_t *vha, u8 type)
  576. {
  577. struct qla_hw_data *ha = vha->hw;
  578. if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
  579. ql_dbg(ql_dbg_disc, vha, 0x2046,
  580. "RFF_ID call not supported on ISP2100/ISP2200.\n");
  581. return (QLA_SUCCESS);
  582. }
  583. return qla_async_rffid(vha, &vha->d_id, qlt_rff_id(vha), type);
  584. }
  585. static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id,
  586. u8 fc4feature, u8 fc4type)
  587. {
  588. int rval = QLA_MEMORY_ALLOC_FAILED;
  589. struct ct_sns_req *ct_req;
  590. srb_t *sp;
  591. struct ct_sns_pkt *ct_sns;
  592. /* ref: INIT */
  593. sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
  594. if (!sp)
  595. goto done;
  596. sp->type = SRB_CT_PTHRU_CMD;
  597. sp->name = "rff_id";
  598. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  599. qla2x00_async_sns_sp_done);
  600. sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
  601. sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
  602. GFP_KERNEL);
  603. sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
  604. if (!sp->u.iocb_cmd.u.ctarg.req) {
  605. ql_log(ql_log_warn, vha, 0xd041,
  606. "%s: Failed to allocate ct_sns request.\n",
  607. __func__);
  608. goto done_free_sp;
  609. }
  610. sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
  611. sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
  612. GFP_KERNEL);
  613. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
  614. if (!sp->u.iocb_cmd.u.ctarg.rsp) {
  615. ql_log(ql_log_warn, vha, 0xd042,
  616. "%s: Failed to allocate ct_sns request.\n",
  617. __func__);
  618. goto done_free_sp;
  619. }
  620. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
  621. memset(ct_sns, 0, sizeof(*ct_sns));
  622. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
  623. /* Prepare CT request */
  624. ct_req = qla2x00_prep_ct_req(ct_sns, RFF_ID_CMD, RFF_ID_RSP_SIZE);
  625. /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
  626. ct_req->req.rff_id.port_id = port_id_to_be_id(*d_id);
  627. ct_req->req.rff_id.fc4_feature = fc4feature;
  628. ct_req->req.rff_id.fc4_type = fc4type; /* SCSI-FCP or FC-NVMe */
  629. sp->u.iocb_cmd.u.ctarg.req_size = RFF_ID_REQ_SIZE;
  630. sp->u.iocb_cmd.u.ctarg.rsp_size = RFF_ID_RSP_SIZE;
  631. sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
  632. ql_dbg(ql_dbg_disc, vha, 0xffff,
  633. "Async-%s - hdl=%x portid %06x feature %x type %x.\n",
  634. sp->name, sp->handle, d_id->b24, fc4feature, fc4type);
  635. rval = qla2x00_start_sp(sp);
  636. if (rval != QLA_SUCCESS) {
  637. ql_dbg(ql_dbg_disc, vha, 0x2047,
  638. "RFF_ID issue IOCB failed (%d).\n", rval);
  639. goto done_free_sp;
  640. }
  641. return rval;
  642. done_free_sp:
  643. /* ref: INIT */
  644. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  645. done:
  646. return rval;
  647. }
  648. /**
  649. * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
  650. * @vha: HA context
  651. *
  652. * Returns 0 on success.
  653. */
  654. int
  655. qla2x00_rnn_id(scsi_qla_host_t *vha)
  656. {
  657. struct qla_hw_data *ha = vha->hw;
  658. if (IS_QLA2100(ha) || IS_QLA2200(ha))
  659. return qla2x00_sns_rnn_id(vha);
  660. return qla_async_rnnid(vha, &vha->d_id, vha->node_name);
  661. }
  662. static int qla_async_rnnid(scsi_qla_host_t *vha, port_id_t *d_id,
  663. u8 *node_name)
  664. {
  665. int rval = QLA_MEMORY_ALLOC_FAILED;
  666. struct ct_sns_req *ct_req;
  667. srb_t *sp;
  668. struct ct_sns_pkt *ct_sns;
  669. /* ref: INIT */
  670. sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
  671. if (!sp)
  672. goto done;
  673. sp->type = SRB_CT_PTHRU_CMD;
  674. sp->name = "rnid";
  675. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  676. qla2x00_async_sns_sp_done);
  677. sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
  678. sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
  679. GFP_KERNEL);
  680. sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
  681. if (!sp->u.iocb_cmd.u.ctarg.req) {
  682. ql_log(ql_log_warn, vha, 0xd041,
  683. "%s: Failed to allocate ct_sns request.\n",
  684. __func__);
  685. goto done_free_sp;
  686. }
  687. sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
  688. sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
  689. GFP_KERNEL);
  690. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
  691. if (!sp->u.iocb_cmd.u.ctarg.rsp) {
  692. ql_log(ql_log_warn, vha, 0xd042,
  693. "%s: Failed to allocate ct_sns request.\n",
  694. __func__);
  695. goto done_free_sp;
  696. }
  697. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
  698. memset(ct_sns, 0, sizeof(*ct_sns));
  699. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
  700. /* Prepare CT request */
  701. ct_req = qla2x00_prep_ct_req(ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE);
  702. /* Prepare CT arguments -- port_id, node_name */
  703. ct_req->req.rnn_id.port_id = port_id_to_be_id(vha->d_id);
  704. memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE);
  705. sp->u.iocb_cmd.u.ctarg.req_size = RNN_ID_REQ_SIZE;
  706. sp->u.iocb_cmd.u.ctarg.rsp_size = RNN_ID_RSP_SIZE;
  707. sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
  708. ql_dbg(ql_dbg_disc, vha, 0xffff,
  709. "Async-%s - hdl=%x portid %06x\n",
  710. sp->name, sp->handle, d_id->b24);
  711. rval = qla2x00_start_sp(sp);
  712. if (rval != QLA_SUCCESS) {
  713. ql_dbg(ql_dbg_disc, vha, 0x204d,
  714. "RNN_ID issue IOCB failed (%d).\n", rval);
  715. goto done_free_sp;
  716. }
  717. return rval;
  718. done_free_sp:
  719. /* ref: INIT */
  720. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  721. done:
  722. return rval;
  723. }
  724. size_t
  725. qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size)
  726. {
  727. struct qla_hw_data *ha = vha->hw;
  728. if (IS_QLAFX00(ha))
  729. return scnprintf(snn, size, "%s FW:v%s DVR:v%s",
  730. ha->model_number, ha->mr.fw_version, qla2x00_version_str);
  731. return scnprintf(snn, size, "%s FW:v%d.%02d.%02d DVR:v%s",
  732. ha->model_number, ha->fw_major_version, ha->fw_minor_version,
  733. ha->fw_subminor_version, qla2x00_version_str);
  734. }
  735. /**
  736. * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
  737. * @vha: HA context
  738. *
  739. * Returns 0 on success.
  740. */
  741. int
  742. qla2x00_rsnn_nn(scsi_qla_host_t *vha)
  743. {
  744. struct qla_hw_data *ha = vha->hw;
  745. if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
  746. ql_dbg(ql_dbg_disc, vha, 0x2050,
  747. "RSNN_ID call unsupported on ISP2100/ISP2200.\n");
  748. return (QLA_SUCCESS);
  749. }
  750. return qla_async_rsnn_nn(vha);
  751. }
  752. static int qla_async_rsnn_nn(scsi_qla_host_t *vha)
  753. {
  754. int rval = QLA_MEMORY_ALLOC_FAILED;
  755. struct ct_sns_req *ct_req;
  756. srb_t *sp;
  757. struct ct_sns_pkt *ct_sns;
  758. /* ref: INIT */
  759. sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
  760. if (!sp)
  761. goto done;
  762. sp->type = SRB_CT_PTHRU_CMD;
  763. sp->name = "rsnn_nn";
  764. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  765. qla2x00_async_sns_sp_done);
  766. sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
  767. sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
  768. GFP_KERNEL);
  769. sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
  770. if (!sp->u.iocb_cmd.u.ctarg.req) {
  771. ql_log(ql_log_warn, vha, 0xd041,
  772. "%s: Failed to allocate ct_sns request.\n",
  773. __func__);
  774. goto done_free_sp;
  775. }
  776. sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
  777. sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
  778. GFP_KERNEL);
  779. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
  780. if (!sp->u.iocb_cmd.u.ctarg.rsp) {
  781. ql_log(ql_log_warn, vha, 0xd042,
  782. "%s: Failed to allocate ct_sns request.\n",
  783. __func__);
  784. goto done_free_sp;
  785. }
  786. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
  787. memset(ct_sns, 0, sizeof(*ct_sns));
  788. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
  789. /* Prepare CT request */
  790. ct_req = qla2x00_prep_ct_req(ct_sns, RSNN_NN_CMD, RSNN_NN_RSP_SIZE);
  791. /* Prepare CT arguments -- node_name, symbolic node_name, size */
  792. memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE);
  793. /* Prepare the Symbolic Node Name */
  794. qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name,
  795. sizeof(ct_req->req.rsnn_nn.sym_node_name));
  796. ct_req->req.rsnn_nn.name_len =
  797. (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
  798. sp->u.iocb_cmd.u.ctarg.req_size = 24 + 1 + ct_req->req.rsnn_nn.name_len;
  799. sp->u.iocb_cmd.u.ctarg.rsp_size = RSNN_NN_RSP_SIZE;
  800. sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
  801. ql_dbg(ql_dbg_disc, vha, 0xffff,
  802. "Async-%s - hdl=%x.\n",
  803. sp->name, sp->handle);
  804. rval = qla2x00_start_sp(sp);
  805. if (rval != QLA_SUCCESS) {
  806. ql_dbg(ql_dbg_disc, vha, 0x2043,
  807. "RFT_ID issue IOCB failed (%d).\n", rval);
  808. goto done_free_sp;
  809. }
  810. return rval;
  811. done_free_sp:
  812. /* ref: INIT */
  813. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  814. done:
  815. return rval;
  816. }
  817. /**
  818. * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
  819. * @vha: HA context
  820. * @cmd: GS command
  821. * @scmd_len: Subcommand length
  822. * @data_size: response size in bytes
  823. *
  824. * Returns a pointer to the @ha's sns_cmd.
  825. */
  826. static inline struct sns_cmd_pkt *
  827. qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
  828. uint16_t data_size)
  829. {
  830. uint16_t wc;
  831. struct sns_cmd_pkt *sns_cmd;
  832. struct qla_hw_data *ha = vha->hw;
  833. sns_cmd = ha->sns_cmd;
  834. memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
  835. wc = data_size / 2; /* Size in 16bit words. */
  836. sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
  837. put_unaligned_le64(ha->sns_cmd_dma, &sns_cmd->p.cmd.buffer_address);
  838. sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
  839. sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
  840. wc = (data_size - 16) / 4; /* Size in 32bit words. */
  841. sns_cmd->p.cmd.size = cpu_to_le16(wc);
  842. vha->qla_stats.control_requests++;
  843. return (sns_cmd);
  844. }
  845. /**
  846. * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
  847. * @vha: HA context
  848. * @fcport: fcport entry to updated
  849. *
  850. * This command uses the old Exectute SNS Command mailbox routine.
  851. *
  852. * Returns 0 on success.
  853. */
  854. static int
  855. qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
  856. {
  857. int rval = QLA_SUCCESS;
  858. struct qla_hw_data *ha = vha->hw;
  859. struct sns_cmd_pkt *sns_cmd;
  860. /* Issue GA_NXT. */
  861. /* Prepare SNS command request. */
  862. sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN,
  863. GA_NXT_SNS_DATA_SIZE);
  864. /* Prepare SNS command arguments -- port_id. */
  865. sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa;
  866. sns_cmd->p.cmd.param[1] = fcport->d_id.b.area;
  867. sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain;
  868. /* Execute SNS command. */
  869. rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2,
  870. sizeof(struct sns_cmd_pkt));
  871. if (rval != QLA_SUCCESS) {
  872. /*EMPTY*/
  873. ql_dbg(ql_dbg_disc, vha, 0x205f,
  874. "GA_NXT Send SNS failed (%d).\n", rval);
  875. } else if (sns_cmd->p.gan_data[8] != 0x80 ||
  876. sns_cmd->p.gan_data[9] != 0x02) {
  877. ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084,
  878. "GA_NXT failed, rejected request ga_nxt_rsp:\n");
  879. ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074,
  880. sns_cmd->p.gan_data, 16);
  881. rval = QLA_FUNCTION_FAILED;
  882. } else {
  883. /* Populate fc_port_t entry. */
  884. fcport->d_id.b.domain = sns_cmd->p.gan_data[17];
  885. fcport->d_id.b.area = sns_cmd->p.gan_data[18];
  886. fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19];
  887. memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE);
  888. memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE);
  889. if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE &&
  890. sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE)
  891. fcport->d_id.b.domain = 0xf0;
  892. ql_dbg(ql_dbg_disc, vha, 0x2061,
  893. "GA_NXT entry - nn %8phN pn %8phN "
  894. "port_id=%02x%02x%02x.\n",
  895. fcport->node_name, fcport->port_name,
  896. fcport->d_id.b.domain, fcport->d_id.b.area,
  897. fcport->d_id.b.al_pa);
  898. }
  899. return (rval);
  900. }
  901. /**
  902. * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
  903. * @vha: HA context
  904. * @list: switch info entries to populate
  905. *
  906. * This command uses the old Exectute SNS Command mailbox routine.
  907. *
  908. * NOTE: Non-Nx_Ports are not requested.
  909. *
  910. * Returns 0 on success.
  911. */
  912. static int
  913. qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
  914. {
  915. int rval;
  916. struct qla_hw_data *ha = vha->hw;
  917. uint16_t i;
  918. uint8_t *entry;
  919. struct sns_cmd_pkt *sns_cmd;
  920. uint16_t gid_pt_sns_data_size;
  921. gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha);
  922. /* Issue GID_PT. */
  923. /* Prepare SNS command request. */
  924. sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
  925. gid_pt_sns_data_size);
  926. /* Prepare SNS command arguments -- port_type. */
  927. sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
  928. /* Execute SNS command. */
  929. rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2,
  930. sizeof(struct sns_cmd_pkt));
  931. if (rval != QLA_SUCCESS) {
  932. /*EMPTY*/
  933. ql_dbg(ql_dbg_disc, vha, 0x206d,
  934. "GID_PT Send SNS failed (%d).\n", rval);
  935. } else if (sns_cmd->p.gid_data[8] != 0x80 ||
  936. sns_cmd->p.gid_data[9] != 0x02) {
  937. ql_dbg(ql_dbg_disc, vha, 0x202f,
  938. "GID_PT failed, rejected request, gid_rsp:\n");
  939. ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081,
  940. sns_cmd->p.gid_data, 16);
  941. rval = QLA_FUNCTION_FAILED;
  942. } else {
  943. /* Set port IDs in switch info list. */
  944. for (i = 0; i < ha->max_fibre_devices; i++) {
  945. entry = &sns_cmd->p.gid_data[(i * 4) + 16];
  946. list[i].d_id.b.domain = entry[1];
  947. list[i].d_id.b.area = entry[2];
  948. list[i].d_id.b.al_pa = entry[3];
  949. /* Last one exit. */
  950. if (entry[0] & BIT_7) {
  951. list[i].d_id.b.rsvd_1 = entry[0];
  952. break;
  953. }
  954. }
  955. /*
  956. * If we've used all available slots, then the switch is
  957. * reporting back more devices that we can handle with this
  958. * single call. Return a failed status, and let GA_NXT handle
  959. * the overload.
  960. */
  961. if (i == ha->max_fibre_devices)
  962. rval = QLA_FUNCTION_FAILED;
  963. }
  964. return (rval);
  965. }
  966. /**
  967. * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
  968. * @vha: HA context
  969. * @list: switch info entries to populate
  970. *
  971. * This command uses the old Exectute SNS Command mailbox routine.
  972. *
  973. * Returns 0 on success.
  974. */
  975. static int
  976. qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
  977. {
  978. int rval = QLA_SUCCESS;
  979. struct qla_hw_data *ha = vha->hw;
  980. uint16_t i;
  981. struct sns_cmd_pkt *sns_cmd;
  982. for (i = 0; i < ha->max_fibre_devices; i++) {
  983. /* Issue GPN_ID */
  984. /* Prepare SNS command request. */
  985. sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD,
  986. GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE);
  987. /* Prepare SNS command arguments -- port_id. */
  988. sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
  989. sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
  990. sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
  991. /* Execute SNS command. */
  992. rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
  993. GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
  994. if (rval != QLA_SUCCESS) {
  995. /*EMPTY*/
  996. ql_dbg(ql_dbg_disc, vha, 0x2032,
  997. "GPN_ID Send SNS failed (%d).\n", rval);
  998. } else if (sns_cmd->p.gpn_data[8] != 0x80 ||
  999. sns_cmd->p.gpn_data[9] != 0x02) {
  1000. ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e,
  1001. "GPN_ID failed, rejected request, gpn_rsp:\n");
  1002. ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207f,
  1003. sns_cmd->p.gpn_data, 16);
  1004. rval = QLA_FUNCTION_FAILED;
  1005. } else {
  1006. /* Save portname */
  1007. memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16],
  1008. WWN_SIZE);
  1009. }
  1010. /* Last device exit. */
  1011. if (list[i].d_id.b.rsvd_1 != 0)
  1012. break;
  1013. }
  1014. return (rval);
  1015. }
  1016. /**
  1017. * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
  1018. * @vha: HA context
  1019. * @list: switch info entries to populate
  1020. *
  1021. * This command uses the old Exectute SNS Command mailbox routine.
  1022. *
  1023. * Returns 0 on success.
  1024. */
  1025. static int
  1026. qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
  1027. {
  1028. int rval = QLA_SUCCESS;
  1029. struct qla_hw_data *ha = vha->hw;
  1030. uint16_t i;
  1031. struct sns_cmd_pkt *sns_cmd;
  1032. for (i = 0; i < ha->max_fibre_devices; i++) {
  1033. /* Issue GNN_ID */
  1034. /* Prepare SNS command request. */
  1035. sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD,
  1036. GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE);
  1037. /* Prepare SNS command arguments -- port_id. */
  1038. sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
  1039. sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
  1040. sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
  1041. /* Execute SNS command. */
  1042. rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
  1043. GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
  1044. if (rval != QLA_SUCCESS) {
  1045. /*EMPTY*/
  1046. ql_dbg(ql_dbg_disc, vha, 0x203f,
  1047. "GNN_ID Send SNS failed (%d).\n", rval);
  1048. } else if (sns_cmd->p.gnn_data[8] != 0x80 ||
  1049. sns_cmd->p.gnn_data[9] != 0x02) {
  1050. ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082,
  1051. "GNN_ID failed, rejected request, gnn_rsp:\n");
  1052. ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a,
  1053. sns_cmd->p.gnn_data, 16);
  1054. rval = QLA_FUNCTION_FAILED;
  1055. } else {
  1056. /* Save nodename */
  1057. memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16],
  1058. WWN_SIZE);
  1059. ql_dbg(ql_dbg_disc, vha, 0x206e,
  1060. "GID_PT entry - nn %8phN pn %8phN "
  1061. "port_id=%02x%02x%02x.\n",
  1062. list[i].node_name, list[i].port_name,
  1063. list[i].d_id.b.domain, list[i].d_id.b.area,
  1064. list[i].d_id.b.al_pa);
  1065. }
  1066. /* Last device exit. */
  1067. if (list[i].d_id.b.rsvd_1 != 0)
  1068. break;
  1069. }
  1070. return (rval);
  1071. }
  1072. /**
  1073. * qla2x00_sns_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
  1074. * @vha: HA context
  1075. *
  1076. * This command uses the old Exectute SNS Command mailbox routine.
  1077. *
  1078. * Returns 0 on success.
  1079. */
  1080. static int
  1081. qla2x00_sns_rft_id(scsi_qla_host_t *vha)
  1082. {
  1083. int rval;
  1084. struct qla_hw_data *ha = vha->hw;
  1085. struct sns_cmd_pkt *sns_cmd;
  1086. /* Issue RFT_ID. */
  1087. /* Prepare SNS command request. */
  1088. sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN,
  1089. RFT_ID_SNS_DATA_SIZE);
  1090. /* Prepare SNS command arguments -- port_id, FC-4 types */
  1091. sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
  1092. sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
  1093. sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
  1094. sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */
  1095. /* Execute SNS command. */
  1096. rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2,
  1097. sizeof(struct sns_cmd_pkt));
  1098. if (rval != QLA_SUCCESS) {
  1099. /*EMPTY*/
  1100. ql_dbg(ql_dbg_disc, vha, 0x2060,
  1101. "RFT_ID Send SNS failed (%d).\n", rval);
  1102. } else if (sns_cmd->p.rft_data[8] != 0x80 ||
  1103. sns_cmd->p.rft_data[9] != 0x02) {
  1104. ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083,
  1105. "RFT_ID failed, rejected request rft_rsp:\n");
  1106. ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080,
  1107. sns_cmd->p.rft_data, 16);
  1108. rval = QLA_FUNCTION_FAILED;
  1109. } else {
  1110. ql_dbg(ql_dbg_disc, vha, 0x2073,
  1111. "RFT_ID exiting normally.\n");
  1112. }
  1113. return (rval);
  1114. }
  1115. /**
  1116. * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
  1117. * @vha: HA context
  1118. *
  1119. * This command uses the old Exectute SNS Command mailbox routine.
  1120. *
  1121. * Returns 0 on success.
  1122. */
  1123. static int
  1124. qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
  1125. {
  1126. int rval;
  1127. struct qla_hw_data *ha = vha->hw;
  1128. struct sns_cmd_pkt *sns_cmd;
  1129. /* Issue RNN_ID. */
  1130. /* Prepare SNS command request. */
  1131. sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN,
  1132. RNN_ID_SNS_DATA_SIZE);
  1133. /* Prepare SNS command arguments -- port_id, nodename. */
  1134. sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
  1135. sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
  1136. sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
  1137. sns_cmd->p.cmd.param[4] = vha->node_name[7];
  1138. sns_cmd->p.cmd.param[5] = vha->node_name[6];
  1139. sns_cmd->p.cmd.param[6] = vha->node_name[5];
  1140. sns_cmd->p.cmd.param[7] = vha->node_name[4];
  1141. sns_cmd->p.cmd.param[8] = vha->node_name[3];
  1142. sns_cmd->p.cmd.param[9] = vha->node_name[2];
  1143. sns_cmd->p.cmd.param[10] = vha->node_name[1];
  1144. sns_cmd->p.cmd.param[11] = vha->node_name[0];
  1145. /* Execute SNS command. */
  1146. rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
  1147. sizeof(struct sns_cmd_pkt));
  1148. if (rval != QLA_SUCCESS) {
  1149. /*EMPTY*/
  1150. ql_dbg(ql_dbg_disc, vha, 0x204a,
  1151. "RNN_ID Send SNS failed (%d).\n", rval);
  1152. } else if (sns_cmd->p.rnn_data[8] != 0x80 ||
  1153. sns_cmd->p.rnn_data[9] != 0x02) {
  1154. ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b,
  1155. "RNN_ID failed, rejected request, rnn_rsp:\n");
  1156. ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c,
  1157. sns_cmd->p.rnn_data, 16);
  1158. rval = QLA_FUNCTION_FAILED;
  1159. } else {
  1160. ql_dbg(ql_dbg_disc, vha, 0x204c,
  1161. "RNN_ID exiting normally.\n");
  1162. }
  1163. return (rval);
  1164. }
  1165. /**
  1166. * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
  1167. * @vha: HA context
  1168. *
  1169. * Returns 0 on success.
  1170. */
  1171. int
  1172. qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
  1173. {
  1174. int ret, rval;
  1175. uint16_t mb[MAILBOX_REGISTER_COUNT];
  1176. struct qla_hw_data *ha = vha->hw;
  1177. ret = QLA_SUCCESS;
  1178. if (vha->flags.management_server_logged_in)
  1179. return ret;
  1180. rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
  1181. 0xfa, mb, BIT_1);
  1182. if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
  1183. if (rval == QLA_MEMORY_ALLOC_FAILED)
  1184. ql_dbg(ql_dbg_disc, vha, 0x2085,
  1185. "Failed management_server login: loopid=%x "
  1186. "rval=%d\n", vha->mgmt_svr_loop_id, rval);
  1187. else
  1188. ql_dbg(ql_dbg_disc, vha, 0x2024,
  1189. "Failed management_server login: loopid=%x "
  1190. "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
  1191. vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6],
  1192. mb[7]);
  1193. ret = QLA_FUNCTION_FAILED;
  1194. } else
  1195. vha->flags.management_server_logged_in = 1;
  1196. return ret;
  1197. }
  1198. /**
  1199. * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
  1200. * @vha: HA context
  1201. * @req_size: request size in bytes
  1202. * @rsp_size: response size in bytes
  1203. *
  1204. * Returns a pointer to the @ha's ms_iocb.
  1205. */
  1206. void *
  1207. qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
  1208. uint32_t rsp_size)
  1209. {
  1210. ms_iocb_entry_t *ms_pkt;
  1211. struct qla_hw_data *ha = vha->hw;
  1212. ms_pkt = ha->ms_iocb;
  1213. memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
  1214. ms_pkt->entry_type = MS_IOCB_TYPE;
  1215. ms_pkt->entry_count = 1;
  1216. SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id);
  1217. ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
  1218. ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
  1219. ms_pkt->cmd_dsd_count = cpu_to_le16(1);
  1220. ms_pkt->total_dsd_count = cpu_to_le16(2);
  1221. ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
  1222. ms_pkt->req_bytecount = cpu_to_le32(req_size);
  1223. put_unaligned_le64(ha->ct_sns_dma, &ms_pkt->req_dsd.address);
  1224. ms_pkt->req_dsd.length = ms_pkt->req_bytecount;
  1225. put_unaligned_le64(ha->ct_sns_dma, &ms_pkt->rsp_dsd.address);
  1226. ms_pkt->rsp_dsd.length = ms_pkt->rsp_bytecount;
  1227. return ms_pkt;
  1228. }
  1229. /**
  1230. * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
  1231. * @vha: HA context
  1232. * @req_size: request size in bytes
  1233. * @rsp_size: response size in bytes
  1234. *
  1235. * Returns a pointer to the @ha's ms_iocb.
  1236. */
  1237. void *
  1238. qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
  1239. uint32_t rsp_size)
  1240. {
  1241. struct ct_entry_24xx *ct_pkt;
  1242. struct qla_hw_data *ha = vha->hw;
  1243. ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
  1244. memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
  1245. ct_pkt->entry_type = CT_IOCB_TYPE;
  1246. ct_pkt->entry_count = 1;
  1247. ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
  1248. ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
  1249. ct_pkt->cmd_dsd_count = cpu_to_le16(1);
  1250. ct_pkt->rsp_dsd_count = cpu_to_le16(1);
  1251. ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
  1252. ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
  1253. put_unaligned_le64(ha->ct_sns_dma, &ct_pkt->dsd[0].address);
  1254. ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
  1255. put_unaligned_le64(ha->ct_sns_dma, &ct_pkt->dsd[1].address);
  1256. ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count;
  1257. ct_pkt->vp_index = vha->vp_idx;
  1258. return ct_pkt;
  1259. }
  1260. static void
  1261. qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
  1262. {
  1263. struct qla_hw_data *ha = vha->hw;
  1264. ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
  1265. struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
  1266. if (IS_FWI2_CAPABLE(ha)) {
  1267. ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
  1268. ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
  1269. } else {
  1270. ms_pkt->req_bytecount = cpu_to_le32(req_size);
  1271. ms_pkt->req_dsd.length = ms_pkt->req_bytecount;
  1272. }
  1273. }
  1274. /**
  1275. * qla2x00_prep_ct_fdmi_req() - Prepare common CT request fields for SNS query.
  1276. * @p: CT request buffer
  1277. * @cmd: GS command
  1278. * @rsp_size: response size in bytes
  1279. *
  1280. * Returns a pointer to the intitialized @ct_req.
  1281. */
  1282. static inline struct ct_sns_req *
  1283. qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
  1284. uint16_t rsp_size)
  1285. {
  1286. memset(p, 0, sizeof(struct ct_sns_pkt));
  1287. p->p.req.header.revision = 0x01;
  1288. p->p.req.header.gs_type = 0xFA;
  1289. p->p.req.header.gs_subtype = 0x10;
  1290. p->p.req.command = cpu_to_be16(cmd);
  1291. p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
  1292. return &p->p.req;
  1293. }
  1294. uint
  1295. qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha)
  1296. {
  1297. uint speeds = 0;
  1298. if (IS_CNA_CAPABLE(ha))
  1299. return FDMI_PORT_SPEED_10GB;
  1300. if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
  1301. if (ha->max_supported_speed == 2) {
  1302. if (ha->min_supported_speed <= 6)
  1303. speeds |= FDMI_PORT_SPEED_64GB;
  1304. }
  1305. if (ha->max_supported_speed == 2 ||
  1306. ha->max_supported_speed == 1) {
  1307. if (ha->min_supported_speed <= 5)
  1308. speeds |= FDMI_PORT_SPEED_32GB;
  1309. }
  1310. if (ha->max_supported_speed == 2 ||
  1311. ha->max_supported_speed == 1 ||
  1312. ha->max_supported_speed == 0) {
  1313. if (ha->min_supported_speed <= 4)
  1314. speeds |= FDMI_PORT_SPEED_16GB;
  1315. }
  1316. if (ha->max_supported_speed == 1 ||
  1317. ha->max_supported_speed == 0) {
  1318. if (ha->min_supported_speed <= 3)
  1319. speeds |= FDMI_PORT_SPEED_8GB;
  1320. }
  1321. if (ha->max_supported_speed == 0) {
  1322. if (ha->min_supported_speed <= 2)
  1323. speeds |= FDMI_PORT_SPEED_4GB;
  1324. }
  1325. return speeds;
  1326. }
  1327. if (IS_QLA2031(ha)) {
  1328. if ((ha->pdev->subsystem_vendor == 0x103C) &&
  1329. ((ha->pdev->subsystem_device == 0x8002) ||
  1330. (ha->pdev->subsystem_device == 0x8086))) {
  1331. speeds = FDMI_PORT_SPEED_16GB;
  1332. } else {
  1333. speeds = FDMI_PORT_SPEED_16GB|FDMI_PORT_SPEED_8GB|
  1334. FDMI_PORT_SPEED_4GB;
  1335. }
  1336. return speeds;
  1337. }
  1338. if (IS_QLA25XX(ha) || IS_QLAFX00(ha))
  1339. return FDMI_PORT_SPEED_8GB|FDMI_PORT_SPEED_4GB|
  1340. FDMI_PORT_SPEED_2GB|FDMI_PORT_SPEED_1GB;
  1341. if (IS_QLA24XX_TYPE(ha))
  1342. return FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_2GB|
  1343. FDMI_PORT_SPEED_1GB;
  1344. if (IS_QLA23XX(ha))
  1345. return FDMI_PORT_SPEED_2GB|FDMI_PORT_SPEED_1GB;
  1346. return FDMI_PORT_SPEED_1GB;
  1347. }
  1348. uint
  1349. qla25xx_fdmi_port_speed_currently(struct qla_hw_data *ha)
  1350. {
  1351. switch (ha->link_data_rate) {
  1352. case PORT_SPEED_1GB:
  1353. return FDMI_PORT_SPEED_1GB;
  1354. case PORT_SPEED_2GB:
  1355. return FDMI_PORT_SPEED_2GB;
  1356. case PORT_SPEED_4GB:
  1357. return FDMI_PORT_SPEED_4GB;
  1358. case PORT_SPEED_8GB:
  1359. return FDMI_PORT_SPEED_8GB;
  1360. case PORT_SPEED_10GB:
  1361. return FDMI_PORT_SPEED_10GB;
  1362. case PORT_SPEED_16GB:
  1363. return FDMI_PORT_SPEED_16GB;
  1364. case PORT_SPEED_32GB:
  1365. return FDMI_PORT_SPEED_32GB;
  1366. case PORT_SPEED_64GB:
  1367. return FDMI_PORT_SPEED_64GB;
  1368. default:
  1369. return FDMI_PORT_SPEED_UNKNOWN;
  1370. }
  1371. }
  1372. /**
  1373. * qla2x00_hba_attributes() - perform HBA attributes registration
  1374. * @vha: HA context
  1375. * @entries: number of entries to use
  1376. * @callopt: Option to issue extended or standard FDMI
  1377. * command parameter
  1378. *
  1379. * Returns 0 on success.
  1380. */
  1381. static unsigned long
  1382. qla2x00_hba_attributes(scsi_qla_host_t *vha, void *entries,
  1383. unsigned int callopt)
  1384. {
  1385. struct qla_hw_data *ha = vha->hw;
  1386. struct new_utsname *p_sysid = utsname();
  1387. struct ct_fdmi_hba_attr *eiter;
  1388. uint16_t alen;
  1389. unsigned long size = 0;
  1390. /* Nodename. */
  1391. eiter = entries + size;
  1392. eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME);
  1393. memcpy(eiter->a.node_name, vha->node_name, sizeof(eiter->a.node_name));
  1394. alen = sizeof(eiter->a.node_name);
  1395. alen += FDMI_ATTR_TYPELEN(eiter);
  1396. eiter->len = cpu_to_be16(alen);
  1397. size += alen;
  1398. ql_dbg(ql_dbg_disc, vha, 0x20a0,
  1399. "NODENAME = %016llx.\n", wwn_to_u64(eiter->a.node_name));
  1400. /* Manufacturer. */
  1401. eiter = entries + size;
  1402. eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER);
  1403. alen = scnprintf(
  1404. eiter->a.manufacturer, sizeof(eiter->a.manufacturer),
  1405. "%s", QLA2XXX_MANUFACTURER);
  1406. alen += FDMI_ATTR_ALIGNMENT(alen);
  1407. alen += FDMI_ATTR_TYPELEN(eiter);
  1408. eiter->len = cpu_to_be16(alen);
  1409. size += alen;
  1410. ql_dbg(ql_dbg_disc, vha, 0x20a1,
  1411. "MANUFACTURER = %s.\n", eiter->a.manufacturer);
  1412. /* Serial number. */
  1413. eiter = entries + size;
  1414. eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
  1415. alen = 0;
  1416. if (IS_FWI2_CAPABLE(ha)) {
  1417. alen = qla2xxx_get_vpd_field(vha, "SN",
  1418. eiter->a.serial_num, sizeof(eiter->a.serial_num));
  1419. }
  1420. if (!alen) {
  1421. uint32_t sn = ((ha->serial0 & 0x1f) << 16) |
  1422. (ha->serial2 << 8) | ha->serial1;
  1423. alen = scnprintf(
  1424. eiter->a.serial_num, sizeof(eiter->a.serial_num),
  1425. "%c%05d", 'A' + sn / 100000, sn % 100000);
  1426. }
  1427. alen += FDMI_ATTR_ALIGNMENT(alen);
  1428. alen += FDMI_ATTR_TYPELEN(eiter);
  1429. eiter->len = cpu_to_be16(alen);
  1430. size += alen;
  1431. ql_dbg(ql_dbg_disc, vha, 0x20a2,
  1432. "SERIAL NUMBER = %s.\n", eiter->a.serial_num);
  1433. /* Model name. */
  1434. eiter = entries + size;
  1435. eiter->type = cpu_to_be16(FDMI_HBA_MODEL);
  1436. alen = scnprintf(
  1437. eiter->a.model, sizeof(eiter->a.model),
  1438. "%s", ha->model_number);
  1439. alen += FDMI_ATTR_ALIGNMENT(alen);
  1440. alen += FDMI_ATTR_TYPELEN(eiter);
  1441. eiter->len = cpu_to_be16(alen);
  1442. size += alen;
  1443. ql_dbg(ql_dbg_disc, vha, 0x20a3,
  1444. "MODEL NAME = %s.\n", eiter->a.model);
  1445. /* Model description. */
  1446. eiter = entries + size;
  1447. eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
  1448. alen = scnprintf(
  1449. eiter->a.model_desc, sizeof(eiter->a.model_desc),
  1450. "%s", ha->model_desc);
  1451. alen += FDMI_ATTR_ALIGNMENT(alen);
  1452. alen += FDMI_ATTR_TYPELEN(eiter);
  1453. eiter->len = cpu_to_be16(alen);
  1454. size += alen;
  1455. ql_dbg(ql_dbg_disc, vha, 0x20a4,
  1456. "MODEL DESCRIPTION = %s.\n", eiter->a.model_desc);
  1457. /* Hardware version. */
  1458. eiter = entries + size;
  1459. eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
  1460. alen = 0;
  1461. if (IS_FWI2_CAPABLE(ha)) {
  1462. if (!alen) {
  1463. alen = qla2xxx_get_vpd_field(vha, "MN",
  1464. eiter->a.hw_version, sizeof(eiter->a.hw_version));
  1465. }
  1466. if (!alen) {
  1467. alen = qla2xxx_get_vpd_field(vha, "EC",
  1468. eiter->a.hw_version, sizeof(eiter->a.hw_version));
  1469. }
  1470. }
  1471. if (!alen) {
  1472. alen = scnprintf(
  1473. eiter->a.hw_version, sizeof(eiter->a.hw_version),
  1474. "HW:%s", ha->adapter_id);
  1475. }
  1476. alen += FDMI_ATTR_ALIGNMENT(alen);
  1477. alen += FDMI_ATTR_TYPELEN(eiter);
  1478. eiter->len = cpu_to_be16(alen);
  1479. size += alen;
  1480. ql_dbg(ql_dbg_disc, vha, 0x20a5,
  1481. "HARDWARE VERSION = %s.\n", eiter->a.hw_version);
  1482. /* Driver version. */
  1483. eiter = entries + size;
  1484. eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
  1485. alen = scnprintf(
  1486. eiter->a.driver_version, sizeof(eiter->a.driver_version),
  1487. "%s", qla2x00_version_str);
  1488. alen += FDMI_ATTR_ALIGNMENT(alen);
  1489. alen += FDMI_ATTR_TYPELEN(eiter);
  1490. eiter->len = cpu_to_be16(alen);
  1491. size += alen;
  1492. ql_dbg(ql_dbg_disc, vha, 0x20a6,
  1493. "DRIVER VERSION = %s.\n", eiter->a.driver_version);
  1494. /* Option ROM version. */
  1495. eiter = entries + size;
  1496. eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
  1497. alen = scnprintf(
  1498. eiter->a.orom_version, sizeof(eiter->a.orom_version),
  1499. "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
  1500. alen += FDMI_ATTR_ALIGNMENT(alen);
  1501. alen += FDMI_ATTR_TYPELEN(eiter);
  1502. eiter->len = cpu_to_be16(alen);
  1503. size += alen;
  1504. ql_dbg(ql_dbg_disc, vha, 0x20a7,
  1505. "OPTROM VERSION = %d.%02d.\n",
  1506. eiter->a.orom_version[1], eiter->a.orom_version[0]);
  1507. /* Firmware version */
  1508. eiter = entries + size;
  1509. eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
  1510. ha->isp_ops->fw_version_str(vha, eiter->a.fw_version,
  1511. sizeof(eiter->a.fw_version));
  1512. alen += FDMI_ATTR_ALIGNMENT(alen);
  1513. alen += FDMI_ATTR_TYPELEN(eiter);
  1514. eiter->len = cpu_to_be16(alen);
  1515. size += alen;
  1516. ql_dbg(ql_dbg_disc, vha, 0x20a8,
  1517. "FIRMWARE VERSION = %s.\n", eiter->a.fw_version);
  1518. /* OS Name and Version */
  1519. eiter = entries + size;
  1520. eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION);
  1521. alen = 0;
  1522. if (p_sysid) {
  1523. alen = scnprintf(
  1524. eiter->a.os_version, sizeof(eiter->a.os_version),
  1525. "%s %s %s",
  1526. p_sysid->sysname, p_sysid->release, p_sysid->machine);
  1527. }
  1528. if (!alen) {
  1529. alen = scnprintf(
  1530. eiter->a.os_version, sizeof(eiter->a.os_version),
  1531. "%s %s",
  1532. "Linux", fc_host_system_hostname(vha->host));
  1533. }
  1534. alen += FDMI_ATTR_ALIGNMENT(alen);
  1535. alen += FDMI_ATTR_TYPELEN(eiter);
  1536. eiter->len = cpu_to_be16(alen);
  1537. size += alen;
  1538. ql_dbg(ql_dbg_disc, vha, 0x20a9,
  1539. "OS VERSION = %s.\n", eiter->a.os_version);
  1540. if (callopt == CALLOPT_FDMI1)
  1541. goto done;
  1542. /* MAX CT Payload Length */
  1543. eiter = entries + size;
  1544. eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH);
  1545. eiter->a.max_ct_len = cpu_to_be32(ha->frame_payload_size >> 2);
  1546. alen = sizeof(eiter->a.max_ct_len);
  1547. alen += FDMI_ATTR_TYPELEN(eiter);
  1548. eiter->len = cpu_to_be16(alen);
  1549. size += alen;
  1550. ql_dbg(ql_dbg_disc, vha, 0x20aa,
  1551. "CT PAYLOAD LENGTH = 0x%x.\n", be32_to_cpu(eiter->a.max_ct_len));
  1552. /* Node Symbolic Name */
  1553. eiter = entries + size;
  1554. eiter->type = cpu_to_be16(FDMI_HBA_NODE_SYMBOLIC_NAME);
  1555. alen = qla2x00_get_sym_node_name(vha, eiter->a.sym_name,
  1556. sizeof(eiter->a.sym_name));
  1557. alen += FDMI_ATTR_ALIGNMENT(alen);
  1558. alen += FDMI_ATTR_TYPELEN(eiter);
  1559. eiter->len = cpu_to_be16(alen);
  1560. size += alen;
  1561. ql_dbg(ql_dbg_disc, vha, 0x20ab,
  1562. "SYMBOLIC NAME = %s.\n", eiter->a.sym_name);
  1563. /* Vendor Specific information */
  1564. eiter = entries + size;
  1565. eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_SPECIFIC_INFO);
  1566. eiter->a.vendor_specific_info = cpu_to_be32(PCI_VENDOR_ID_QLOGIC);
  1567. alen = sizeof(eiter->a.vendor_specific_info);
  1568. alen += FDMI_ATTR_TYPELEN(eiter);
  1569. eiter->len = cpu_to_be16(alen);
  1570. size += alen;
  1571. ql_dbg(ql_dbg_disc, vha, 0x20ac,
  1572. "VENDOR SPECIFIC INFO = 0x%x.\n",
  1573. be32_to_cpu(eiter->a.vendor_specific_info));
  1574. /* Num Ports */
  1575. eiter = entries + size;
  1576. eiter->type = cpu_to_be16(FDMI_HBA_NUM_PORTS);
  1577. eiter->a.num_ports = cpu_to_be32(1);
  1578. alen = sizeof(eiter->a.num_ports);
  1579. alen += FDMI_ATTR_TYPELEN(eiter);
  1580. eiter->len = cpu_to_be16(alen);
  1581. size += alen;
  1582. ql_dbg(ql_dbg_disc, vha, 0x20ad,
  1583. "PORT COUNT = %x.\n", be32_to_cpu(eiter->a.num_ports));
  1584. /* Fabric Name */
  1585. eiter = entries + size;
  1586. eiter->type = cpu_to_be16(FDMI_HBA_FABRIC_NAME);
  1587. memcpy(eiter->a.fabric_name, vha->fabric_node_name,
  1588. sizeof(eiter->a.fabric_name));
  1589. alen = sizeof(eiter->a.fabric_name);
  1590. alen += FDMI_ATTR_TYPELEN(eiter);
  1591. eiter->len = cpu_to_be16(alen);
  1592. size += alen;
  1593. ql_dbg(ql_dbg_disc, vha, 0x20ae,
  1594. "FABRIC NAME = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
  1595. /* BIOS Version */
  1596. eiter = entries + size;
  1597. eiter->type = cpu_to_be16(FDMI_HBA_BOOT_BIOS_NAME);
  1598. alen = scnprintf(
  1599. eiter->a.bios_name, sizeof(eiter->a.bios_name),
  1600. "BIOS %d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
  1601. alen += FDMI_ATTR_ALIGNMENT(alen);
  1602. alen += FDMI_ATTR_TYPELEN(eiter);
  1603. eiter->len = cpu_to_be16(alen);
  1604. size += alen;
  1605. ql_dbg(ql_dbg_disc, vha, 0x20af,
  1606. "BIOS NAME = %s\n", eiter->a.bios_name);
  1607. /* Vendor Identifier */
  1608. eiter = entries + size;
  1609. eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_IDENTIFIER);
  1610. alen = scnprintf(
  1611. eiter->a.vendor_identifier, sizeof(eiter->a.vendor_identifier),
  1612. "%s", "QLGC");
  1613. alen += FDMI_ATTR_ALIGNMENT(alen);
  1614. alen += FDMI_ATTR_TYPELEN(eiter);
  1615. eiter->len = cpu_to_be16(alen);
  1616. size += alen;
  1617. ql_dbg(ql_dbg_disc, vha, 0x20b0,
  1618. "VENDOR IDENTIFIER = %s.\n", eiter->a.vendor_identifier);
  1619. done:
  1620. return size;
  1621. }
  1622. /**
  1623. * qla2x00_port_attributes() - perform Port attributes registration
  1624. * @vha: HA context
  1625. * @entries: number of entries to use
  1626. * @callopt: Option to issue extended or standard FDMI
  1627. * command parameter
  1628. *
  1629. * Returns 0 on success.
  1630. */
  1631. static unsigned long
  1632. qla2x00_port_attributes(scsi_qla_host_t *vha, void *entries,
  1633. unsigned int callopt)
  1634. {
  1635. struct qla_hw_data *ha = vha->hw;
  1636. struct new_utsname *p_sysid = utsname();
  1637. char *hostname = p_sysid ?
  1638. p_sysid->nodename : fc_host_system_hostname(vha->host);
  1639. struct ct_fdmi_port_attr *eiter;
  1640. uint16_t alen;
  1641. unsigned long size = 0;
  1642. /* FC4 types. */
  1643. eiter = entries + size;
  1644. eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES);
  1645. eiter->a.fc4_types[0] = 0x00;
  1646. eiter->a.fc4_types[1] = 0x00;
  1647. eiter->a.fc4_types[2] = 0x01;
  1648. eiter->a.fc4_types[3] = 0x00;
  1649. alen = sizeof(eiter->a.fc4_types);
  1650. alen += FDMI_ATTR_TYPELEN(eiter);
  1651. eiter->len = cpu_to_be16(alen);
  1652. size += alen;
  1653. ql_dbg(ql_dbg_disc, vha, 0x20c0,
  1654. "FC4 TYPES = %016llx.\n", *(uint64_t *)eiter->a.fc4_types);
  1655. if (vha->flags.nvme_enabled) {
  1656. eiter->a.fc4_types[6] = 1; /* NVMe type 28h */
  1657. ql_dbg(ql_dbg_disc, vha, 0x211f,
  1658. "NVME FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
  1659. eiter->a.fc4_types[6]);
  1660. }
  1661. /* Supported speed. */
  1662. eiter = entries + size;
  1663. eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
  1664. eiter->a.sup_speed = cpu_to_be32(
  1665. qla25xx_fdmi_port_speed_capability(ha));
  1666. alen = sizeof(eiter->a.sup_speed);
  1667. alen += FDMI_ATTR_TYPELEN(eiter);
  1668. eiter->len = cpu_to_be16(alen);
  1669. size += alen;
  1670. ql_dbg(ql_dbg_disc, vha, 0x20c1,
  1671. "SUPPORTED SPEED = %x.\n", be32_to_cpu(eiter->a.sup_speed));
  1672. /* Current speed. */
  1673. eiter = entries + size;
  1674. eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
  1675. eiter->a.cur_speed = cpu_to_be32(
  1676. qla25xx_fdmi_port_speed_currently(ha));
  1677. alen = sizeof(eiter->a.cur_speed);
  1678. alen += FDMI_ATTR_TYPELEN(eiter);
  1679. eiter->len = cpu_to_be16(alen);
  1680. size += alen;
  1681. ql_dbg(ql_dbg_disc, vha, 0x20c2,
  1682. "CURRENT SPEED = %x.\n", be32_to_cpu(eiter->a.cur_speed));
  1683. /* Max frame size. */
  1684. eiter = entries + size;
  1685. eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
  1686. eiter->a.max_frame_size = cpu_to_be32(ha->frame_payload_size);
  1687. alen = sizeof(eiter->a.max_frame_size);
  1688. alen += FDMI_ATTR_TYPELEN(eiter);
  1689. eiter->len = cpu_to_be16(alen);
  1690. size += alen;
  1691. ql_dbg(ql_dbg_disc, vha, 0x20c3,
  1692. "MAX FRAME SIZE = %x.\n", be32_to_cpu(eiter->a.max_frame_size));
  1693. /* OS device name. */
  1694. eiter = entries + size;
  1695. eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
  1696. alen = scnprintf(
  1697. eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name),
  1698. "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
  1699. alen += FDMI_ATTR_ALIGNMENT(alen);
  1700. alen += FDMI_ATTR_TYPELEN(eiter);
  1701. eiter->len = cpu_to_be16(alen);
  1702. size += alen;
  1703. ql_dbg(ql_dbg_disc, vha, 0x20c4,
  1704. "OS DEVICE NAME = %s.\n", eiter->a.os_dev_name);
  1705. /* Hostname. */
  1706. eiter = entries + size;
  1707. eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME);
  1708. if (!*hostname || !strncmp(hostname, "(none)", 6))
  1709. hostname = "Linux-default";
  1710. alen = scnprintf(
  1711. eiter->a.host_name, sizeof(eiter->a.host_name),
  1712. "%s", hostname);
  1713. alen += FDMI_ATTR_ALIGNMENT(alen);
  1714. alen += FDMI_ATTR_TYPELEN(eiter);
  1715. eiter->len = cpu_to_be16(alen);
  1716. size += alen;
  1717. ql_dbg(ql_dbg_disc, vha, 0x20c5,
  1718. "HOSTNAME = %s.\n", eiter->a.host_name);
  1719. if (callopt == CALLOPT_FDMI1)
  1720. goto done;
  1721. /* Node Name */
  1722. eiter = entries + size;
  1723. eiter->type = cpu_to_be16(FDMI_PORT_NODE_NAME);
  1724. memcpy(eiter->a.node_name, vha->node_name, sizeof(eiter->a.node_name));
  1725. alen = sizeof(eiter->a.node_name);
  1726. alen += FDMI_ATTR_TYPELEN(eiter);
  1727. eiter->len = cpu_to_be16(alen);
  1728. size += alen;
  1729. ql_dbg(ql_dbg_disc, vha, 0x20c6,
  1730. "NODENAME = %016llx.\n", wwn_to_u64(eiter->a.node_name));
  1731. /* Port Name */
  1732. eiter = entries + size;
  1733. eiter->type = cpu_to_be16(FDMI_PORT_NAME);
  1734. memcpy(eiter->a.port_name, vha->port_name, sizeof(eiter->a.port_name));
  1735. alen = sizeof(eiter->a.port_name);
  1736. alen += FDMI_ATTR_TYPELEN(eiter);
  1737. eiter->len = cpu_to_be16(alen);
  1738. size += alen;
  1739. ql_dbg(ql_dbg_disc, vha, 0x20c7,
  1740. "PORTNAME = %016llx.\n", wwn_to_u64(eiter->a.port_name));
  1741. /* Port Symbolic Name */
  1742. eiter = entries + size;
  1743. eiter->type = cpu_to_be16(FDMI_PORT_SYM_NAME);
  1744. alen = qla2x00_get_sym_node_name(vha, eiter->a.port_sym_name,
  1745. sizeof(eiter->a.port_sym_name));
  1746. alen += FDMI_ATTR_ALIGNMENT(alen);
  1747. alen += FDMI_ATTR_TYPELEN(eiter);
  1748. eiter->len = cpu_to_be16(alen);
  1749. size += alen;
  1750. ql_dbg(ql_dbg_disc, vha, 0x20c8,
  1751. "PORT SYMBOLIC NAME = %s\n", eiter->a.port_sym_name);
  1752. /* Port Type */
  1753. eiter = entries + size;
  1754. eiter->type = cpu_to_be16(FDMI_PORT_TYPE);
  1755. eiter->a.port_type = cpu_to_be32(NS_NX_PORT_TYPE);
  1756. alen = sizeof(eiter->a.port_type);
  1757. alen += FDMI_ATTR_TYPELEN(eiter);
  1758. eiter->len = cpu_to_be16(alen);
  1759. size += alen;
  1760. ql_dbg(ql_dbg_disc, vha, 0x20c9,
  1761. "PORT TYPE = %x.\n", be32_to_cpu(eiter->a.port_type));
  1762. /* Supported Class of Service */
  1763. eiter = entries + size;
  1764. eiter->type = cpu_to_be16(FDMI_PORT_SUPP_COS);
  1765. eiter->a.port_supported_cos = cpu_to_be32(FC_CLASS_3);
  1766. alen = sizeof(eiter->a.port_supported_cos);
  1767. alen += FDMI_ATTR_TYPELEN(eiter);
  1768. eiter->len = cpu_to_be16(alen);
  1769. size += alen;
  1770. ql_dbg(ql_dbg_disc, vha, 0x20ca,
  1771. "SUPPORTED COS = %08x\n", be32_to_cpu(eiter->a.port_supported_cos));
  1772. /* Port Fabric Name */
  1773. eiter = entries + size;
  1774. eiter->type = cpu_to_be16(FDMI_PORT_FABRIC_NAME);
  1775. memcpy(eiter->a.fabric_name, vha->fabric_node_name,
  1776. sizeof(eiter->a.fabric_name));
  1777. alen = sizeof(eiter->a.fabric_name);
  1778. alen += FDMI_ATTR_TYPELEN(eiter);
  1779. eiter->len = cpu_to_be16(alen);
  1780. size += alen;
  1781. ql_dbg(ql_dbg_disc, vha, 0x20cb,
  1782. "FABRIC NAME = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
  1783. /* FC4_type */
  1784. eiter = entries + size;
  1785. eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPE);
  1786. eiter->a.port_fc4_type[0] = 0x00;
  1787. eiter->a.port_fc4_type[1] = 0x00;
  1788. eiter->a.port_fc4_type[2] = 0x01;
  1789. eiter->a.port_fc4_type[3] = 0x00;
  1790. alen = sizeof(eiter->a.port_fc4_type);
  1791. alen += FDMI_ATTR_TYPELEN(eiter);
  1792. eiter->len = cpu_to_be16(alen);
  1793. size += alen;
  1794. ql_dbg(ql_dbg_disc, vha, 0x20cc,
  1795. "PORT ACTIVE FC4 TYPE = %016llx.\n",
  1796. *(uint64_t *)eiter->a.port_fc4_type);
  1797. /* Port State */
  1798. eiter = entries + size;
  1799. eiter->type = cpu_to_be16(FDMI_PORT_STATE);
  1800. eiter->a.port_state = cpu_to_be32(2);
  1801. alen = sizeof(eiter->a.port_state);
  1802. alen += FDMI_ATTR_TYPELEN(eiter);
  1803. eiter->len = cpu_to_be16(alen);
  1804. size += alen;
  1805. ql_dbg(ql_dbg_disc, vha, 0x20cd,
  1806. "PORT_STATE = %x.\n", be32_to_cpu(eiter->a.port_state));
  1807. /* Number of Ports */
  1808. eiter = entries + size;
  1809. eiter->type = cpu_to_be16(FDMI_PORT_COUNT);
  1810. eiter->a.num_ports = cpu_to_be32(1);
  1811. alen = sizeof(eiter->a.num_ports);
  1812. alen += FDMI_ATTR_TYPELEN(eiter);
  1813. eiter->len = cpu_to_be16(alen);
  1814. size += alen;
  1815. ql_dbg(ql_dbg_disc, vha, 0x20ce,
  1816. "PORT COUNT = %x.\n", be32_to_cpu(eiter->a.num_ports));
  1817. /* Port Identifier */
  1818. eiter = entries + size;
  1819. eiter->type = cpu_to_be16(FDMI_PORT_IDENTIFIER);
  1820. eiter->a.port_id = cpu_to_be32(vha->d_id.b24);
  1821. alen = sizeof(eiter->a.port_id);
  1822. alen += FDMI_ATTR_TYPELEN(eiter);
  1823. eiter->len = cpu_to_be16(alen);
  1824. size += alen;
  1825. ql_dbg(ql_dbg_disc, vha, 0x20cf,
  1826. "PORT ID = %x.\n", be32_to_cpu(eiter->a.port_id));
  1827. if (callopt == CALLOPT_FDMI2 || !ql2xsmartsan)
  1828. goto done;
  1829. /* Smart SAN Service Category (Populate Smart SAN Initiator)*/
  1830. eiter = entries + size;
  1831. eiter->type = cpu_to_be16(FDMI_SMARTSAN_SERVICE);
  1832. alen = scnprintf(
  1833. eiter->a.smartsan_service, sizeof(eiter->a.smartsan_service),
  1834. "%s", "Smart SAN Initiator");
  1835. alen += FDMI_ATTR_ALIGNMENT(alen);
  1836. alen += FDMI_ATTR_TYPELEN(eiter);
  1837. eiter->len = cpu_to_be16(alen);
  1838. size += alen;
  1839. ql_dbg(ql_dbg_disc, vha, 0x20d0,
  1840. "SMARTSAN SERVICE CATEGORY = %s.\n", eiter->a.smartsan_service);
  1841. /* Smart SAN GUID (NWWN+PWWN) */
  1842. eiter = entries + size;
  1843. eiter->type = cpu_to_be16(FDMI_SMARTSAN_GUID);
  1844. memcpy(eiter->a.smartsan_guid, vha->node_name, WWN_SIZE);
  1845. memcpy(eiter->a.smartsan_guid + WWN_SIZE, vha->port_name, WWN_SIZE);
  1846. alen = sizeof(eiter->a.smartsan_guid);
  1847. alen += FDMI_ATTR_TYPELEN(eiter);
  1848. eiter->len = cpu_to_be16(alen);
  1849. size += alen;
  1850. ql_dbg(ql_dbg_disc, vha, 0x20d1,
  1851. "Smart SAN GUID = %016llx-%016llx\n",
  1852. wwn_to_u64(eiter->a.smartsan_guid),
  1853. wwn_to_u64(eiter->a.smartsan_guid + WWN_SIZE));
  1854. /* Smart SAN Version (populate "Smart SAN Version 1.0") */
  1855. eiter = entries + size;
  1856. eiter->type = cpu_to_be16(FDMI_SMARTSAN_VERSION);
  1857. alen = scnprintf(
  1858. eiter->a.smartsan_version, sizeof(eiter->a.smartsan_version),
  1859. "%s", "Smart SAN Version 2.0");
  1860. alen += FDMI_ATTR_ALIGNMENT(alen);
  1861. alen += FDMI_ATTR_TYPELEN(eiter);
  1862. eiter->len = cpu_to_be16(alen);
  1863. size += alen;
  1864. ql_dbg(ql_dbg_disc, vha, 0x20d2,
  1865. "SMARTSAN VERSION = %s\n", eiter->a.smartsan_version);
  1866. /* Smart SAN Product Name (Specify Adapter Model No) */
  1867. eiter = entries + size;
  1868. eiter->type = cpu_to_be16(FDMI_SMARTSAN_PROD_NAME);
  1869. alen = scnprintf(eiter->a.smartsan_prod_name,
  1870. sizeof(eiter->a.smartsan_prod_name),
  1871. "ISP%04x", ha->pdev->device);
  1872. alen += FDMI_ATTR_ALIGNMENT(alen);
  1873. alen += FDMI_ATTR_TYPELEN(eiter);
  1874. eiter->len = cpu_to_be16(alen);
  1875. size += alen;
  1876. ql_dbg(ql_dbg_disc, vha, 0x20d3,
  1877. "SMARTSAN PRODUCT NAME = %s\n", eiter->a.smartsan_prod_name);
  1878. /* Smart SAN Port Info (specify: 1=Physical, 2=NPIV, 3=SRIOV) */
  1879. eiter = entries + size;
  1880. eiter->type = cpu_to_be16(FDMI_SMARTSAN_PORT_INFO);
  1881. eiter->a.smartsan_port_info = cpu_to_be32(vha->vp_idx ? 2 : 1);
  1882. alen = sizeof(eiter->a.smartsan_port_info);
  1883. alen += FDMI_ATTR_TYPELEN(eiter);
  1884. eiter->len = cpu_to_be16(alen);
  1885. size += alen;
  1886. ql_dbg(ql_dbg_disc, vha, 0x20d4,
  1887. "SMARTSAN PORT INFO = %x\n", eiter->a.smartsan_port_info);
  1888. /* Smart SAN Security Support */
  1889. eiter = entries + size;
  1890. eiter->type = cpu_to_be16(FDMI_SMARTSAN_SECURITY_SUPPORT);
  1891. eiter->a.smartsan_security_support = cpu_to_be32(1);
  1892. alen = sizeof(eiter->a.smartsan_security_support);
  1893. alen += FDMI_ATTR_TYPELEN(eiter);
  1894. eiter->len = cpu_to_be16(alen);
  1895. size += alen;
  1896. ql_dbg(ql_dbg_disc, vha, 0x20d6,
  1897. "SMARTSAN SECURITY SUPPORT = %d\n",
  1898. be32_to_cpu(eiter->a.smartsan_security_support));
  1899. done:
  1900. return size;
  1901. }
  1902. /**
  1903. * qla2x00_fdmi_rhba() - perform RHBA FDMI registration
  1904. * @vha: HA context
  1905. * @callopt: Option to issue FDMI registration
  1906. *
  1907. * Returns 0 on success.
  1908. */
  1909. static int
  1910. qla2x00_fdmi_rhba(scsi_qla_host_t *vha, unsigned int callopt)
  1911. {
  1912. struct qla_hw_data *ha = vha->hw;
  1913. unsigned long size = 0;
  1914. unsigned int rval, count;
  1915. ms_iocb_entry_t *ms_pkt;
  1916. struct ct_sns_req *ct_req;
  1917. struct ct_sns_rsp *ct_rsp;
  1918. void *entries;
  1919. count = callopt != CALLOPT_FDMI1 ?
  1920. FDMI2_HBA_ATTR_COUNT : FDMI1_HBA_ATTR_COUNT;
  1921. size = RHBA_RSP_SIZE;
  1922. ql_dbg(ql_dbg_disc, vha, 0x20e0,
  1923. "RHBA (callopt=%x count=%u size=%lu).\n", callopt, count, size);
  1924. /* Request size adjusted after CT preparation */
  1925. ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, size);
  1926. /* Prepare CT request */
  1927. ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, size);
  1928. ct_rsp = &ha->ct_sns->p.rsp;
  1929. /* Prepare FDMI command entries */
  1930. memcpy(ct_req->req.rhba.hba_identifier, vha->port_name,
  1931. sizeof(ct_req->req.rhba.hba_identifier));
  1932. size += sizeof(ct_req->req.rhba.hba_identifier);
  1933. ct_req->req.rhba.entry_count = cpu_to_be32(1);
  1934. size += sizeof(ct_req->req.rhba.entry_count);
  1935. memcpy(ct_req->req.rhba.port_name, vha->port_name,
  1936. sizeof(ct_req->req.rhba.port_name));
  1937. size += sizeof(ct_req->req.rhba.port_name);
  1938. /* Attribute count */
  1939. ct_req->req.rhba.attrs.count = cpu_to_be32(count);
  1940. size += sizeof(ct_req->req.rhba.attrs.count);
  1941. /* Attribute block */
  1942. entries = &ct_req->req.rhba.attrs.entry;
  1943. size += qla2x00_hba_attributes(vha, entries, callopt);
  1944. /* Update MS request size. */
  1945. qla2x00_update_ms_fdmi_iocb(vha, size + 16);
  1946. ql_dbg(ql_dbg_disc, vha, 0x20e1,
  1947. "RHBA %016llx %016llx.\n",
  1948. wwn_to_u64(ct_req->req.rhba.hba_identifier),
  1949. wwn_to_u64(ct_req->req.rhba.port_name));
  1950. ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20e2,
  1951. entries, size);
  1952. /* Execute MS IOCB */
  1953. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  1954. sizeof(*ha->ms_iocb));
  1955. if (rval) {
  1956. ql_dbg(ql_dbg_disc, vha, 0x20e3,
  1957. "RHBA iocb failed (%d).\n", rval);
  1958. return rval;
  1959. }
  1960. rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA");
  1961. if (rval) {
  1962. if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
  1963. ct_rsp->header.explanation_code ==
  1964. CT_EXPL_ALREADY_REGISTERED) {
  1965. ql_dbg(ql_dbg_disc, vha, 0x20e4,
  1966. "RHBA already registered.\n");
  1967. return QLA_ALREADY_REGISTERED;
  1968. }
  1969. ql_dbg(ql_dbg_disc, vha, 0x20e5,
  1970. "RHBA failed, CT Reason %#x, CT Explanation %#x\n",
  1971. ct_rsp->header.reason_code,
  1972. ct_rsp->header.explanation_code);
  1973. return rval;
  1974. }
  1975. ql_dbg(ql_dbg_disc, vha, 0x20e6, "RHBA exiting normally.\n");
  1976. return rval;
  1977. }
  1978. static int
  1979. qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
  1980. {
  1981. int rval;
  1982. struct qla_hw_data *ha = vha->hw;
  1983. ms_iocb_entry_t *ms_pkt;
  1984. struct ct_sns_req *ct_req;
  1985. struct ct_sns_rsp *ct_rsp;
  1986. /* Issue RPA */
  1987. /* Prepare common MS IOCB */
  1988. ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE,
  1989. DHBA_RSP_SIZE);
  1990. /* Prepare CT request */
  1991. ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE);
  1992. ct_rsp = &ha->ct_sns->p.rsp;
  1993. /* Prepare FDMI command arguments -- portname. */
  1994. memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE);
  1995. ql_dbg(ql_dbg_disc, vha, 0x2036,
  1996. "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name);
  1997. /* Execute MS IOCB */
  1998. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  1999. sizeof(ms_iocb_entry_t));
  2000. if (rval != QLA_SUCCESS) {
  2001. /*EMPTY*/
  2002. ql_dbg(ql_dbg_disc, vha, 0x2037,
  2003. "DHBA issue IOCB failed (%d).\n", rval);
  2004. } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") !=
  2005. QLA_SUCCESS) {
  2006. rval = QLA_FUNCTION_FAILED;
  2007. } else {
  2008. ql_dbg(ql_dbg_disc, vha, 0x2038,
  2009. "DHBA exiting normally.\n");
  2010. }
  2011. return rval;
  2012. }
  2013. /**
  2014. * qla2x00_fdmi_rprt() - perform RPRT registration
  2015. * @vha: HA context
  2016. * @callopt: Option to issue extended or standard FDMI
  2017. * command parameter
  2018. *
  2019. * Returns 0 on success.
  2020. */
  2021. static int
  2022. qla2x00_fdmi_rprt(scsi_qla_host_t *vha, int callopt)
  2023. {
  2024. struct scsi_qla_host *base_vha = pci_get_drvdata(vha->hw->pdev);
  2025. struct qla_hw_data *ha = vha->hw;
  2026. ulong size = 0;
  2027. uint rval, count;
  2028. ms_iocb_entry_t *ms_pkt;
  2029. struct ct_sns_req *ct_req;
  2030. struct ct_sns_rsp *ct_rsp;
  2031. void *entries;
  2032. count = callopt == CALLOPT_FDMI2_SMARTSAN && ql2xsmartsan ?
  2033. FDMI2_SMARTSAN_PORT_ATTR_COUNT :
  2034. callopt != CALLOPT_FDMI1 ?
  2035. FDMI2_PORT_ATTR_COUNT : FDMI1_PORT_ATTR_COUNT;
  2036. size = RPRT_RSP_SIZE;
  2037. ql_dbg(ql_dbg_disc, vha, 0x20e8,
  2038. "RPRT (callopt=%x count=%u size=%lu).\n", callopt, count, size);
  2039. /* Request size adjusted after CT preparation */
  2040. ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, size);
  2041. /* Prepare CT request */
  2042. ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPRT_CMD, size);
  2043. ct_rsp = &ha->ct_sns->p.rsp;
  2044. /* Prepare FDMI command entries */
  2045. memcpy(ct_req->req.rprt.hba_identifier, base_vha->port_name,
  2046. sizeof(ct_req->req.rprt.hba_identifier));
  2047. size += sizeof(ct_req->req.rprt.hba_identifier);
  2048. memcpy(ct_req->req.rprt.port_name, vha->port_name,
  2049. sizeof(ct_req->req.rprt.port_name));
  2050. size += sizeof(ct_req->req.rprt.port_name);
  2051. /* Attribute count */
  2052. ct_req->req.rprt.attrs.count = cpu_to_be32(count);
  2053. size += sizeof(ct_req->req.rprt.attrs.count);
  2054. /* Attribute block */
  2055. entries = ct_req->req.rprt.attrs.entry;
  2056. size += qla2x00_port_attributes(vha, entries, callopt);
  2057. /* Update MS request size. */
  2058. qla2x00_update_ms_fdmi_iocb(vha, size + 16);
  2059. ql_dbg(ql_dbg_disc, vha, 0x20e9,
  2060. "RPRT %016llx %016llx.\n",
  2061. wwn_to_u64(ct_req->req.rprt.port_name),
  2062. wwn_to_u64(ct_req->req.rprt.port_name));
  2063. ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20ea,
  2064. entries, size);
  2065. /* Execute MS IOCB */
  2066. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  2067. sizeof(*ha->ms_iocb));
  2068. if (rval) {
  2069. ql_dbg(ql_dbg_disc, vha, 0x20eb,
  2070. "RPRT iocb failed (%d).\n", rval);
  2071. return rval;
  2072. }
  2073. rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPRT");
  2074. if (rval) {
  2075. if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
  2076. ct_rsp->header.explanation_code ==
  2077. CT_EXPL_ALREADY_REGISTERED) {
  2078. ql_dbg(ql_dbg_disc, vha, 0x20ec,
  2079. "RPRT already registered.\n");
  2080. return QLA_ALREADY_REGISTERED;
  2081. }
  2082. ql_dbg(ql_dbg_disc, vha, 0x20ed,
  2083. "RPRT failed, CT Reason code: %#x, CT Explanation %#x\n",
  2084. ct_rsp->header.reason_code,
  2085. ct_rsp->header.explanation_code);
  2086. return rval;
  2087. }
  2088. ql_dbg(ql_dbg_disc, vha, 0x20ee, "RPRT exiting normally.\n");
  2089. return rval;
  2090. }
  2091. /**
  2092. * qla2x00_fdmi_rpa() - perform RPA registration
  2093. * @vha: HA context
  2094. * @callopt: Option to issue FDMI registration
  2095. *
  2096. * Returns 0 on success.
  2097. */
  2098. static int
  2099. qla2x00_fdmi_rpa(scsi_qla_host_t *vha, uint callopt)
  2100. {
  2101. struct qla_hw_data *ha = vha->hw;
  2102. ulong size = 0;
  2103. uint rval, count;
  2104. ms_iocb_entry_t *ms_pkt;
  2105. struct ct_sns_req *ct_req;
  2106. struct ct_sns_rsp *ct_rsp;
  2107. void *entries;
  2108. count =
  2109. callopt == CALLOPT_FDMI2_SMARTSAN && ql2xsmartsan ?
  2110. FDMI2_SMARTSAN_PORT_ATTR_COUNT :
  2111. callopt != CALLOPT_FDMI1 ?
  2112. FDMI2_PORT_ATTR_COUNT : FDMI1_PORT_ATTR_COUNT;
  2113. size =
  2114. callopt != CALLOPT_FDMI1 ?
  2115. SMARTSAN_RPA_RSP_SIZE : RPA_RSP_SIZE;
  2116. ql_dbg(ql_dbg_disc, vha, 0x20f0,
  2117. "RPA (callopt=%x count=%u size=%lu).\n", callopt, count, size);
  2118. /* Request size adjusted after CT preparation */
  2119. ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, size);
  2120. /* Prepare CT request */
  2121. ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, size);
  2122. ct_rsp = &ha->ct_sns->p.rsp;
  2123. /* Prepare FDMI command entries. */
  2124. memcpy(ct_req->req.rpa.port_name, vha->port_name,
  2125. sizeof(ct_req->req.rpa.port_name));
  2126. size += sizeof(ct_req->req.rpa.port_name);
  2127. /* Attribute count */
  2128. ct_req->req.rpa.attrs.count = cpu_to_be32(count);
  2129. size += sizeof(ct_req->req.rpa.attrs.count);
  2130. /* Attribute block */
  2131. entries = ct_req->req.rpa.attrs.entry;
  2132. size += qla2x00_port_attributes(vha, entries, callopt);
  2133. /* Update MS request size. */
  2134. qla2x00_update_ms_fdmi_iocb(vha, size + 16);
  2135. ql_dbg(ql_dbg_disc, vha, 0x20f1,
  2136. "RPA %016llx.\n", wwn_to_u64(ct_req->req.rpa.port_name));
  2137. ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20f2,
  2138. entries, size);
  2139. /* Execute MS IOCB */
  2140. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  2141. sizeof(*ha->ms_iocb));
  2142. if (rval) {
  2143. ql_dbg(ql_dbg_disc, vha, 0x20f3,
  2144. "RPA iocb failed (%d).\n", rval);
  2145. return rval;
  2146. }
  2147. rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA");
  2148. if (rval) {
  2149. if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
  2150. ct_rsp->header.explanation_code ==
  2151. CT_EXPL_ALREADY_REGISTERED) {
  2152. ql_dbg(ql_dbg_disc, vha, 0x20f4,
  2153. "RPA already registered.\n");
  2154. return QLA_ALREADY_REGISTERED;
  2155. }
  2156. ql_dbg(ql_dbg_disc, vha, 0x20f5,
  2157. "RPA failed, CT Reason code: %#x, CT Explanation %#x\n",
  2158. ct_rsp->header.reason_code,
  2159. ct_rsp->header.explanation_code);
  2160. return rval;
  2161. }
  2162. ql_dbg(ql_dbg_disc, vha, 0x20f6, "RPA exiting normally.\n");
  2163. return rval;
  2164. }
  2165. /**
  2166. * qla2x00_fdmi_register() -
  2167. * @vha: HA context
  2168. *
  2169. * Returns 0 on success.
  2170. */
  2171. int
  2172. qla2x00_fdmi_register(scsi_qla_host_t *vha)
  2173. {
  2174. int rval = QLA_SUCCESS;
  2175. struct qla_hw_data *ha = vha->hw;
  2176. if (IS_QLA2100(ha) || IS_QLA2200(ha) ||
  2177. IS_QLAFX00(ha))
  2178. return rval;
  2179. rval = qla2x00_mgmt_svr_login(vha);
  2180. if (rval)
  2181. return rval;
  2182. /* For npiv/vport send rprt only */
  2183. if (vha->vp_idx) {
  2184. if (ql2xsmartsan)
  2185. rval = qla2x00_fdmi_rprt(vha, CALLOPT_FDMI2_SMARTSAN);
  2186. if (rval || !ql2xsmartsan)
  2187. rval = qla2x00_fdmi_rprt(vha, CALLOPT_FDMI2);
  2188. if (rval)
  2189. rval = qla2x00_fdmi_rprt(vha, CALLOPT_FDMI1);
  2190. return rval;
  2191. }
  2192. /* Try fdmi2 first, if fails then try fdmi1 */
  2193. rval = qla2x00_fdmi_rhba(vha, CALLOPT_FDMI2);
  2194. if (rval) {
  2195. if (rval != QLA_ALREADY_REGISTERED)
  2196. goto try_fdmi;
  2197. rval = qla2x00_fdmi_dhba(vha);
  2198. if (rval)
  2199. goto try_fdmi;
  2200. rval = qla2x00_fdmi_rhba(vha, CALLOPT_FDMI2);
  2201. if (rval)
  2202. goto try_fdmi;
  2203. }
  2204. if (ql2xsmartsan)
  2205. rval = qla2x00_fdmi_rpa(vha, CALLOPT_FDMI2_SMARTSAN);
  2206. if (rval || !ql2xsmartsan)
  2207. rval = qla2x00_fdmi_rpa(vha, CALLOPT_FDMI2);
  2208. if (rval)
  2209. goto try_fdmi;
  2210. return rval;
  2211. try_fdmi:
  2212. rval = qla2x00_fdmi_rhba(vha, CALLOPT_FDMI1);
  2213. if (rval) {
  2214. if (rval != QLA_ALREADY_REGISTERED)
  2215. return rval;
  2216. rval = qla2x00_fdmi_dhba(vha);
  2217. if (rval)
  2218. return rval;
  2219. rval = qla2x00_fdmi_rhba(vha, CALLOPT_FDMI1);
  2220. if (rval)
  2221. return rval;
  2222. }
  2223. rval = qla2x00_fdmi_rpa(vha, CALLOPT_FDMI1);
  2224. return rval;
  2225. }
  2226. /**
  2227. * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
  2228. * @vha: HA context
  2229. * @list: switch info entries to populate
  2230. *
  2231. * Returns 0 on success.
  2232. */
  2233. int
  2234. qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
  2235. {
  2236. int rval = QLA_SUCCESS;
  2237. uint16_t i;
  2238. struct qla_hw_data *ha = vha->hw;
  2239. ms_iocb_entry_t *ms_pkt;
  2240. struct ct_sns_req *ct_req;
  2241. struct ct_sns_rsp *ct_rsp;
  2242. struct ct_arg arg;
  2243. if (!IS_IIDMA_CAPABLE(ha))
  2244. return QLA_FUNCTION_FAILED;
  2245. arg.iocb = ha->ms_iocb;
  2246. arg.req_dma = ha->ct_sns_dma;
  2247. arg.rsp_dma = ha->ct_sns_dma;
  2248. arg.req_size = GFPN_ID_REQ_SIZE;
  2249. arg.rsp_size = GFPN_ID_RSP_SIZE;
  2250. arg.nport_handle = NPH_SNS;
  2251. for (i = 0; i < ha->max_fibre_devices; i++) {
  2252. /* Issue GFPN_ID */
  2253. /* Prepare common MS IOCB */
  2254. ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
  2255. /* Prepare CT request */
  2256. ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD,
  2257. GFPN_ID_RSP_SIZE);
  2258. ct_rsp = &ha->ct_sns->p.rsp;
  2259. /* Prepare CT arguments -- port_id */
  2260. ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
  2261. /* Execute MS IOCB */
  2262. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  2263. sizeof(ms_iocb_entry_t));
  2264. if (rval != QLA_SUCCESS) {
  2265. /*EMPTY*/
  2266. ql_dbg(ql_dbg_disc, vha, 0x2023,
  2267. "GFPN_ID issue IOCB failed (%d).\n", rval);
  2268. break;
  2269. } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
  2270. "GFPN_ID") != QLA_SUCCESS) {
  2271. rval = QLA_FUNCTION_FAILED;
  2272. break;
  2273. } else {
  2274. /* Save fabric portname */
  2275. memcpy(list[i].fabric_port_name,
  2276. ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
  2277. }
  2278. /* Last device exit. */
  2279. if (list[i].d_id.b.rsvd_1 != 0)
  2280. break;
  2281. }
  2282. return (rval);
  2283. }
  2284. static inline struct ct_sns_req *
  2285. qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
  2286. uint16_t rsp_size)
  2287. {
  2288. memset(p, 0, sizeof(struct ct_sns_pkt));
  2289. p->p.req.header.revision = 0x01;
  2290. p->p.req.header.gs_type = 0xFA;
  2291. p->p.req.header.gs_subtype = 0x01;
  2292. p->p.req.command = cpu_to_be16(cmd);
  2293. p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
  2294. return &p->p.req;
  2295. }
  2296. static uint16_t
  2297. qla2x00_port_speed_capability(uint16_t speed)
  2298. {
  2299. switch (speed) {
  2300. case BIT_15:
  2301. return PORT_SPEED_1GB;
  2302. case BIT_14:
  2303. return PORT_SPEED_2GB;
  2304. case BIT_13:
  2305. return PORT_SPEED_4GB;
  2306. case BIT_12:
  2307. return PORT_SPEED_10GB;
  2308. case BIT_11:
  2309. return PORT_SPEED_8GB;
  2310. case BIT_10:
  2311. return PORT_SPEED_16GB;
  2312. case BIT_8:
  2313. return PORT_SPEED_32GB;
  2314. case BIT_7:
  2315. return PORT_SPEED_64GB;
  2316. default:
  2317. return PORT_SPEED_UNKNOWN;
  2318. }
  2319. }
  2320. /**
  2321. * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
  2322. * @vha: HA context
  2323. * @list: switch info entries to populate
  2324. *
  2325. * Returns 0 on success.
  2326. */
  2327. int
  2328. qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
  2329. {
  2330. int rval;
  2331. uint16_t i;
  2332. struct qla_hw_data *ha = vha->hw;
  2333. ms_iocb_entry_t *ms_pkt;
  2334. struct ct_sns_req *ct_req;
  2335. struct ct_sns_rsp *ct_rsp;
  2336. struct ct_arg arg;
  2337. if (!IS_IIDMA_CAPABLE(ha))
  2338. return QLA_FUNCTION_FAILED;
  2339. if (!ha->flags.gpsc_supported)
  2340. return QLA_FUNCTION_FAILED;
  2341. rval = qla2x00_mgmt_svr_login(vha);
  2342. if (rval)
  2343. return rval;
  2344. arg.iocb = ha->ms_iocb;
  2345. arg.req_dma = ha->ct_sns_dma;
  2346. arg.rsp_dma = ha->ct_sns_dma;
  2347. arg.req_size = GPSC_REQ_SIZE;
  2348. arg.rsp_size = GPSC_RSP_SIZE;
  2349. arg.nport_handle = vha->mgmt_svr_loop_id;
  2350. for (i = 0; i < ha->max_fibre_devices; i++) {
  2351. /* Issue GFPN_ID */
  2352. /* Prepare common MS IOCB */
  2353. ms_pkt = qla24xx_prep_ms_iocb(vha, &arg);
  2354. /* Prepare CT request */
  2355. ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD,
  2356. GPSC_RSP_SIZE);
  2357. ct_rsp = &ha->ct_sns->p.rsp;
  2358. /* Prepare CT arguments -- port_name */
  2359. memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
  2360. WWN_SIZE);
  2361. /* Execute MS IOCB */
  2362. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  2363. sizeof(ms_iocb_entry_t));
  2364. if (rval != QLA_SUCCESS) {
  2365. /*EMPTY*/
  2366. ql_dbg(ql_dbg_disc, vha, 0x2059,
  2367. "GPSC issue IOCB failed (%d).\n", rval);
  2368. } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
  2369. "GPSC")) != QLA_SUCCESS) {
  2370. /* FM command unsupported? */
  2371. if (rval == QLA_INVALID_COMMAND &&
  2372. (ct_rsp->header.reason_code ==
  2373. CT_REASON_INVALID_COMMAND_CODE ||
  2374. ct_rsp->header.reason_code ==
  2375. CT_REASON_COMMAND_UNSUPPORTED)) {
  2376. ql_dbg(ql_dbg_disc, vha, 0x205a,
  2377. "GPSC command unsupported, disabling "
  2378. "query.\n");
  2379. ha->flags.gpsc_supported = 0;
  2380. rval = QLA_FUNCTION_FAILED;
  2381. break;
  2382. }
  2383. rval = QLA_FUNCTION_FAILED;
  2384. } else {
  2385. list->fp_speed = qla2x00_port_speed_capability(
  2386. be16_to_cpu(ct_rsp->rsp.gpsc.speed));
  2387. ql_dbg(ql_dbg_disc, vha, 0x205b,
  2388. "GPSC ext entry - fpn "
  2389. "%8phN speeds=%04x speed=%04x.\n",
  2390. list[i].fabric_port_name,
  2391. be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
  2392. be16_to_cpu(ct_rsp->rsp.gpsc.speed));
  2393. }
  2394. /* Last device exit. */
  2395. if (list[i].d_id.b.rsvd_1 != 0)
  2396. break;
  2397. }
  2398. return (rval);
  2399. }
  2400. /**
  2401. * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
  2402. *
  2403. * @vha: HA context
  2404. * @list: switch info entries to populate
  2405. *
  2406. */
  2407. void
  2408. qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
  2409. {
  2410. int rval;
  2411. uint16_t i;
  2412. ms_iocb_entry_t *ms_pkt;
  2413. struct ct_sns_req *ct_req;
  2414. struct ct_sns_rsp *ct_rsp;
  2415. struct qla_hw_data *ha = vha->hw;
  2416. uint8_t fcp_scsi_features = 0, nvme_features = 0;
  2417. struct ct_arg arg;
  2418. for (i = 0; i < ha->max_fibre_devices; i++) {
  2419. /* Set default FC4 Type as UNKNOWN so the default is to
  2420. * Process this port */
  2421. list[i].fc4_type = 0;
  2422. /* Do not attempt GFF_ID if we are not FWI_2 capable */
  2423. if (!IS_FWI2_CAPABLE(ha))
  2424. continue;
  2425. arg.iocb = ha->ms_iocb;
  2426. arg.req_dma = ha->ct_sns_dma;
  2427. arg.rsp_dma = ha->ct_sns_dma;
  2428. arg.req_size = GFF_ID_REQ_SIZE;
  2429. arg.rsp_size = GFF_ID_RSP_SIZE;
  2430. arg.nport_handle = NPH_SNS;
  2431. /* Prepare common MS IOCB */
  2432. ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
  2433. /* Prepare CT request */
  2434. ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD,
  2435. GFF_ID_RSP_SIZE);
  2436. ct_rsp = &ha->ct_sns->p.rsp;
  2437. /* Prepare CT arguments -- port_id */
  2438. ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
  2439. /* Execute MS IOCB */
  2440. rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
  2441. sizeof(ms_iocb_entry_t));
  2442. if (rval != QLA_SUCCESS) {
  2443. ql_dbg(ql_dbg_disc, vha, 0x205c,
  2444. "GFF_ID issue IOCB failed (%d).\n", rval);
  2445. } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
  2446. "GFF_ID") != QLA_SUCCESS) {
  2447. ql_dbg(ql_dbg_disc, vha, 0x205d,
  2448. "GFF_ID IOCB status had a failure status code.\n");
  2449. } else {
  2450. fcp_scsi_features =
  2451. ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
  2452. fcp_scsi_features &= 0x0f;
  2453. if (fcp_scsi_features) {
  2454. list[i].fc4_type = FS_FC4TYPE_FCP;
  2455. list[i].fc4_features = fcp_scsi_features;
  2456. }
  2457. nvme_features =
  2458. ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
  2459. nvme_features &= 0xf;
  2460. if (nvme_features) {
  2461. list[i].fc4_type |= FS_FC4TYPE_NVME;
  2462. list[i].fc4_features = nvme_features;
  2463. }
  2464. }
  2465. /* Last device exit. */
  2466. if (list[i].d_id.b.rsvd_1 != 0)
  2467. break;
  2468. }
  2469. }
  2470. int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport)
  2471. {
  2472. struct qla_work_evt *e;
  2473. e = qla2x00_alloc_work(vha, QLA_EVT_GPSC);
  2474. if (!e)
  2475. return QLA_FUNCTION_FAILED;
  2476. e->u.fcport.fcport = fcport;
  2477. return qla2x00_post_work(vha, e);
  2478. }
  2479. void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea)
  2480. {
  2481. struct fc_port *fcport = ea->fcport;
  2482. ql_dbg(ql_dbg_disc, vha, 0x20d8,
  2483. "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
  2484. __func__, fcport->port_name, fcport->disc_state,
  2485. fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen,
  2486. ea->sp->gen2, fcport->rscn_gen|ea->sp->gen1, fcport->loop_id);
  2487. if (fcport->disc_state == DSC_DELETE_PEND)
  2488. return;
  2489. /* We will figure-out what happen after AUTH completes */
  2490. if (fcport->disc_state == DSC_LOGIN_AUTH_PEND)
  2491. return;
  2492. if (ea->sp->gen2 != fcport->login_gen) {
  2493. /* target side must have changed it. */
  2494. ql_dbg(ql_dbg_disc, vha, 0x20d3,
  2495. "%s %8phC generation changed\n",
  2496. __func__, fcport->port_name);
  2497. return;
  2498. } else if (ea->sp->gen1 != fcport->rscn_gen) {
  2499. return;
  2500. }
  2501. qla_post_iidma_work(vha, fcport);
  2502. }
  2503. static void qla24xx_async_gpsc_sp_done(srb_t *sp, int res)
  2504. {
  2505. struct scsi_qla_host *vha = sp->vha;
  2506. struct qla_hw_data *ha = vha->hw;
  2507. fc_port_t *fcport = sp->fcport;
  2508. struct ct_sns_rsp *ct_rsp;
  2509. struct event_arg ea;
  2510. ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
  2511. ql_dbg(ql_dbg_disc, vha, 0x2053,
  2512. "Async done-%s res %x, WWPN %8phC \n",
  2513. sp->name, res, fcport->port_name);
  2514. fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
  2515. if (res == QLA_FUNCTION_TIMEOUT)
  2516. goto done;
  2517. if (res == (DID_ERROR << 16)) {
  2518. /* entry status error */
  2519. goto done;
  2520. } else if (res) {
  2521. if ((ct_rsp->header.reason_code ==
  2522. CT_REASON_INVALID_COMMAND_CODE) ||
  2523. (ct_rsp->header.reason_code ==
  2524. CT_REASON_COMMAND_UNSUPPORTED)) {
  2525. ql_dbg(ql_dbg_disc, vha, 0x2019,
  2526. "GPSC command unsupported, disabling query.\n");
  2527. ha->flags.gpsc_supported = 0;
  2528. goto done;
  2529. }
  2530. } else {
  2531. fcport->fp_speed = qla2x00_port_speed_capability(
  2532. be16_to_cpu(ct_rsp->rsp.gpsc.speed));
  2533. ql_dbg(ql_dbg_disc, vha, 0x2054,
  2534. "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n",
  2535. sp->name, fcport->fabric_port_name,
  2536. be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
  2537. be16_to_cpu(ct_rsp->rsp.gpsc.speed));
  2538. }
  2539. memset(&ea, 0, sizeof(ea));
  2540. ea.rc = res;
  2541. ea.fcport = fcport;
  2542. ea.sp = sp;
  2543. qla24xx_handle_gpsc_event(vha, &ea);
  2544. done:
  2545. /* ref: INIT */
  2546. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  2547. }
  2548. int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
  2549. {
  2550. int rval = QLA_FUNCTION_FAILED;
  2551. struct ct_sns_req *ct_req;
  2552. srb_t *sp;
  2553. if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
  2554. return rval;
  2555. /* ref: INIT */
  2556. sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
  2557. if (!sp)
  2558. goto done;
  2559. sp->type = SRB_CT_PTHRU_CMD;
  2560. sp->name = "gpsc";
  2561. sp->gen1 = fcport->rscn_gen;
  2562. sp->gen2 = fcport->login_gen;
  2563. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  2564. qla24xx_async_gpsc_sp_done);
  2565. /* CT_IU preamble */
  2566. ct_req = qla24xx_prep_ct_fm_req(fcport->ct_desc.ct_sns, GPSC_CMD,
  2567. GPSC_RSP_SIZE);
  2568. /* GPSC req */
  2569. memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name,
  2570. WWN_SIZE);
  2571. sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
  2572. sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
  2573. sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
  2574. sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
  2575. sp->u.iocb_cmd.u.ctarg.req_size = GPSC_REQ_SIZE;
  2576. sp->u.iocb_cmd.u.ctarg.rsp_size = GPSC_RSP_SIZE;
  2577. sp->u.iocb_cmd.u.ctarg.nport_handle = vha->mgmt_svr_loop_id;
  2578. ql_dbg(ql_dbg_disc, vha, 0x205e,
  2579. "Async-%s %8phC hdl=%x loopid=%x portid=%02x%02x%02x.\n",
  2580. sp->name, fcport->port_name, sp->handle,
  2581. fcport->loop_id, fcport->d_id.b.domain,
  2582. fcport->d_id.b.area, fcport->d_id.b.al_pa);
  2583. rval = qla2x00_start_sp(sp);
  2584. if (rval != QLA_SUCCESS)
  2585. goto done_free_sp;
  2586. return rval;
  2587. done_free_sp:
  2588. /* ref: INIT */
  2589. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  2590. done:
  2591. return rval;
  2592. }
  2593. int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id)
  2594. {
  2595. struct qla_work_evt *e;
  2596. if (test_bit(UNLOADING, &vha->dpc_flags) ||
  2597. (vha->vp_idx && test_bit(VPORT_DELETE, &vha->dpc_flags)))
  2598. return 0;
  2599. e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
  2600. if (!e)
  2601. return QLA_FUNCTION_FAILED;
  2602. e->u.gpnid.id = *id;
  2603. return qla2x00_post_work(vha, e);
  2604. }
  2605. void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp)
  2606. {
  2607. struct srb_iocb *c = &sp->u.iocb_cmd;
  2608. switch (sp->type) {
  2609. case SRB_ELS_DCMD:
  2610. qla2x00_els_dcmd2_free(vha, &c->u.els_plogi);
  2611. break;
  2612. case SRB_CT_PTHRU_CMD:
  2613. default:
  2614. if (sp->u.iocb_cmd.u.ctarg.req) {
  2615. dma_free_coherent(&vha->hw->pdev->dev,
  2616. sp->u.iocb_cmd.u.ctarg.req_allocated_size,
  2617. sp->u.iocb_cmd.u.ctarg.req,
  2618. sp->u.iocb_cmd.u.ctarg.req_dma);
  2619. sp->u.iocb_cmd.u.ctarg.req = NULL;
  2620. }
  2621. if (sp->u.iocb_cmd.u.ctarg.rsp) {
  2622. dma_free_coherent(&vha->hw->pdev->dev,
  2623. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
  2624. sp->u.iocb_cmd.u.ctarg.rsp,
  2625. sp->u.iocb_cmd.u.ctarg.rsp_dma);
  2626. sp->u.iocb_cmd.u.ctarg.rsp = NULL;
  2627. }
  2628. break;
  2629. }
  2630. /* ref: INIT */
  2631. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  2632. }
  2633. void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
  2634. {
  2635. fc_port_t *fcport, *conflict, *t;
  2636. u16 data[2];
  2637. ql_dbg(ql_dbg_disc, vha, 0xffff,
  2638. "%s %d port_id: %06x\n",
  2639. __func__, __LINE__, ea->id.b24);
  2640. if (ea->rc) {
  2641. /* cable is disconnected */
  2642. list_for_each_entry_safe(fcport, t, &vha->vp_fcports, list) {
  2643. if (fcport->d_id.b24 == ea->id.b24)
  2644. fcport->scan_state = QLA_FCPORT_SCAN;
  2645. qlt_schedule_sess_for_deletion(fcport);
  2646. }
  2647. } else {
  2648. /* cable is connected */
  2649. fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1);
  2650. if (fcport) {
  2651. list_for_each_entry_safe(conflict, t, &vha->vp_fcports,
  2652. list) {
  2653. if ((conflict->d_id.b24 == ea->id.b24) &&
  2654. (fcport != conflict))
  2655. /*
  2656. * 2 fcports with conflict Nport ID or
  2657. * an existing fcport is having nport ID
  2658. * conflict with new fcport.
  2659. */
  2660. conflict->scan_state = QLA_FCPORT_SCAN;
  2661. qlt_schedule_sess_for_deletion(conflict);
  2662. }
  2663. fcport->scan_needed = 0;
  2664. fcport->rscn_gen++;
  2665. fcport->scan_state = QLA_FCPORT_FOUND;
  2666. fcport->flags |= FCF_FABRIC_DEVICE;
  2667. if (fcport->login_retry == 0) {
  2668. fcport->login_retry =
  2669. vha->hw->login_retry_count;
  2670. ql_dbg(ql_dbg_disc, vha, 0xffff,
  2671. "Port login retry %8phN, lid 0x%04x cnt=%d.\n",
  2672. fcport->port_name, fcport->loop_id,
  2673. fcport->login_retry);
  2674. }
  2675. switch (fcport->disc_state) {
  2676. case DSC_LOGIN_COMPLETE:
  2677. /* recheck session is still intact. */
  2678. ql_dbg(ql_dbg_disc, vha, 0x210d,
  2679. "%s %d %8phC revalidate session with ADISC\n",
  2680. __func__, __LINE__, fcport->port_name);
  2681. data[0] = data[1] = 0;
  2682. qla2x00_post_async_adisc_work(vha, fcport,
  2683. data);
  2684. break;
  2685. case DSC_DELETED:
  2686. ql_dbg(ql_dbg_disc, vha, 0x210d,
  2687. "%s %d %8phC login\n", __func__, __LINE__,
  2688. fcport->port_name);
  2689. fcport->d_id = ea->id;
  2690. qla24xx_fcport_handle_login(vha, fcport);
  2691. break;
  2692. case DSC_DELETE_PEND:
  2693. fcport->d_id = ea->id;
  2694. break;
  2695. default:
  2696. fcport->d_id = ea->id;
  2697. break;
  2698. }
  2699. } else {
  2700. list_for_each_entry_safe(conflict, t, &vha->vp_fcports,
  2701. list) {
  2702. if (conflict->d_id.b24 == ea->id.b24) {
  2703. /* 2 fcports with conflict Nport ID or
  2704. * an existing fcport is having nport ID
  2705. * conflict with new fcport.
  2706. */
  2707. ql_dbg(ql_dbg_disc, vha, 0xffff,
  2708. "%s %d %8phC DS %d\n",
  2709. __func__, __LINE__,
  2710. conflict->port_name,
  2711. conflict->disc_state);
  2712. conflict->scan_state = QLA_FCPORT_SCAN;
  2713. qlt_schedule_sess_for_deletion(conflict);
  2714. }
  2715. }
  2716. /* create new fcport */
  2717. ql_dbg(ql_dbg_disc, vha, 0x2065,
  2718. "%s %d %8phC post new sess\n",
  2719. __func__, __LINE__, ea->port_name);
  2720. qla24xx_post_newsess_work(vha, &ea->id,
  2721. ea->port_name, NULL, NULL, 0);
  2722. }
  2723. }
  2724. }
  2725. static void qla2x00_async_gpnid_sp_done(srb_t *sp, int res)
  2726. {
  2727. struct scsi_qla_host *vha = sp->vha;
  2728. struct ct_sns_req *ct_req =
  2729. (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
  2730. struct ct_sns_rsp *ct_rsp =
  2731. (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
  2732. struct event_arg ea;
  2733. struct qla_work_evt *e;
  2734. unsigned long flags;
  2735. if (res)
  2736. ql_dbg(ql_dbg_disc, vha, 0x2066,
  2737. "Async done-%s fail res %x rscn gen %d ID %3phC. %8phC\n",
  2738. sp->name, res, sp->gen1, &ct_req->req.port_id.port_id,
  2739. ct_rsp->rsp.gpn_id.port_name);
  2740. else
  2741. ql_dbg(ql_dbg_disc, vha, 0x2066,
  2742. "Async done-%s good rscn gen %d ID %3phC. %8phC\n",
  2743. sp->name, sp->gen1, &ct_req->req.port_id.port_id,
  2744. ct_rsp->rsp.gpn_id.port_name);
  2745. memset(&ea, 0, sizeof(ea));
  2746. memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
  2747. ea.sp = sp;
  2748. ea.id = be_to_port_id(ct_req->req.port_id.port_id);
  2749. ea.rc = res;
  2750. spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
  2751. list_del(&sp->elem);
  2752. spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
  2753. if (res) {
  2754. if (res == QLA_FUNCTION_TIMEOUT) {
  2755. qla24xx_post_gpnid_work(sp->vha, &ea.id);
  2756. /* ref: INIT */
  2757. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  2758. return;
  2759. }
  2760. } else if (sp->gen1) {
  2761. /* There was another RSCN for this Nport ID */
  2762. qla24xx_post_gpnid_work(sp->vha, &ea.id);
  2763. /* ref: INIT */
  2764. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  2765. return;
  2766. }
  2767. qla24xx_handle_gpnid_event(vha, &ea);
  2768. e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
  2769. if (!e) {
  2770. /* please ignore kernel warning. otherwise, we have mem leak. */
  2771. dma_free_coherent(&vha->hw->pdev->dev,
  2772. sp->u.iocb_cmd.u.ctarg.req_allocated_size,
  2773. sp->u.iocb_cmd.u.ctarg.req,
  2774. sp->u.iocb_cmd.u.ctarg.req_dma);
  2775. sp->u.iocb_cmd.u.ctarg.req = NULL;
  2776. dma_free_coherent(&vha->hw->pdev->dev,
  2777. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
  2778. sp->u.iocb_cmd.u.ctarg.rsp,
  2779. sp->u.iocb_cmd.u.ctarg.rsp_dma);
  2780. sp->u.iocb_cmd.u.ctarg.rsp = NULL;
  2781. /* ref: INIT */
  2782. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  2783. return;
  2784. }
  2785. e->u.iosb.sp = sp;
  2786. qla2x00_post_work(vha, e);
  2787. }
  2788. /* Get WWPN with Nport ID. */
  2789. int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
  2790. {
  2791. int rval = QLA_FUNCTION_FAILED;
  2792. struct ct_sns_req *ct_req;
  2793. srb_t *sp, *tsp;
  2794. struct ct_sns_pkt *ct_sns;
  2795. unsigned long flags;
  2796. if (!vha->flags.online)
  2797. goto done;
  2798. /* ref: INIT */
  2799. sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
  2800. if (!sp)
  2801. goto done;
  2802. sp->type = SRB_CT_PTHRU_CMD;
  2803. sp->name = "gpnid";
  2804. sp->u.iocb_cmd.u.ctarg.id = *id;
  2805. sp->gen1 = 0;
  2806. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  2807. qla2x00_async_gpnid_sp_done);
  2808. spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
  2809. list_for_each_entry(tsp, &vha->gpnid_list, elem) {
  2810. if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) {
  2811. tsp->gen1++;
  2812. spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
  2813. /* ref: INIT */
  2814. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  2815. goto done;
  2816. }
  2817. }
  2818. list_add_tail(&sp->elem, &vha->gpnid_list);
  2819. spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
  2820. sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
  2821. sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
  2822. GFP_KERNEL);
  2823. sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
  2824. if (!sp->u.iocb_cmd.u.ctarg.req) {
  2825. ql_log(ql_log_warn, vha, 0xd041,
  2826. "Failed to allocate ct_sns request.\n");
  2827. goto done_free_sp;
  2828. }
  2829. sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
  2830. sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
  2831. GFP_KERNEL);
  2832. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
  2833. if (!sp->u.iocb_cmd.u.ctarg.rsp) {
  2834. ql_log(ql_log_warn, vha, 0xd042,
  2835. "Failed to allocate ct_sns request.\n");
  2836. goto done_free_sp;
  2837. }
  2838. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
  2839. memset(ct_sns, 0, sizeof(*ct_sns));
  2840. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
  2841. /* CT_IU preamble */
  2842. ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE);
  2843. /* GPN_ID req */
  2844. ct_req->req.port_id.port_id = port_id_to_be_id(*id);
  2845. sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE;
  2846. sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE;
  2847. sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
  2848. ql_dbg(ql_dbg_disc, vha, 0x2067,
  2849. "Async-%s hdl=%x ID %3phC.\n", sp->name,
  2850. sp->handle, &ct_req->req.port_id.port_id);
  2851. rval = qla2x00_start_sp(sp);
  2852. if (rval != QLA_SUCCESS)
  2853. goto done_free_sp;
  2854. return rval;
  2855. done_free_sp:
  2856. spin_lock_irqsave(&vha->hw->vport_slock, flags);
  2857. list_del(&sp->elem);
  2858. spin_unlock_irqrestore(&vha->hw->vport_slock, flags);
  2859. if (sp->u.iocb_cmd.u.ctarg.req) {
  2860. dma_free_coherent(&vha->hw->pdev->dev,
  2861. sizeof(struct ct_sns_pkt),
  2862. sp->u.iocb_cmd.u.ctarg.req,
  2863. sp->u.iocb_cmd.u.ctarg.req_dma);
  2864. sp->u.iocb_cmd.u.ctarg.req = NULL;
  2865. }
  2866. if (sp->u.iocb_cmd.u.ctarg.rsp) {
  2867. dma_free_coherent(&vha->hw->pdev->dev,
  2868. sizeof(struct ct_sns_pkt),
  2869. sp->u.iocb_cmd.u.ctarg.rsp,
  2870. sp->u.iocb_cmd.u.ctarg.rsp_dma);
  2871. sp->u.iocb_cmd.u.ctarg.rsp = NULL;
  2872. }
  2873. /* ref: INIT */
  2874. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  2875. done:
  2876. return rval;
  2877. }
  2878. void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
  2879. {
  2880. struct scsi_qla_host *vha = sp->vha;
  2881. fc_port_t *fcport = sp->fcport;
  2882. struct ct_sns_rsp *ct_rsp;
  2883. uint8_t fc4_scsi_feat;
  2884. uint8_t fc4_nvme_feat;
  2885. ql_dbg(ql_dbg_disc, vha, 0x2133,
  2886. "Async done-%s res %x ID %x. %8phC\n",
  2887. sp->name, res, fcport->d_id.b24, fcport->port_name);
  2888. ct_rsp = sp->u.iocb_cmd.u.ctarg.rsp;
  2889. fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
  2890. fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
  2891. sp->rc = res;
  2892. /*
  2893. * FC-GS-7, 5.2.3.12 FC-4 Features - format
  2894. * The format of the FC-4 Features object, as defined by the FC-4,
  2895. * Shall be an array of 4-bit values, one for each type code value
  2896. */
  2897. if (!res) {
  2898. if (fc4_scsi_feat & 0xf) {
  2899. /* w1 b00:03 */
  2900. fcport->fc4_type = FS_FC4TYPE_FCP;
  2901. fcport->fc4_features = fc4_scsi_feat & 0xf;
  2902. }
  2903. if (fc4_nvme_feat & 0xf) {
  2904. /* w5 [00:03]/28h */
  2905. fcport->fc4_type |= FS_FC4TYPE_NVME;
  2906. fcport->fc4_features = fc4_nvme_feat & 0xf;
  2907. }
  2908. }
  2909. if (sp->flags & SRB_WAKEUP_ON_COMP) {
  2910. complete(sp->comp);
  2911. } else {
  2912. if (sp->u.iocb_cmd.u.ctarg.req) {
  2913. dma_free_coherent(&vha->hw->pdev->dev,
  2914. sp->u.iocb_cmd.u.ctarg.req_allocated_size,
  2915. sp->u.iocb_cmd.u.ctarg.req,
  2916. sp->u.iocb_cmd.u.ctarg.req_dma);
  2917. sp->u.iocb_cmd.u.ctarg.req = NULL;
  2918. }
  2919. if (sp->u.iocb_cmd.u.ctarg.rsp) {
  2920. dma_free_coherent(&vha->hw->pdev->dev,
  2921. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
  2922. sp->u.iocb_cmd.u.ctarg.rsp,
  2923. sp->u.iocb_cmd.u.ctarg.rsp_dma);
  2924. sp->u.iocb_cmd.u.ctarg.rsp = NULL;
  2925. }
  2926. /* ref: INIT */
  2927. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  2928. /* we should not be here */
  2929. dump_stack();
  2930. }
  2931. }
  2932. /* Get FC4 Feature with Nport ID. */
  2933. int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool wait)
  2934. {
  2935. int rval = QLA_FUNCTION_FAILED;
  2936. struct ct_sns_req *ct_req;
  2937. srb_t *sp;
  2938. DECLARE_COMPLETION_ONSTACK(comp);
  2939. /* this routine does not have handling for no wait */
  2940. if (!vha->flags.online || !wait)
  2941. return rval;
  2942. /* ref: INIT */
  2943. sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
  2944. if (!sp)
  2945. return rval;
  2946. sp->type = SRB_CT_PTHRU_CMD;
  2947. sp->name = "gffid";
  2948. sp->gen1 = fcport->rscn_gen;
  2949. sp->gen2 = fcport->login_gen;
  2950. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  2951. qla24xx_async_gffid_sp_done);
  2952. sp->comp = &comp;
  2953. sp->u.iocb_cmd.timeout = qla2x00_els_dcmd2_iocb_timeout;
  2954. if (wait)
  2955. sp->flags = SRB_WAKEUP_ON_COMP;
  2956. sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
  2957. sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
  2958. sp->u.iocb_cmd.u.ctarg.req_allocated_size,
  2959. &sp->u.iocb_cmd.u.ctarg.req_dma,
  2960. GFP_KERNEL);
  2961. if (!sp->u.iocb_cmd.u.ctarg.req) {
  2962. ql_log(ql_log_warn, vha, 0xd041,
  2963. "%s: Failed to allocate ct_sns request.\n",
  2964. __func__);
  2965. goto done_free_sp;
  2966. }
  2967. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
  2968. sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
  2969. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
  2970. &sp->u.iocb_cmd.u.ctarg.rsp_dma,
  2971. GFP_KERNEL);
  2972. if (!sp->u.iocb_cmd.u.ctarg.rsp) {
  2973. ql_log(ql_log_warn, vha, 0xd041,
  2974. "%s: Failed to allocate ct_sns response.\n",
  2975. __func__);
  2976. goto done_free_sp;
  2977. }
  2978. /* CT_IU preamble */
  2979. ct_req = qla2x00_prep_ct_req(sp->u.iocb_cmd.u.ctarg.req, GFF_ID_CMD, GFF_ID_RSP_SIZE);
  2980. ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
  2981. ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
  2982. ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
  2983. sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE;
  2984. sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
  2985. sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
  2986. rval = qla2x00_start_sp(sp);
  2987. if (rval != QLA_SUCCESS) {
  2988. rval = QLA_FUNCTION_FAILED;
  2989. goto done_free_sp;
  2990. } else {
  2991. ql_dbg(ql_dbg_disc, vha, 0x3074,
  2992. "Async-%s hdl=%x portid %06x\n",
  2993. sp->name, sp->handle, fcport->d_id.b24);
  2994. }
  2995. wait_for_completion(sp->comp);
  2996. rval = sp->rc;
  2997. done_free_sp:
  2998. if (sp->u.iocb_cmd.u.ctarg.req) {
  2999. dma_free_coherent(&vha->hw->pdev->dev,
  3000. sp->u.iocb_cmd.u.ctarg.req_allocated_size,
  3001. sp->u.iocb_cmd.u.ctarg.req,
  3002. sp->u.iocb_cmd.u.ctarg.req_dma);
  3003. sp->u.iocb_cmd.u.ctarg.req = NULL;
  3004. }
  3005. if (sp->u.iocb_cmd.u.ctarg.rsp) {
  3006. dma_free_coherent(&vha->hw->pdev->dev,
  3007. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
  3008. sp->u.iocb_cmd.u.ctarg.rsp,
  3009. sp->u.iocb_cmd.u.ctarg.rsp_dma);
  3010. sp->u.iocb_cmd.u.ctarg.rsp = NULL;
  3011. }
  3012. /* ref: INIT */
  3013. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  3014. return rval;
  3015. }
  3016. /* GPN_FT + GNN_FT*/
  3017. static int qla2x00_is_a_vp(scsi_qla_host_t *vha, u64 wwn)
  3018. {
  3019. struct qla_hw_data *ha = vha->hw;
  3020. scsi_qla_host_t *vp;
  3021. unsigned long flags;
  3022. u64 twwn;
  3023. int rc = 0;
  3024. if (!ha->num_vhosts)
  3025. return 0;
  3026. spin_lock_irqsave(&ha->vport_slock, flags);
  3027. list_for_each_entry(vp, &ha->vp_list, list) {
  3028. twwn = wwn_to_u64(vp->port_name);
  3029. if (wwn == twwn) {
  3030. rc = 1;
  3031. break;
  3032. }
  3033. }
  3034. spin_unlock_irqrestore(&ha->vport_slock, flags);
  3035. return rc;
  3036. }
  3037. void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
  3038. {
  3039. fc_port_t *fcport;
  3040. u32 i, rc;
  3041. bool found;
  3042. struct fab_scan_rp *rp, *trp;
  3043. unsigned long flags;
  3044. u8 recheck = 0;
  3045. u16 dup = 0, dup_cnt = 0;
  3046. ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
  3047. "%s enter\n", __func__);
  3048. if (sp->gen1 != vha->hw->base_qpair->chip_reset) {
  3049. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3050. "%s scan stop due to chip reset %x/%x\n",
  3051. sp->name, sp->gen1, vha->hw->base_qpair->chip_reset);
  3052. goto out;
  3053. }
  3054. rc = sp->rc;
  3055. if (rc) {
  3056. vha->scan.scan_retry++;
  3057. if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
  3058. set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
  3059. set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  3060. goto out;
  3061. } else {
  3062. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3063. "%s: Fabric scan failed for %d retries.\n",
  3064. __func__, vha->scan.scan_retry);
  3065. /*
  3066. * Unable to scan any rports. logout loop below
  3067. * will unregister all sessions.
  3068. */
  3069. list_for_each_entry(fcport, &vha->vp_fcports, list) {
  3070. if ((fcport->flags & FCF_FABRIC_DEVICE) != 0) {
  3071. fcport->scan_state = QLA_FCPORT_SCAN;
  3072. if (fcport->loop_id == FC_NO_LOOP_ID)
  3073. fcport->logout_on_delete = 0;
  3074. else
  3075. fcport->logout_on_delete = 1;
  3076. }
  3077. }
  3078. goto login_logout;
  3079. }
  3080. }
  3081. vha->scan.scan_retry = 0;
  3082. list_for_each_entry(fcport, &vha->vp_fcports, list)
  3083. fcport->scan_state = QLA_FCPORT_SCAN;
  3084. for (i = 0; i < vha->hw->max_fibre_devices; i++) {
  3085. u64 wwn;
  3086. int k;
  3087. rp = &vha->scan.l[i];
  3088. found = false;
  3089. wwn = wwn_to_u64(rp->port_name);
  3090. if (wwn == 0)
  3091. continue;
  3092. /* Remove duplicate NPORT ID entries from switch data base */
  3093. for (k = i + 1; k < vha->hw->max_fibre_devices; k++) {
  3094. trp = &vha->scan.l[k];
  3095. if (rp->id.b24 == trp->id.b24) {
  3096. dup = 1;
  3097. dup_cnt++;
  3098. ql_dbg(ql_dbg_disc + ql_dbg_verbose,
  3099. vha, 0xffff,
  3100. "Detected duplicate NPORT ID from switch data base: ID %06x WWN %8phN WWN %8phN\n",
  3101. rp->id.b24, rp->port_name, trp->port_name);
  3102. memset(trp, 0, sizeof(*trp));
  3103. }
  3104. }
  3105. if (!memcmp(rp->port_name, vha->port_name, WWN_SIZE))
  3106. continue;
  3107. /* Bypass reserved domain fields. */
  3108. if ((rp->id.b.domain & 0xf0) == 0xf0)
  3109. continue;
  3110. /* Bypass virtual ports of the same host. */
  3111. if (qla2x00_is_a_vp(vha, wwn))
  3112. continue;
  3113. list_for_each_entry(fcport, &vha->vp_fcports, list) {
  3114. if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE))
  3115. continue;
  3116. fcport->scan_state = QLA_FCPORT_FOUND;
  3117. fcport->last_rscn_gen = fcport->rscn_gen;
  3118. fcport->fc4_type = rp->fc4type;
  3119. found = true;
  3120. if (fcport->scan_needed) {
  3121. if (NVME_PRIORITY(vha->hw, fcport))
  3122. fcport->do_prli_nvme = 1;
  3123. else
  3124. fcport->do_prli_nvme = 0;
  3125. }
  3126. /*
  3127. * If device was not a fabric device before.
  3128. */
  3129. if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
  3130. qla2x00_clear_loop_id(fcport);
  3131. fcport->flags |= FCF_FABRIC_DEVICE;
  3132. } else if (fcport->d_id.b24 != rp->id.b24 ||
  3133. (fcport->scan_needed &&
  3134. fcport->port_type != FCT_INITIATOR &&
  3135. fcport->port_type != FCT_NVME_INITIATOR)) {
  3136. qlt_schedule_sess_for_deletion(fcport);
  3137. }
  3138. fcport->d_id.b24 = rp->id.b24;
  3139. fcport->scan_needed = 0;
  3140. break;
  3141. }
  3142. if (!found) {
  3143. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3144. "%s %d %8phC post new sess\n",
  3145. __func__, __LINE__, rp->port_name);
  3146. qla24xx_post_newsess_work(vha, &rp->id, rp->port_name,
  3147. rp->node_name, NULL, rp->fc4type);
  3148. }
  3149. }
  3150. if (dup) {
  3151. ql_log(ql_log_warn, vha, 0xffff,
  3152. "Detected %d duplicate NPORT ID(s) from switch data base\n",
  3153. dup_cnt);
  3154. }
  3155. login_logout:
  3156. /*
  3157. * Logout all previous fabric dev marked lost, except FCP2 devices.
  3158. */
  3159. list_for_each_entry(fcport, &vha->vp_fcports, list) {
  3160. if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
  3161. fcport->scan_needed = 0;
  3162. continue;
  3163. }
  3164. if (fcport->scan_state != QLA_FCPORT_FOUND) {
  3165. bool do_delete = false;
  3166. if (fcport->scan_needed &&
  3167. fcport->disc_state == DSC_LOGIN_PEND) {
  3168. /* Cable got disconnected after we sent
  3169. * a login. Do delete to prevent timeout.
  3170. */
  3171. fcport->logout_on_delete = 1;
  3172. do_delete = true;
  3173. }
  3174. fcport->scan_needed = 0;
  3175. if (((qla_dual_mode_enabled(vha) ||
  3176. qla_ini_mode_enabled(vha)) &&
  3177. atomic_read(&fcport->state) == FCS_ONLINE) ||
  3178. do_delete) {
  3179. if (fcport->loop_id != FC_NO_LOOP_ID) {
  3180. if (fcport->flags & FCF_FCP2_DEVICE)
  3181. continue;
  3182. ql_log(ql_log_warn, vha, 0x20f0,
  3183. "%s %d %8phC post del sess\n",
  3184. __func__, __LINE__,
  3185. fcport->port_name);
  3186. fcport->tgt_link_down_time = 0;
  3187. qlt_schedule_sess_for_deletion(fcport);
  3188. continue;
  3189. }
  3190. }
  3191. } else {
  3192. if (fcport->scan_needed ||
  3193. fcport->disc_state != DSC_LOGIN_COMPLETE) {
  3194. if (fcport->login_retry == 0) {
  3195. fcport->login_retry =
  3196. vha->hw->login_retry_count;
  3197. ql_dbg(ql_dbg_disc, vha, 0x20a3,
  3198. "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n",
  3199. fcport->port_name, fcport->loop_id,
  3200. fcport->login_retry);
  3201. }
  3202. fcport->scan_needed = 0;
  3203. qla24xx_fcport_handle_login(vha, fcport);
  3204. }
  3205. }
  3206. }
  3207. recheck = 1;
  3208. out:
  3209. qla24xx_sp_unmap(vha, sp);
  3210. spin_lock_irqsave(&vha->work_lock, flags);
  3211. vha->scan.scan_flags &= ~SF_SCANNING;
  3212. spin_unlock_irqrestore(&vha->work_lock, flags);
  3213. if (recheck) {
  3214. list_for_each_entry(fcport, &vha->vp_fcports, list) {
  3215. if (fcport->scan_needed) {
  3216. set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
  3217. set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  3218. break;
  3219. }
  3220. }
  3221. }
  3222. }
  3223. static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha,
  3224. srb_t *sp, int cmd)
  3225. {
  3226. struct qla_work_evt *e;
  3227. if (cmd != QLA_EVT_GPNFT_DONE && cmd != QLA_EVT_GNNFT_DONE)
  3228. return QLA_PARAMETER_ERROR;
  3229. e = qla2x00_alloc_work(vha, cmd);
  3230. if (!e)
  3231. return QLA_FUNCTION_FAILED;
  3232. e->u.iosb.sp = sp;
  3233. return qla2x00_post_work(vha, e);
  3234. }
  3235. static int qla2x00_post_nvme_gpnft_work(struct scsi_qla_host *vha,
  3236. srb_t *sp, int cmd)
  3237. {
  3238. struct qla_work_evt *e;
  3239. if (cmd != QLA_EVT_GPNFT)
  3240. return QLA_PARAMETER_ERROR;
  3241. e = qla2x00_alloc_work(vha, cmd);
  3242. if (!e)
  3243. return QLA_FUNCTION_FAILED;
  3244. e->u.gpnft.fc4_type = FC4_TYPE_NVME;
  3245. e->u.gpnft.sp = sp;
  3246. return qla2x00_post_work(vha, e);
  3247. }
  3248. static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
  3249. struct srb *sp)
  3250. {
  3251. struct qla_hw_data *ha = vha->hw;
  3252. int num_fibre_dev = ha->max_fibre_devices;
  3253. struct ct_sns_req *ct_req =
  3254. (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
  3255. struct ct_sns_gpnft_rsp *ct_rsp =
  3256. (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
  3257. struct ct_sns_gpn_ft_data *d;
  3258. struct fab_scan_rp *rp;
  3259. u16 cmd = be16_to_cpu(ct_req->command);
  3260. u8 fc4_type = sp->gen2;
  3261. int i, j, k;
  3262. port_id_t id;
  3263. u8 found;
  3264. u64 wwn;
  3265. j = 0;
  3266. for (i = 0; i < num_fibre_dev; i++) {
  3267. d = &ct_rsp->entries[i];
  3268. id.b.rsvd_1 = 0;
  3269. id.b.domain = d->port_id[0];
  3270. id.b.area = d->port_id[1];
  3271. id.b.al_pa = d->port_id[2];
  3272. wwn = wwn_to_u64(d->port_name);
  3273. if (id.b24 == 0 || wwn == 0)
  3274. continue;
  3275. if (fc4_type == FC4_TYPE_FCP_SCSI) {
  3276. if (cmd == GPN_FT_CMD) {
  3277. rp = &vha->scan.l[j];
  3278. rp->id = id;
  3279. memcpy(rp->port_name, d->port_name, 8);
  3280. j++;
  3281. rp->fc4type = FS_FC4TYPE_FCP;
  3282. } else {
  3283. for (k = 0; k < num_fibre_dev; k++) {
  3284. rp = &vha->scan.l[k];
  3285. if (id.b24 == rp->id.b24) {
  3286. memcpy(rp->node_name,
  3287. d->port_name, 8);
  3288. break;
  3289. }
  3290. }
  3291. }
  3292. } else {
  3293. /* Search if the fibre device supports FC4_TYPE_NVME */
  3294. if (cmd == GPN_FT_CMD) {
  3295. found = 0;
  3296. for (k = 0; k < num_fibre_dev; k++) {
  3297. rp = &vha->scan.l[k];
  3298. if (!memcmp(rp->port_name,
  3299. d->port_name, 8)) {
  3300. /*
  3301. * Supports FC-NVMe & FCP
  3302. */
  3303. rp->fc4type |= FS_FC4TYPE_NVME;
  3304. found = 1;
  3305. break;
  3306. }
  3307. }
  3308. /* We found new FC-NVMe only port */
  3309. if (!found) {
  3310. for (k = 0; k < num_fibre_dev; k++) {
  3311. rp = &vha->scan.l[k];
  3312. if (wwn_to_u64(rp->port_name)) {
  3313. continue;
  3314. } else {
  3315. rp->id = id;
  3316. memcpy(rp->port_name,
  3317. d->port_name, 8);
  3318. rp->fc4type =
  3319. FS_FC4TYPE_NVME;
  3320. break;
  3321. }
  3322. }
  3323. }
  3324. } else {
  3325. for (k = 0; k < num_fibre_dev; k++) {
  3326. rp = &vha->scan.l[k];
  3327. if (id.b24 == rp->id.b24) {
  3328. memcpy(rp->node_name,
  3329. d->port_name, 8);
  3330. break;
  3331. }
  3332. }
  3333. }
  3334. }
  3335. }
  3336. }
  3337. static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res)
  3338. {
  3339. struct scsi_qla_host *vha = sp->vha;
  3340. struct ct_sns_req *ct_req =
  3341. (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
  3342. u16 cmd = be16_to_cpu(ct_req->command);
  3343. u8 fc4_type = sp->gen2;
  3344. unsigned long flags;
  3345. int rc;
  3346. /* gen2 field is holding the fc4type */
  3347. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3348. "Async done-%s res %x FC4Type %x\n",
  3349. sp->name, res, sp->gen2);
  3350. sp->rc = res;
  3351. if (res) {
  3352. unsigned long flags;
  3353. const char *name = sp->name;
  3354. if (res == QLA_OS_TIMER_EXPIRED) {
  3355. /* switch is ignoring all commands.
  3356. * This might be a zone disable behavior.
  3357. * This means we hit 64s timeout.
  3358. * 22s GPNFT + 44s Abort = 64s
  3359. */
  3360. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3361. "%s: Switch Zone check please .\n",
  3362. name);
  3363. qla2x00_mark_all_devices_lost(vha);
  3364. }
  3365. /*
  3366. * We are in an Interrupt context, queue up this
  3367. * sp for GNNFT_DONE work. This will allow all
  3368. * the resource to get freed up.
  3369. */
  3370. rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
  3371. QLA_EVT_GNNFT_DONE);
  3372. if (rc) {
  3373. /* Cleanup here to prevent memory leak */
  3374. qla24xx_sp_unmap(vha, sp);
  3375. spin_lock_irqsave(&vha->work_lock, flags);
  3376. vha->scan.scan_flags &= ~SF_SCANNING;
  3377. vha->scan.scan_retry++;
  3378. spin_unlock_irqrestore(&vha->work_lock, flags);
  3379. if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
  3380. set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
  3381. set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  3382. qla2xxx_wake_dpc(vha);
  3383. } else {
  3384. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3385. "Async done-%s rescan failed on all retries.\n",
  3386. name);
  3387. }
  3388. }
  3389. return;
  3390. }
  3391. qla2x00_find_free_fcp_nvme_slot(vha, sp);
  3392. if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled &&
  3393. cmd == GNN_FT_CMD) {
  3394. spin_lock_irqsave(&vha->work_lock, flags);
  3395. vha->scan.scan_flags &= ~SF_SCANNING;
  3396. spin_unlock_irqrestore(&vha->work_lock, flags);
  3397. sp->rc = res;
  3398. rc = qla2x00_post_nvme_gpnft_work(vha, sp, QLA_EVT_GPNFT);
  3399. if (rc) {
  3400. qla24xx_sp_unmap(vha, sp);
  3401. set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
  3402. set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  3403. }
  3404. return;
  3405. }
  3406. if (cmd == GPN_FT_CMD) {
  3407. rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
  3408. QLA_EVT_GPNFT_DONE);
  3409. } else {
  3410. rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
  3411. QLA_EVT_GNNFT_DONE);
  3412. }
  3413. if (rc) {
  3414. qla24xx_sp_unmap(vha, sp);
  3415. set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
  3416. set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  3417. return;
  3418. }
  3419. }
  3420. /*
  3421. * Get WWNN list for fc4_type
  3422. *
  3423. * It is assumed the same SRB is re-used from GPNFT to avoid
  3424. * mem free & re-alloc
  3425. */
  3426. static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
  3427. u8 fc4_type)
  3428. {
  3429. int rval = QLA_FUNCTION_FAILED;
  3430. struct ct_sns_req *ct_req;
  3431. struct ct_sns_pkt *ct_sns;
  3432. unsigned long flags;
  3433. if (!vha->flags.online) {
  3434. spin_lock_irqsave(&vha->work_lock, flags);
  3435. vha->scan.scan_flags &= ~SF_SCANNING;
  3436. spin_unlock_irqrestore(&vha->work_lock, flags);
  3437. goto done_free_sp;
  3438. }
  3439. if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) {
  3440. ql_log(ql_log_warn, vha, 0xffff,
  3441. "%s: req %p rsp %p are not setup\n",
  3442. __func__, sp->u.iocb_cmd.u.ctarg.req,
  3443. sp->u.iocb_cmd.u.ctarg.rsp);
  3444. spin_lock_irqsave(&vha->work_lock, flags);
  3445. vha->scan.scan_flags &= ~SF_SCANNING;
  3446. spin_unlock_irqrestore(&vha->work_lock, flags);
  3447. WARN_ON(1);
  3448. set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
  3449. set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  3450. goto done_free_sp;
  3451. }
  3452. ql_dbg(ql_dbg_disc, vha, 0xfffff,
  3453. "%s: FC4Type %x, CT-PASSTHRU %s command ctarg rsp size %d, ctarg req size %d\n",
  3454. __func__, fc4_type, sp->name, sp->u.iocb_cmd.u.ctarg.rsp_size,
  3455. sp->u.iocb_cmd.u.ctarg.req_size);
  3456. sp->type = SRB_CT_PTHRU_CMD;
  3457. sp->name = "gnnft";
  3458. sp->gen1 = vha->hw->base_qpair->chip_reset;
  3459. sp->gen2 = fc4_type;
  3460. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  3461. qla2x00_async_gpnft_gnnft_sp_done);
  3462. memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
  3463. memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
  3464. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
  3465. /* CT_IU preamble */
  3466. ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD,
  3467. sp->u.iocb_cmd.u.ctarg.rsp_size);
  3468. /* GPN_FT req */
  3469. ct_req->req.gpn_ft.port_type = fc4_type;
  3470. sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE;
  3471. sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
  3472. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3473. "Async-%s hdl=%x FC4Type %x.\n", sp->name,
  3474. sp->handle, ct_req->req.gpn_ft.port_type);
  3475. rval = qla2x00_start_sp(sp);
  3476. if (rval != QLA_SUCCESS) {
  3477. goto done_free_sp;
  3478. }
  3479. return rval;
  3480. done_free_sp:
  3481. if (sp->u.iocb_cmd.u.ctarg.req) {
  3482. dma_free_coherent(&vha->hw->pdev->dev,
  3483. sp->u.iocb_cmd.u.ctarg.req_allocated_size,
  3484. sp->u.iocb_cmd.u.ctarg.req,
  3485. sp->u.iocb_cmd.u.ctarg.req_dma);
  3486. sp->u.iocb_cmd.u.ctarg.req = NULL;
  3487. }
  3488. if (sp->u.iocb_cmd.u.ctarg.rsp) {
  3489. dma_free_coherent(&vha->hw->pdev->dev,
  3490. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
  3491. sp->u.iocb_cmd.u.ctarg.rsp,
  3492. sp->u.iocb_cmd.u.ctarg.rsp_dma);
  3493. sp->u.iocb_cmd.u.ctarg.rsp = NULL;
  3494. }
  3495. /* ref: INIT */
  3496. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  3497. spin_lock_irqsave(&vha->work_lock, flags);
  3498. vha->scan.scan_flags &= ~SF_SCANNING;
  3499. if (vha->scan.scan_flags == 0) {
  3500. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3501. "%s: schedule\n", __func__);
  3502. vha->scan.scan_flags |= SF_QUEUED;
  3503. schedule_delayed_work(&vha->scan.scan_work, 5);
  3504. }
  3505. spin_unlock_irqrestore(&vha->work_lock, flags);
  3506. return rval;
  3507. } /* GNNFT */
  3508. void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp)
  3509. {
  3510. ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
  3511. "%s enter\n", __func__);
  3512. qla24xx_async_gnnft(vha, sp, sp->gen2);
  3513. }
  3514. /* Get WWPN list for certain fc4_type */
  3515. int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
  3516. {
  3517. int rval = QLA_FUNCTION_FAILED;
  3518. struct ct_sns_req *ct_req;
  3519. struct ct_sns_pkt *ct_sns;
  3520. u32 rspsz;
  3521. unsigned long flags;
  3522. ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
  3523. "%s enter\n", __func__);
  3524. if (!vha->flags.online)
  3525. return rval;
  3526. spin_lock_irqsave(&vha->work_lock, flags);
  3527. if (vha->scan.scan_flags & SF_SCANNING) {
  3528. spin_unlock_irqrestore(&vha->work_lock, flags);
  3529. ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
  3530. "%s: scan active\n", __func__);
  3531. return rval;
  3532. }
  3533. vha->scan.scan_flags |= SF_SCANNING;
  3534. spin_unlock_irqrestore(&vha->work_lock, flags);
  3535. if (fc4_type == FC4_TYPE_FCP_SCSI) {
  3536. ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
  3537. "%s: Performing FCP Scan\n", __func__);
  3538. if (sp) {
  3539. /* ref: INIT */
  3540. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  3541. }
  3542. /* ref: INIT */
  3543. sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
  3544. if (!sp) {
  3545. spin_lock_irqsave(&vha->work_lock, flags);
  3546. vha->scan.scan_flags &= ~SF_SCANNING;
  3547. spin_unlock_irqrestore(&vha->work_lock, flags);
  3548. return rval;
  3549. }
  3550. sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
  3551. sizeof(struct ct_sns_pkt),
  3552. &sp->u.iocb_cmd.u.ctarg.req_dma,
  3553. GFP_KERNEL);
  3554. sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
  3555. if (!sp->u.iocb_cmd.u.ctarg.req) {
  3556. ql_log(ql_log_warn, vha, 0xffff,
  3557. "Failed to allocate ct_sns request.\n");
  3558. spin_lock_irqsave(&vha->work_lock, flags);
  3559. vha->scan.scan_flags &= ~SF_SCANNING;
  3560. spin_unlock_irqrestore(&vha->work_lock, flags);
  3561. qla2x00_rel_sp(sp);
  3562. return rval;
  3563. }
  3564. sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
  3565. rspsz = sizeof(struct ct_sns_gpnft_rsp) +
  3566. ((vha->hw->max_fibre_devices - 1) *
  3567. sizeof(struct ct_sns_gpn_ft_data));
  3568. sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
  3569. rspsz,
  3570. &sp->u.iocb_cmd.u.ctarg.rsp_dma,
  3571. GFP_KERNEL);
  3572. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz;
  3573. if (!sp->u.iocb_cmd.u.ctarg.rsp) {
  3574. ql_log(ql_log_warn, vha, 0xffff,
  3575. "Failed to allocate ct_sns request.\n");
  3576. spin_lock_irqsave(&vha->work_lock, flags);
  3577. vha->scan.scan_flags &= ~SF_SCANNING;
  3578. spin_unlock_irqrestore(&vha->work_lock, flags);
  3579. dma_free_coherent(&vha->hw->pdev->dev,
  3580. sp->u.iocb_cmd.u.ctarg.req_allocated_size,
  3581. sp->u.iocb_cmd.u.ctarg.req,
  3582. sp->u.iocb_cmd.u.ctarg.req_dma);
  3583. sp->u.iocb_cmd.u.ctarg.req = NULL;
  3584. /* ref: INIT */
  3585. qla2x00_rel_sp(sp);
  3586. return rval;
  3587. }
  3588. sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz;
  3589. ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
  3590. "%s scan list size %d\n", __func__, vha->scan.size);
  3591. memset(vha->scan.l, 0, vha->scan.size);
  3592. } else if (!sp) {
  3593. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3594. "NVME scan did not provide SP\n");
  3595. return rval;
  3596. }
  3597. sp->type = SRB_CT_PTHRU_CMD;
  3598. sp->name = "gpnft";
  3599. sp->gen1 = vha->hw->base_qpair->chip_reset;
  3600. sp->gen2 = fc4_type;
  3601. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  3602. qla2x00_async_gpnft_gnnft_sp_done);
  3603. rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size;
  3604. memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
  3605. memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
  3606. ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
  3607. /* CT_IU preamble */
  3608. ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz);
  3609. /* GPN_FT req */
  3610. ct_req->req.gpn_ft.port_type = fc4_type;
  3611. sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
  3612. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3613. "Async-%s hdl=%x FC4Type %x.\n", sp->name,
  3614. sp->handle, ct_req->req.gpn_ft.port_type);
  3615. rval = qla2x00_start_sp(sp);
  3616. if (rval != QLA_SUCCESS) {
  3617. goto done_free_sp;
  3618. }
  3619. return rval;
  3620. done_free_sp:
  3621. if (sp->u.iocb_cmd.u.ctarg.req) {
  3622. dma_free_coherent(&vha->hw->pdev->dev,
  3623. sp->u.iocb_cmd.u.ctarg.req_allocated_size,
  3624. sp->u.iocb_cmd.u.ctarg.req,
  3625. sp->u.iocb_cmd.u.ctarg.req_dma);
  3626. sp->u.iocb_cmd.u.ctarg.req = NULL;
  3627. }
  3628. if (sp->u.iocb_cmd.u.ctarg.rsp) {
  3629. dma_free_coherent(&vha->hw->pdev->dev,
  3630. sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
  3631. sp->u.iocb_cmd.u.ctarg.rsp,
  3632. sp->u.iocb_cmd.u.ctarg.rsp_dma);
  3633. sp->u.iocb_cmd.u.ctarg.rsp = NULL;
  3634. }
  3635. /* ref: INIT */
  3636. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  3637. spin_lock_irqsave(&vha->work_lock, flags);
  3638. vha->scan.scan_flags &= ~SF_SCANNING;
  3639. if (vha->scan.scan_flags == 0) {
  3640. ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
  3641. "%s: Scan scheduled.\n", __func__);
  3642. vha->scan.scan_flags |= SF_QUEUED;
  3643. schedule_delayed_work(&vha->scan.scan_work, 5);
  3644. }
  3645. spin_unlock_irqrestore(&vha->work_lock, flags);
  3646. return rval;
  3647. }
  3648. void qla_scan_work_fn(struct work_struct *work)
  3649. {
  3650. struct fab_scan *s = container_of(to_delayed_work(work),
  3651. struct fab_scan, scan_work);
  3652. struct scsi_qla_host *vha = container_of(s, struct scsi_qla_host,
  3653. scan);
  3654. unsigned long flags;
  3655. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3656. "%s: schedule loop resync\n", __func__);
  3657. set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
  3658. set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  3659. qla2xxx_wake_dpc(vha);
  3660. spin_lock_irqsave(&vha->work_lock, flags);
  3661. vha->scan.scan_flags &= ~SF_QUEUED;
  3662. spin_unlock_irqrestore(&vha->work_lock, flags);
  3663. }
  3664. /* GNN_ID */
  3665. void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
  3666. {
  3667. qla24xx_post_gnl_work(vha, ea->fcport);
  3668. }
  3669. static void qla2x00_async_gnnid_sp_done(srb_t *sp, int res)
  3670. {
  3671. struct scsi_qla_host *vha = sp->vha;
  3672. fc_port_t *fcport = sp->fcport;
  3673. u8 *node_name = fcport->ct_desc.ct_sns->p.rsp.rsp.gnn_id.node_name;
  3674. struct event_arg ea;
  3675. u64 wwnn;
  3676. fcport->flags &= ~FCF_ASYNC_SENT;
  3677. wwnn = wwn_to_u64(node_name);
  3678. if (wwnn)
  3679. memcpy(fcport->node_name, node_name, WWN_SIZE);
  3680. memset(&ea, 0, sizeof(ea));
  3681. ea.fcport = fcport;
  3682. ea.sp = sp;
  3683. ea.rc = res;
  3684. ql_dbg(ql_dbg_disc, vha, 0x204f,
  3685. "Async done-%s res %x, WWPN %8phC %8phC\n",
  3686. sp->name, res, fcport->port_name, fcport->node_name);
  3687. qla24xx_handle_gnnid_event(vha, &ea);
  3688. /* ref: INIT */
  3689. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  3690. }
  3691. int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
  3692. {
  3693. int rval = QLA_FUNCTION_FAILED;
  3694. struct ct_sns_req *ct_req;
  3695. srb_t *sp;
  3696. if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
  3697. return rval;
  3698. qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID);
  3699. /* ref: INIT */
  3700. sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
  3701. if (!sp)
  3702. goto done;
  3703. fcport->flags |= FCF_ASYNC_SENT;
  3704. sp->type = SRB_CT_PTHRU_CMD;
  3705. sp->name = "gnnid";
  3706. sp->gen1 = fcport->rscn_gen;
  3707. sp->gen2 = fcport->login_gen;
  3708. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  3709. qla2x00_async_gnnid_sp_done);
  3710. /* CT_IU preamble */
  3711. ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GNN_ID_CMD,
  3712. GNN_ID_RSP_SIZE);
  3713. /* GNN_ID req */
  3714. ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
  3715. /* req & rsp use the same buffer */
  3716. sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
  3717. sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
  3718. sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
  3719. sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
  3720. sp->u.iocb_cmd.u.ctarg.req_size = GNN_ID_REQ_SIZE;
  3721. sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE;
  3722. sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
  3723. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3724. "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
  3725. sp->name, fcport->port_name,
  3726. sp->handle, fcport->loop_id, fcport->d_id.b24);
  3727. rval = qla2x00_start_sp(sp);
  3728. if (rval != QLA_SUCCESS)
  3729. goto done_free_sp;
  3730. return rval;
  3731. done_free_sp:
  3732. /* ref: INIT */
  3733. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  3734. fcport->flags &= ~FCF_ASYNC_SENT;
  3735. done:
  3736. return rval;
  3737. }
  3738. int qla24xx_post_gnnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
  3739. {
  3740. struct qla_work_evt *e;
  3741. int ls;
  3742. ls = atomic_read(&vha->loop_state);
  3743. if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
  3744. test_bit(UNLOADING, &vha->dpc_flags))
  3745. return 0;
  3746. e = qla2x00_alloc_work(vha, QLA_EVT_GNNID);
  3747. if (!e)
  3748. return QLA_FUNCTION_FAILED;
  3749. e->u.fcport.fcport = fcport;
  3750. return qla2x00_post_work(vha, e);
  3751. }
  3752. /* GPFN_ID */
  3753. void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
  3754. {
  3755. fc_port_t *fcport = ea->fcport;
  3756. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3757. "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d fcpcnt %d\n",
  3758. __func__, fcport->port_name, fcport->disc_state,
  3759. fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
  3760. fcport->rscn_gen, ea->sp->gen1, vha->fcport_count);
  3761. if (fcport->disc_state == DSC_DELETE_PEND)
  3762. return;
  3763. if (ea->sp->gen2 != fcport->login_gen) {
  3764. /* target side must have changed it. */
  3765. ql_dbg(ql_dbg_disc, vha, 0x20d3,
  3766. "%s %8phC generation changed\n",
  3767. __func__, fcport->port_name);
  3768. return;
  3769. } else if (ea->sp->gen1 != fcport->rscn_gen) {
  3770. return;
  3771. }
  3772. qla24xx_post_gpsc_work(vha, fcport);
  3773. }
  3774. static void qla2x00_async_gfpnid_sp_done(srb_t *sp, int res)
  3775. {
  3776. struct scsi_qla_host *vha = sp->vha;
  3777. fc_port_t *fcport = sp->fcport;
  3778. u8 *fpn = fcport->ct_desc.ct_sns->p.rsp.rsp.gfpn_id.port_name;
  3779. struct event_arg ea;
  3780. u64 wwn;
  3781. wwn = wwn_to_u64(fpn);
  3782. if (wwn)
  3783. memcpy(fcport->fabric_port_name, fpn, WWN_SIZE);
  3784. memset(&ea, 0, sizeof(ea));
  3785. ea.fcport = fcport;
  3786. ea.sp = sp;
  3787. ea.rc = res;
  3788. ql_dbg(ql_dbg_disc, vha, 0x204f,
  3789. "Async done-%s res %x, WWPN %8phC %8phC\n",
  3790. sp->name, res, fcport->port_name, fcport->fabric_port_name);
  3791. qla24xx_handle_gfpnid_event(vha, &ea);
  3792. /* ref: INIT */
  3793. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  3794. }
  3795. int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport)
  3796. {
  3797. int rval = QLA_FUNCTION_FAILED;
  3798. struct ct_sns_req *ct_req;
  3799. srb_t *sp;
  3800. if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
  3801. return rval;
  3802. /* ref: INIT */
  3803. sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
  3804. if (!sp)
  3805. goto done;
  3806. sp->type = SRB_CT_PTHRU_CMD;
  3807. sp->name = "gfpnid";
  3808. sp->gen1 = fcport->rscn_gen;
  3809. sp->gen2 = fcport->login_gen;
  3810. qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
  3811. qla2x00_async_gfpnid_sp_done);
  3812. /* CT_IU preamble */
  3813. ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFPN_ID_CMD,
  3814. GFPN_ID_RSP_SIZE);
  3815. /* GFPN_ID req */
  3816. ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
  3817. /* req & rsp use the same buffer */
  3818. sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
  3819. sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
  3820. sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
  3821. sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
  3822. sp->u.iocb_cmd.u.ctarg.req_size = GFPN_ID_REQ_SIZE;
  3823. sp->u.iocb_cmd.u.ctarg.rsp_size = GFPN_ID_RSP_SIZE;
  3824. sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
  3825. ql_dbg(ql_dbg_disc, vha, 0xffff,
  3826. "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
  3827. sp->name, fcport->port_name,
  3828. sp->handle, fcport->loop_id, fcport->d_id.b24);
  3829. rval = qla2x00_start_sp(sp);
  3830. if (rval != QLA_SUCCESS)
  3831. goto done_free_sp;
  3832. return rval;
  3833. done_free_sp:
  3834. /* ref: INIT */
  3835. kref_put(&sp->cmd_kref, qla2x00_sp_release);
  3836. done:
  3837. return rval;
  3838. }
  3839. int qla24xx_post_gfpnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
  3840. {
  3841. struct qla_work_evt *e;
  3842. int ls;
  3843. ls = atomic_read(&vha->loop_state);
  3844. if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
  3845. test_bit(UNLOADING, &vha->dpc_flags))
  3846. return 0;
  3847. e = qla2x00_alloc_work(vha, QLA_EVT_GFPNID);
  3848. if (!e)
  3849. return QLA_FUNCTION_FAILED;
  3850. e->u.fcport.fcport = fcport;
  3851. return qla2x00_post_work(vha, e);
  3852. }