be_mgmt.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554
  1. /*
  2. * This file is part of the Emulex Linux Device Driver for Enterprise iSCSI
  3. * Host Bus Adapters. Refer to the README file included with this package
  4. * for driver version and adapter compatibility.
  5. *
  6. * Copyright (c) 2018 Broadcom. All Rights Reserved.
  7. * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of version 2 of the GNU General Public License as published
  11. * by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful. ALL EXPRESS
  14. * OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
  15. * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
  16. * OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
  17. * DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
  18. * See the GNU General Public License for more details, a copy of which
  19. * can be found in the file COPYING included with this package.
  20. *
  21. * Contact Information:
  22. * linux-drivers@broadcom.com
  23. *
  24. */
  25. #include <linux/bsg-lib.h>
  26. #include <scsi/scsi_transport_iscsi.h>
  27. #include <scsi/scsi_bsg_iscsi.h>
  28. #include "be_mgmt.h"
  29. #include "be_iscsi.h"
  30. #include "be_main.h"
  31. unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
  32. struct beiscsi_hba *phba,
  33. struct bsg_job *job,
  34. struct be_dma_mem *nonemb_cmd)
  35. {
  36. struct be_mcc_wrb *wrb;
  37. struct be_sge *mcc_sge;
  38. unsigned int tag = 0;
  39. struct iscsi_bsg_request *bsg_req = job->request;
  40. struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
  41. unsigned short region, sector_size, sector, offset;
  42. nonemb_cmd->size = job->request_payload.payload_len;
  43. memset(nonemb_cmd->va, 0, nonemb_cmd->size);
  44. region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
  45. sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
  46. sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
  47. offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4];
  48. req->region = region;
  49. req->sector = sector;
  50. req->offset = offset;
  51. if (mutex_lock_interruptible(&ctrl->mbox_lock))
  52. return 0;
  53. switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
  54. case BEISCSI_WRITE_FLASH:
  55. offset = sector * sector_size + offset;
  56. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  57. OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
  58. sg_copy_to_buffer(job->request_payload.sg_list,
  59. job->request_payload.sg_cnt,
  60. nonemb_cmd->va + offset, job->request_len);
  61. break;
  62. case BEISCSI_READ_FLASH:
  63. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  64. OPCODE_COMMON_READ_FLASH, sizeof(*req));
  65. break;
  66. default:
  67. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  68. "BG_%d : Unsupported cmd = 0x%x\n\n",
  69. bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
  70. mutex_unlock(&ctrl->mbox_lock);
  71. return -EPERM;
  72. }
  73. wrb = alloc_mcc_wrb(phba, &tag);
  74. if (!wrb) {
  75. mutex_unlock(&ctrl->mbox_lock);
  76. return 0;
  77. }
  78. mcc_sge = nonembedded_sgl(wrb);
  79. be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
  80. job->request_payload.sg_cnt);
  81. mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  82. mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
  83. mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
  84. be_mcc_notify(phba, tag);
  85. mutex_unlock(&ctrl->mbox_lock);
  86. return tag;
  87. }
  88. /**
  89. * mgmt_open_connection()- Establish a TCP CXN
  90. * @dst_addr: Destination Address
  91. * @beiscsi_ep: ptr to device endpoint struct
  92. * @nonemb_cmd: ptr to memory allocated for command
  93. *
  94. * return
  95. * Success: Tag number of the MBX Command issued
  96. * Failure: Error code
  97. **/
  98. int mgmt_open_connection(struct beiscsi_hba *phba,
  99. struct sockaddr *dst_addr,
  100. struct beiscsi_endpoint *beiscsi_ep,
  101. struct be_dma_mem *nonemb_cmd)
  102. {
  103. struct hwi_controller *phwi_ctrlr;
  104. struct hwi_context_memory *phwi_context;
  105. struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
  106. struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
  107. struct be_ctrl_info *ctrl = &phba->ctrl;
  108. struct be_mcc_wrb *wrb;
  109. struct tcp_connect_and_offload_in_v1 *req;
  110. unsigned short def_hdr_id;
  111. unsigned short def_data_id;
  112. struct phys_addr template_address = { 0, 0 };
  113. struct phys_addr *ptemplate_address;
  114. unsigned int tag = 0;
  115. unsigned int i, ulp_num;
  116. unsigned short cid = beiscsi_ep->ep_cid;
  117. struct be_sge *sge;
  118. if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
  119. beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
  120. "BG_%d : unknown addr family %d\n",
  121. dst_addr->sa_family);
  122. return 0;
  123. }
  124. phwi_ctrlr = phba->phwi_ctrlr;
  125. phwi_context = phwi_ctrlr->phwi_ctxt;
  126. ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
  127. def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
  128. def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
  129. ptemplate_address = &template_address;
  130. ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
  131. if (mutex_lock_interruptible(&ctrl->mbox_lock))
  132. return 0;
  133. wrb = alloc_mcc_wrb(phba, &tag);
  134. if (!wrb) {
  135. mutex_unlock(&ctrl->mbox_lock);
  136. return 0;
  137. }
  138. sge = nonembedded_sgl(wrb);
  139. req = nonemb_cmd->va;
  140. memset(req, 0, sizeof(*req));
  141. be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
  142. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  143. OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
  144. nonemb_cmd->size);
  145. if (dst_addr->sa_family == PF_INET) {
  146. __be32 s_addr = daddr_in->sin_addr.s_addr;
  147. req->ip_address.ip_type = BEISCSI_IP_TYPE_V4;
  148. req->ip_address.addr[0] = s_addr & 0x000000ff;
  149. req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
  150. req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
  151. req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
  152. req->tcp_port = ntohs(daddr_in->sin_port);
  153. beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
  154. beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
  155. beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4;
  156. } else {
  157. /* else its PF_INET6 family */
  158. req->ip_address.ip_type = BEISCSI_IP_TYPE_V6;
  159. memcpy(&req->ip_address.addr,
  160. &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
  161. req->tcp_port = ntohs(daddr_in6->sin6_port);
  162. beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
  163. memcpy(&beiscsi_ep->dst6_addr,
  164. &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
  165. beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6;
  166. }
  167. req->cid = cid;
  168. i = phba->nxt_cqid++;
  169. if (phba->nxt_cqid == phba->num_cpus)
  170. phba->nxt_cqid = 0;
  171. req->cq_id = phwi_context->be_cq[i].id;
  172. beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
  173. "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
  174. req->defq_id = def_hdr_id;
  175. req->hdr_ring_id = def_hdr_id;
  176. req->data_ring_id = def_data_id;
  177. req->do_offload = 1;
  178. req->dataout_template_pa.lo = ptemplate_address->lo;
  179. req->dataout_template_pa.hi = ptemplate_address->hi;
  180. sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  181. sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
  182. sge->len = cpu_to_le32(nonemb_cmd->size);
  183. if (!is_chip_be2_be3r(phba)) {
  184. req->hdr.version = MBX_CMD_VER1;
  185. req->tcp_window_size = 0x8000;
  186. req->tcp_window_scale_count = 2;
  187. }
  188. be_mcc_notify(phba, tag);
  189. mutex_unlock(&ctrl->mbox_lock);
  190. return tag;
  191. }
  192. /*
  193. * beiscsi_exec_nemb_cmd()- execute non-embedded MBX cmd
  194. * @phba: driver priv structure
  195. * @nonemb_cmd: DMA address of the MBX command to be issued
  196. * @cbfn: callback func on MCC completion
  197. * @resp_buf: buffer to copy the MBX cmd response
  198. * @resp_buf_len: response length to be copied
  199. *
  200. **/
  201. static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba,
  202. struct be_dma_mem *nonemb_cmd,
  203. void (*cbfn)(struct beiscsi_hba *,
  204. unsigned int),
  205. void *resp_buf, u32 resp_buf_len)
  206. {
  207. struct be_ctrl_info *ctrl = &phba->ctrl;
  208. struct be_mcc_wrb *wrb;
  209. struct be_sge *sge;
  210. unsigned int tag;
  211. int rc = 0;
  212. mutex_lock(&ctrl->mbox_lock);
  213. wrb = alloc_mcc_wrb(phba, &tag);
  214. if (!wrb) {
  215. mutex_unlock(&ctrl->mbox_lock);
  216. rc = -ENOMEM;
  217. goto free_cmd;
  218. }
  219. sge = nonembedded_sgl(wrb);
  220. be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
  221. sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  222. sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
  223. sge->len = cpu_to_le32(nonemb_cmd->size);
  224. if (cbfn) {
  225. struct be_dma_mem *tag_mem;
  226. set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
  227. ctrl->ptag_state[tag].cbfn = cbfn;
  228. tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
  229. /* store DMA mem to be freed in callback */
  230. tag_mem->size = nonemb_cmd->size;
  231. tag_mem->va = nonemb_cmd->va;
  232. tag_mem->dma = nonemb_cmd->dma;
  233. }
  234. be_mcc_notify(phba, tag);
  235. mutex_unlock(&ctrl->mbox_lock);
  236. /* with cbfn set, its async cmd, don't wait */
  237. if (cbfn)
  238. return 0;
  239. rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd);
  240. /* copy the response, if any */
  241. if (resp_buf)
  242. memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
  243. /**
  244. * This is special case of NTWK_GET_IF_INFO where the size of
  245. * response is not known. beiscsi_if_get_info checks the return
  246. * value to free DMA buffer.
  247. */
  248. if (rc == -EAGAIN)
  249. return rc;
  250. /**
  251. * If FW is busy that is driver timed out, DMA buffer is saved with
  252. * the tag, only when the cmd completes this buffer is freed.
  253. */
  254. if (rc == -EBUSY)
  255. return rc;
  256. free_cmd:
  257. pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
  258. nonemb_cmd->va, nonemb_cmd->dma);
  259. return rc;
  260. }
  261. static int beiscsi_prep_nemb_cmd(struct beiscsi_hba *phba,
  262. struct be_dma_mem *cmd,
  263. u8 subsystem, u8 opcode, u32 size)
  264. {
  265. cmd->va = pci_zalloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
  266. if (!cmd->va) {
  267. beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
  268. "BG_%d : Failed to allocate memory for if info\n");
  269. return -ENOMEM;
  270. }
  271. cmd->size = size;
  272. be_cmd_hdr_prepare(cmd->va, subsystem, opcode, size);
  273. beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
  274. "BG_%d : subsystem %u cmd %u size %u\n",
  275. subsystem, opcode, size);
  276. return 0;
  277. }
  278. static void __beiscsi_eq_delay_compl(struct beiscsi_hba *phba, unsigned int tag)
  279. {
  280. struct be_dma_mem *tag_mem;
  281. /* status is ignored */
  282. __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
  283. tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
  284. if (tag_mem->size) {
  285. pci_free_consistent(phba->pcidev, tag_mem->size,
  286. tag_mem->va, tag_mem->dma);
  287. tag_mem->size = 0;
  288. }
  289. }
  290. int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
  291. struct be_set_eqd *set_eqd, int num)
  292. {
  293. struct be_cmd_req_modify_eq_delay *req;
  294. struct be_dma_mem nonemb_cmd;
  295. int i, rc;
  296. rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_COMMON,
  297. OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
  298. if (rc)
  299. return rc;
  300. req = nonemb_cmd.va;
  301. req->num_eq = cpu_to_le32(num);
  302. for (i = 0; i < num; i++) {
  303. req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
  304. req->delay[i].phase = 0;
  305. req->delay[i].delay_multiplier =
  306. cpu_to_le32(set_eqd[i].delay_multiplier);
  307. }
  308. return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd,
  309. __beiscsi_eq_delay_compl, NULL, 0);
  310. }
  311. /**
  312. * beiscsi_get_initiator_name - read initiator name from flash
  313. * @phba: device priv structure
  314. * @name: buffer pointer
  315. * @cfg: fetch user configured
  316. *
  317. */
  318. int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name, bool cfg)
  319. {
  320. struct be_dma_mem nonemb_cmd;
  321. struct be_cmd_hba_name resp;
  322. struct be_cmd_hba_name *req;
  323. int rc;
  324. rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI_INI,
  325. OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, sizeof(resp));
  326. if (rc)
  327. return rc;
  328. req = nonemb_cmd.va;
  329. if (cfg)
  330. req->hdr.version = 1;
  331. rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
  332. &resp, sizeof(resp));
  333. if (rc) {
  334. beiscsi_log(phba, KERN_ERR,
  335. BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
  336. "BS_%d : Initiator Name MBX Failed\n");
  337. return rc;
  338. }
  339. rc = sprintf(name, "%s\n", resp.initiator_name);
  340. return rc;
  341. }
  342. unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba)
  343. {
  344. struct be_ctrl_info *ctrl = &phba->ctrl;
  345. struct be_mcc_wrb *wrb;
  346. struct be_cmd_get_all_if_id_req *req;
  347. struct be_cmd_get_all_if_id_req *pbe_allid;
  348. unsigned int tag;
  349. int status = 0;
  350. if (mutex_lock_interruptible(&ctrl->mbox_lock))
  351. return -EINTR;
  352. wrb = alloc_mcc_wrb(phba, &tag);
  353. if (!wrb) {
  354. mutex_unlock(&ctrl->mbox_lock);
  355. return -ENOMEM;
  356. }
  357. req = embedded_payload(wrb);
  358. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  359. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  360. OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
  361. sizeof(*req));
  362. be_mcc_notify(phba, tag);
  363. mutex_unlock(&ctrl->mbox_lock);
  364. status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
  365. if (status) {
  366. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  367. "BG_%d : %s failed: %d\n", __func__, status);
  368. return -EBUSY;
  369. }
  370. pbe_allid = embedded_payload(wrb);
  371. /* we now support only one interface per function */
  372. phba->interface_handle = pbe_allid->if_hndl_list[0];
  373. return status;
  374. }
  375. static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type)
  376. {
  377. u32 len;
  378. len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
  379. while (len && !ip[len - 1])
  380. len--;
  381. return (len == 0);
  382. }
  383. static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
  384. u32 action, u32 ip_type, u8 *gw)
  385. {
  386. struct be_cmd_set_def_gateway_req *req;
  387. struct be_dma_mem nonemb_cmd;
  388. int rt_val;
  389. rt_val = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
  390. OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
  391. sizeof(*req));
  392. if (rt_val)
  393. return rt_val;
  394. req = nonemb_cmd.va;
  395. req->action = action;
  396. req->ip_addr.ip_type = ip_type;
  397. memcpy(req->ip_addr.addr, gw,
  398. (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
  399. return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
  400. }
  401. int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw)
  402. {
  403. struct be_cmd_get_def_gateway_resp gw_resp;
  404. int rt_val;
  405. memset(&gw_resp, 0, sizeof(gw_resp));
  406. rt_val = beiscsi_if_get_gw(phba, ip_type, &gw_resp);
  407. if (rt_val) {
  408. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  409. "BG_%d : Failed to Get Gateway Addr\n");
  410. return rt_val;
  411. }
  412. if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) {
  413. rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type,
  414. gw_resp.ip_addr.addr);
  415. if (rt_val) {
  416. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  417. "BG_%d : Failed to clear Gateway Addr Set\n");
  418. return rt_val;
  419. }
  420. }
  421. rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw);
  422. if (rt_val)
  423. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  424. "BG_%d : Failed to Set Gateway Addr\n");
  425. return rt_val;
  426. }
  427. int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
  428. struct be_cmd_get_def_gateway_resp *resp)
  429. {
  430. struct be_cmd_get_def_gateway_req *req;
  431. struct be_dma_mem nonemb_cmd;
  432. int rc;
  433. rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
  434. OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
  435. sizeof(*resp));
  436. if (rc)
  437. return rc;
  438. req = nonemb_cmd.va;
  439. req->ip_type = ip_type;
  440. return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
  441. resp, sizeof(*resp));
  442. }
  443. static int
  444. beiscsi_if_clr_ip(struct beiscsi_hba *phba,
  445. struct be_cmd_get_if_info_resp *if_info)
  446. {
  447. struct be_cmd_set_ip_addr_req *req;
  448. struct be_dma_mem nonemb_cmd;
  449. int rc;
  450. rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
  451. OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
  452. sizeof(*req));
  453. if (rc)
  454. return rc;
  455. req = nonemb_cmd.va;
  456. req->ip_params.record_entry_count = 1;
  457. req->ip_params.ip_record.action = IP_ACTION_DEL;
  458. req->ip_params.ip_record.interface_hndl =
  459. phba->interface_handle;
  460. req->ip_params.ip_record.ip_addr.size_of_structure =
  461. sizeof(struct be_ip_addr_subnet_format);
  462. req->ip_params.ip_record.ip_addr.ip_type = if_info->ip_addr.ip_type;
  463. memcpy(req->ip_params.ip_record.ip_addr.addr,
  464. if_info->ip_addr.addr,
  465. sizeof(if_info->ip_addr.addr));
  466. memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
  467. if_info->ip_addr.subnet_mask,
  468. sizeof(if_info->ip_addr.subnet_mask));
  469. rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
  470. if (rc < 0 || req->ip_params.ip_record.status) {
  471. beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
  472. "BG_%d : failed to clear IP: rc %d status %d\n",
  473. rc, req->ip_params.ip_record.status);
  474. }
  475. return rc;
  476. }
  477. static int
  478. beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip,
  479. u8 *subnet, u32 ip_type)
  480. {
  481. struct be_cmd_set_ip_addr_req *req;
  482. struct be_dma_mem nonemb_cmd;
  483. uint32_t ip_len;
  484. int rc;
  485. rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
  486. OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
  487. sizeof(*req));
  488. if (rc)
  489. return rc;
  490. req = nonemb_cmd.va;
  491. req->ip_params.record_entry_count = 1;
  492. req->ip_params.ip_record.action = IP_ACTION_ADD;
  493. req->ip_params.ip_record.interface_hndl =
  494. phba->interface_handle;
  495. req->ip_params.ip_record.ip_addr.size_of_structure =
  496. sizeof(struct be_ip_addr_subnet_format);
  497. req->ip_params.ip_record.ip_addr.ip_type = ip_type;
  498. ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
  499. memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len);
  500. if (subnet)
  501. memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
  502. subnet, ip_len);
  503. rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
  504. /**
  505. * In some cases, host needs to look into individual record status
  506. * even though FW reported success for that IOCTL.
  507. */
  508. if (rc < 0 || req->ip_params.ip_record.status) {
  509. __beiscsi_log(phba, KERN_ERR,
  510. "BG_%d : failed to set IP: rc %d status %d\n",
  511. rc, req->ip_params.ip_record.status);
  512. if (req->ip_params.ip_record.status)
  513. rc = -EINVAL;
  514. }
  515. return rc;
  516. }
  517. int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
  518. u8 *ip, u8 *subnet)
  519. {
  520. struct be_cmd_get_if_info_resp *if_info;
  521. struct be_cmd_rel_dhcp_req *reldhcp;
  522. struct be_dma_mem nonemb_cmd;
  523. int rc;
  524. rc = beiscsi_if_get_info(phba, ip_type, &if_info);
  525. if (rc)
  526. return rc;
  527. if (if_info->dhcp_state) {
  528. rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
  529. CMD_SUBSYSTEM_ISCSI,
  530. OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
  531. sizeof(*reldhcp));
  532. if (rc)
  533. goto exit;
  534. reldhcp = nonemb_cmd.va;
  535. reldhcp->interface_hndl = phba->interface_handle;
  536. reldhcp->ip_type = ip_type;
  537. rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
  538. if (rc < 0) {
  539. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  540. "BG_%d : failed to release existing DHCP: %d\n",
  541. rc);
  542. goto exit;
  543. }
  544. }
  545. /* first delete any IP set */
  546. if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
  547. rc = beiscsi_if_clr_ip(phba, if_info);
  548. if (rc)
  549. goto exit;
  550. }
  551. /* if ip == NULL then this is called just to release DHCP IP */
  552. if (ip)
  553. rc = beiscsi_if_set_ip(phba, ip, subnet, ip_type);
  554. exit:
  555. kfree(if_info);
  556. return rc;
  557. }
  558. int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type)
  559. {
  560. struct be_cmd_get_def_gateway_resp gw_resp;
  561. struct be_cmd_get_if_info_resp *if_info;
  562. struct be_cmd_set_dhcp_req *dhcpreq;
  563. struct be_dma_mem nonemb_cmd;
  564. u8 *gw;
  565. int rc;
  566. rc = beiscsi_if_get_info(phba, ip_type, &if_info);
  567. if (rc)
  568. return rc;
  569. if (if_info->dhcp_state) {
  570. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  571. "BG_%d : DHCP Already Enabled\n");
  572. goto exit;
  573. }
  574. /* first delete any IP set */
  575. if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
  576. rc = beiscsi_if_clr_ip(phba, if_info);
  577. if (rc)
  578. goto exit;
  579. }
  580. /* delete gateway settings if mode change is to DHCP */
  581. memset(&gw_resp, 0, sizeof(gw_resp));
  582. /* use ip_type provided in if_info */
  583. rc = beiscsi_if_get_gw(phba, if_info->ip_addr.ip_type, &gw_resp);
  584. if (rc) {
  585. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  586. "BG_%d : Failed to Get Gateway Addr\n");
  587. goto exit;
  588. }
  589. gw = (u8 *)&gw_resp.ip_addr.addr;
  590. if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) {
  591. rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL,
  592. if_info->ip_addr.ip_type, gw);
  593. if (rc) {
  594. beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  595. "BG_%d : Failed to clear Gateway Addr Set\n");
  596. goto exit;
  597. }
  598. }
  599. rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
  600. OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
  601. sizeof(*dhcpreq));
  602. if (rc)
  603. goto exit;
  604. dhcpreq = nonemb_cmd.va;
  605. dhcpreq->flags = 1; /* 1 - blocking; 0 - non-blocking */
  606. dhcpreq->retry_count = 1;
  607. dhcpreq->interface_hndl = phba->interface_handle;
  608. dhcpreq->ip_type = ip_type;
  609. rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
  610. exit:
  611. kfree(if_info);
  612. return rc;
  613. }
  614. /**
  615. * beiscsi_if_set_vlan()- Issue and wait for CMD completion
  616. * @phba: device private structure instance
  617. * @vlan_tag: VLAN tag
  618. *
  619. * Issue the MBX Cmd and wait for the completion of the
  620. * command.
  621. *
  622. * returns
  623. * Success: 0
  624. * Failure: Non-Xero Value
  625. **/
  626. int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag)
  627. {
  628. int rc;
  629. unsigned int tag;
  630. tag = be_cmd_set_vlan(phba, vlan_tag);
  631. if (!tag) {
  632. beiscsi_log(phba, KERN_ERR,
  633. (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
  634. "BG_%d : VLAN Setting Failed\n");
  635. return -EBUSY;
  636. }
  637. rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
  638. if (rc) {
  639. beiscsi_log(phba, KERN_ERR,
  640. (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
  641. "BS_%d : VLAN MBX Cmd Failed\n");
  642. return rc;
  643. }
  644. return rc;
  645. }
  646. int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
  647. struct be_cmd_get_if_info_resp **if_info)
  648. {
  649. struct be_cmd_get_if_info_req *req;
  650. struct be_dma_mem nonemb_cmd;
  651. uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
  652. int rc;
  653. rc = beiscsi_if_get_handle(phba);
  654. if (rc)
  655. return rc;
  656. do {
  657. rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
  658. CMD_SUBSYSTEM_ISCSI,
  659. OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
  660. ioctl_size);
  661. if (rc)
  662. return rc;
  663. req = nonemb_cmd.va;
  664. req->interface_hndl = phba->interface_handle;
  665. req->ip_type = ip_type;
  666. /* Allocate memory for if_info */
  667. *if_info = kzalloc(ioctl_size, GFP_KERNEL);
  668. if (!*if_info) {
  669. beiscsi_log(phba, KERN_ERR,
  670. BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
  671. "BG_%d : Memory Allocation Failure\n");
  672. /* Free the DMA memory for the IOCTL issuing */
  673. pci_free_consistent(phba->ctrl.pdev,
  674. nonemb_cmd.size,
  675. nonemb_cmd.va,
  676. nonemb_cmd.dma);
  677. return -ENOMEM;
  678. }
  679. rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, *if_info,
  680. ioctl_size);
  681. /* Check if the error is because of Insufficent_Buffer */
  682. if (rc == -EAGAIN) {
  683. /* Get the new memory size */
  684. ioctl_size = ((struct be_cmd_resp_hdr *)
  685. nonemb_cmd.va)->actual_resp_len;
  686. ioctl_size += sizeof(struct be_cmd_req_hdr);
  687. /* Free the previous allocated DMA memory */
  688. pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
  689. nonemb_cmd.va,
  690. nonemb_cmd.dma);
  691. /* Free the virtual memory */
  692. kfree(*if_info);
  693. } else
  694. break;
  695. } while (true);
  696. return rc;
  697. }
  698. int mgmt_get_nic_conf(struct beiscsi_hba *phba,
  699. struct be_cmd_get_nic_conf_resp *nic)
  700. {
  701. struct be_dma_mem nonemb_cmd;
  702. int rc;
  703. rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
  704. OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
  705. sizeof(*nic));
  706. if (rc)
  707. return rc;
  708. return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
  709. nic, sizeof(*nic));
  710. }
  711. static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
  712. unsigned int tag)
  713. {
  714. struct be_cmd_get_boot_target_resp *boot_resp;
  715. struct be_cmd_resp_logout_fw_sess *logo_resp;
  716. struct be_cmd_get_session_resp *sess_resp;
  717. struct be_mcc_wrb *wrb;
  718. struct boot_struct *bs;
  719. int boot_work, status;
  720. if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
  721. __beiscsi_log(phba, KERN_ERR,
  722. "BG_%d : %s no boot work %lx\n",
  723. __func__, phba->state);
  724. return;
  725. }
  726. if (phba->boot_struct.tag != tag) {
  727. __beiscsi_log(phba, KERN_ERR,
  728. "BG_%d : %s tag mismatch %d:%d\n",
  729. __func__, tag, phba->boot_struct.tag);
  730. return;
  731. }
  732. bs = &phba->boot_struct;
  733. boot_work = 1;
  734. status = 0;
  735. switch (bs->action) {
  736. case BEISCSI_BOOT_REOPEN_SESS:
  737. status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
  738. if (!status)
  739. bs->action = BEISCSI_BOOT_GET_SHANDLE;
  740. else
  741. bs->retry--;
  742. break;
  743. case BEISCSI_BOOT_GET_SHANDLE:
  744. status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
  745. if (!status) {
  746. boot_resp = embedded_payload(wrb);
  747. bs->s_handle = boot_resp->boot_session_handle;
  748. }
  749. if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
  750. bs->action = BEISCSI_BOOT_REOPEN_SESS;
  751. bs->retry--;
  752. } else {
  753. bs->action = BEISCSI_BOOT_GET_SINFO;
  754. }
  755. break;
  756. case BEISCSI_BOOT_GET_SINFO:
  757. status = __beiscsi_mcc_compl_status(phba, tag, NULL,
  758. &bs->nonemb_cmd);
  759. if (!status) {
  760. sess_resp = bs->nonemb_cmd.va;
  761. memcpy(&bs->boot_sess, &sess_resp->session_info,
  762. sizeof(struct mgmt_session_info));
  763. bs->action = BEISCSI_BOOT_LOGOUT_SESS;
  764. } else {
  765. __beiscsi_log(phba, KERN_ERR,
  766. "BG_%d : get boot session info error : 0x%x\n",
  767. status);
  768. boot_work = 0;
  769. }
  770. pci_free_consistent(phba->ctrl.pdev, bs->nonemb_cmd.size,
  771. bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
  772. bs->nonemb_cmd.va = NULL;
  773. break;
  774. case BEISCSI_BOOT_LOGOUT_SESS:
  775. status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
  776. if (!status) {
  777. logo_resp = embedded_payload(wrb);
  778. if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
  779. __beiscsi_log(phba, KERN_ERR,
  780. "BG_%d : FW boot session logout error : 0x%x\n",
  781. logo_resp->session_status);
  782. }
  783. }
  784. /* continue to create boot_kset even if logout failed? */
  785. bs->action = BEISCSI_BOOT_CREATE_KSET;
  786. break;
  787. default:
  788. break;
  789. }
  790. /* clear the tag so no other completion matches this tag */
  791. bs->tag = 0;
  792. if (!bs->retry) {
  793. boot_work = 0;
  794. __beiscsi_log(phba, KERN_ERR,
  795. "BG_%d : failed to setup boot target: status %d action %d\n",
  796. status, bs->action);
  797. }
  798. if (!boot_work) {
  799. /* wait for next event to start boot_work */
  800. clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
  801. return;
  802. }
  803. schedule_work(&phba->boot_work);
  804. }
  805. /**
  806. * beiscsi_boot_logout_sess()- Logout from boot FW session
  807. * @phba: Device priv structure instance
  808. *
  809. * return
  810. * the TAG used for MBOX Command
  811. *
  812. */
  813. unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
  814. {
  815. struct be_ctrl_info *ctrl = &phba->ctrl;
  816. struct be_mcc_wrb *wrb;
  817. struct be_cmd_req_logout_fw_sess *req;
  818. unsigned int tag;
  819. mutex_lock(&ctrl->mbox_lock);
  820. wrb = alloc_mcc_wrb(phba, &tag);
  821. if (!wrb) {
  822. mutex_unlock(&ctrl->mbox_lock);
  823. return 0;
  824. }
  825. req = embedded_payload(wrb);
  826. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  827. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
  828. OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
  829. sizeof(struct be_cmd_req_logout_fw_sess));
  830. /* Use the session handle copied into boot_sess */
  831. req->session_handle = phba->boot_struct.boot_sess.session_handle;
  832. phba->boot_struct.tag = tag;
  833. set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
  834. ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
  835. be_mcc_notify(phba, tag);
  836. mutex_unlock(&ctrl->mbox_lock);
  837. return tag;
  838. }
  839. /**
  840. * beiscsi_boot_reopen_sess()- Reopen boot session
  841. * @phba: Device priv structure instance
  842. *
  843. * return
  844. * the TAG used for MBOX Command
  845. *
  846. **/
  847. unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
  848. {
  849. struct be_ctrl_info *ctrl = &phba->ctrl;
  850. struct be_mcc_wrb *wrb;
  851. struct be_cmd_reopen_session_req *req;
  852. unsigned int tag;
  853. mutex_lock(&ctrl->mbox_lock);
  854. wrb = alloc_mcc_wrb(phba, &tag);
  855. if (!wrb) {
  856. mutex_unlock(&ctrl->mbox_lock);
  857. return 0;
  858. }
  859. req = embedded_payload(wrb);
  860. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  861. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
  862. OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
  863. sizeof(struct be_cmd_reopen_session_resp));
  864. req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
  865. req->session_handle = BE_BOOT_INVALID_SHANDLE;
  866. phba->boot_struct.tag = tag;
  867. set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
  868. ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
  869. be_mcc_notify(phba, tag);
  870. mutex_unlock(&ctrl->mbox_lock);
  871. return tag;
  872. }
  873. /**
  874. * beiscsi_boot_get_sinfo()- Get boot session info
  875. * @phba: device priv structure instance
  876. *
  877. * Fetches the boot_struct.s_handle info from FW.
  878. * return
  879. * the TAG used for MBOX Command
  880. *
  881. **/
  882. unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
  883. {
  884. struct be_ctrl_info *ctrl = &phba->ctrl;
  885. struct be_cmd_get_session_req *req;
  886. struct be_dma_mem *nonemb_cmd;
  887. struct be_mcc_wrb *wrb;
  888. struct be_sge *sge;
  889. unsigned int tag;
  890. mutex_lock(&ctrl->mbox_lock);
  891. wrb = alloc_mcc_wrb(phba, &tag);
  892. if (!wrb) {
  893. mutex_unlock(&ctrl->mbox_lock);
  894. return 0;
  895. }
  896. nonemb_cmd = &phba->boot_struct.nonemb_cmd;
  897. nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp);
  898. nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
  899. nonemb_cmd->size,
  900. &nonemb_cmd->dma);
  901. if (!nonemb_cmd->va) {
  902. mutex_unlock(&ctrl->mbox_lock);
  903. return 0;
  904. }
  905. req = nonemb_cmd->va;
  906. memset(req, 0, sizeof(*req));
  907. sge = nonembedded_sgl(wrb);
  908. be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
  909. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
  910. OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
  911. sizeof(struct be_cmd_get_session_resp));
  912. req->session_handle = phba->boot_struct.s_handle;
  913. sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  914. sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
  915. sge->len = cpu_to_le32(nonemb_cmd->size);
  916. phba->boot_struct.tag = tag;
  917. set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
  918. ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
  919. be_mcc_notify(phba, tag);
  920. mutex_unlock(&ctrl->mbox_lock);
  921. return tag;
  922. }
  923. unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
  924. {
  925. struct be_ctrl_info *ctrl = &phba->ctrl;
  926. struct be_mcc_wrb *wrb;
  927. struct be_cmd_get_boot_target_req *req;
  928. unsigned int tag;
  929. mutex_lock(&ctrl->mbox_lock);
  930. wrb = alloc_mcc_wrb(phba, &tag);
  931. if (!wrb) {
  932. mutex_unlock(&ctrl->mbox_lock);
  933. return 0;
  934. }
  935. req = embedded_payload(wrb);
  936. be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
  937. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
  938. OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
  939. sizeof(struct be_cmd_get_boot_target_resp));
  940. if (async) {
  941. phba->boot_struct.tag = tag;
  942. set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
  943. ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
  944. }
  945. be_mcc_notify(phba, tag);
  946. mutex_unlock(&ctrl->mbox_lock);
  947. return tag;
  948. }
  949. /**
  950. * beiscsi_boot_get_shandle()- Get boot session handle
  951. * @phba: device priv structure instance
  952. * @s_handle: session handle returned for boot session.
  953. *
  954. * return
  955. * Success: 1
  956. * Failure: negative
  957. *
  958. **/
  959. int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
  960. {
  961. struct be_cmd_get_boot_target_resp *boot_resp;
  962. struct be_mcc_wrb *wrb;
  963. unsigned int tag;
  964. int rc;
  965. *s_handle = BE_BOOT_INVALID_SHANDLE;
  966. /* get configured boot session count and handle */
  967. tag = __beiscsi_boot_get_shandle(phba, 0);
  968. if (!tag) {
  969. beiscsi_log(phba, KERN_ERR,
  970. BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
  971. "BG_%d : Getting Boot Target Info Failed\n");
  972. return -EAGAIN;
  973. }
  974. rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
  975. if (rc) {
  976. beiscsi_log(phba, KERN_ERR,
  977. BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
  978. "BG_%d : MBX CMD get_boot_target Failed\n");
  979. return -EBUSY;
  980. }
  981. boot_resp = embedded_payload(wrb);
  982. /* check if there are any boot targets configured */
  983. if (!boot_resp->boot_session_count) {
  984. __beiscsi_log(phba, KERN_INFO,
  985. "BG_%d : No boot targets configured\n");
  986. return -ENXIO;
  987. }
  988. /* only if FW has logged in to the boot target, s_handle is valid */
  989. *s_handle = boot_resp->boot_session_handle;
  990. return 1;
  991. }
  992. /**
  993. * beiscsi_drvr_ver_disp()- Display the driver Name and Version
  994. * @dev: ptr to device not used.
  995. * @attr: device attribute, not used.
  996. * @buf: contains formatted text driver name and version
  997. *
  998. * return
  999. * size of the formatted string
  1000. **/
  1001. ssize_t
  1002. beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
  1003. char *buf)
  1004. {
  1005. return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
  1006. }
  1007. /**
  1008. * beiscsi_fw_ver_disp()- Display Firmware Version
  1009. * @dev: ptr to device not used.
  1010. * @attr: device attribute, not used.
  1011. * @buf: contains formatted text Firmware version
  1012. *
  1013. * return
  1014. * size of the formatted string
  1015. **/
  1016. ssize_t
  1017. beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
  1018. char *buf)
  1019. {
  1020. struct Scsi_Host *shost = class_to_shost(dev);
  1021. struct beiscsi_hba *phba = iscsi_host_priv(shost);
  1022. return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
  1023. }
  1024. /**
  1025. * beiscsi_active_session_disp()- Display Sessions Active
  1026. * @dev: ptr to device not used.
  1027. * @attr: device attribute, not used.
  1028. * @buf: contains formatted text Session Count
  1029. *
  1030. * return
  1031. * size of the formatted string
  1032. **/
  1033. ssize_t
  1034. beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
  1035. char *buf)
  1036. {
  1037. struct Scsi_Host *shost = class_to_shost(dev);
  1038. struct beiscsi_hba *phba = iscsi_host_priv(shost);
  1039. uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
  1040. for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
  1041. if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
  1042. avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
  1043. total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
  1044. len += snprintf(buf+len, PAGE_SIZE - len,
  1045. "ULP%d : %d\n", ulp_num,
  1046. (total_cids - avlbl_cids));
  1047. } else
  1048. len += snprintf(buf+len, PAGE_SIZE - len,
  1049. "ULP%d : %d\n", ulp_num, 0);
  1050. }
  1051. return len;
  1052. }
  1053. /**
  1054. * beiscsi_free_session_disp()- Display Avaliable Session
  1055. * @dev: ptr to device not used.
  1056. * @attr: device attribute, not used.
  1057. * @buf: contains formatted text Session Count
  1058. *
  1059. * return
  1060. * size of the formatted string
  1061. **/
  1062. ssize_t
  1063. beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
  1064. char *buf)
  1065. {
  1066. struct Scsi_Host *shost = class_to_shost(dev);
  1067. struct beiscsi_hba *phba = iscsi_host_priv(shost);
  1068. uint16_t ulp_num, len = 0;
  1069. for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
  1070. if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
  1071. len += snprintf(buf+len, PAGE_SIZE - len,
  1072. "ULP%d : %d\n", ulp_num,
  1073. BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
  1074. else
  1075. len += snprintf(buf+len, PAGE_SIZE - len,
  1076. "ULP%d : %d\n", ulp_num, 0);
  1077. }
  1078. return len;
  1079. }
  1080. /**
  1081. * beiscsi_adap_family_disp()- Display adapter family.
  1082. * @dev: ptr to device to get priv structure
  1083. * @attr: device attribute, not used.
  1084. * @buf: contains formatted text driver name and version
  1085. *
  1086. * return
  1087. * size of the formatted string
  1088. **/
  1089. ssize_t
  1090. beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
  1091. char *buf)
  1092. {
  1093. uint16_t dev_id = 0;
  1094. struct Scsi_Host *shost = class_to_shost(dev);
  1095. struct beiscsi_hba *phba = iscsi_host_priv(shost);
  1096. dev_id = phba->pcidev->device;
  1097. switch (dev_id) {
  1098. case BE_DEVICE_ID1:
  1099. case OC_DEVICE_ID1:
  1100. case OC_DEVICE_ID2:
  1101. return snprintf(buf, PAGE_SIZE,
  1102. "Obsolete/Unsupported BE2 Adapter Family\n");
  1103. break;
  1104. case BE_DEVICE_ID2:
  1105. case OC_DEVICE_ID3:
  1106. return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
  1107. break;
  1108. case OC_SKH_ID1:
  1109. return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
  1110. break;
  1111. default:
  1112. return snprintf(buf, PAGE_SIZE,
  1113. "Unknown Adapter Family: 0x%x\n", dev_id);
  1114. break;
  1115. }
  1116. }
  1117. /**
  1118. * beiscsi_phys_port()- Display Physical Port Identifier
  1119. * @dev: ptr to device not used.
  1120. * @attr: device attribute, not used.
  1121. * @buf: contains formatted text port identifier
  1122. *
  1123. * return
  1124. * size of the formatted string
  1125. **/
  1126. ssize_t
  1127. beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
  1128. char *buf)
  1129. {
  1130. struct Scsi_Host *shost = class_to_shost(dev);
  1131. struct beiscsi_hba *phba = iscsi_host_priv(shost);
  1132. return snprintf(buf, PAGE_SIZE, "Port Identifier : %u\n",
  1133. phba->fw_config.phys_port);
  1134. }
  1135. void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
  1136. struct wrb_handle *pwrb_handle,
  1137. struct be_mem_descriptor *mem_descr,
  1138. struct hwi_wrb_context *pwrb_context)
  1139. {
  1140. struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
  1141. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1142. max_send_data_segment_length, pwrb,
  1143. params->dw[offsetof(struct amap_beiscsi_offload_params,
  1144. max_send_data_segment_length) / 32]);
  1145. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
  1146. BE_TGT_CTX_UPDT_CMD);
  1147. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1148. first_burst_length,
  1149. pwrb,
  1150. params->dw[offsetof(struct amap_beiscsi_offload_params,
  1151. first_burst_length) / 32]);
  1152. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
  1153. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1154. erl) / 32] & OFFLD_PARAMS_ERL));
  1155. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
  1156. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1157. dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
  1158. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
  1159. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1160. hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
  1161. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
  1162. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1163. ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
  1164. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
  1165. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1166. imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
  1167. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
  1168. pwrb,
  1169. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1170. exp_statsn) / 32] + 1));
  1171. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
  1172. pwrb, pwrb_handle->wrb_index);
  1173. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1174. max_burst_length, pwrb, params->dw[offsetof
  1175. (struct amap_beiscsi_offload_params,
  1176. max_burst_length) / 32]);
  1177. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
  1178. pwrb, pwrb_handle->wrb_index);
  1179. if (pwrb_context->plast_wrb)
  1180. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1181. ptr2nextwrb,
  1182. pwrb_context->plast_wrb,
  1183. pwrb_handle->wrb_index);
  1184. pwrb_context->plast_wrb = pwrb;
  1185. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1186. session_state, pwrb, 0);
  1187. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
  1188. pwrb, 1);
  1189. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
  1190. pwrb, 0);
  1191. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
  1192. 0);
  1193. mem_descr += ISCSI_MEM_GLOBAL_HEADER;
  1194. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1195. pad_buffer_addr_hi, pwrb,
  1196. mem_descr->mem_array[0].bus_address.u.a32.address_hi);
  1197. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
  1198. pad_buffer_addr_lo, pwrb,
  1199. mem_descr->mem_array[0].bus_address.u.a32.address_lo);
  1200. }
  1201. void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
  1202. struct wrb_handle *pwrb_handle,
  1203. struct hwi_wrb_context *pwrb_context)
  1204. {
  1205. struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
  1206. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1207. max_burst_length, pwrb, params->dw[offsetof
  1208. (struct amap_beiscsi_offload_params,
  1209. max_burst_length) / 32]);
  1210. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1211. type, pwrb,
  1212. BE_TGT_CTX_UPDT_CMD);
  1213. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1214. ptr2nextwrb,
  1215. pwrb, pwrb_handle->wrb_index);
  1216. if (pwrb_context->plast_wrb)
  1217. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1218. ptr2nextwrb,
  1219. pwrb_context->plast_wrb,
  1220. pwrb_handle->wrb_index);
  1221. pwrb_context->plast_wrb = pwrb;
  1222. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
  1223. pwrb, pwrb_handle->wrb_index);
  1224. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1225. max_send_data_segment_length, pwrb,
  1226. params->dw[offsetof(struct amap_beiscsi_offload_params,
  1227. max_send_data_segment_length) / 32]);
  1228. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1229. first_burst_length, pwrb,
  1230. params->dw[offsetof(struct amap_beiscsi_offload_params,
  1231. first_burst_length) / 32]);
  1232. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1233. max_recv_dataseg_len, pwrb,
  1234. params->dw[offsetof(struct amap_beiscsi_offload_params,
  1235. max_recv_data_segment_length) / 32]);
  1236. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1237. max_cxns, pwrb, BEISCSI_MAX_CXNS);
  1238. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
  1239. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1240. erl) / 32] & OFFLD_PARAMS_ERL));
  1241. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
  1242. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1243. dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
  1244. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
  1245. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1246. hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
  1247. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1248. ir2t, pwrb,
  1249. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1250. ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
  1251. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
  1252. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1253. imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
  1254. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1255. data_seq_inorder,
  1256. pwrb,
  1257. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1258. data_seq_inorder) / 32] &
  1259. OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
  1260. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
  1261. pdu_seq_inorder,
  1262. pwrb,
  1263. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1264. pdu_seq_inorder) / 32] &
  1265. OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
  1266. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
  1267. pwrb,
  1268. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1269. max_r2t) / 32] &
  1270. OFFLD_PARAMS_MAX_R2T) >> 8);
  1271. AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
  1272. pwrb,
  1273. (params->dw[offsetof(struct amap_beiscsi_offload_params,
  1274. exp_statsn) / 32] + 1));
  1275. }
  1276. unsigned int beiscsi_invalidate_cxn(struct beiscsi_hba *phba,
  1277. struct beiscsi_endpoint *beiscsi_ep)
  1278. {
  1279. struct be_invalidate_connection_params_in *req;
  1280. struct be_ctrl_info *ctrl = &phba->ctrl;
  1281. struct be_mcc_wrb *wrb;
  1282. unsigned int tag = 0;
  1283. mutex_lock(&ctrl->mbox_lock);
  1284. wrb = alloc_mcc_wrb(phba, &tag);
  1285. if (!wrb) {
  1286. mutex_unlock(&ctrl->mbox_lock);
  1287. return 0;
  1288. }
  1289. req = embedded_payload(wrb);
  1290. be_wrb_hdr_prepare(wrb, sizeof(union be_invalidate_connection_params),
  1291. true, 0);
  1292. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
  1293. OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
  1294. sizeof(*req));
  1295. req->session_handle = beiscsi_ep->fw_handle;
  1296. req->cid = beiscsi_ep->ep_cid;
  1297. if (beiscsi_ep->conn)
  1298. req->cleanup_type = BE_CLEANUP_TYPE_INVALIDATE;
  1299. else
  1300. req->cleanup_type = BE_CLEANUP_TYPE_ISSUE_TCP_RST;
  1301. /**
  1302. * 0 - non-persistent targets
  1303. * 1 - save session info on flash
  1304. */
  1305. req->save_cfg = 0;
  1306. be_mcc_notify(phba, tag);
  1307. mutex_unlock(&ctrl->mbox_lock);
  1308. return tag;
  1309. }
  1310. unsigned int beiscsi_upload_cxn(struct beiscsi_hba *phba,
  1311. struct beiscsi_endpoint *beiscsi_ep)
  1312. {
  1313. struct be_ctrl_info *ctrl = &phba->ctrl;
  1314. struct be_mcc_wrb *wrb;
  1315. struct be_tcp_upload_params_in *req;
  1316. unsigned int tag;
  1317. mutex_lock(&ctrl->mbox_lock);
  1318. wrb = alloc_mcc_wrb(phba, &tag);
  1319. if (!wrb) {
  1320. mutex_unlock(&ctrl->mbox_lock);
  1321. return 0;
  1322. }
  1323. req = embedded_payload(wrb);
  1324. be_wrb_hdr_prepare(wrb, sizeof(union be_tcp_upload_params), true, 0);
  1325. be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
  1326. OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
  1327. req->id = beiscsi_ep->ep_cid;
  1328. if (beiscsi_ep->conn)
  1329. req->upload_type = BE_UPLOAD_TYPE_GRACEFUL;
  1330. else
  1331. req->upload_type = BE_UPLOAD_TYPE_ABORT;
  1332. be_mcc_notify(phba, tag);
  1333. mutex_unlock(&ctrl->mbox_lock);
  1334. return tag;
  1335. }
  1336. int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba,
  1337. struct invldt_cmd_tbl *inv_tbl,
  1338. unsigned int nents)
  1339. {
  1340. struct be_ctrl_info *ctrl = &phba->ctrl;
  1341. struct invldt_cmds_params_in *req;
  1342. struct be_dma_mem nonemb_cmd;
  1343. struct be_mcc_wrb *wrb;
  1344. unsigned int i, tag;
  1345. struct be_sge *sge;
  1346. int rc;
  1347. if (!nents || nents > BE_INVLDT_CMD_TBL_SZ)
  1348. return -EINVAL;
  1349. nonemb_cmd.size = sizeof(union be_invldt_cmds_params);
  1350. nonemb_cmd.va = pci_zalloc_consistent(phba->ctrl.pdev,
  1351. nonemb_cmd.size,
  1352. &nonemb_cmd.dma);
  1353. if (!nonemb_cmd.va) {
  1354. beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
  1355. "BM_%d : invldt_cmds_params alloc failed\n");
  1356. return -ENOMEM;
  1357. }
  1358. mutex_lock(&ctrl->mbox_lock);
  1359. wrb = alloc_mcc_wrb(phba, &tag);
  1360. if (!wrb) {
  1361. mutex_unlock(&ctrl->mbox_lock);
  1362. pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
  1363. nonemb_cmd.va, nonemb_cmd.dma);
  1364. return -ENOMEM;
  1365. }
  1366. req = nonemb_cmd.va;
  1367. be_wrb_hdr_prepare(wrb, nonemb_cmd.size, false, 1);
  1368. be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  1369. OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
  1370. sizeof(*req));
  1371. req->ref_handle = 0;
  1372. req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
  1373. for (i = 0; i < nents; i++) {
  1374. req->table[i].icd = inv_tbl[i].icd;
  1375. req->table[i].cid = inv_tbl[i].cid;
  1376. req->icd_count++;
  1377. }
  1378. sge = nonembedded_sgl(wrb);
  1379. sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
  1380. sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd.dma));
  1381. sge->len = cpu_to_le32(nonemb_cmd.size);
  1382. be_mcc_notify(phba, tag);
  1383. mutex_unlock(&ctrl->mbox_lock);
  1384. rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
  1385. if (rc != -EBUSY)
  1386. pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
  1387. nonemb_cmd.va, nonemb_cmd.dma);
  1388. return rc;
  1389. }