be_mgmt.c 43 KB

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