bfad_bsg.c 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163
  1. /*
  2. * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
  3. * All rights reserved
  4. * www.brocade.com
  5. *
  6. * Linux driver for Brocade Fibre Channel Host Bus Adapter.
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License (GPL) Version 2 as
  10. * published by the Free Software Foundation
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. */
  17. #include <linux/uaccess.h>
  18. #include "bfad_drv.h"
  19. #include "bfad_im.h"
  20. #include "bfad_bsg.h"
  21. BFA_TRC_FILE(LDRV, BSG);
  22. int
  23. bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd)
  24. {
  25. struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
  26. int rc = 0;
  27. unsigned long flags;
  28. spin_lock_irqsave(&bfad->bfad_lock, flags);
  29. /* If IOC is not in disabled state - return */
  30. if (!bfa_ioc_is_disabled(&bfad->bfa.ioc)) {
  31. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  32. iocmd->status = BFA_STATUS_IOC_FAILURE;
  33. return rc;
  34. }
  35. init_completion(&bfad->enable_comp);
  36. bfa_iocfc_enable(&bfad->bfa);
  37. iocmd->status = BFA_STATUS_OK;
  38. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  39. wait_for_completion(&bfad->enable_comp);
  40. return rc;
  41. }
  42. int
  43. bfad_iocmd_ioc_disable(struct bfad_s *bfad, void *cmd)
  44. {
  45. struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
  46. int rc = 0;
  47. unsigned long flags;
  48. spin_lock_irqsave(&bfad->bfad_lock, flags);
  49. if (bfad->disable_active) {
  50. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  51. return EBUSY;
  52. }
  53. bfad->disable_active = BFA_TRUE;
  54. init_completion(&bfad->disable_comp);
  55. bfa_iocfc_disable(&bfad->bfa);
  56. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  57. wait_for_completion(&bfad->disable_comp);
  58. bfad->disable_active = BFA_FALSE;
  59. iocmd->status = BFA_STATUS_OK;
  60. return rc;
  61. }
  62. static int
  63. bfad_iocmd_ioc_get_info(struct bfad_s *bfad, void *cmd)
  64. {
  65. int i;
  66. struct bfa_bsg_ioc_info_s *iocmd = (struct bfa_bsg_ioc_info_s *)cmd;
  67. struct bfad_im_port_s *im_port;
  68. struct bfa_port_attr_s pattr;
  69. unsigned long flags;
  70. spin_lock_irqsave(&bfad->bfad_lock, flags);
  71. bfa_fcport_get_attr(&bfad->bfa, &pattr);
  72. iocmd->nwwn = pattr.nwwn;
  73. iocmd->pwwn = pattr.pwwn;
  74. iocmd->ioc_type = bfa_get_type(&bfad->bfa);
  75. iocmd->mac = bfa_get_mac(&bfad->bfa);
  76. iocmd->factory_mac = bfa_get_mfg_mac(&bfad->bfa);
  77. bfa_get_adapter_serial_num(&bfad->bfa, iocmd->serialnum);
  78. iocmd->factorynwwn = pattr.factorynwwn;
  79. iocmd->factorypwwn = pattr.factorypwwn;
  80. im_port = bfad->pport.im_port;
  81. iocmd->host = im_port->shost->host_no;
  82. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  83. strcpy(iocmd->name, bfad->adapter_name);
  84. strcpy(iocmd->port_name, bfad->port_name);
  85. strcpy(iocmd->hwpath, bfad->pci_name);
  86. /* set adapter hw path */
  87. strcpy(iocmd->adapter_hwpath, bfad->pci_name);
  88. i = strlen(iocmd->adapter_hwpath) - 1;
  89. while (iocmd->adapter_hwpath[i] != '.')
  90. i--;
  91. iocmd->adapter_hwpath[i] = '\0';
  92. iocmd->status = BFA_STATUS_OK;
  93. return 0;
  94. }
  95. static int
  96. bfad_iocmd_ioc_get_attr(struct bfad_s *bfad, void *cmd)
  97. {
  98. struct bfa_bsg_ioc_attr_s *iocmd = (struct bfa_bsg_ioc_attr_s *)cmd;
  99. unsigned long flags;
  100. spin_lock_irqsave(&bfad->bfad_lock, flags);
  101. bfa_ioc_get_attr(&bfad->bfa.ioc, &iocmd->ioc_attr);
  102. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  103. /* fill in driver attr info */
  104. strcpy(iocmd->ioc_attr.driver_attr.driver, BFAD_DRIVER_NAME);
  105. strncpy(iocmd->ioc_attr.driver_attr.driver_ver,
  106. BFAD_DRIVER_VERSION, BFA_VERSION_LEN);
  107. strcpy(iocmd->ioc_attr.driver_attr.fw_ver,
  108. iocmd->ioc_attr.adapter_attr.fw_ver);
  109. strcpy(iocmd->ioc_attr.driver_attr.bios_ver,
  110. iocmd->ioc_attr.adapter_attr.optrom_ver);
  111. /* copy chip rev info first otherwise it will be overwritten */
  112. memcpy(bfad->pci_attr.chip_rev, iocmd->ioc_attr.pci_attr.chip_rev,
  113. sizeof(bfad->pci_attr.chip_rev));
  114. memcpy(&iocmd->ioc_attr.pci_attr, &bfad->pci_attr,
  115. sizeof(struct bfa_ioc_pci_attr_s));
  116. iocmd->status = BFA_STATUS_OK;
  117. return 0;
  118. }
  119. int
  120. bfad_iocmd_ioc_get_stats(struct bfad_s *bfad, void *cmd)
  121. {
  122. struct bfa_bsg_ioc_stats_s *iocmd = (struct bfa_bsg_ioc_stats_s *)cmd;
  123. bfa_ioc_get_stats(&bfad->bfa, &iocmd->ioc_stats);
  124. iocmd->status = BFA_STATUS_OK;
  125. return 0;
  126. }
  127. int
  128. bfad_iocmd_ioc_get_fwstats(struct bfad_s *bfad, void *cmd,
  129. unsigned int payload_len)
  130. {
  131. struct bfa_bsg_ioc_fwstats_s *iocmd =
  132. (struct bfa_bsg_ioc_fwstats_s *)cmd;
  133. void *iocmd_bufptr;
  134. unsigned long flags;
  135. if (bfad_chk_iocmd_sz(payload_len,
  136. sizeof(struct bfa_bsg_ioc_fwstats_s),
  137. sizeof(struct bfa_fw_stats_s)) != BFA_STATUS_OK) {
  138. iocmd->status = BFA_STATUS_VERSION_FAIL;
  139. goto out;
  140. }
  141. iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_ioc_fwstats_s);
  142. spin_lock_irqsave(&bfad->bfad_lock, flags);
  143. iocmd->status = bfa_ioc_fw_stats_get(&bfad->bfa.ioc, iocmd_bufptr);
  144. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  145. if (iocmd->status != BFA_STATUS_OK) {
  146. bfa_trc(bfad, iocmd->status);
  147. goto out;
  148. }
  149. out:
  150. bfa_trc(bfad, 0x6666);
  151. return 0;
  152. }
  153. int
  154. bfad_iocmd_iocfc_get_attr(struct bfad_s *bfad, void *cmd)
  155. {
  156. struct bfa_bsg_iocfc_attr_s *iocmd = (struct bfa_bsg_iocfc_attr_s *)cmd;
  157. iocmd->status = BFA_STATUS_OK;
  158. bfa_iocfc_get_attr(&bfad->bfa, &iocmd->iocfc_attr);
  159. return 0;
  160. }
  161. int
  162. bfad_iocmd_iocfc_set_intr(struct bfad_s *bfad, void *cmd)
  163. {
  164. struct bfa_bsg_iocfc_intr_s *iocmd = (struct bfa_bsg_iocfc_intr_s *)cmd;
  165. unsigned long flags;
  166. spin_lock_irqsave(&bfad->bfad_lock, flags);
  167. iocmd->status = bfa_iocfc_israttr_set(&bfad->bfa, &iocmd->attr);
  168. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  169. return 0;
  170. }
  171. int
  172. bfad_iocmd_port_enable(struct bfad_s *bfad, void *cmd)
  173. {
  174. struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
  175. struct bfad_hal_comp fcomp;
  176. unsigned long flags;
  177. init_completion(&fcomp.comp);
  178. spin_lock_irqsave(&bfad->bfad_lock, flags);
  179. iocmd->status = bfa_port_enable(&bfad->bfa.modules.port,
  180. bfad_hcb_comp, &fcomp);
  181. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  182. if (iocmd->status != BFA_STATUS_OK) {
  183. bfa_trc(bfad, iocmd->status);
  184. return 0;
  185. }
  186. wait_for_completion(&fcomp.comp);
  187. iocmd->status = fcomp.status;
  188. return 0;
  189. }
  190. int
  191. bfad_iocmd_port_disable(struct bfad_s *bfad, void *cmd)
  192. {
  193. struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
  194. struct bfad_hal_comp fcomp;
  195. unsigned long flags;
  196. init_completion(&fcomp.comp);
  197. spin_lock_irqsave(&bfad->bfad_lock, flags);
  198. iocmd->status = bfa_port_disable(&bfad->bfa.modules.port,
  199. bfad_hcb_comp, &fcomp);
  200. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  201. if (iocmd->status != BFA_STATUS_OK) {
  202. bfa_trc(bfad, iocmd->status);
  203. return 0;
  204. }
  205. wait_for_completion(&fcomp.comp);
  206. iocmd->status = fcomp.status;
  207. return 0;
  208. }
  209. static int
  210. bfad_iocmd_port_get_attr(struct bfad_s *bfad, void *cmd)
  211. {
  212. struct bfa_bsg_port_attr_s *iocmd = (struct bfa_bsg_port_attr_s *)cmd;
  213. struct bfa_lport_attr_s port_attr;
  214. unsigned long flags;
  215. spin_lock_irqsave(&bfad->bfad_lock, flags);
  216. bfa_fcport_get_attr(&bfad->bfa, &iocmd->attr);
  217. bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
  218. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  219. if (iocmd->attr.topology != BFA_PORT_TOPOLOGY_NONE)
  220. iocmd->attr.pid = port_attr.pid;
  221. else
  222. iocmd->attr.pid = 0;
  223. iocmd->attr.port_type = port_attr.port_type;
  224. iocmd->attr.loopback = port_attr.loopback;
  225. iocmd->attr.authfail = port_attr.authfail;
  226. strncpy(iocmd->attr.port_symname.symname,
  227. port_attr.port_cfg.sym_name.symname,
  228. sizeof(port_attr.port_cfg.sym_name.symname));
  229. iocmd->status = BFA_STATUS_OK;
  230. return 0;
  231. }
  232. int
  233. bfad_iocmd_port_get_stats(struct bfad_s *bfad, void *cmd,
  234. unsigned int payload_len)
  235. {
  236. struct bfa_bsg_port_stats_s *iocmd = (struct bfa_bsg_port_stats_s *)cmd;
  237. struct bfad_hal_comp fcomp;
  238. void *iocmd_bufptr;
  239. unsigned long flags;
  240. if (bfad_chk_iocmd_sz(payload_len,
  241. sizeof(struct bfa_bsg_port_stats_s),
  242. sizeof(union bfa_port_stats_u)) != BFA_STATUS_OK) {
  243. iocmd->status = BFA_STATUS_VERSION_FAIL;
  244. return 0;
  245. }
  246. iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_port_stats_s);
  247. init_completion(&fcomp.comp);
  248. spin_lock_irqsave(&bfad->bfad_lock, flags);
  249. iocmd->status = bfa_port_get_stats(&bfad->bfa.modules.port,
  250. iocmd_bufptr, bfad_hcb_comp, &fcomp);
  251. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  252. if (iocmd->status != BFA_STATUS_OK) {
  253. bfa_trc(bfad, iocmd->status);
  254. goto out;
  255. }
  256. wait_for_completion(&fcomp.comp);
  257. iocmd->status = fcomp.status;
  258. out:
  259. return 0;
  260. }
  261. static int
  262. bfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd)
  263. {
  264. struct bfa_fcs_lport_s *fcs_port;
  265. struct bfa_bsg_lport_attr_s *iocmd = (struct bfa_bsg_lport_attr_s *)cmd;
  266. unsigned long flags;
  267. spin_lock_irqsave(&bfad->bfad_lock, flags);
  268. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
  269. iocmd->vf_id, iocmd->pwwn);
  270. if (fcs_port == NULL) {
  271. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  272. iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
  273. goto out;
  274. }
  275. bfa_fcs_lport_get_attr(fcs_port, &iocmd->port_attr);
  276. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  277. iocmd->status = BFA_STATUS_OK;
  278. out:
  279. return 0;
  280. }
  281. int
  282. bfad_iocmd_lport_get_stats(struct bfad_s *bfad, void *cmd)
  283. {
  284. struct bfa_fcs_lport_s *fcs_port;
  285. struct bfa_bsg_lport_stats_s *iocmd =
  286. (struct bfa_bsg_lport_stats_s *)cmd;
  287. unsigned long flags;
  288. spin_lock_irqsave(&bfad->bfad_lock, flags);
  289. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
  290. iocmd->vf_id, iocmd->pwwn);
  291. if (fcs_port == NULL) {
  292. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  293. iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
  294. goto out;
  295. }
  296. bfa_fcs_lport_get_stats(fcs_port, &iocmd->port_stats);
  297. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  298. iocmd->status = BFA_STATUS_OK;
  299. out:
  300. return 0;
  301. }
  302. int
  303. bfad_iocmd_lport_get_iostats(struct bfad_s *bfad, void *cmd)
  304. {
  305. struct bfa_fcs_lport_s *fcs_port;
  306. struct bfa_bsg_lport_iostats_s *iocmd =
  307. (struct bfa_bsg_lport_iostats_s *)cmd;
  308. unsigned long flags;
  309. spin_lock_irqsave(&bfad->bfad_lock, flags);
  310. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
  311. iocmd->vf_id, iocmd->pwwn);
  312. if (fcs_port == NULL) {
  313. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  314. iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
  315. goto out;
  316. }
  317. bfa_fcpim_port_iostats(&bfad->bfa, &iocmd->iostats,
  318. fcs_port->lp_tag);
  319. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  320. iocmd->status = BFA_STATUS_OK;
  321. out:
  322. return 0;
  323. }
  324. int
  325. bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd,
  326. unsigned int payload_len)
  327. {
  328. struct bfa_bsg_lport_get_rports_s *iocmd =
  329. (struct bfa_bsg_lport_get_rports_s *)cmd;
  330. struct bfa_fcs_lport_s *fcs_port;
  331. unsigned long flags;
  332. void *iocmd_bufptr;
  333. if (iocmd->nrports == 0)
  334. return EINVAL;
  335. if (bfad_chk_iocmd_sz(payload_len,
  336. sizeof(struct bfa_bsg_lport_get_rports_s),
  337. sizeof(wwn_t) * iocmd->nrports) != BFA_STATUS_OK) {
  338. iocmd->status = BFA_STATUS_VERSION_FAIL;
  339. return 0;
  340. }
  341. iocmd_bufptr = (char *)iocmd +
  342. sizeof(struct bfa_bsg_lport_get_rports_s);
  343. spin_lock_irqsave(&bfad->bfad_lock, flags);
  344. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
  345. iocmd->vf_id, iocmd->pwwn);
  346. if (fcs_port == NULL) {
  347. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  348. bfa_trc(bfad, 0);
  349. iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
  350. goto out;
  351. }
  352. bfa_fcs_lport_get_rports(fcs_port, (wwn_t *)iocmd_bufptr,
  353. &iocmd->nrports);
  354. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  355. iocmd->status = BFA_STATUS_OK;
  356. out:
  357. return 0;
  358. }
  359. int
  360. bfad_iocmd_rport_get_attr(struct bfad_s *bfad, void *cmd)
  361. {
  362. struct bfa_bsg_rport_attr_s *iocmd = (struct bfa_bsg_rport_attr_s *)cmd;
  363. struct bfa_fcs_lport_s *fcs_port;
  364. struct bfa_fcs_rport_s *fcs_rport;
  365. unsigned long flags;
  366. spin_lock_irqsave(&bfad->bfad_lock, flags);
  367. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
  368. iocmd->vf_id, iocmd->pwwn);
  369. if (fcs_port == NULL) {
  370. bfa_trc(bfad, 0);
  371. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  372. iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
  373. goto out;
  374. }
  375. fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
  376. if (fcs_rport == NULL) {
  377. bfa_trc(bfad, 0);
  378. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  379. iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
  380. goto out;
  381. }
  382. bfa_fcs_rport_get_attr(fcs_rport, &iocmd->attr);
  383. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  384. iocmd->status = BFA_STATUS_OK;
  385. out:
  386. return 0;
  387. }
  388. static int
  389. bfad_iocmd_rport_get_addr(struct bfad_s *bfad, void *cmd)
  390. {
  391. struct bfa_bsg_rport_scsi_addr_s *iocmd =
  392. (struct bfa_bsg_rport_scsi_addr_s *)cmd;
  393. struct bfa_fcs_lport_s *fcs_port;
  394. struct bfa_fcs_itnim_s *fcs_itnim;
  395. struct bfad_itnim_s *drv_itnim;
  396. unsigned long flags;
  397. spin_lock_irqsave(&bfad->bfad_lock, flags);
  398. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
  399. iocmd->vf_id, iocmd->pwwn);
  400. if (fcs_port == NULL) {
  401. bfa_trc(bfad, 0);
  402. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  403. iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
  404. goto out;
  405. }
  406. fcs_itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn);
  407. if (fcs_itnim == NULL) {
  408. bfa_trc(bfad, 0);
  409. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  410. iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
  411. goto out;
  412. }
  413. drv_itnim = fcs_itnim->itnim_drv;
  414. if (drv_itnim && drv_itnim->im_port)
  415. iocmd->host = drv_itnim->im_port->shost->host_no;
  416. else {
  417. bfa_trc(bfad, 0);
  418. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  419. iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
  420. goto out;
  421. }
  422. iocmd->target = drv_itnim->scsi_tgt_id;
  423. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  424. iocmd->bus = 0;
  425. iocmd->lun = 0;
  426. iocmd->status = BFA_STATUS_OK;
  427. out:
  428. return 0;
  429. }
  430. int
  431. bfad_iocmd_rport_get_stats(struct bfad_s *bfad, void *cmd)
  432. {
  433. struct bfa_bsg_rport_stats_s *iocmd =
  434. (struct bfa_bsg_rport_stats_s *)cmd;
  435. struct bfa_fcs_lport_s *fcs_port;
  436. struct bfa_fcs_rport_s *fcs_rport;
  437. unsigned long flags;
  438. spin_lock_irqsave(&bfad->bfad_lock, flags);
  439. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
  440. iocmd->vf_id, iocmd->pwwn);
  441. if (fcs_port == NULL) {
  442. bfa_trc(bfad, 0);
  443. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  444. iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
  445. goto out;
  446. }
  447. fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
  448. if (fcs_rport == NULL) {
  449. bfa_trc(bfad, 0);
  450. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  451. iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
  452. goto out;
  453. }
  454. memcpy((void *)&iocmd->stats, (void *)&fcs_rport->stats,
  455. sizeof(struct bfa_rport_stats_s));
  456. memcpy((void *)&iocmd->stats.hal_stats,
  457. (void *)&(bfa_fcs_rport_get_halrport(fcs_rport)->stats),
  458. sizeof(struct bfa_rport_hal_stats_s));
  459. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  460. iocmd->status = BFA_STATUS_OK;
  461. out:
  462. return 0;
  463. }
  464. static int
  465. bfad_iocmd_fabric_get_lports(struct bfad_s *bfad, void *cmd,
  466. unsigned int payload_len)
  467. {
  468. struct bfa_bsg_fabric_get_lports_s *iocmd =
  469. (struct bfa_bsg_fabric_get_lports_s *)cmd;
  470. bfa_fcs_vf_t *fcs_vf;
  471. uint32_t nports = iocmd->nports;
  472. unsigned long flags;
  473. void *iocmd_bufptr;
  474. if (nports == 0) {
  475. iocmd->status = BFA_STATUS_EINVAL;
  476. goto out;
  477. }
  478. if (bfad_chk_iocmd_sz(payload_len,
  479. sizeof(struct bfa_bsg_fabric_get_lports_s),
  480. sizeof(wwn_t[iocmd->nports])) != BFA_STATUS_OK) {
  481. iocmd->status = BFA_STATUS_VERSION_FAIL;
  482. goto out;
  483. }
  484. iocmd_bufptr = (char *)iocmd +
  485. sizeof(struct bfa_bsg_fabric_get_lports_s);
  486. spin_lock_irqsave(&bfad->bfad_lock, flags);
  487. fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id);
  488. if (fcs_vf == NULL) {
  489. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  490. iocmd->status = BFA_STATUS_UNKNOWN_VFID;
  491. goto out;
  492. }
  493. bfa_fcs_vf_get_ports(fcs_vf, (wwn_t *)iocmd_bufptr, &nports);
  494. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  495. iocmd->nports = nports;
  496. iocmd->status = BFA_STATUS_OK;
  497. out:
  498. return 0;
  499. }
  500. int
  501. bfad_iocmd_fcpim_get_modstats(struct bfad_s *bfad, void *cmd)
  502. {
  503. struct bfa_bsg_fcpim_modstats_s *iocmd =
  504. (struct bfa_bsg_fcpim_modstats_s *)cmd;
  505. struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa);
  506. struct list_head *qe, *qen;
  507. struct bfa_itnim_s *itnim;
  508. unsigned long flags;
  509. spin_lock_irqsave(&bfad->bfad_lock, flags);
  510. /* accumulate IO stats from itnim */
  511. memset((void *)&iocmd->modstats, 0, sizeof(struct bfa_itnim_iostats_s));
  512. list_for_each_safe(qe, qen, &fcpim->itnim_q) {
  513. itnim = (struct bfa_itnim_s *) qe;
  514. bfa_fcpim_add_stats(&iocmd->modstats, &(itnim->stats));
  515. }
  516. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  517. iocmd->status = BFA_STATUS_OK;
  518. return 0;
  519. }
  520. int
  521. bfad_iocmd_fcpim_get_del_itn_stats(struct bfad_s *bfad, void *cmd)
  522. {
  523. struct bfa_bsg_fcpim_del_itn_stats_s *iocmd =
  524. (struct bfa_bsg_fcpim_del_itn_stats_s *)cmd;
  525. struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa);
  526. unsigned long flags;
  527. spin_lock_irqsave(&bfad->bfad_lock, flags);
  528. memcpy((void *)&iocmd->modstats, (void *)&fcpim->del_itn_stats,
  529. sizeof(struct bfa_fcpim_del_itn_stats_s));
  530. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  531. iocmd->status = BFA_STATUS_OK;
  532. return 0;
  533. }
  534. static int
  535. bfad_iocmd_itnim_get_attr(struct bfad_s *bfad, void *cmd)
  536. {
  537. struct bfa_bsg_itnim_attr_s *iocmd = (struct bfa_bsg_itnim_attr_s *)cmd;
  538. struct bfa_fcs_lport_s *fcs_port;
  539. unsigned long flags;
  540. spin_lock_irqsave(&bfad->bfad_lock, flags);
  541. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
  542. iocmd->vf_id, iocmd->lpwwn);
  543. if (!fcs_port)
  544. iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
  545. else
  546. iocmd->status = bfa_fcs_itnim_attr_get(fcs_port,
  547. iocmd->rpwwn, &iocmd->attr);
  548. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  549. return 0;
  550. }
  551. static int
  552. bfad_iocmd_itnim_get_iostats(struct bfad_s *bfad, void *cmd)
  553. {
  554. struct bfa_bsg_itnim_iostats_s *iocmd =
  555. (struct bfa_bsg_itnim_iostats_s *)cmd;
  556. struct bfa_fcs_lport_s *fcs_port;
  557. struct bfa_fcs_itnim_s *itnim;
  558. unsigned long flags;
  559. spin_lock_irqsave(&bfad->bfad_lock, flags);
  560. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
  561. iocmd->vf_id, iocmd->lpwwn);
  562. if (!fcs_port) {
  563. iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
  564. bfa_trc(bfad, 0);
  565. } else {
  566. itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn);
  567. if (itnim == NULL)
  568. iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
  569. else {
  570. iocmd->status = BFA_STATUS_OK;
  571. memcpy((void *)&iocmd->iostats, (void *)
  572. &(bfa_fcs_itnim_get_halitn(itnim)->stats),
  573. sizeof(struct bfa_itnim_iostats_s));
  574. }
  575. }
  576. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  577. return 0;
  578. }
  579. static int
  580. bfad_iocmd_itnim_get_itnstats(struct bfad_s *bfad, void *cmd)
  581. {
  582. struct bfa_bsg_itnim_itnstats_s *iocmd =
  583. (struct bfa_bsg_itnim_itnstats_s *)cmd;
  584. struct bfa_fcs_lport_s *fcs_port;
  585. struct bfa_fcs_itnim_s *itnim;
  586. unsigned long flags;
  587. spin_lock_irqsave(&bfad->bfad_lock, flags);
  588. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
  589. iocmd->vf_id, iocmd->lpwwn);
  590. if (!fcs_port) {
  591. iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
  592. bfa_trc(bfad, 0);
  593. } else {
  594. itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn);
  595. if (itnim == NULL)
  596. iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
  597. else {
  598. iocmd->status = BFA_STATUS_OK;
  599. bfa_fcs_itnim_stats_get(fcs_port, iocmd->rpwwn,
  600. &iocmd->itnstats);
  601. }
  602. }
  603. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  604. return 0;
  605. }
  606. int
  607. bfad_iocmd_fcport_enable(struct bfad_s *bfad, void *cmd)
  608. {
  609. struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
  610. unsigned long flags;
  611. spin_lock_irqsave(&bfad->bfad_lock, flags);
  612. iocmd->status = bfa_fcport_enable(&bfad->bfa);
  613. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  614. return 0;
  615. }
  616. int
  617. bfad_iocmd_fcport_disable(struct bfad_s *bfad, void *cmd)
  618. {
  619. struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
  620. unsigned long flags;
  621. spin_lock_irqsave(&bfad->bfad_lock, flags);
  622. iocmd->status = bfa_fcport_disable(&bfad->bfa);
  623. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  624. return 0;
  625. }
  626. int
  627. bfad_iocmd_ioc_get_pcifn_cfg(struct bfad_s *bfad, void *cmd)
  628. {
  629. struct bfa_bsg_pcifn_cfg_s *iocmd = (struct bfa_bsg_pcifn_cfg_s *)cmd;
  630. struct bfad_hal_comp fcomp;
  631. unsigned long flags;
  632. init_completion(&fcomp.comp);
  633. spin_lock_irqsave(&bfad->bfad_lock, flags);
  634. iocmd->status = bfa_ablk_query(&bfad->bfa.modules.ablk,
  635. &iocmd->pcifn_cfg,
  636. bfad_hcb_comp, &fcomp);
  637. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  638. if (iocmd->status != BFA_STATUS_OK)
  639. goto out;
  640. wait_for_completion(&fcomp.comp);
  641. iocmd->status = fcomp.status;
  642. out:
  643. return 0;
  644. }
  645. int
  646. bfad_iocmd_pcifn_create(struct bfad_s *bfad, void *cmd)
  647. {
  648. struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd;
  649. struct bfad_hal_comp fcomp;
  650. unsigned long flags;
  651. init_completion(&fcomp.comp);
  652. spin_lock_irqsave(&bfad->bfad_lock, flags);
  653. iocmd->status = bfa_ablk_pf_create(&bfad->bfa.modules.ablk,
  654. &iocmd->pcifn_id, iocmd->port,
  655. iocmd->pcifn_class, iocmd->bandwidth,
  656. bfad_hcb_comp, &fcomp);
  657. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  658. if (iocmd->status != BFA_STATUS_OK)
  659. goto out;
  660. wait_for_completion(&fcomp.comp);
  661. iocmd->status = fcomp.status;
  662. out:
  663. return 0;
  664. }
  665. int
  666. bfad_iocmd_pcifn_delete(struct bfad_s *bfad, void *cmd)
  667. {
  668. struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd;
  669. struct bfad_hal_comp fcomp;
  670. unsigned long flags;
  671. init_completion(&fcomp.comp);
  672. spin_lock_irqsave(&bfad->bfad_lock, flags);
  673. iocmd->status = bfa_ablk_pf_delete(&bfad->bfa.modules.ablk,
  674. iocmd->pcifn_id,
  675. bfad_hcb_comp, &fcomp);
  676. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  677. if (iocmd->status != BFA_STATUS_OK)
  678. goto out;
  679. wait_for_completion(&fcomp.comp);
  680. iocmd->status = fcomp.status;
  681. out:
  682. return 0;
  683. }
  684. int
  685. bfad_iocmd_pcifn_bw(struct bfad_s *bfad, void *cmd)
  686. {
  687. struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd;
  688. struct bfad_hal_comp fcomp;
  689. unsigned long flags;
  690. init_completion(&fcomp.comp);
  691. spin_lock_irqsave(&bfad->bfad_lock, flags);
  692. iocmd->status = bfa_ablk_pf_update(&bfad->bfa.modules.ablk,
  693. iocmd->pcifn_id, iocmd->bandwidth,
  694. bfad_hcb_comp, &fcomp);
  695. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  696. bfa_trc(bfad, iocmd->status);
  697. if (iocmd->status != BFA_STATUS_OK)
  698. goto out;
  699. wait_for_completion(&fcomp.comp);
  700. iocmd->status = fcomp.status;
  701. bfa_trc(bfad, iocmd->status);
  702. out:
  703. return 0;
  704. }
  705. int
  706. bfad_iocmd_adapter_cfg_mode(struct bfad_s *bfad, void *cmd)
  707. {
  708. struct bfa_bsg_adapter_cfg_mode_s *iocmd =
  709. (struct bfa_bsg_adapter_cfg_mode_s *)cmd;
  710. struct bfad_hal_comp fcomp;
  711. unsigned long flags = 0;
  712. init_completion(&fcomp.comp);
  713. spin_lock_irqsave(&bfad->bfad_lock, flags);
  714. iocmd->status = bfa_ablk_adapter_config(&bfad->bfa.modules.ablk,
  715. iocmd->cfg.mode, iocmd->cfg.max_pf,
  716. iocmd->cfg.max_vf, bfad_hcb_comp, &fcomp);
  717. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  718. if (iocmd->status != BFA_STATUS_OK)
  719. goto out;
  720. wait_for_completion(&fcomp.comp);
  721. iocmd->status = fcomp.status;
  722. out:
  723. return 0;
  724. }
  725. int
  726. bfad_iocmd_port_cfg_mode(struct bfad_s *bfad, void *cmd)
  727. {
  728. struct bfa_bsg_port_cfg_mode_s *iocmd =
  729. (struct bfa_bsg_port_cfg_mode_s *)cmd;
  730. struct bfad_hal_comp fcomp;
  731. unsigned long flags = 0;
  732. init_completion(&fcomp.comp);
  733. spin_lock_irqsave(&bfad->bfad_lock, flags);
  734. iocmd->status = bfa_ablk_port_config(&bfad->bfa.modules.ablk,
  735. iocmd->instance, iocmd->cfg.mode,
  736. iocmd->cfg.max_pf, iocmd->cfg.max_vf,
  737. bfad_hcb_comp, &fcomp);
  738. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  739. if (iocmd->status != BFA_STATUS_OK)
  740. goto out;
  741. wait_for_completion(&fcomp.comp);
  742. iocmd->status = fcomp.status;
  743. out:
  744. return 0;
  745. }
  746. int
  747. bfad_iocmd_ablk_optrom(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
  748. {
  749. struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
  750. struct bfad_hal_comp fcomp;
  751. unsigned long flags;
  752. init_completion(&fcomp.comp);
  753. spin_lock_irqsave(&bfad->bfad_lock, flags);
  754. if (cmd == IOCMD_FLASH_ENABLE_OPTROM)
  755. iocmd->status = bfa_ablk_optrom_en(&bfad->bfa.modules.ablk,
  756. bfad_hcb_comp, &fcomp);
  757. else
  758. iocmd->status = bfa_ablk_optrom_dis(&bfad->bfa.modules.ablk,
  759. bfad_hcb_comp, &fcomp);
  760. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  761. if (iocmd->status != BFA_STATUS_OK)
  762. goto out;
  763. wait_for_completion(&fcomp.comp);
  764. iocmd->status = fcomp.status;
  765. out:
  766. return 0;
  767. }
  768. int
  769. bfad_iocmd_faa_enable(struct bfad_s *bfad, void *cmd)
  770. {
  771. struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
  772. unsigned long flags;
  773. struct bfad_hal_comp fcomp;
  774. init_completion(&fcomp.comp);
  775. iocmd->status = BFA_STATUS_OK;
  776. spin_lock_irqsave(&bfad->bfad_lock, flags);
  777. iocmd->status = bfa_faa_enable(&bfad->bfa, bfad_hcb_comp, &fcomp);
  778. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  779. if (iocmd->status != BFA_STATUS_OK)
  780. goto out;
  781. wait_for_completion(&fcomp.comp);
  782. iocmd->status = fcomp.status;
  783. out:
  784. return 0;
  785. }
  786. int
  787. bfad_iocmd_faa_disable(struct bfad_s *bfad, void *cmd)
  788. {
  789. struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
  790. unsigned long flags;
  791. struct bfad_hal_comp fcomp;
  792. init_completion(&fcomp.comp);
  793. iocmd->status = BFA_STATUS_OK;
  794. spin_lock_irqsave(&bfad->bfad_lock, flags);
  795. iocmd->status = bfa_faa_disable(&bfad->bfa, bfad_hcb_comp, &fcomp);
  796. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  797. if (iocmd->status != BFA_STATUS_OK)
  798. goto out;
  799. wait_for_completion(&fcomp.comp);
  800. iocmd->status = fcomp.status;
  801. out:
  802. return 0;
  803. }
  804. int
  805. bfad_iocmd_faa_query(struct bfad_s *bfad, void *cmd)
  806. {
  807. struct bfa_bsg_faa_attr_s *iocmd = (struct bfa_bsg_faa_attr_s *)cmd;
  808. struct bfad_hal_comp fcomp;
  809. unsigned long flags;
  810. init_completion(&fcomp.comp);
  811. iocmd->status = BFA_STATUS_OK;
  812. spin_lock_irqsave(&bfad->bfad_lock, flags);
  813. iocmd->status = bfa_faa_query(&bfad->bfa, &iocmd->faa_attr,
  814. bfad_hcb_comp, &fcomp);
  815. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  816. if (iocmd->status != BFA_STATUS_OK)
  817. goto out;
  818. wait_for_completion(&fcomp.comp);
  819. iocmd->status = fcomp.status;
  820. out:
  821. return 0;
  822. }
  823. int
  824. bfad_iocmd_cee_attr(struct bfad_s *bfad, void *cmd, unsigned int payload_len)
  825. {
  826. struct bfa_bsg_cee_attr_s *iocmd =
  827. (struct bfa_bsg_cee_attr_s *)cmd;
  828. void *iocmd_bufptr;
  829. struct bfad_hal_comp cee_comp;
  830. unsigned long flags;
  831. if (bfad_chk_iocmd_sz(payload_len,
  832. sizeof(struct bfa_bsg_cee_attr_s),
  833. sizeof(struct bfa_cee_attr_s)) != BFA_STATUS_OK) {
  834. iocmd->status = BFA_STATUS_VERSION_FAIL;
  835. return 0;
  836. }
  837. iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_cee_attr_s);
  838. cee_comp.status = 0;
  839. init_completion(&cee_comp.comp);
  840. mutex_lock(&bfad_mutex);
  841. spin_lock_irqsave(&bfad->bfad_lock, flags);
  842. iocmd->status = bfa_cee_get_attr(&bfad->bfa.modules.cee, iocmd_bufptr,
  843. bfad_hcb_comp, &cee_comp);
  844. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  845. if (iocmd->status != BFA_STATUS_OK) {
  846. mutex_unlock(&bfad_mutex);
  847. bfa_trc(bfad, 0x5555);
  848. goto out;
  849. }
  850. wait_for_completion(&cee_comp.comp);
  851. mutex_unlock(&bfad_mutex);
  852. out:
  853. return 0;
  854. }
  855. int
  856. bfad_iocmd_cee_get_stats(struct bfad_s *bfad, void *cmd,
  857. unsigned int payload_len)
  858. {
  859. struct bfa_bsg_cee_stats_s *iocmd =
  860. (struct bfa_bsg_cee_stats_s *)cmd;
  861. void *iocmd_bufptr;
  862. struct bfad_hal_comp cee_comp;
  863. unsigned long flags;
  864. if (bfad_chk_iocmd_sz(payload_len,
  865. sizeof(struct bfa_bsg_cee_stats_s),
  866. sizeof(struct bfa_cee_stats_s)) != BFA_STATUS_OK) {
  867. iocmd->status = BFA_STATUS_VERSION_FAIL;
  868. return 0;
  869. }
  870. iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_cee_stats_s);
  871. cee_comp.status = 0;
  872. init_completion(&cee_comp.comp);
  873. mutex_lock(&bfad_mutex);
  874. spin_lock_irqsave(&bfad->bfad_lock, flags);
  875. iocmd->status = bfa_cee_get_stats(&bfad->bfa.modules.cee, iocmd_bufptr,
  876. bfad_hcb_comp, &cee_comp);
  877. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  878. if (iocmd->status != BFA_STATUS_OK) {
  879. mutex_unlock(&bfad_mutex);
  880. bfa_trc(bfad, 0x5555);
  881. goto out;
  882. }
  883. wait_for_completion(&cee_comp.comp);
  884. mutex_unlock(&bfad_mutex);
  885. out:
  886. return 0;
  887. }
  888. int
  889. bfad_iocmd_cee_reset_stats(struct bfad_s *bfad, void *cmd)
  890. {
  891. struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
  892. unsigned long flags;
  893. spin_lock_irqsave(&bfad->bfad_lock, flags);
  894. iocmd->status = bfa_cee_reset_stats(&bfad->bfa.modules.cee, NULL, NULL);
  895. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  896. if (iocmd->status != BFA_STATUS_OK)
  897. bfa_trc(bfad, 0x5555);
  898. return 0;
  899. }
  900. int
  901. bfad_iocmd_sfp_media(struct bfad_s *bfad, void *cmd)
  902. {
  903. struct bfa_bsg_sfp_media_s *iocmd = (struct bfa_bsg_sfp_media_s *)cmd;
  904. struct bfad_hal_comp fcomp;
  905. unsigned long flags;
  906. init_completion(&fcomp.comp);
  907. spin_lock_irqsave(&bfad->bfad_lock, flags);
  908. iocmd->status = bfa_sfp_media(BFA_SFP_MOD(&bfad->bfa), &iocmd->media,
  909. bfad_hcb_comp, &fcomp);
  910. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  911. bfa_trc(bfad, iocmd->status);
  912. if (iocmd->status != BFA_STATUS_SFP_NOT_READY)
  913. goto out;
  914. wait_for_completion(&fcomp.comp);
  915. iocmd->status = fcomp.status;
  916. out:
  917. return 0;
  918. }
  919. int
  920. bfad_iocmd_sfp_speed(struct bfad_s *bfad, void *cmd)
  921. {
  922. struct bfa_bsg_sfp_speed_s *iocmd = (struct bfa_bsg_sfp_speed_s *)cmd;
  923. struct bfad_hal_comp fcomp;
  924. unsigned long flags;
  925. init_completion(&fcomp.comp);
  926. spin_lock_irqsave(&bfad->bfad_lock, flags);
  927. iocmd->status = bfa_sfp_speed(BFA_SFP_MOD(&bfad->bfa), iocmd->speed,
  928. bfad_hcb_comp, &fcomp);
  929. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  930. bfa_trc(bfad, iocmd->status);
  931. if (iocmd->status != BFA_STATUS_SFP_NOT_READY)
  932. goto out;
  933. wait_for_completion(&fcomp.comp);
  934. iocmd->status = fcomp.status;
  935. out:
  936. return 0;
  937. }
  938. int
  939. bfad_iocmd_flash_get_attr(struct bfad_s *bfad, void *cmd)
  940. {
  941. struct bfa_bsg_flash_attr_s *iocmd =
  942. (struct bfa_bsg_flash_attr_s *)cmd;
  943. struct bfad_hal_comp fcomp;
  944. unsigned long flags;
  945. init_completion(&fcomp.comp);
  946. spin_lock_irqsave(&bfad->bfad_lock, flags);
  947. iocmd->status = bfa_flash_get_attr(BFA_FLASH(&bfad->bfa), &iocmd->attr,
  948. bfad_hcb_comp, &fcomp);
  949. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  950. if (iocmd->status != BFA_STATUS_OK)
  951. goto out;
  952. wait_for_completion(&fcomp.comp);
  953. iocmd->status = fcomp.status;
  954. out:
  955. return 0;
  956. }
  957. int
  958. bfad_iocmd_flash_erase_part(struct bfad_s *bfad, void *cmd)
  959. {
  960. struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd;
  961. struct bfad_hal_comp fcomp;
  962. unsigned long flags;
  963. init_completion(&fcomp.comp);
  964. spin_lock_irqsave(&bfad->bfad_lock, flags);
  965. iocmd->status = bfa_flash_erase_part(BFA_FLASH(&bfad->bfa), iocmd->type,
  966. iocmd->instance, bfad_hcb_comp, &fcomp);
  967. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  968. if (iocmd->status != BFA_STATUS_OK)
  969. goto out;
  970. wait_for_completion(&fcomp.comp);
  971. iocmd->status = fcomp.status;
  972. out:
  973. return 0;
  974. }
  975. int
  976. bfad_iocmd_flash_update_part(struct bfad_s *bfad, void *cmd,
  977. unsigned int payload_len)
  978. {
  979. struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd;
  980. void *iocmd_bufptr;
  981. struct bfad_hal_comp fcomp;
  982. unsigned long flags;
  983. if (bfad_chk_iocmd_sz(payload_len,
  984. sizeof(struct bfa_bsg_flash_s),
  985. iocmd->bufsz) != BFA_STATUS_OK) {
  986. iocmd->status = BFA_STATUS_VERSION_FAIL;
  987. return 0;
  988. }
  989. iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_flash_s);
  990. init_completion(&fcomp.comp);
  991. spin_lock_irqsave(&bfad->bfad_lock, flags);
  992. iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa),
  993. iocmd->type, iocmd->instance, iocmd_bufptr,
  994. iocmd->bufsz, 0, bfad_hcb_comp, &fcomp);
  995. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  996. if (iocmd->status != BFA_STATUS_OK)
  997. goto out;
  998. wait_for_completion(&fcomp.comp);
  999. iocmd->status = fcomp.status;
  1000. out:
  1001. return 0;
  1002. }
  1003. int
  1004. bfad_iocmd_flash_read_part(struct bfad_s *bfad, void *cmd,
  1005. unsigned int payload_len)
  1006. {
  1007. struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd;
  1008. struct bfad_hal_comp fcomp;
  1009. void *iocmd_bufptr;
  1010. unsigned long flags;
  1011. if (bfad_chk_iocmd_sz(payload_len,
  1012. sizeof(struct bfa_bsg_flash_s),
  1013. iocmd->bufsz) != BFA_STATUS_OK) {
  1014. iocmd->status = BFA_STATUS_VERSION_FAIL;
  1015. return 0;
  1016. }
  1017. iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_flash_s);
  1018. init_completion(&fcomp.comp);
  1019. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1020. iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), iocmd->type,
  1021. iocmd->instance, iocmd_bufptr, iocmd->bufsz, 0,
  1022. bfad_hcb_comp, &fcomp);
  1023. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1024. if (iocmd->status != BFA_STATUS_OK)
  1025. goto out;
  1026. wait_for_completion(&fcomp.comp);
  1027. iocmd->status = fcomp.status;
  1028. out:
  1029. return 0;
  1030. }
  1031. int
  1032. bfad_iocmd_diag_temp(struct bfad_s *bfad, void *cmd)
  1033. {
  1034. struct bfa_bsg_diag_get_temp_s *iocmd =
  1035. (struct bfa_bsg_diag_get_temp_s *)cmd;
  1036. struct bfad_hal_comp fcomp;
  1037. unsigned long flags;
  1038. init_completion(&fcomp.comp);
  1039. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1040. iocmd->status = bfa_diag_tsensor_query(BFA_DIAG_MOD(&bfad->bfa),
  1041. &iocmd->result, bfad_hcb_comp, &fcomp);
  1042. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1043. bfa_trc(bfad, iocmd->status);
  1044. if (iocmd->status != BFA_STATUS_OK)
  1045. goto out;
  1046. wait_for_completion(&fcomp.comp);
  1047. iocmd->status = fcomp.status;
  1048. out:
  1049. return 0;
  1050. }
  1051. int
  1052. bfad_iocmd_diag_memtest(struct bfad_s *bfad, void *cmd)
  1053. {
  1054. struct bfa_bsg_diag_memtest_s *iocmd =
  1055. (struct bfa_bsg_diag_memtest_s *)cmd;
  1056. struct bfad_hal_comp fcomp;
  1057. unsigned long flags;
  1058. init_completion(&fcomp.comp);
  1059. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1060. iocmd->status = bfa_diag_memtest(BFA_DIAG_MOD(&bfad->bfa),
  1061. &iocmd->memtest, iocmd->pat,
  1062. &iocmd->result, bfad_hcb_comp, &fcomp);
  1063. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1064. bfa_trc(bfad, iocmd->status);
  1065. if (iocmd->status != BFA_STATUS_OK)
  1066. goto out;
  1067. wait_for_completion(&fcomp.comp);
  1068. iocmd->status = fcomp.status;
  1069. out:
  1070. return 0;
  1071. }
  1072. int
  1073. bfad_iocmd_diag_loopback(struct bfad_s *bfad, void *cmd)
  1074. {
  1075. struct bfa_bsg_diag_loopback_s *iocmd =
  1076. (struct bfa_bsg_diag_loopback_s *)cmd;
  1077. struct bfad_hal_comp fcomp;
  1078. unsigned long flags;
  1079. init_completion(&fcomp.comp);
  1080. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1081. iocmd->status = bfa_fcdiag_loopback(&bfad->bfa, iocmd->opmode,
  1082. iocmd->speed, iocmd->lpcnt, iocmd->pat,
  1083. &iocmd->result, bfad_hcb_comp, &fcomp);
  1084. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1085. bfa_trc(bfad, iocmd->status);
  1086. if (iocmd->status != BFA_STATUS_OK)
  1087. goto out;
  1088. wait_for_completion(&fcomp.comp);
  1089. iocmd->status = fcomp.status;
  1090. out:
  1091. return 0;
  1092. }
  1093. int
  1094. bfad_iocmd_diag_fwping(struct bfad_s *bfad, void *cmd)
  1095. {
  1096. struct bfa_bsg_diag_fwping_s *iocmd =
  1097. (struct bfa_bsg_diag_fwping_s *)cmd;
  1098. struct bfad_hal_comp fcomp;
  1099. unsigned long flags;
  1100. init_completion(&fcomp.comp);
  1101. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1102. iocmd->status = bfa_diag_fwping(BFA_DIAG_MOD(&bfad->bfa), iocmd->cnt,
  1103. iocmd->pattern, &iocmd->result,
  1104. bfad_hcb_comp, &fcomp);
  1105. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1106. bfa_trc(bfad, iocmd->status);
  1107. if (iocmd->status != BFA_STATUS_OK)
  1108. goto out;
  1109. bfa_trc(bfad, 0x77771);
  1110. wait_for_completion(&fcomp.comp);
  1111. iocmd->status = fcomp.status;
  1112. out:
  1113. return 0;
  1114. }
  1115. int
  1116. bfad_iocmd_diag_queuetest(struct bfad_s *bfad, void *cmd)
  1117. {
  1118. struct bfa_bsg_diag_qtest_s *iocmd = (struct bfa_bsg_diag_qtest_s *)cmd;
  1119. struct bfad_hal_comp fcomp;
  1120. unsigned long flags;
  1121. init_completion(&fcomp.comp);
  1122. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1123. iocmd->status = bfa_fcdiag_queuetest(&bfad->bfa, iocmd->force,
  1124. iocmd->queue, &iocmd->result,
  1125. bfad_hcb_comp, &fcomp);
  1126. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1127. if (iocmd->status != BFA_STATUS_OK)
  1128. goto out;
  1129. wait_for_completion(&fcomp.comp);
  1130. iocmd->status = fcomp.status;
  1131. out:
  1132. return 0;
  1133. }
  1134. int
  1135. bfad_iocmd_diag_sfp(struct bfad_s *bfad, void *cmd)
  1136. {
  1137. struct bfa_bsg_sfp_show_s *iocmd =
  1138. (struct bfa_bsg_sfp_show_s *)cmd;
  1139. struct bfad_hal_comp fcomp;
  1140. unsigned long flags;
  1141. init_completion(&fcomp.comp);
  1142. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1143. iocmd->status = bfa_sfp_show(BFA_SFP_MOD(&bfad->bfa), &iocmd->sfp,
  1144. bfad_hcb_comp, &fcomp);
  1145. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1146. bfa_trc(bfad, iocmd->status);
  1147. if (iocmd->status != BFA_STATUS_OK)
  1148. goto out;
  1149. wait_for_completion(&fcomp.comp);
  1150. iocmd->status = fcomp.status;
  1151. bfa_trc(bfad, iocmd->status);
  1152. out:
  1153. return 0;
  1154. }
  1155. int
  1156. bfad_iocmd_diag_led(struct bfad_s *bfad, void *cmd)
  1157. {
  1158. struct bfa_bsg_diag_led_s *iocmd = (struct bfa_bsg_diag_led_s *)cmd;
  1159. unsigned long flags;
  1160. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1161. iocmd->status = bfa_diag_ledtest(BFA_DIAG_MOD(&bfad->bfa),
  1162. &iocmd->ledtest);
  1163. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1164. return 0;
  1165. }
  1166. int
  1167. bfad_iocmd_diag_beacon_lport(struct bfad_s *bfad, void *cmd)
  1168. {
  1169. struct bfa_bsg_diag_beacon_s *iocmd =
  1170. (struct bfa_bsg_diag_beacon_s *)cmd;
  1171. unsigned long flags;
  1172. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1173. iocmd->status = bfa_diag_beacon_port(BFA_DIAG_MOD(&bfad->bfa),
  1174. iocmd->beacon, iocmd->link_e2e_beacon,
  1175. iocmd->second);
  1176. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1177. return 0;
  1178. }
  1179. int
  1180. bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd)
  1181. {
  1182. struct bfa_bsg_diag_lb_stat_s *iocmd =
  1183. (struct bfa_bsg_diag_lb_stat_s *)cmd;
  1184. unsigned long flags;
  1185. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1186. iocmd->status = bfa_fcdiag_lb_is_running(&bfad->bfa);
  1187. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1188. bfa_trc(bfad, iocmd->status);
  1189. return 0;
  1190. }
  1191. int
  1192. bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd)
  1193. {
  1194. struct bfa_bsg_phy_attr_s *iocmd =
  1195. (struct bfa_bsg_phy_attr_s *)cmd;
  1196. struct bfad_hal_comp fcomp;
  1197. unsigned long flags;
  1198. init_completion(&fcomp.comp);
  1199. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1200. iocmd->status = bfa_phy_get_attr(BFA_PHY(&bfad->bfa), iocmd->instance,
  1201. &iocmd->attr, bfad_hcb_comp, &fcomp);
  1202. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1203. if (iocmd->status != BFA_STATUS_OK)
  1204. goto out;
  1205. wait_for_completion(&fcomp.comp);
  1206. iocmd->status = fcomp.status;
  1207. out:
  1208. return 0;
  1209. }
  1210. int
  1211. bfad_iocmd_phy_get_stats(struct bfad_s *bfad, void *cmd)
  1212. {
  1213. struct bfa_bsg_phy_stats_s *iocmd =
  1214. (struct bfa_bsg_phy_stats_s *)cmd;
  1215. struct bfad_hal_comp fcomp;
  1216. unsigned long flags;
  1217. init_completion(&fcomp.comp);
  1218. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1219. iocmd->status = bfa_phy_get_stats(BFA_PHY(&bfad->bfa), iocmd->instance,
  1220. &iocmd->stats, bfad_hcb_comp, &fcomp);
  1221. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1222. if (iocmd->status != BFA_STATUS_OK)
  1223. goto out;
  1224. wait_for_completion(&fcomp.comp);
  1225. iocmd->status = fcomp.status;
  1226. out:
  1227. return 0;
  1228. }
  1229. int
  1230. bfad_iocmd_phy_read(struct bfad_s *bfad, void *cmd, unsigned int payload_len)
  1231. {
  1232. struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd;
  1233. struct bfad_hal_comp fcomp;
  1234. void *iocmd_bufptr;
  1235. unsigned long flags;
  1236. if (bfad_chk_iocmd_sz(payload_len,
  1237. sizeof(struct bfa_bsg_phy_s),
  1238. iocmd->bufsz) != BFA_STATUS_OK) {
  1239. iocmd->status = BFA_STATUS_VERSION_FAIL;
  1240. return 0;
  1241. }
  1242. iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s);
  1243. init_completion(&fcomp.comp);
  1244. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1245. iocmd->status = bfa_phy_read(BFA_PHY(&bfad->bfa),
  1246. iocmd->instance, iocmd_bufptr, iocmd->bufsz,
  1247. 0, bfad_hcb_comp, &fcomp);
  1248. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1249. if (iocmd->status != BFA_STATUS_OK)
  1250. goto out;
  1251. wait_for_completion(&fcomp.comp);
  1252. iocmd->status = fcomp.status;
  1253. if (iocmd->status != BFA_STATUS_OK)
  1254. goto out;
  1255. out:
  1256. return 0;
  1257. }
  1258. int
  1259. bfad_iocmd_vhba_query(struct bfad_s *bfad, void *cmd)
  1260. {
  1261. struct bfa_bsg_vhba_attr_s *iocmd =
  1262. (struct bfa_bsg_vhba_attr_s *)cmd;
  1263. struct bfa_vhba_attr_s *attr = &iocmd->attr;
  1264. unsigned long flags;
  1265. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1266. attr->pwwn = bfad->bfa.ioc.attr->pwwn;
  1267. attr->nwwn = bfad->bfa.ioc.attr->nwwn;
  1268. attr->plog_enabled = (bfa_boolean_t)bfad->bfa.plog->plog_enabled;
  1269. attr->io_profile = bfa_fcpim_get_io_profile(&bfad->bfa);
  1270. attr->path_tov = bfa_fcpim_path_tov_get(&bfad->bfa);
  1271. iocmd->status = BFA_STATUS_OK;
  1272. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1273. return 0;
  1274. }
  1275. int
  1276. bfad_iocmd_phy_update(struct bfad_s *bfad, void *cmd, unsigned int payload_len)
  1277. {
  1278. struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd;
  1279. void *iocmd_bufptr;
  1280. struct bfad_hal_comp fcomp;
  1281. unsigned long flags;
  1282. if (bfad_chk_iocmd_sz(payload_len,
  1283. sizeof(struct bfa_bsg_phy_s),
  1284. iocmd->bufsz) != BFA_STATUS_OK) {
  1285. iocmd->status = BFA_STATUS_VERSION_FAIL;
  1286. return 0;
  1287. }
  1288. iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s);
  1289. init_completion(&fcomp.comp);
  1290. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1291. iocmd->status = bfa_phy_update(BFA_PHY(&bfad->bfa),
  1292. iocmd->instance, iocmd_bufptr, iocmd->bufsz,
  1293. 0, bfad_hcb_comp, &fcomp);
  1294. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1295. if (iocmd->status != BFA_STATUS_OK)
  1296. goto out;
  1297. wait_for_completion(&fcomp.comp);
  1298. iocmd->status = fcomp.status;
  1299. out:
  1300. return 0;
  1301. }
  1302. int
  1303. bfad_iocmd_porglog_get(struct bfad_s *bfad, void *cmd)
  1304. {
  1305. struct bfa_bsg_debug_s *iocmd = (struct bfa_bsg_debug_s *)cmd;
  1306. void *iocmd_bufptr;
  1307. if (iocmd->bufsz < sizeof(struct bfa_plog_s)) {
  1308. bfa_trc(bfad, sizeof(struct bfa_plog_s));
  1309. iocmd->status = BFA_STATUS_EINVAL;
  1310. goto out;
  1311. }
  1312. iocmd->status = BFA_STATUS_OK;
  1313. iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_debug_s);
  1314. memcpy(iocmd_bufptr, (u8 *) &bfad->plog_buf, sizeof(struct bfa_plog_s));
  1315. out:
  1316. return 0;
  1317. }
  1318. static int
  1319. bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
  1320. unsigned int payload_len)
  1321. {
  1322. int rc = EINVAL;
  1323. switch (cmd) {
  1324. case IOCMD_IOC_ENABLE:
  1325. rc = bfad_iocmd_ioc_enable(bfad, iocmd);
  1326. break;
  1327. case IOCMD_IOC_DISABLE:
  1328. rc = bfad_iocmd_ioc_disable(bfad, iocmd);
  1329. break;
  1330. case IOCMD_IOC_GET_INFO:
  1331. rc = bfad_iocmd_ioc_get_info(bfad, iocmd);
  1332. break;
  1333. case IOCMD_IOC_GET_ATTR:
  1334. rc = bfad_iocmd_ioc_get_attr(bfad, iocmd);
  1335. break;
  1336. case IOCMD_IOC_GET_STATS:
  1337. rc = bfad_iocmd_ioc_get_stats(bfad, iocmd);
  1338. break;
  1339. case IOCMD_IOC_GET_FWSTATS:
  1340. rc = bfad_iocmd_ioc_get_fwstats(bfad, iocmd, payload_len);
  1341. break;
  1342. case IOCMD_IOCFC_GET_ATTR:
  1343. rc = bfad_iocmd_iocfc_get_attr(bfad, iocmd);
  1344. break;
  1345. case IOCMD_IOCFC_SET_INTR:
  1346. rc = bfad_iocmd_iocfc_set_intr(bfad, iocmd);
  1347. break;
  1348. case IOCMD_PORT_ENABLE:
  1349. rc = bfad_iocmd_port_enable(bfad, iocmd);
  1350. break;
  1351. case IOCMD_PORT_DISABLE:
  1352. rc = bfad_iocmd_port_disable(bfad, iocmd);
  1353. break;
  1354. case IOCMD_PORT_GET_ATTR:
  1355. rc = bfad_iocmd_port_get_attr(bfad, iocmd);
  1356. break;
  1357. case IOCMD_PORT_GET_STATS:
  1358. rc = bfad_iocmd_port_get_stats(bfad, iocmd, payload_len);
  1359. break;
  1360. case IOCMD_LPORT_GET_ATTR:
  1361. rc = bfad_iocmd_lport_get_attr(bfad, iocmd);
  1362. break;
  1363. case IOCMD_LPORT_GET_STATS:
  1364. rc = bfad_iocmd_lport_get_stats(bfad, iocmd);
  1365. break;
  1366. case IOCMD_LPORT_GET_IOSTATS:
  1367. rc = bfad_iocmd_lport_get_iostats(bfad, iocmd);
  1368. break;
  1369. case IOCMD_LPORT_GET_RPORTS:
  1370. rc = bfad_iocmd_lport_get_rports(bfad, iocmd, payload_len);
  1371. break;
  1372. case IOCMD_RPORT_GET_ATTR:
  1373. rc = bfad_iocmd_rport_get_attr(bfad, iocmd);
  1374. break;
  1375. case IOCMD_RPORT_GET_ADDR:
  1376. rc = bfad_iocmd_rport_get_addr(bfad, iocmd);
  1377. break;
  1378. case IOCMD_RPORT_GET_STATS:
  1379. rc = bfad_iocmd_rport_get_stats(bfad, iocmd);
  1380. break;
  1381. case IOCMD_FABRIC_GET_LPORTS:
  1382. rc = bfad_iocmd_fabric_get_lports(bfad, iocmd, payload_len);
  1383. break;
  1384. case IOCMD_FCPIM_MODSTATS:
  1385. rc = bfad_iocmd_fcpim_get_modstats(bfad, iocmd);
  1386. break;
  1387. case IOCMD_FCPIM_DEL_ITN_STATS:
  1388. rc = bfad_iocmd_fcpim_get_del_itn_stats(bfad, iocmd);
  1389. break;
  1390. case IOCMD_ITNIM_GET_ATTR:
  1391. rc = bfad_iocmd_itnim_get_attr(bfad, iocmd);
  1392. break;
  1393. case IOCMD_ITNIM_GET_IOSTATS:
  1394. rc = bfad_iocmd_itnim_get_iostats(bfad, iocmd);
  1395. break;
  1396. case IOCMD_ITNIM_GET_ITNSTATS:
  1397. rc = bfad_iocmd_itnim_get_itnstats(bfad, iocmd);
  1398. break;
  1399. case IOCMD_FCPORT_ENABLE:
  1400. rc = bfad_iocmd_fcport_enable(bfad, iocmd);
  1401. break;
  1402. case IOCMD_FCPORT_DISABLE:
  1403. rc = bfad_iocmd_fcport_disable(bfad, iocmd);
  1404. break;
  1405. case IOCMD_IOC_PCIFN_CFG:
  1406. rc = bfad_iocmd_ioc_get_pcifn_cfg(bfad, iocmd);
  1407. break;
  1408. case IOCMD_PCIFN_CREATE:
  1409. rc = bfad_iocmd_pcifn_create(bfad, iocmd);
  1410. break;
  1411. case IOCMD_PCIFN_DELETE:
  1412. rc = bfad_iocmd_pcifn_delete(bfad, iocmd);
  1413. break;
  1414. case IOCMD_PCIFN_BW:
  1415. rc = bfad_iocmd_pcifn_bw(bfad, iocmd);
  1416. break;
  1417. case IOCMD_ADAPTER_CFG_MODE:
  1418. rc = bfad_iocmd_adapter_cfg_mode(bfad, iocmd);
  1419. break;
  1420. case IOCMD_PORT_CFG_MODE:
  1421. rc = bfad_iocmd_port_cfg_mode(bfad, iocmd);
  1422. break;
  1423. case IOCMD_FLASH_ENABLE_OPTROM:
  1424. case IOCMD_FLASH_DISABLE_OPTROM:
  1425. rc = bfad_iocmd_ablk_optrom(bfad, cmd, iocmd);
  1426. break;
  1427. case IOCMD_FAA_ENABLE:
  1428. rc = bfad_iocmd_faa_enable(bfad, iocmd);
  1429. break;
  1430. case IOCMD_FAA_DISABLE:
  1431. rc = bfad_iocmd_faa_disable(bfad, iocmd);
  1432. break;
  1433. case IOCMD_FAA_QUERY:
  1434. rc = bfad_iocmd_faa_query(bfad, iocmd);
  1435. break;
  1436. case IOCMD_CEE_GET_ATTR:
  1437. rc = bfad_iocmd_cee_attr(bfad, iocmd, payload_len);
  1438. break;
  1439. case IOCMD_CEE_GET_STATS:
  1440. rc = bfad_iocmd_cee_get_stats(bfad, iocmd, payload_len);
  1441. break;
  1442. case IOCMD_CEE_RESET_STATS:
  1443. rc = bfad_iocmd_cee_reset_stats(bfad, iocmd);
  1444. break;
  1445. case IOCMD_SFP_MEDIA:
  1446. rc = bfad_iocmd_sfp_media(bfad, iocmd);
  1447. break;
  1448. case IOCMD_SFP_SPEED:
  1449. rc = bfad_iocmd_sfp_speed(bfad, iocmd);
  1450. break;
  1451. case IOCMD_FLASH_GET_ATTR:
  1452. rc = bfad_iocmd_flash_get_attr(bfad, iocmd);
  1453. break;
  1454. case IOCMD_FLASH_ERASE_PART:
  1455. rc = bfad_iocmd_flash_erase_part(bfad, iocmd);
  1456. break;
  1457. case IOCMD_FLASH_UPDATE_PART:
  1458. rc = bfad_iocmd_flash_update_part(bfad, iocmd, payload_len);
  1459. break;
  1460. case IOCMD_FLASH_READ_PART:
  1461. rc = bfad_iocmd_flash_read_part(bfad, iocmd, payload_len);
  1462. break;
  1463. case IOCMD_DIAG_TEMP:
  1464. rc = bfad_iocmd_diag_temp(bfad, iocmd);
  1465. break;
  1466. case IOCMD_DIAG_MEMTEST:
  1467. rc = bfad_iocmd_diag_memtest(bfad, iocmd);
  1468. break;
  1469. case IOCMD_DIAG_LOOPBACK:
  1470. rc = bfad_iocmd_diag_loopback(bfad, iocmd);
  1471. break;
  1472. case IOCMD_DIAG_FWPING:
  1473. rc = bfad_iocmd_diag_fwping(bfad, iocmd);
  1474. break;
  1475. case IOCMD_DIAG_QUEUETEST:
  1476. rc = bfad_iocmd_diag_queuetest(bfad, iocmd);
  1477. break;
  1478. case IOCMD_DIAG_SFP:
  1479. rc = bfad_iocmd_diag_sfp(bfad, iocmd);
  1480. break;
  1481. case IOCMD_DIAG_LED:
  1482. rc = bfad_iocmd_diag_led(bfad, iocmd);
  1483. break;
  1484. case IOCMD_DIAG_BEACON_LPORT:
  1485. rc = bfad_iocmd_diag_beacon_lport(bfad, iocmd);
  1486. break;
  1487. case IOCMD_DIAG_LB_STAT:
  1488. rc = bfad_iocmd_diag_lb_stat(bfad, iocmd);
  1489. break;
  1490. case IOCMD_PHY_GET_ATTR:
  1491. rc = bfad_iocmd_phy_get_attr(bfad, iocmd);
  1492. break;
  1493. case IOCMD_PHY_GET_STATS:
  1494. rc = bfad_iocmd_phy_get_stats(bfad, iocmd);
  1495. break;
  1496. case IOCMD_PHY_UPDATE_FW:
  1497. rc = bfad_iocmd_phy_update(bfad, iocmd, payload_len);
  1498. break;
  1499. case IOCMD_PHY_READ_FW:
  1500. rc = bfad_iocmd_phy_read(bfad, iocmd, payload_len);
  1501. break;
  1502. case IOCMD_VHBA_QUERY:
  1503. rc = bfad_iocmd_vhba_query(bfad, iocmd);
  1504. break;
  1505. case IOCMD_DEBUG_PORTLOG:
  1506. rc = bfad_iocmd_porglog_get(bfad, iocmd);
  1507. break;
  1508. default:
  1509. rc = EINVAL;
  1510. break;
  1511. }
  1512. return -rc;
  1513. }
  1514. static int
  1515. bfad_im_bsg_vendor_request(struct fc_bsg_job *job)
  1516. {
  1517. uint32_t vendor_cmd = job->request->rqst_data.h_vendor.vendor_cmd[0];
  1518. struct bfad_im_port_s *im_port =
  1519. (struct bfad_im_port_s *) job->shost->hostdata[0];
  1520. struct bfad_s *bfad = im_port->bfad;
  1521. void *payload_kbuf;
  1522. int rc = -EINVAL;
  1523. /* Allocate a temp buffer to hold the passed in user space command */
  1524. payload_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL);
  1525. if (!payload_kbuf) {
  1526. rc = -ENOMEM;
  1527. goto out;
  1528. }
  1529. /* Copy the sg_list passed in to a linear buffer: holds the cmnd data */
  1530. sg_copy_to_buffer(job->request_payload.sg_list,
  1531. job->request_payload.sg_cnt, payload_kbuf,
  1532. job->request_payload.payload_len);
  1533. /* Invoke IOCMD handler - to handle all the vendor command requests */
  1534. rc = bfad_iocmd_handler(bfad, vendor_cmd, payload_kbuf,
  1535. job->request_payload.payload_len);
  1536. if (rc != BFA_STATUS_OK)
  1537. goto error;
  1538. /* Copy the response data to the job->reply_payload sg_list */
  1539. sg_copy_from_buffer(job->reply_payload.sg_list,
  1540. job->reply_payload.sg_cnt,
  1541. payload_kbuf,
  1542. job->reply_payload.payload_len);
  1543. /* free the command buffer */
  1544. kfree(payload_kbuf);
  1545. /* Fill the BSG job reply data */
  1546. job->reply_len = job->reply_payload.payload_len;
  1547. job->reply->reply_payload_rcv_len = job->reply_payload.payload_len;
  1548. job->reply->result = rc;
  1549. job->job_done(job);
  1550. return rc;
  1551. error:
  1552. /* free the command buffer */
  1553. kfree(payload_kbuf);
  1554. out:
  1555. job->reply->result = rc;
  1556. job->reply_len = sizeof(uint32_t);
  1557. job->reply->reply_payload_rcv_len = 0;
  1558. return rc;
  1559. }
  1560. /* FC passthru call backs */
  1561. u64
  1562. bfad_fcxp_get_req_sgaddr_cb(void *bfad_fcxp, int sgeid)
  1563. {
  1564. struct bfad_fcxp *drv_fcxp = bfad_fcxp;
  1565. struct bfa_sge_s *sge;
  1566. u64 addr;
  1567. sge = drv_fcxp->req_sge + sgeid;
  1568. addr = (u64)(size_t) sge->sg_addr;
  1569. return addr;
  1570. }
  1571. u32
  1572. bfad_fcxp_get_req_sglen_cb(void *bfad_fcxp, int sgeid)
  1573. {
  1574. struct bfad_fcxp *drv_fcxp = bfad_fcxp;
  1575. struct bfa_sge_s *sge;
  1576. sge = drv_fcxp->req_sge + sgeid;
  1577. return sge->sg_len;
  1578. }
  1579. u64
  1580. bfad_fcxp_get_rsp_sgaddr_cb(void *bfad_fcxp, int sgeid)
  1581. {
  1582. struct bfad_fcxp *drv_fcxp = bfad_fcxp;
  1583. struct bfa_sge_s *sge;
  1584. u64 addr;
  1585. sge = drv_fcxp->rsp_sge + sgeid;
  1586. addr = (u64)(size_t) sge->sg_addr;
  1587. return addr;
  1588. }
  1589. u32
  1590. bfad_fcxp_get_rsp_sglen_cb(void *bfad_fcxp, int sgeid)
  1591. {
  1592. struct bfad_fcxp *drv_fcxp = bfad_fcxp;
  1593. struct bfa_sge_s *sge;
  1594. sge = drv_fcxp->rsp_sge + sgeid;
  1595. return sge->sg_len;
  1596. }
  1597. void
  1598. bfad_send_fcpt_cb(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
  1599. bfa_status_t req_status, u32 rsp_len, u32 resid_len,
  1600. struct fchs_s *rsp_fchs)
  1601. {
  1602. struct bfad_fcxp *drv_fcxp = bfad_fcxp;
  1603. drv_fcxp->req_status = req_status;
  1604. drv_fcxp->rsp_len = rsp_len;
  1605. /* bfa_fcxp will be automatically freed by BFA */
  1606. drv_fcxp->bfa_fcxp = NULL;
  1607. complete(&drv_fcxp->comp);
  1608. }
  1609. struct bfad_buf_info *
  1610. bfad_fcxp_map_sg(struct bfad_s *bfad, void *payload_kbuf,
  1611. uint32_t payload_len, uint32_t *num_sgles)
  1612. {
  1613. struct bfad_buf_info *buf_base, *buf_info;
  1614. struct bfa_sge_s *sg_table;
  1615. int sge_num = 1;
  1616. buf_base = kzalloc((sizeof(struct bfad_buf_info) +
  1617. sizeof(struct bfa_sge_s)) * sge_num, GFP_KERNEL);
  1618. if (!buf_base)
  1619. return NULL;
  1620. sg_table = (struct bfa_sge_s *) (((uint8_t *)buf_base) +
  1621. (sizeof(struct bfad_buf_info) * sge_num));
  1622. /* Allocate dma coherent memory */
  1623. buf_info = buf_base;
  1624. buf_info->size = payload_len;
  1625. buf_info->virt = dma_alloc_coherent(&bfad->pcidev->dev, buf_info->size,
  1626. &buf_info->phys, GFP_KERNEL);
  1627. if (!buf_info->virt)
  1628. goto out_free_mem;
  1629. /* copy the linear bsg buffer to buf_info */
  1630. memset(buf_info->virt, 0, buf_info->size);
  1631. memcpy(buf_info->virt, payload_kbuf, buf_info->size);
  1632. /*
  1633. * Setup SG table
  1634. */
  1635. sg_table->sg_len = buf_info->size;
  1636. sg_table->sg_addr = (void *)(size_t) buf_info->phys;
  1637. *num_sgles = sge_num;
  1638. return buf_base;
  1639. out_free_mem:
  1640. kfree(buf_base);
  1641. return NULL;
  1642. }
  1643. void
  1644. bfad_fcxp_free_mem(struct bfad_s *bfad, struct bfad_buf_info *buf_base,
  1645. uint32_t num_sgles)
  1646. {
  1647. int i;
  1648. struct bfad_buf_info *buf_info = buf_base;
  1649. if (buf_base) {
  1650. for (i = 0; i < num_sgles; buf_info++, i++) {
  1651. if (buf_info->virt != NULL)
  1652. dma_free_coherent(&bfad->pcidev->dev,
  1653. buf_info->size, buf_info->virt,
  1654. buf_info->phys);
  1655. }
  1656. kfree(buf_base);
  1657. }
  1658. }
  1659. int
  1660. bfad_fcxp_bsg_send(struct fc_bsg_job *job, struct bfad_fcxp *drv_fcxp,
  1661. bfa_bsg_fcpt_t *bsg_fcpt)
  1662. {
  1663. struct bfa_fcxp_s *hal_fcxp;
  1664. struct bfad_s *bfad = drv_fcxp->port->bfad;
  1665. unsigned long flags;
  1666. uint8_t lp_tag;
  1667. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1668. /* Allocate bfa_fcxp structure */
  1669. hal_fcxp = bfa_fcxp_alloc(drv_fcxp, &bfad->bfa,
  1670. drv_fcxp->num_req_sgles,
  1671. drv_fcxp->num_rsp_sgles,
  1672. bfad_fcxp_get_req_sgaddr_cb,
  1673. bfad_fcxp_get_req_sglen_cb,
  1674. bfad_fcxp_get_rsp_sgaddr_cb,
  1675. bfad_fcxp_get_rsp_sglen_cb);
  1676. if (!hal_fcxp) {
  1677. bfa_trc(bfad, 0);
  1678. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1679. return BFA_STATUS_ENOMEM;
  1680. }
  1681. drv_fcxp->bfa_fcxp = hal_fcxp;
  1682. lp_tag = bfa_lps_get_tag_from_pid(&bfad->bfa, bsg_fcpt->fchs.s_id);
  1683. bfa_fcxp_send(hal_fcxp, drv_fcxp->bfa_rport, bsg_fcpt->vf_id, lp_tag,
  1684. bsg_fcpt->cts, bsg_fcpt->cos,
  1685. job->request_payload.payload_len,
  1686. &bsg_fcpt->fchs, bfad_send_fcpt_cb, bfad,
  1687. job->reply_payload.payload_len, bsg_fcpt->tsecs);
  1688. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1689. return BFA_STATUS_OK;
  1690. }
  1691. int
  1692. bfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
  1693. {
  1694. struct bfa_bsg_data *bsg_data;
  1695. struct bfad_im_port_s *im_port =
  1696. (struct bfad_im_port_s *) job->shost->hostdata[0];
  1697. struct bfad_s *bfad = im_port->bfad;
  1698. bfa_bsg_fcpt_t *bsg_fcpt;
  1699. struct bfad_fcxp *drv_fcxp;
  1700. struct bfa_fcs_lport_s *fcs_port;
  1701. struct bfa_fcs_rport_s *fcs_rport;
  1702. uint32_t command_type = job->request->msgcode;
  1703. unsigned long flags;
  1704. struct bfad_buf_info *rsp_buf_info;
  1705. void *req_kbuf = NULL, *rsp_kbuf = NULL;
  1706. int rc = -EINVAL;
  1707. job->reply_len = sizeof(uint32_t); /* Atleast uint32_t reply_len */
  1708. job->reply->reply_payload_rcv_len = 0;
  1709. /* Get the payload passed in from userspace */
  1710. bsg_data = (struct bfa_bsg_data *) (((char *)job->request) +
  1711. sizeof(struct fc_bsg_request));
  1712. if (bsg_data == NULL)
  1713. goto out;
  1714. /*
  1715. * Allocate buffer for bsg_fcpt and do a copy_from_user op for payload
  1716. * buffer of size bsg_data->payload_len
  1717. */
  1718. bsg_fcpt = (struct bfa_bsg_fcpt_s *)
  1719. kzalloc(bsg_data->payload_len, GFP_KERNEL);
  1720. if (!bsg_fcpt)
  1721. goto out;
  1722. if (copy_from_user((uint8_t *)bsg_fcpt, bsg_data->payload,
  1723. bsg_data->payload_len)) {
  1724. kfree(bsg_fcpt);
  1725. goto out;
  1726. }
  1727. drv_fcxp = kzalloc(sizeof(struct bfad_fcxp), GFP_KERNEL);
  1728. if (drv_fcxp == NULL) {
  1729. rc = -ENOMEM;
  1730. goto out;
  1731. }
  1732. spin_lock_irqsave(&bfad->bfad_lock, flags);
  1733. fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, bsg_fcpt->vf_id,
  1734. bsg_fcpt->lpwwn);
  1735. if (fcs_port == NULL) {
  1736. bsg_fcpt->status = BFA_STATUS_UNKNOWN_LWWN;
  1737. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1738. goto out_free_mem;
  1739. }
  1740. /* Check if the port is online before sending FC Passthru cmd */
  1741. if (!bfa_fcs_lport_is_online(fcs_port)) {
  1742. bsg_fcpt->status = BFA_STATUS_PORT_OFFLINE;
  1743. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1744. goto out_free_mem;
  1745. }
  1746. drv_fcxp->port = fcs_port->bfad_port;
  1747. if (drv_fcxp->port->bfad == 0)
  1748. drv_fcxp->port->bfad = bfad;
  1749. /* Fetch the bfa_rport - if nexus needed */
  1750. if (command_type == FC_BSG_HST_ELS_NOLOGIN ||
  1751. command_type == FC_BSG_HST_CT) {
  1752. /* BSG HST commands: no nexus needed */
  1753. drv_fcxp->bfa_rport = NULL;
  1754. } else if (command_type == FC_BSG_RPT_ELS ||
  1755. command_type == FC_BSG_RPT_CT) {
  1756. /* BSG RPT commands: nexus needed */
  1757. fcs_rport = bfa_fcs_lport_get_rport_by_pwwn(fcs_port,
  1758. bsg_fcpt->dpwwn);
  1759. if (fcs_rport == NULL) {
  1760. bsg_fcpt->status = BFA_STATUS_UNKNOWN_RWWN;
  1761. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1762. goto out_free_mem;
  1763. }
  1764. drv_fcxp->bfa_rport = fcs_rport->bfa_rport;
  1765. } else { /* Unknown BSG msgcode; return -EINVAL */
  1766. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1767. goto out_free_mem;
  1768. }
  1769. spin_unlock_irqrestore(&bfad->bfad_lock, flags);
  1770. /* allocate memory for req / rsp buffers */
  1771. req_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL);
  1772. if (!req_kbuf) {
  1773. printk(KERN_INFO "bfa %s: fcpt request buffer alloc failed\n",
  1774. bfad->pci_name);
  1775. rc = -ENOMEM;
  1776. goto out_free_mem;
  1777. }
  1778. rsp_kbuf = kzalloc(job->reply_payload.payload_len, GFP_KERNEL);
  1779. if (!rsp_kbuf) {
  1780. printk(KERN_INFO "bfa %s: fcpt response buffer alloc failed\n",
  1781. bfad->pci_name);
  1782. rc = -ENOMEM;
  1783. goto out_free_mem;
  1784. }
  1785. /* map req sg - copy the sg_list passed in to the linear buffer */
  1786. sg_copy_to_buffer(job->request_payload.sg_list,
  1787. job->request_payload.sg_cnt, req_kbuf,
  1788. job->request_payload.payload_len);
  1789. drv_fcxp->reqbuf_info = bfad_fcxp_map_sg(bfad, req_kbuf,
  1790. job->request_payload.payload_len,
  1791. &drv_fcxp->num_req_sgles);
  1792. if (!drv_fcxp->reqbuf_info) {
  1793. printk(KERN_INFO "bfa %s: fcpt request fcxp_map_sg failed\n",
  1794. bfad->pci_name);
  1795. rc = -ENOMEM;
  1796. goto out_free_mem;
  1797. }
  1798. drv_fcxp->req_sge = (struct bfa_sge_s *)
  1799. (((uint8_t *)drv_fcxp->reqbuf_info) +
  1800. (sizeof(struct bfad_buf_info) *
  1801. drv_fcxp->num_req_sgles));
  1802. /* map rsp sg */
  1803. drv_fcxp->rspbuf_info = bfad_fcxp_map_sg(bfad, rsp_kbuf,
  1804. job->reply_payload.payload_len,
  1805. &drv_fcxp->num_rsp_sgles);
  1806. if (!drv_fcxp->rspbuf_info) {
  1807. printk(KERN_INFO "bfa %s: fcpt response fcxp_map_sg failed\n",
  1808. bfad->pci_name);
  1809. rc = -ENOMEM;
  1810. goto out_free_mem;
  1811. }
  1812. rsp_buf_info = (struct bfad_buf_info *)drv_fcxp->rspbuf_info;
  1813. drv_fcxp->rsp_sge = (struct bfa_sge_s *)
  1814. (((uint8_t *)drv_fcxp->rspbuf_info) +
  1815. (sizeof(struct bfad_buf_info) *
  1816. drv_fcxp->num_rsp_sgles));
  1817. /* fcxp send */
  1818. init_completion(&drv_fcxp->comp);
  1819. rc = bfad_fcxp_bsg_send(job, drv_fcxp, bsg_fcpt);
  1820. if (rc == BFA_STATUS_OK) {
  1821. wait_for_completion(&drv_fcxp->comp);
  1822. bsg_fcpt->status = drv_fcxp->req_status;
  1823. } else {
  1824. bsg_fcpt->status = rc;
  1825. goto out_free_mem;
  1826. }
  1827. /* fill the job->reply data */
  1828. if (drv_fcxp->req_status == BFA_STATUS_OK) {
  1829. job->reply_len = drv_fcxp->rsp_len;
  1830. job->reply->reply_payload_rcv_len = drv_fcxp->rsp_len;
  1831. job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
  1832. } else {
  1833. job->reply->reply_payload_rcv_len =
  1834. sizeof(struct fc_bsg_ctels_reply);
  1835. job->reply_len = sizeof(uint32_t);
  1836. job->reply->reply_data.ctels_reply.status =
  1837. FC_CTELS_STATUS_REJECT;
  1838. }
  1839. /* Copy the response data to the reply_payload sg list */
  1840. sg_copy_from_buffer(job->reply_payload.sg_list,
  1841. job->reply_payload.sg_cnt,
  1842. (uint8_t *)rsp_buf_info->virt,
  1843. job->reply_payload.payload_len);
  1844. out_free_mem:
  1845. bfad_fcxp_free_mem(bfad, drv_fcxp->rspbuf_info,
  1846. drv_fcxp->num_rsp_sgles);
  1847. bfad_fcxp_free_mem(bfad, drv_fcxp->reqbuf_info,
  1848. drv_fcxp->num_req_sgles);
  1849. kfree(req_kbuf);
  1850. kfree(rsp_kbuf);
  1851. /* Need a copy to user op */
  1852. if (copy_to_user(bsg_data->payload, (void *) bsg_fcpt,
  1853. bsg_data->payload_len))
  1854. rc = -EIO;
  1855. kfree(bsg_fcpt);
  1856. kfree(drv_fcxp);
  1857. out:
  1858. job->reply->result = rc;
  1859. if (rc == BFA_STATUS_OK)
  1860. job->job_done(job);
  1861. return rc;
  1862. }
  1863. int
  1864. bfad_im_bsg_request(struct fc_bsg_job *job)
  1865. {
  1866. uint32_t rc = BFA_STATUS_OK;
  1867. switch (job->request->msgcode) {
  1868. case FC_BSG_HST_VENDOR:
  1869. /* Process BSG HST Vendor requests */
  1870. rc = bfad_im_bsg_vendor_request(job);
  1871. break;
  1872. case FC_BSG_HST_ELS_NOLOGIN:
  1873. case FC_BSG_RPT_ELS:
  1874. case FC_BSG_HST_CT:
  1875. case FC_BSG_RPT_CT:
  1876. /* Process BSG ELS/CT commands */
  1877. rc = bfad_im_bsg_els_ct_request(job);
  1878. break;
  1879. default:
  1880. job->reply->result = rc = -EINVAL;
  1881. job->reply->reply_payload_rcv_len = 0;
  1882. break;
  1883. }
  1884. return rc;
  1885. }
  1886. int
  1887. bfad_im_bsg_timeout(struct fc_bsg_job *job)
  1888. {
  1889. /* Don't complete the BSG job request - return -EAGAIN
  1890. * to reset bsg job timeout : for ELS/CT pass thru we
  1891. * already have timer to track the request.
  1892. */
  1893. return -EAGAIN;
  1894. }