1942b7654SJitendra Bhivare /*
294583217SKetan Mukadam * This file is part of the Emulex Linux Device Driver for Enterprise iSCSI
394583217SKetan Mukadam * Host Bus Adapters. Refer to the README file included with this package
494583217SKetan Mukadam * for driver version and adapter compatibility.
56733b39aSJayamohan Kallickal *
694583217SKetan Mukadam * Copyright (c) 2018 Broadcom. All Rights Reserved.
794583217SKetan Mukadam * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
894583217SKetan Mukadam *
994583217SKetan Mukadam * This program is free software; you can redistribute it and/or modify it
1094583217SKetan Mukadam * under the terms of version 2 of the GNU General Public License as published
1194583217SKetan Mukadam * by the Free Software Foundation.
1294583217SKetan Mukadam *
1394583217SKetan Mukadam * This program is distributed in the hope that it will be useful. ALL EXPRESS
1494583217SKetan Mukadam * OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
1594583217SKetan Mukadam * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
1694583217SKetan Mukadam * OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
1794583217SKetan Mukadam * DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
1894583217SKetan Mukadam * See the GNU General Public License for more details, a copy of which
1994583217SKetan Mukadam * can be found in the file COPYING included with this package.
206733b39aSJayamohan Kallickal *
216733b39aSJayamohan Kallickal * Contact Information:
2260f36e04SJitendra Bhivare * linux-drivers@broadcom.com
236733b39aSJayamohan Kallickal *
246733b39aSJayamohan Kallickal */
256733b39aSJayamohan Kallickal
26ffce3e2eSJayamohan Kallickal #include <linux/bsg-lib.h>
27ffce3e2eSJayamohan Kallickal #include <scsi/scsi_transport_iscsi.h>
28ffce3e2eSJayamohan Kallickal #include <scsi/scsi_bsg_iscsi.h>
296733b39aSJayamohan Kallickal #include "be_mgmt.h"
306733b39aSJayamohan Kallickal #include "be_iscsi.h"
317a158003SJohn Soni Jose #include "be_main.h"
327a158003SJohn Soni Jose
mgmt_vendor_specific_fw_cmd(struct be_ctrl_info * ctrl,struct beiscsi_hba * phba,struct bsg_job * job,struct be_dma_mem * nonemb_cmd)33ffce3e2eSJayamohan Kallickal unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
34ffce3e2eSJayamohan Kallickal struct beiscsi_hba *phba,
35ffce3e2eSJayamohan Kallickal struct bsg_job *job,
36ffce3e2eSJayamohan Kallickal struct be_dma_mem *nonemb_cmd)
37ffce3e2eSJayamohan Kallickal {
38daa8dc08SJayamohan Kallickal struct be_mcc_wrb *wrb;
39daa8dc08SJayamohan Kallickal struct be_sge *mcc_sge;
40ffce3e2eSJayamohan Kallickal unsigned int tag = 0;
41ffce3e2eSJayamohan Kallickal struct iscsi_bsg_request *bsg_req = job->request;
42ffce3e2eSJayamohan Kallickal struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
43ffce3e2eSJayamohan Kallickal unsigned short region, sector_size, sector, offset;
44ffce3e2eSJayamohan Kallickal
45ffce3e2eSJayamohan Kallickal nonemb_cmd->size = job->request_payload.payload_len;
46ffce3e2eSJayamohan Kallickal memset(nonemb_cmd->va, 0, nonemb_cmd->size);
47ffce3e2eSJayamohan Kallickal region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
48ffce3e2eSJayamohan Kallickal sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
49ffce3e2eSJayamohan Kallickal sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
50ffce3e2eSJayamohan Kallickal offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4];
51ffce3e2eSJayamohan Kallickal req->region = region;
52ffce3e2eSJayamohan Kallickal req->sector = sector;
53ffce3e2eSJayamohan Kallickal req->offset = offset;
54ffce3e2eSJayamohan Kallickal
55c03a50f7SJitendra Bhivare if (mutex_lock_interruptible(&ctrl->mbox_lock))
56c03a50f7SJitendra Bhivare return 0;
57ffce3e2eSJayamohan Kallickal switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
58ffce3e2eSJayamohan Kallickal case BEISCSI_WRITE_FLASH:
59ffce3e2eSJayamohan Kallickal offset = sector * sector_size + offset;
60ffce3e2eSJayamohan Kallickal be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
61ffce3e2eSJayamohan Kallickal OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
62ffce3e2eSJayamohan Kallickal sg_copy_to_buffer(job->request_payload.sg_list,
63ffce3e2eSJayamohan Kallickal job->request_payload.sg_cnt,
64ffce3e2eSJayamohan Kallickal nonemb_cmd->va + offset, job->request_len);
65ffce3e2eSJayamohan Kallickal break;
66ffce3e2eSJayamohan Kallickal case BEISCSI_READ_FLASH:
67ffce3e2eSJayamohan Kallickal be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
68ffce3e2eSJayamohan Kallickal OPCODE_COMMON_READ_FLASH, sizeof(*req));
69ffce3e2eSJayamohan Kallickal break;
70ffce3e2eSJayamohan Kallickal default:
7199bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
7299bc5d55SJohn Soni Jose "BG_%d : Unsupported cmd = 0x%x\n\n",
7399bc5d55SJohn Soni Jose bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
7499bc5d55SJohn Soni Jose
75c03a50f7SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
76c5bf8889SJitendra Bhivare return -EPERM;
77ffce3e2eSJayamohan Kallickal }
78ffce3e2eSJayamohan Kallickal
79090e2184SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
80090e2184SJitendra Bhivare if (!wrb) {
81c03a50f7SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
82090e2184SJitendra Bhivare return 0;
83ffce3e2eSJayamohan Kallickal }
84ffce3e2eSJayamohan Kallickal
85daa8dc08SJayamohan Kallickal mcc_sge = nonembedded_sgl(wrb);
86ffce3e2eSJayamohan Kallickal be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
87ffce3e2eSJayamohan Kallickal job->request_payload.sg_cnt);
88ffce3e2eSJayamohan Kallickal mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
89ffce3e2eSJayamohan Kallickal mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
90ffce3e2eSJayamohan Kallickal mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
91ffce3e2eSJayamohan Kallickal
92cdde6682SJitendra Bhivare be_mcc_notify(phba, tag);
93ffce3e2eSJayamohan Kallickal
94c03a50f7SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
95ffce3e2eSJayamohan Kallickal return tag;
96ffce3e2eSJayamohan Kallickal }
97ffce3e2eSJayamohan Kallickal
981e4be6ffSJayamohan Kallickal /**
991e4be6ffSJayamohan Kallickal * mgmt_open_connection()- Establish a TCP CXN
1007405edfdSLee Jones * @phba: driver priv structure
1011e4be6ffSJayamohan Kallickal * @dst_addr: Destination Address
1021e4be6ffSJayamohan Kallickal * @beiscsi_ep: ptr to device endpoint struct
1031e4be6ffSJayamohan Kallickal * @nonemb_cmd: ptr to memory allocated for command
1041e4be6ffSJayamohan Kallickal *
1051e4be6ffSJayamohan Kallickal * return
1061e4be6ffSJayamohan Kallickal * Success: Tag number of the MBX Command issued
1071e4be6ffSJayamohan Kallickal * Failure: Error code
1081e4be6ffSJayamohan Kallickal **/
mgmt_open_connection(struct beiscsi_hba * phba,struct sockaddr * dst_addr,struct beiscsi_endpoint * beiscsi_ep,struct be_dma_mem * nonemb_cmd)1096733b39aSJayamohan Kallickal int mgmt_open_connection(struct beiscsi_hba *phba,
1106733b39aSJayamohan Kallickal struct sockaddr *dst_addr,
1113cbb7a74SJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep,
1123cbb7a74SJayamohan Kallickal struct be_dma_mem *nonemb_cmd)
1136733b39aSJayamohan Kallickal {
1146733b39aSJayamohan Kallickal struct hwi_controller *phwi_ctrlr;
1156733b39aSJayamohan Kallickal struct hwi_context_memory *phwi_context;
1166733b39aSJayamohan Kallickal struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
1176733b39aSJayamohan Kallickal struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
1186733b39aSJayamohan Kallickal struct be_ctrl_info *ctrl = &phba->ctrl;
119756d29c8SJayamohan Kallickal struct be_mcc_wrb *wrb;
120b3c202dcSJayamohan Kallickal struct tcp_connect_and_offload_in_v1 *req;
1216733b39aSJayamohan Kallickal unsigned short def_hdr_id;
1226733b39aSJayamohan Kallickal unsigned short def_data_id;
1236733b39aSJayamohan Kallickal struct phys_addr template_address = { 0, 0 };
1246733b39aSJayamohan Kallickal struct phys_addr *ptemplate_address;
125756d29c8SJayamohan Kallickal unsigned int tag = 0;
1261e4be6ffSJayamohan Kallickal unsigned int i, ulp_num;
1276733b39aSJayamohan Kallickal unsigned short cid = beiscsi_ep->ep_cid;
1283cbb7a74SJayamohan Kallickal struct be_sge *sge;
1296733b39aSJayamohan Kallickal
130291fef26SJitendra Bhivare if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
131291fef26SJitendra Bhivare beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
132291fef26SJitendra Bhivare "BG_%d : unknown addr family %d\n",
133291fef26SJitendra Bhivare dst_addr->sa_family);
1348dd998e6SJitendra Bhivare return 0;
135291fef26SJitendra Bhivare }
136291fef26SJitendra Bhivare
1376733b39aSJayamohan Kallickal phwi_ctrlr = phba->phwi_ctrlr;
1386733b39aSJayamohan Kallickal phwi_context = phwi_ctrlr->phwi_ctxt;
1391e4be6ffSJayamohan Kallickal
1401e4be6ffSJayamohan Kallickal ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
1411e4be6ffSJayamohan Kallickal
1421e4be6ffSJayamohan Kallickal def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
1431e4be6ffSJayamohan Kallickal def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
1446733b39aSJayamohan Kallickal
1456733b39aSJayamohan Kallickal ptemplate_address = &template_address;
1466733b39aSJayamohan Kallickal ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
147c03a50f7SJitendra Bhivare if (mutex_lock_interruptible(&ctrl->mbox_lock))
148c03a50f7SJitendra Bhivare return 0;
149090e2184SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
150090e2184SJitendra Bhivare if (!wrb) {
151c03a50f7SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
152090e2184SJitendra Bhivare return 0;
153756d29c8SJayamohan Kallickal }
1543cbb7a74SJayamohan Kallickal
155090e2184SJitendra Bhivare sge = nonembedded_sgl(wrb);
1563cbb7a74SJayamohan Kallickal req = nonemb_cmd->va;
1573cbb7a74SJayamohan Kallickal memset(req, 0, sizeof(*req));
1586733b39aSJayamohan Kallickal
159b3c202dcSJayamohan Kallickal be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
1606733b39aSJayamohan Kallickal be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1616733b39aSJayamohan Kallickal OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
162b3c202dcSJayamohan Kallickal nonemb_cmd->size);
1636733b39aSJayamohan Kallickal if (dst_addr->sa_family == PF_INET) {
1646733b39aSJayamohan Kallickal __be32 s_addr = daddr_in->sin_addr.s_addr;
165290aa376SJitendra Bhivare req->ip_address.ip_type = BEISCSI_IP_TYPE_V4;
1660e43895eSMike Christie req->ip_address.addr[0] = s_addr & 0x000000ff;
1670e43895eSMike Christie req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
1680e43895eSMike Christie req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
1690e43895eSMike Christie req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
1706733b39aSJayamohan Kallickal req->tcp_port = ntohs(daddr_in->sin_port);
1716733b39aSJayamohan Kallickal beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
1726733b39aSJayamohan Kallickal beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
173290aa376SJitendra Bhivare beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4;
174291fef26SJitendra Bhivare } else {
175291fef26SJitendra Bhivare /* else its PF_INET6 family */
176290aa376SJitendra Bhivare req->ip_address.ip_type = BEISCSI_IP_TYPE_V6;
1770e43895eSMike Christie memcpy(&req->ip_address.addr,
1786733b39aSJayamohan Kallickal &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
1796733b39aSJayamohan Kallickal req->tcp_port = ntohs(daddr_in6->sin6_port);
1806733b39aSJayamohan Kallickal beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
1816733b39aSJayamohan Kallickal memcpy(&beiscsi_ep->dst6_addr,
1826733b39aSJayamohan Kallickal &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
183290aa376SJitendra Bhivare beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6;
1846733b39aSJayamohan Kallickal }
1856733b39aSJayamohan Kallickal req->cid = cid;
186bfead3b2SJayamohan Kallickal i = phba->nxt_cqid++;
187bfead3b2SJayamohan Kallickal if (phba->nxt_cqid == phba->num_cpus)
188bfead3b2SJayamohan Kallickal phba->nxt_cqid = 0;
189bfead3b2SJayamohan Kallickal req->cq_id = phwi_context->be_cq[i].id;
19099bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
19199bc5d55SJohn Soni Jose "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
1926733b39aSJayamohan Kallickal req->defq_id = def_hdr_id;
1936733b39aSJayamohan Kallickal req->hdr_ring_id = def_hdr_id;
1946733b39aSJayamohan Kallickal req->data_ring_id = def_data_id;
1956733b39aSJayamohan Kallickal req->do_offload = 1;
1966733b39aSJayamohan Kallickal req->dataout_template_pa.lo = ptemplate_address->lo;
1976733b39aSJayamohan Kallickal req->dataout_template_pa.hi = ptemplate_address->hi;
1983cbb7a74SJayamohan Kallickal sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
1993cbb7a74SJayamohan Kallickal sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
2003cbb7a74SJayamohan Kallickal sge->len = cpu_to_le32(nonemb_cmd->size);
201b3c202dcSJayamohan Kallickal
202b3c202dcSJayamohan Kallickal if (!is_chip_be2_be3r(phba)) {
203b3c202dcSJayamohan Kallickal req->hdr.version = MBX_CMD_VER1;
2041b7a7ddcSJitendra Bhivare req->tcp_window_size = 0x8000;
205b3c202dcSJayamohan Kallickal req->tcp_window_scale_count = 2;
206b3c202dcSJayamohan Kallickal }
207b3c202dcSJayamohan Kallickal
208cdde6682SJitendra Bhivare be_mcc_notify(phba, tag);
209c03a50f7SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
210756d29c8SJayamohan Kallickal return tag;
2116733b39aSJayamohan Kallickal }
212bfead3b2SJayamohan Kallickal
2137405edfdSLee Jones /**
214a39e9f71SJitendra Bhivare * beiscsi_exec_nemb_cmd()- execute non-embedded MBX cmd
215a39e9f71SJitendra Bhivare * @phba: driver priv structure
216a39e9f71SJitendra Bhivare * @nonemb_cmd: DMA address of the MBX command to be issued
217a39e9f71SJitendra Bhivare * @cbfn: callback func on MCC completion
218a39e9f71SJitendra Bhivare * @resp_buf: buffer to copy the MBX cmd response
219a39e9f71SJitendra Bhivare * @resp_buf_len: response length to be copied
220e175defeSJohn Soni Jose *
221e175defeSJohn Soni Jose **/
beiscsi_exec_nemb_cmd(struct beiscsi_hba * phba,struct be_dma_mem * nonemb_cmd,void (* cbfn)(struct beiscsi_hba *,unsigned int),void * resp_buf,u32 resp_buf_len)222a39e9f71SJitendra Bhivare static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba,
223a39e9f71SJitendra Bhivare struct be_dma_mem *nonemb_cmd,
224a39e9f71SJitendra Bhivare void (*cbfn)(struct beiscsi_hba *,
225a39e9f71SJitendra Bhivare unsigned int),
226a39e9f71SJitendra Bhivare void *resp_buf, u32 resp_buf_len)
2270e43895eSMike Christie {
2280e43895eSMike Christie struct be_ctrl_info *ctrl = &phba->ctrl;
229daa8dc08SJayamohan Kallickal struct be_mcc_wrb *wrb;
2300e43895eSMike Christie struct be_sge *sge;
2310e43895eSMike Christie unsigned int tag;
2320e43895eSMike Christie int rc = 0;
2330e43895eSMike Christie
234c03a50f7SJitendra Bhivare mutex_lock(&ctrl->mbox_lock);
235090e2184SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
236090e2184SJitendra Bhivare if (!wrb) {
237c03a50f7SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
2387b0ddc13SMike Christie return -ENOMEM;
239756d29c8SJayamohan Kallickal }
240daa8dc08SJayamohan Kallickal
2410e43895eSMike Christie sge = nonembedded_sgl(wrb);
2420e43895eSMike Christie be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
2430e43895eSMike Christie sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
244e175defeSJohn Soni Jose sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
2450e43895eSMike Christie sge->len = cpu_to_le32(nonemb_cmd->size);
246bfead3b2SJayamohan Kallickal
247a39e9f71SJitendra Bhivare if (cbfn) {
248a39e9f71SJitendra Bhivare struct be_dma_mem *tag_mem;
249a39e9f71SJitendra Bhivare
250a39e9f71SJitendra Bhivare set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
251a39e9f71SJitendra Bhivare ctrl->ptag_state[tag].cbfn = cbfn;
252a39e9f71SJitendra Bhivare tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
253a39e9f71SJitendra Bhivare
254a39e9f71SJitendra Bhivare /* store DMA mem to be freed in callback */
255a39e9f71SJitendra Bhivare tag_mem->size = nonemb_cmd->size;
256a39e9f71SJitendra Bhivare tag_mem->va = nonemb_cmd->va;
257a39e9f71SJitendra Bhivare tag_mem->dma = nonemb_cmd->dma;
258a39e9f71SJitendra Bhivare }
259cdde6682SJitendra Bhivare be_mcc_notify(phba, tag);
260c03a50f7SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
2610e43895eSMike Christie
262a39e9f71SJitendra Bhivare /* with cbfn set, its async cmd, don't wait */
263a39e9f71SJitendra Bhivare if (cbfn)
264a39e9f71SJitendra Bhivare return 0;
265a39e9f71SJitendra Bhivare
26688840332SJitendra Bhivare rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd);
267bfead3b2SJayamohan Kallickal
268a39e9f71SJitendra Bhivare /* copy the response, if any */
2690e43895eSMike Christie if (resp_buf)
2700e43895eSMike Christie memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
2710e43895eSMike Christie return rc;
2720e43895eSMike Christie }
2730e43895eSMike Christie
beiscsi_prep_nemb_cmd(struct beiscsi_hba * phba,struct be_dma_mem * cmd,u8 subsystem,u8 opcode,u32 size)274a39e9f71SJitendra Bhivare static int beiscsi_prep_nemb_cmd(struct beiscsi_hba *phba,
275a39e9f71SJitendra Bhivare struct be_dma_mem *cmd,
276a39e9f71SJitendra Bhivare u8 subsystem, u8 opcode, u32 size)
2770e43895eSMike Christie {
278750afb08SLuis Chamberlain cmd->va = dma_alloc_coherent(&phba->ctrl.pdev->dev, size, &cmd->dma,
27926a4c991SChristoph Hellwig GFP_KERNEL);
2800e43895eSMike Christie if (!cmd->va) {
28199bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
28299bc5d55SJohn Soni Jose "BG_%d : Failed to allocate memory for if info\n");
2830e43895eSMike Christie return -ENOMEM;
2840e43895eSMike Christie }
2850e43895eSMike Christie cmd->size = size;
286a39e9f71SJitendra Bhivare be_cmd_hdr_prepare(cmd->va, subsystem, opcode, size);
287db02aea9SJitendra Bhivare beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
288a39e9f71SJitendra Bhivare "BG_%d : subsystem %u cmd %u size %u\n",
289a39e9f71SJitendra Bhivare subsystem, opcode, size);
2900e43895eSMike Christie return 0;
2910e43895eSMike Christie }
2920e43895eSMike Christie
beiscsi_free_nemb_cmd(struct beiscsi_hba * phba,struct be_dma_mem * cmd,int rc)2937b0ddc13SMike Christie static void beiscsi_free_nemb_cmd(struct beiscsi_hba *phba,
2947b0ddc13SMike Christie struct be_dma_mem *cmd, int rc)
2957b0ddc13SMike Christie {
2967b0ddc13SMike Christie /*
2977b0ddc13SMike Christie * If FW is busy the DMA buffer is saved with the tag. When the cmd
2987b0ddc13SMike Christie * completes this buffer is freed.
2997b0ddc13SMike Christie */
3007b0ddc13SMike Christie if (rc == -EBUSY)
3017b0ddc13SMike Christie return;
3027b0ddc13SMike Christie
3037b0ddc13SMike Christie dma_free_coherent(&phba->ctrl.pdev->dev, cmd->size, cmd->va, cmd->dma);
3047b0ddc13SMike Christie }
3057b0ddc13SMike Christie
__beiscsi_eq_delay_compl(struct beiscsi_hba * phba,unsigned int tag)306a39e9f71SJitendra Bhivare static void __beiscsi_eq_delay_compl(struct beiscsi_hba *phba, unsigned int tag)
307a39e9f71SJitendra Bhivare {
308a39e9f71SJitendra Bhivare struct be_dma_mem *tag_mem;
309a39e9f71SJitendra Bhivare
310a39e9f71SJitendra Bhivare /* status is ignored */
311a39e9f71SJitendra Bhivare __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
312a39e9f71SJitendra Bhivare tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
313a39e9f71SJitendra Bhivare if (tag_mem->size) {
31426a4c991SChristoph Hellwig dma_free_coherent(&phba->pcidev->dev, tag_mem->size,
315a39e9f71SJitendra Bhivare tag_mem->va, tag_mem->dma);
316a39e9f71SJitendra Bhivare tag_mem->size = 0;
317a39e9f71SJitendra Bhivare }
318a39e9f71SJitendra Bhivare }
319a39e9f71SJitendra Bhivare
beiscsi_modify_eq_delay(struct beiscsi_hba * phba,struct be_set_eqd * set_eqd,int num)320a39e9f71SJitendra Bhivare int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
321a39e9f71SJitendra Bhivare struct be_set_eqd *set_eqd, int num)
322a39e9f71SJitendra Bhivare {
323a39e9f71SJitendra Bhivare struct be_cmd_req_modify_eq_delay *req;
324a39e9f71SJitendra Bhivare struct be_dma_mem nonemb_cmd;
325a39e9f71SJitendra Bhivare int i, rc;
326a39e9f71SJitendra Bhivare
327a39e9f71SJitendra Bhivare rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_COMMON,
328a39e9f71SJitendra Bhivare OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
329a39e9f71SJitendra Bhivare if (rc)
330a39e9f71SJitendra Bhivare return rc;
331a39e9f71SJitendra Bhivare
332a39e9f71SJitendra Bhivare req = nonemb_cmd.va;
333a39e9f71SJitendra Bhivare req->num_eq = cpu_to_le32(num);
334a39e9f71SJitendra Bhivare for (i = 0; i < num; i++) {
335a39e9f71SJitendra Bhivare req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
336a39e9f71SJitendra Bhivare req->delay[i].phase = 0;
337a39e9f71SJitendra Bhivare req->delay[i].delay_multiplier =
338a39e9f71SJitendra Bhivare cpu_to_le32(set_eqd[i].delay_multiplier);
339a39e9f71SJitendra Bhivare }
340a39e9f71SJitendra Bhivare
3417b0ddc13SMike Christie rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, __beiscsi_eq_delay_compl,
3427b0ddc13SMike Christie NULL, 0);
3437b0ddc13SMike Christie if (rc) {
3447b0ddc13SMike Christie /*
3457b0ddc13SMike Christie * Only free on failure. Async cmds are handled like -EBUSY
3467b0ddc13SMike Christie * where it's handled for us.
3477b0ddc13SMike Christie */
3487b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
3497b0ddc13SMike Christie }
3507b0ddc13SMike Christie return rc;
351a39e9f71SJitendra Bhivare }
352a39e9f71SJitendra Bhivare
353c5905bf8SJitendra Bhivare /**
354c5905bf8SJitendra Bhivare * beiscsi_get_initiator_name - read initiator name from flash
355c5905bf8SJitendra Bhivare * @phba: device priv structure
356c5905bf8SJitendra Bhivare * @name: buffer pointer
3574788e732SJitendra Bhivare * @cfg: fetch user configured
358c5905bf8SJitendra Bhivare *
359c5905bf8SJitendra Bhivare */
beiscsi_get_initiator_name(struct beiscsi_hba * phba,char * name,bool cfg)3604788e732SJitendra Bhivare int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name, bool cfg)
361c5905bf8SJitendra Bhivare {
362c5905bf8SJitendra Bhivare struct be_dma_mem nonemb_cmd;
363c5905bf8SJitendra Bhivare struct be_cmd_hba_name resp;
3644788e732SJitendra Bhivare struct be_cmd_hba_name *req;
365c5905bf8SJitendra Bhivare int rc;
366c5905bf8SJitendra Bhivare
367c5905bf8SJitendra Bhivare rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI_INI,
368c5905bf8SJitendra Bhivare OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, sizeof(resp));
369c5905bf8SJitendra Bhivare if (rc)
370c5905bf8SJitendra Bhivare return rc;
371c5905bf8SJitendra Bhivare
3724788e732SJitendra Bhivare req = nonemb_cmd.va;
3734788e732SJitendra Bhivare if (cfg)
3744788e732SJitendra Bhivare req->hdr.version = 1;
375c5905bf8SJitendra Bhivare rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
376c5905bf8SJitendra Bhivare &resp, sizeof(resp));
3777b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
378c5905bf8SJitendra Bhivare if (rc) {
379c5905bf8SJitendra Bhivare beiscsi_log(phba, KERN_ERR,
380c5905bf8SJitendra Bhivare BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
381c5905bf8SJitendra Bhivare "BS_%d : Initiator Name MBX Failed\n");
382c5905bf8SJitendra Bhivare return rc;
383c5905bf8SJitendra Bhivare }
384c5905bf8SJitendra Bhivare rc = sprintf(name, "%s\n", resp.initiator_name);
385c5905bf8SJitendra Bhivare return rc;
386c5905bf8SJitendra Bhivare }
387c5905bf8SJitendra Bhivare
beiscsi_if_get_handle(struct beiscsi_hba * phba)388c5bf8889SJitendra Bhivare unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba)
389c5bf8889SJitendra Bhivare {
390c5bf8889SJitendra Bhivare struct be_ctrl_info *ctrl = &phba->ctrl;
391c5bf8889SJitendra Bhivare struct be_mcc_wrb *wrb;
392c5bf8889SJitendra Bhivare struct be_cmd_get_all_if_id_req *req;
393c5bf8889SJitendra Bhivare struct be_cmd_get_all_if_id_req *pbe_allid;
394c5bf8889SJitendra Bhivare unsigned int tag;
395c5bf8889SJitendra Bhivare int status = 0;
396c5bf8889SJitendra Bhivare
397c5bf8889SJitendra Bhivare if (mutex_lock_interruptible(&ctrl->mbox_lock))
398c5bf8889SJitendra Bhivare return -EINTR;
399c5bf8889SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
400c5bf8889SJitendra Bhivare if (!wrb) {
401c5bf8889SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
402c5bf8889SJitendra Bhivare return -ENOMEM;
403c5bf8889SJitendra Bhivare }
404c5bf8889SJitendra Bhivare
405c5bf8889SJitendra Bhivare req = embedded_payload(wrb);
406c5bf8889SJitendra Bhivare be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
407c5bf8889SJitendra Bhivare be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
408c5bf8889SJitendra Bhivare OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
409c5bf8889SJitendra Bhivare sizeof(*req));
410c5bf8889SJitendra Bhivare be_mcc_notify(phba, tag);
411c5bf8889SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
412c5bf8889SJitendra Bhivare
413c5bf8889SJitendra Bhivare status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
414c5bf8889SJitendra Bhivare if (status) {
415c5bf8889SJitendra Bhivare beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
416c5bf8889SJitendra Bhivare "BG_%d : %s failed: %d\n", __func__, status);
417c5bf8889SJitendra Bhivare return -EBUSY;
418c5bf8889SJitendra Bhivare }
419c5bf8889SJitendra Bhivare
420c5bf8889SJitendra Bhivare pbe_allid = embedded_payload(wrb);
421c5bf8889SJitendra Bhivare /* we now support only one interface per function */
422c5bf8889SJitendra Bhivare phba->interface_handle = pbe_allid->if_hndl_list[0];
423c5bf8889SJitendra Bhivare
424c5bf8889SJitendra Bhivare return status;
425c5bf8889SJitendra Bhivare }
426c5bf8889SJitendra Bhivare
beiscsi_if_zero_ip(u8 * ip,u32 ip_type)427290aa376SJitendra Bhivare static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type)
428290aa376SJitendra Bhivare {
429290aa376SJitendra Bhivare u32 len;
430290aa376SJitendra Bhivare
431290aa376SJitendra Bhivare len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
432290aa376SJitendra Bhivare while (len && !ip[len - 1])
433290aa376SJitendra Bhivare len--;
434290aa376SJitendra Bhivare return (len == 0);
435290aa376SJitendra Bhivare }
436290aa376SJitendra Bhivare
beiscsi_if_mod_gw(struct beiscsi_hba * phba,u32 action,u32 ip_type,u8 * gw)43737f21648SJitendra Bhivare static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
43837f21648SJitendra Bhivare u32 action, u32 ip_type, u8 *gw)
4390e43895eSMike Christie {
4400e43895eSMike Christie struct be_cmd_set_def_gateway_req *req;
4410e43895eSMike Christie struct be_dma_mem nonemb_cmd;
4420e43895eSMike Christie int rt_val;
4430e43895eSMike Christie
444a39e9f71SJitendra Bhivare rt_val = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
4450e43895eSMike Christie OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
4460e43895eSMike Christie sizeof(*req));
4470e43895eSMike Christie if (rt_val)
4480e43895eSMike Christie return rt_val;
4490e43895eSMike Christie
4500e43895eSMike Christie req = nonemb_cmd.va;
45137f21648SJitendra Bhivare req->action = action;
45237f21648SJitendra Bhivare req->ip_addr.ip_type = ip_type;
45337f21648SJitendra Bhivare memcpy(req->ip_addr.addr, gw,
454290aa376SJitendra Bhivare (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
4557b0ddc13SMike Christie rt_val = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
4567b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rt_val);
4577b0ddc13SMike Christie return rt_val;
4580e43895eSMike Christie }
4590e43895eSMike Christie
beiscsi_if_set_gw(struct beiscsi_hba * phba,u32 ip_type,u8 * gw)46037f21648SJitendra Bhivare int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw)
46137f21648SJitendra Bhivare {
46237f21648SJitendra Bhivare struct be_cmd_get_def_gateway_resp gw_resp;
46337f21648SJitendra Bhivare int rt_val;
46437f21648SJitendra Bhivare
46537f21648SJitendra Bhivare memset(&gw_resp, 0, sizeof(gw_resp));
46637f21648SJitendra Bhivare rt_val = beiscsi_if_get_gw(phba, ip_type, &gw_resp);
46737f21648SJitendra Bhivare if (rt_val) {
46837f21648SJitendra Bhivare beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
46937f21648SJitendra Bhivare "BG_%d : Failed to Get Gateway Addr\n");
47037f21648SJitendra Bhivare return rt_val;
47137f21648SJitendra Bhivare }
47237f21648SJitendra Bhivare
473290aa376SJitendra Bhivare if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) {
47437f21648SJitendra Bhivare rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type,
47537f21648SJitendra Bhivare gw_resp.ip_addr.addr);
47637f21648SJitendra Bhivare if (rt_val) {
47737f21648SJitendra Bhivare beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
47837f21648SJitendra Bhivare "BG_%d : Failed to clear Gateway Addr Set\n");
47937f21648SJitendra Bhivare return rt_val;
48037f21648SJitendra Bhivare }
481290aa376SJitendra Bhivare }
48237f21648SJitendra Bhivare
48337f21648SJitendra Bhivare rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw);
48437f21648SJitendra Bhivare if (rt_val)
48537f21648SJitendra Bhivare beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
48637f21648SJitendra Bhivare "BG_%d : Failed to Set Gateway Addr\n");
48737f21648SJitendra Bhivare
48837f21648SJitendra Bhivare return rt_val;
48937f21648SJitendra Bhivare }
49037f21648SJitendra Bhivare
beiscsi_if_get_gw(struct beiscsi_hba * phba,u32 ip_type,struct be_cmd_get_def_gateway_resp * resp)49137f21648SJitendra Bhivare int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
49237f21648SJitendra Bhivare struct be_cmd_get_def_gateway_resp *resp)
49337f21648SJitendra Bhivare {
49437f21648SJitendra Bhivare struct be_cmd_get_def_gateway_req *req;
49537f21648SJitendra Bhivare struct be_dma_mem nonemb_cmd;
49637f21648SJitendra Bhivare int rc;
49737f21648SJitendra Bhivare
498a39e9f71SJitendra Bhivare rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
49937f21648SJitendra Bhivare OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
50037f21648SJitendra Bhivare sizeof(*resp));
50137f21648SJitendra Bhivare if (rc)
50237f21648SJitendra Bhivare return rc;
50337f21648SJitendra Bhivare
50437f21648SJitendra Bhivare req = nonemb_cmd.va;
50537f21648SJitendra Bhivare req->ip_type = ip_type;
50637f21648SJitendra Bhivare
5077b0ddc13SMike Christie rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, resp,
5087b0ddc13SMike Christie sizeof(*resp));
5097b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
5107b0ddc13SMike Christie return rc;
51137f21648SJitendra Bhivare }
51237f21648SJitendra Bhivare
5130152a7e9SJitendra Bhivare static int
beiscsi_if_clr_ip(struct beiscsi_hba * phba,struct be_cmd_get_if_info_resp * if_info)5140152a7e9SJitendra Bhivare beiscsi_if_clr_ip(struct beiscsi_hba *phba,
5150152a7e9SJitendra Bhivare struct be_cmd_get_if_info_resp *if_info)
5160e43895eSMike Christie {
5170152a7e9SJitendra Bhivare struct be_cmd_set_ip_addr_req *req;
5180e43895eSMike Christie struct be_dma_mem nonemb_cmd;
5190e43895eSMike Christie int rc;
5200e43895eSMike Christie
521a39e9f71SJitendra Bhivare rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
5220152a7e9SJitendra Bhivare OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
5230152a7e9SJitendra Bhivare sizeof(*req));
5243c9d903bSJitendra Bhivare if (rc)
5253c9d903bSJitendra Bhivare return rc;
5260e43895eSMike Christie
5270152a7e9SJitendra Bhivare req = nonemb_cmd.va;
5280152a7e9SJitendra Bhivare req->ip_params.record_entry_count = 1;
5290152a7e9SJitendra Bhivare req->ip_params.ip_record.action = IP_ACTION_DEL;
5300152a7e9SJitendra Bhivare req->ip_params.ip_record.interface_hndl =
5310152a7e9SJitendra Bhivare phba->interface_handle;
5320152a7e9SJitendra Bhivare req->ip_params.ip_record.ip_addr.size_of_structure =
5330152a7e9SJitendra Bhivare sizeof(struct be_ip_addr_subnet_format);
5340152a7e9SJitendra Bhivare req->ip_params.ip_record.ip_addr.ip_type = if_info->ip_addr.ip_type;
5350152a7e9SJitendra Bhivare memcpy(req->ip_params.ip_record.ip_addr.addr,
5360152a7e9SJitendra Bhivare if_info->ip_addr.addr,
5370152a7e9SJitendra Bhivare sizeof(if_info->ip_addr.addr));
5380152a7e9SJitendra Bhivare memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
5390152a7e9SJitendra Bhivare if_info->ip_addr.subnet_mask,
5400152a7e9SJitendra Bhivare sizeof(if_info->ip_addr.subnet_mask));
541a39e9f71SJitendra Bhivare rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
5420152a7e9SJitendra Bhivare if (rc < 0 || req->ip_params.ip_record.status) {
5430152a7e9SJitendra Bhivare beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
5440152a7e9SJitendra Bhivare "BG_%d : failed to clear IP: rc %d status %d\n",
5450152a7e9SJitendra Bhivare rc, req->ip_params.ip_record.status);
5460152a7e9SJitendra Bhivare }
5477b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
5480152a7e9SJitendra Bhivare return rc;
5490152a7e9SJitendra Bhivare }
5500152a7e9SJitendra Bhivare
5510152a7e9SJitendra Bhivare static int
beiscsi_if_set_ip(struct beiscsi_hba * phba,u8 * ip,u8 * subnet,u32 ip_type)5520152a7e9SJitendra Bhivare beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip,
5530152a7e9SJitendra Bhivare u8 *subnet, u32 ip_type)
5540152a7e9SJitendra Bhivare {
5550152a7e9SJitendra Bhivare struct be_cmd_set_ip_addr_req *req;
5560152a7e9SJitendra Bhivare struct be_dma_mem nonemb_cmd;
5570152a7e9SJitendra Bhivare uint32_t ip_len;
5580152a7e9SJitendra Bhivare int rc;
5590152a7e9SJitendra Bhivare
560a39e9f71SJitendra Bhivare rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
5610152a7e9SJitendra Bhivare OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
5620152a7e9SJitendra Bhivare sizeof(*req));
5630152a7e9SJitendra Bhivare if (rc)
5640152a7e9SJitendra Bhivare return rc;
5650152a7e9SJitendra Bhivare
5660152a7e9SJitendra Bhivare req = nonemb_cmd.va;
5670152a7e9SJitendra Bhivare req->ip_params.record_entry_count = 1;
5680152a7e9SJitendra Bhivare req->ip_params.ip_record.action = IP_ACTION_ADD;
5690152a7e9SJitendra Bhivare req->ip_params.ip_record.interface_hndl =
5700152a7e9SJitendra Bhivare phba->interface_handle;
5710152a7e9SJitendra Bhivare req->ip_params.ip_record.ip_addr.size_of_structure =
5720152a7e9SJitendra Bhivare sizeof(struct be_ip_addr_subnet_format);
5730152a7e9SJitendra Bhivare req->ip_params.ip_record.ip_addr.ip_type = ip_type;
574290aa376SJitendra Bhivare ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
5750152a7e9SJitendra Bhivare memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len);
5760152a7e9SJitendra Bhivare if (subnet)
5770152a7e9SJitendra Bhivare memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
5780152a7e9SJitendra Bhivare subnet, ip_len);
5790152a7e9SJitendra Bhivare
580a39e9f71SJitendra Bhivare rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
5810152a7e9SJitendra Bhivare /**
5820152a7e9SJitendra Bhivare * In some cases, host needs to look into individual record status
5830152a7e9SJitendra Bhivare * even though FW reported success for that IOCTL.
5840152a7e9SJitendra Bhivare */
5850152a7e9SJitendra Bhivare if (rc < 0 || req->ip_params.ip_record.status) {
5860152a7e9SJitendra Bhivare __beiscsi_log(phba, KERN_ERR,
5870152a7e9SJitendra Bhivare "BG_%d : failed to set IP: rc %d status %d\n",
5880152a7e9SJitendra Bhivare rc, req->ip_params.ip_record.status);
5890152a7e9SJitendra Bhivare if (req->ip_params.ip_record.status)
5900152a7e9SJitendra Bhivare rc = -EINVAL;
5910152a7e9SJitendra Bhivare }
5927b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
5930152a7e9SJitendra Bhivare return rc;
5940152a7e9SJitendra Bhivare }
5950152a7e9SJitendra Bhivare
beiscsi_if_en_static(struct beiscsi_hba * phba,u32 ip_type,u8 * ip,u8 * subnet)5960152a7e9SJitendra Bhivare int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
5970152a7e9SJitendra Bhivare u8 *ip, u8 *subnet)
5980152a7e9SJitendra Bhivare {
5990152a7e9SJitendra Bhivare struct be_cmd_get_if_info_resp *if_info;
6000152a7e9SJitendra Bhivare struct be_cmd_rel_dhcp_req *reldhcp;
6010152a7e9SJitendra Bhivare struct be_dma_mem nonemb_cmd;
6020152a7e9SJitendra Bhivare int rc;
6030e43895eSMike Christie
60496b48b92SJitendra Bhivare rc = beiscsi_if_get_info(phba, ip_type, &if_info);
605beff6549STomas Henzl if (rc)
6060e43895eSMike Christie return rc;
6070e43895eSMike Christie
6081f536d49SJayamohan Kallickal if (if_info->dhcp_state) {
609a39e9f71SJitendra Bhivare rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
610a39e9f71SJitendra Bhivare CMD_SUBSYSTEM_ISCSI,
6110e43895eSMike Christie OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
6120e43895eSMike Christie sizeof(*reldhcp));
6130e43895eSMike Christie if (rc)
6146d67726bSMaurizio Lombardi goto exit;
6150e43895eSMike Christie
6160e43895eSMike Christie reldhcp = nonemb_cmd.va;
6170e43895eSMike Christie reldhcp->interface_hndl = phba->interface_handle;
6180e43895eSMike Christie reldhcp->ip_type = ip_type;
619a39e9f71SJitendra Bhivare rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
6207b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
6210e43895eSMike Christie if (rc < 0) {
6220152a7e9SJitendra Bhivare beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
6230152a7e9SJitendra Bhivare "BG_%d : failed to release existing DHCP: %d\n",
6240152a7e9SJitendra Bhivare rc);
6256d67726bSMaurizio Lombardi goto exit;
6260e43895eSMike Christie }
6270e43895eSMike Christie }
6280e43895eSMike Christie
629290aa376SJitendra Bhivare /* first delete any IP set */
630290aa376SJitendra Bhivare if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
6310152a7e9SJitendra Bhivare rc = beiscsi_if_clr_ip(phba, if_info);
6320e43895eSMike Christie if (rc)
6336d67726bSMaurizio Lombardi goto exit;
634290aa376SJitendra Bhivare }
6350152a7e9SJitendra Bhivare
6360152a7e9SJitendra Bhivare /* if ip == NULL then this is called just to release DHCP IP */
6370152a7e9SJitendra Bhivare if (ip)
6380152a7e9SJitendra Bhivare rc = beiscsi_if_set_ip(phba, ip, subnet, ip_type);
6390152a7e9SJitendra Bhivare exit:
6400152a7e9SJitendra Bhivare kfree(if_info);
6410152a7e9SJitendra Bhivare return rc;
6420e43895eSMike Christie }
6430e43895eSMike Christie
beiscsi_if_en_dhcp(struct beiscsi_hba * phba,u32 ip_type)6440152a7e9SJitendra Bhivare int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type)
6450152a7e9SJitendra Bhivare {
6460152a7e9SJitendra Bhivare struct be_cmd_get_def_gateway_resp gw_resp;
6470152a7e9SJitendra Bhivare struct be_cmd_get_if_info_resp *if_info;
6480152a7e9SJitendra Bhivare struct be_cmd_set_dhcp_req *dhcpreq;
6490152a7e9SJitendra Bhivare struct be_dma_mem nonemb_cmd;
6500152a7e9SJitendra Bhivare u8 *gw;
6510152a7e9SJitendra Bhivare int rc;
6520152a7e9SJitendra Bhivare
65396b48b92SJitendra Bhivare rc = beiscsi_if_get_info(phba, ip_type, &if_info);
6540152a7e9SJitendra Bhivare if (rc)
6550152a7e9SJitendra Bhivare return rc;
6560152a7e9SJitendra Bhivare
6570152a7e9SJitendra Bhivare if (if_info->dhcp_state) {
6580152a7e9SJitendra Bhivare beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
6590152a7e9SJitendra Bhivare "BG_%d : DHCP Already Enabled\n");
6600152a7e9SJitendra Bhivare goto exit;
6610152a7e9SJitendra Bhivare }
6620152a7e9SJitendra Bhivare
663290aa376SJitendra Bhivare /* first delete any IP set */
664290aa376SJitendra Bhivare if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
6650152a7e9SJitendra Bhivare rc = beiscsi_if_clr_ip(phba, if_info);
6660152a7e9SJitendra Bhivare if (rc)
6670152a7e9SJitendra Bhivare goto exit;
668290aa376SJitendra Bhivare }
6690152a7e9SJitendra Bhivare
6700152a7e9SJitendra Bhivare /* delete gateway settings if mode change is to DHCP */
6710152a7e9SJitendra Bhivare memset(&gw_resp, 0, sizeof(gw_resp));
6720152a7e9SJitendra Bhivare /* use ip_type provided in if_info */
6730152a7e9SJitendra Bhivare rc = beiscsi_if_get_gw(phba, if_info->ip_addr.ip_type, &gw_resp);
6740e43895eSMike Christie if (rc) {
67599bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
67699bc5d55SJohn Soni Jose "BG_%d : Failed to Get Gateway Addr\n");
6776d67726bSMaurizio Lombardi goto exit;
6780e43895eSMike Christie }
6790152a7e9SJitendra Bhivare gw = (u8 *)&gw_resp.ip_addr.addr;
680290aa376SJitendra Bhivare if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) {
68137f21648SJitendra Bhivare rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL,
6820152a7e9SJitendra Bhivare if_info->ip_addr.ip_type, gw);
6830e43895eSMike Christie if (rc) {
6840152a7e9SJitendra Bhivare beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
68599bc5d55SJohn Soni Jose "BG_%d : Failed to clear Gateway Addr Set\n");
6866d67726bSMaurizio Lombardi goto exit;
6870e43895eSMike Christie }
688290aa376SJitendra Bhivare }
6890e43895eSMike Christie
690a39e9f71SJitendra Bhivare rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
6910e43895eSMike Christie OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
6920e43895eSMike Christie sizeof(*dhcpreq));
6930e43895eSMike Christie if (rc)
6946d67726bSMaurizio Lombardi goto exit;
6950e43895eSMike Christie
6960e43895eSMike Christie dhcpreq = nonemb_cmd.va;
697290aa376SJitendra Bhivare dhcpreq->flags = 1; /* 1 - blocking; 0 - non-blocking */
6980e43895eSMike Christie dhcpreq->retry_count = 1;
6990e43895eSMike Christie dhcpreq->interface_hndl = phba->interface_handle;
7000152a7e9SJitendra Bhivare dhcpreq->ip_type = ip_type;
701a39e9f71SJitendra Bhivare rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
7027b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
7036d67726bSMaurizio Lombardi exit:
7046d67726bSMaurizio Lombardi kfree(if_info);
7050e43895eSMike Christie return rc;
7060e43895eSMike Christie }
7070e43895eSMike Christie
708db02aea9SJitendra Bhivare /**
709db02aea9SJitendra Bhivare * beiscsi_if_set_vlan()- Issue and wait for CMD completion
710db02aea9SJitendra Bhivare * @phba: device private structure instance
711db02aea9SJitendra Bhivare * @vlan_tag: VLAN tag
712db02aea9SJitendra Bhivare *
713db02aea9SJitendra Bhivare * Issue the MBX Cmd and wait for the completion of the
714db02aea9SJitendra Bhivare * command.
715db02aea9SJitendra Bhivare *
716db02aea9SJitendra Bhivare * returns
717db02aea9SJitendra Bhivare * Success: 0
718db02aea9SJitendra Bhivare * Failure: Non-Xero Value
719db02aea9SJitendra Bhivare **/
beiscsi_if_set_vlan(struct beiscsi_hba * phba,uint16_t vlan_tag)720db02aea9SJitendra Bhivare int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag)
721db02aea9SJitendra Bhivare {
722db02aea9SJitendra Bhivare int rc;
723db02aea9SJitendra Bhivare unsigned int tag;
724db02aea9SJitendra Bhivare
725db02aea9SJitendra Bhivare tag = be_cmd_set_vlan(phba, vlan_tag);
726db02aea9SJitendra Bhivare if (!tag) {
727db02aea9SJitendra Bhivare beiscsi_log(phba, KERN_ERR,
728db02aea9SJitendra Bhivare (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
729db02aea9SJitendra Bhivare "BG_%d : VLAN Setting Failed\n");
730db02aea9SJitendra Bhivare return -EBUSY;
731db02aea9SJitendra Bhivare }
732db02aea9SJitendra Bhivare
733db02aea9SJitendra Bhivare rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
734db02aea9SJitendra Bhivare if (rc) {
735db02aea9SJitendra Bhivare beiscsi_log(phba, KERN_ERR,
736db02aea9SJitendra Bhivare (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
737db02aea9SJitendra Bhivare "BS_%d : VLAN MBX Cmd Failed\n");
738db02aea9SJitendra Bhivare return rc;
739db02aea9SJitendra Bhivare }
740db02aea9SJitendra Bhivare return rc;
741db02aea9SJitendra Bhivare }
742db02aea9SJitendra Bhivare
743db02aea9SJitendra Bhivare
beiscsi_if_get_info(struct beiscsi_hba * phba,int ip_type,struct be_cmd_get_if_info_resp ** if_info)74496b48b92SJitendra Bhivare int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
7451f536d49SJayamohan Kallickal struct be_cmd_get_if_info_resp **if_info)
7460e43895eSMike Christie {
7470e43895eSMike Christie struct be_cmd_get_if_info_req *req;
7480e43895eSMike Christie struct be_dma_mem nonemb_cmd;
7491f536d49SJayamohan Kallickal uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
7500e43895eSMike Christie int rc;
7510e43895eSMike Christie
752c5bf8889SJitendra Bhivare rc = beiscsi_if_get_handle(phba);
7533c9d903bSJitendra Bhivare if (rc)
7543c9d903bSJitendra Bhivare return rc;
7550e43895eSMike Christie
7561f536d49SJayamohan Kallickal do {
757a39e9f71SJitendra Bhivare rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
758a39e9f71SJitendra Bhivare CMD_SUBSYSTEM_ISCSI,
7590e43895eSMike Christie OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
7601f536d49SJayamohan Kallickal ioctl_size);
7610e43895eSMike Christie if (rc)
7620e43895eSMike Christie return rc;
7630e43895eSMike Christie
7640e43895eSMike Christie req = nonemb_cmd.va;
7650e43895eSMike Christie req->interface_hndl = phba->interface_handle;
7660e43895eSMike Christie req->ip_type = ip_type;
7670e43895eSMike Christie
7681f536d49SJayamohan Kallickal /* Allocate memory for if_info */
7691f536d49SJayamohan Kallickal *if_info = kzalloc(ioctl_size, GFP_KERNEL);
7701f536d49SJayamohan Kallickal if (!*if_info) {
7711f536d49SJayamohan Kallickal beiscsi_log(phba, KERN_ERR,
7721f536d49SJayamohan Kallickal BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
7731f536d49SJayamohan Kallickal "BG_%d : Memory Allocation Failure\n");
7741f536d49SJayamohan Kallickal
7757b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd,
7767b0ddc13SMike Christie -ENOMEM);
7771f536d49SJayamohan Kallickal return -ENOMEM;
7781f536d49SJayamohan Kallickal }
7791f536d49SJayamohan Kallickal
780a39e9f71SJitendra Bhivare rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, *if_info,
7811f536d49SJayamohan Kallickal ioctl_size);
7821f536d49SJayamohan Kallickal
7831f536d49SJayamohan Kallickal /* Check if the error is because of Insufficent_Buffer */
7841f536d49SJayamohan Kallickal if (rc == -EAGAIN) {
7851f536d49SJayamohan Kallickal
7861f536d49SJayamohan Kallickal /* Get the new memory size */
7871f536d49SJayamohan Kallickal ioctl_size = ((struct be_cmd_resp_hdr *)
7881f536d49SJayamohan Kallickal nonemb_cmd.va)->actual_resp_len;
7891f536d49SJayamohan Kallickal ioctl_size += sizeof(struct be_cmd_req_hdr);
7901f536d49SJayamohan Kallickal
7917b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
7921f536d49SJayamohan Kallickal /* Free the virtual memory */
7931f536d49SJayamohan Kallickal kfree(*if_info);
7947b0ddc13SMike Christie } else {
7957b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
7961f536d49SJayamohan Kallickal break;
7977b0ddc13SMike Christie }
7981f536d49SJayamohan Kallickal } while (true);
7991f536d49SJayamohan Kallickal return rc;
8000e43895eSMike Christie }
8010e43895eSMike Christie
mgmt_get_nic_conf(struct beiscsi_hba * phba,struct be_cmd_get_nic_conf_resp * nic)8020e43895eSMike Christie int mgmt_get_nic_conf(struct beiscsi_hba *phba,
8030e43895eSMike Christie struct be_cmd_get_nic_conf_resp *nic)
8040e43895eSMike Christie {
8050e43895eSMike Christie struct be_dma_mem nonemb_cmd;
8060e43895eSMike Christie int rc;
8070e43895eSMike Christie
808a39e9f71SJitendra Bhivare rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
8090e43895eSMike Christie OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
8100e43895eSMike Christie sizeof(*nic));
8110e43895eSMike Christie if (rc)
8120e43895eSMike Christie return rc;
8130e43895eSMike Christie
8147b0ddc13SMike Christie rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, nic, sizeof(*nic));
8157b0ddc13SMike Christie beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
8167b0ddc13SMike Christie return rc;
8170e43895eSMike Christie }
8180e43895eSMike Christie
beiscsi_boot_process_compl(struct beiscsi_hba * phba,unsigned int tag)81950a4b824SJitendra Bhivare static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
82050a4b824SJitendra Bhivare unsigned int tag)
82150a4b824SJitendra Bhivare {
82250a4b824SJitendra Bhivare struct be_cmd_get_boot_target_resp *boot_resp;
82350a4b824SJitendra Bhivare struct be_cmd_resp_logout_fw_sess *logo_resp;
82450a4b824SJitendra Bhivare struct be_cmd_get_session_resp *sess_resp;
82550a4b824SJitendra Bhivare struct be_mcc_wrb *wrb;
82650a4b824SJitendra Bhivare struct boot_struct *bs;
82750a4b824SJitendra Bhivare int boot_work, status;
82850a4b824SJitendra Bhivare
82950a4b824SJitendra Bhivare if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
83050a4b824SJitendra Bhivare __beiscsi_log(phba, KERN_ERR,
83150a4b824SJitendra Bhivare "BG_%d : %s no boot work %lx\n",
83250a4b824SJitendra Bhivare __func__, phba->state);
83350a4b824SJitendra Bhivare return;
83450a4b824SJitendra Bhivare }
83550a4b824SJitendra Bhivare
83650a4b824SJitendra Bhivare if (phba->boot_struct.tag != tag) {
83750a4b824SJitendra Bhivare __beiscsi_log(phba, KERN_ERR,
83850a4b824SJitendra Bhivare "BG_%d : %s tag mismatch %d:%d\n",
83950a4b824SJitendra Bhivare __func__, tag, phba->boot_struct.tag);
84050a4b824SJitendra Bhivare return;
84150a4b824SJitendra Bhivare }
84250a4b824SJitendra Bhivare bs = &phba->boot_struct;
84350a4b824SJitendra Bhivare boot_work = 1;
84450a4b824SJitendra Bhivare status = 0;
84550a4b824SJitendra Bhivare switch (bs->action) {
84650a4b824SJitendra Bhivare case BEISCSI_BOOT_REOPEN_SESS:
84750a4b824SJitendra Bhivare status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
84850a4b824SJitendra Bhivare if (!status)
84950a4b824SJitendra Bhivare bs->action = BEISCSI_BOOT_GET_SHANDLE;
85050a4b824SJitendra Bhivare else
85150a4b824SJitendra Bhivare bs->retry--;
85250a4b824SJitendra Bhivare break;
85350a4b824SJitendra Bhivare case BEISCSI_BOOT_GET_SHANDLE:
85450a4b824SJitendra Bhivare status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
85550a4b824SJitendra Bhivare if (!status) {
85650a4b824SJitendra Bhivare boot_resp = embedded_payload(wrb);
85750a4b824SJitendra Bhivare bs->s_handle = boot_resp->boot_session_handle;
85850a4b824SJitendra Bhivare }
85950a4b824SJitendra Bhivare if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
86050a4b824SJitendra Bhivare bs->action = BEISCSI_BOOT_REOPEN_SESS;
86150a4b824SJitendra Bhivare bs->retry--;
86250a4b824SJitendra Bhivare } else {
86350a4b824SJitendra Bhivare bs->action = BEISCSI_BOOT_GET_SINFO;
86450a4b824SJitendra Bhivare }
86550a4b824SJitendra Bhivare break;
86650a4b824SJitendra Bhivare case BEISCSI_BOOT_GET_SINFO:
86750a4b824SJitendra Bhivare status = __beiscsi_mcc_compl_status(phba, tag, NULL,
86850a4b824SJitendra Bhivare &bs->nonemb_cmd);
86950a4b824SJitendra Bhivare if (!status) {
87050a4b824SJitendra Bhivare sess_resp = bs->nonemb_cmd.va;
87150a4b824SJitendra Bhivare memcpy(&bs->boot_sess, &sess_resp->session_info,
87250a4b824SJitendra Bhivare sizeof(struct mgmt_session_info));
87350a4b824SJitendra Bhivare bs->action = BEISCSI_BOOT_LOGOUT_SESS;
87450a4b824SJitendra Bhivare } else {
87550a4b824SJitendra Bhivare __beiscsi_log(phba, KERN_ERR,
87650a4b824SJitendra Bhivare "BG_%d : get boot session info error : 0x%x\n",
87750a4b824SJitendra Bhivare status);
87850a4b824SJitendra Bhivare boot_work = 0;
87950a4b824SJitendra Bhivare }
88026a4c991SChristoph Hellwig dma_free_coherent(&phba->ctrl.pdev->dev, bs->nonemb_cmd.size,
88150a4b824SJitendra Bhivare bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
88250a4b824SJitendra Bhivare bs->nonemb_cmd.va = NULL;
88350a4b824SJitendra Bhivare break;
88450a4b824SJitendra Bhivare case BEISCSI_BOOT_LOGOUT_SESS:
88550a4b824SJitendra Bhivare status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
88650a4b824SJitendra Bhivare if (!status) {
88750a4b824SJitendra Bhivare logo_resp = embedded_payload(wrb);
88850a4b824SJitendra Bhivare if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
88950a4b824SJitendra Bhivare __beiscsi_log(phba, KERN_ERR,
89050a4b824SJitendra Bhivare "BG_%d : FW boot session logout error : 0x%x\n",
89150a4b824SJitendra Bhivare logo_resp->session_status);
89250a4b824SJitendra Bhivare }
89350a4b824SJitendra Bhivare }
89450a4b824SJitendra Bhivare /* continue to create boot_kset even if logout failed? */
89550a4b824SJitendra Bhivare bs->action = BEISCSI_BOOT_CREATE_KSET;
89650a4b824SJitendra Bhivare break;
89750a4b824SJitendra Bhivare default:
89850a4b824SJitendra Bhivare break;
89950a4b824SJitendra Bhivare }
90050a4b824SJitendra Bhivare
90150a4b824SJitendra Bhivare /* clear the tag so no other completion matches this tag */
90250a4b824SJitendra Bhivare bs->tag = 0;
90350a4b824SJitendra Bhivare if (!bs->retry) {
90450a4b824SJitendra Bhivare boot_work = 0;
90550a4b824SJitendra Bhivare __beiscsi_log(phba, KERN_ERR,
90650a4b824SJitendra Bhivare "BG_%d : failed to setup boot target: status %d action %d\n",
90750a4b824SJitendra Bhivare status, bs->action);
90850a4b824SJitendra Bhivare }
90950a4b824SJitendra Bhivare if (!boot_work) {
91050a4b824SJitendra Bhivare /* wait for next event to start boot_work */
91150a4b824SJitendra Bhivare clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
91250a4b824SJitendra Bhivare return;
91350a4b824SJitendra Bhivare }
91450a4b824SJitendra Bhivare schedule_work(&phba->boot_work);
91550a4b824SJitendra Bhivare }
91650a4b824SJitendra Bhivare
9179aef4200SJohn Soni Jose /**
91850a4b824SJitendra Bhivare * beiscsi_boot_logout_sess()- Logout from boot FW session
91950a4b824SJitendra Bhivare * @phba: Device priv structure instance
92050a4b824SJitendra Bhivare *
92150a4b824SJitendra Bhivare * return
92250a4b824SJitendra Bhivare * the TAG used for MBOX Command
92350a4b824SJitendra Bhivare *
92450a4b824SJitendra Bhivare */
beiscsi_boot_logout_sess(struct beiscsi_hba * phba)92550a4b824SJitendra Bhivare unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
92650a4b824SJitendra Bhivare {
92750a4b824SJitendra Bhivare struct be_ctrl_info *ctrl = &phba->ctrl;
92850a4b824SJitendra Bhivare struct be_mcc_wrb *wrb;
92950a4b824SJitendra Bhivare struct be_cmd_req_logout_fw_sess *req;
93050a4b824SJitendra Bhivare unsigned int tag;
93150a4b824SJitendra Bhivare
93250a4b824SJitendra Bhivare mutex_lock(&ctrl->mbox_lock);
93350a4b824SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
93450a4b824SJitendra Bhivare if (!wrb) {
93550a4b824SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
93650a4b824SJitendra Bhivare return 0;
93750a4b824SJitendra Bhivare }
93850a4b824SJitendra Bhivare
93950a4b824SJitendra Bhivare req = embedded_payload(wrb);
94050a4b824SJitendra Bhivare be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
94150a4b824SJitendra Bhivare be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
94250a4b824SJitendra Bhivare OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
94350a4b824SJitendra Bhivare sizeof(struct be_cmd_req_logout_fw_sess));
94450a4b824SJitendra Bhivare /* Use the session handle copied into boot_sess */
94550a4b824SJitendra Bhivare req->session_handle = phba->boot_struct.boot_sess.session_handle;
94650a4b824SJitendra Bhivare
94750a4b824SJitendra Bhivare phba->boot_struct.tag = tag;
94850a4b824SJitendra Bhivare set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
94950a4b824SJitendra Bhivare ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
95050a4b824SJitendra Bhivare
95150a4b824SJitendra Bhivare be_mcc_notify(phba, tag);
95250a4b824SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
95350a4b824SJitendra Bhivare
95450a4b824SJitendra Bhivare return tag;
95550a4b824SJitendra Bhivare }
95650a4b824SJitendra Bhivare /**
95750a4b824SJitendra Bhivare * beiscsi_boot_reopen_sess()- Reopen boot session
95850a4b824SJitendra Bhivare * @phba: Device priv structure instance
95950a4b824SJitendra Bhivare *
96050a4b824SJitendra Bhivare * return
96150a4b824SJitendra Bhivare * the TAG used for MBOX Command
96250a4b824SJitendra Bhivare *
96350a4b824SJitendra Bhivare **/
beiscsi_boot_reopen_sess(struct beiscsi_hba * phba)96450a4b824SJitendra Bhivare unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
96550a4b824SJitendra Bhivare {
96650a4b824SJitendra Bhivare struct be_ctrl_info *ctrl = &phba->ctrl;
96750a4b824SJitendra Bhivare struct be_mcc_wrb *wrb;
96850a4b824SJitendra Bhivare struct be_cmd_reopen_session_req *req;
96950a4b824SJitendra Bhivare unsigned int tag;
97050a4b824SJitendra Bhivare
97150a4b824SJitendra Bhivare mutex_lock(&ctrl->mbox_lock);
97250a4b824SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
97350a4b824SJitendra Bhivare if (!wrb) {
97450a4b824SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
97550a4b824SJitendra Bhivare return 0;
97650a4b824SJitendra Bhivare }
97750a4b824SJitendra Bhivare
97850a4b824SJitendra Bhivare req = embedded_payload(wrb);
97950a4b824SJitendra Bhivare be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
98050a4b824SJitendra Bhivare be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
98150a4b824SJitendra Bhivare OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
98250a4b824SJitendra Bhivare sizeof(struct be_cmd_reopen_session_resp));
98350a4b824SJitendra Bhivare req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
98450a4b824SJitendra Bhivare req->session_handle = BE_BOOT_INVALID_SHANDLE;
98550a4b824SJitendra Bhivare
98650a4b824SJitendra Bhivare phba->boot_struct.tag = tag;
98750a4b824SJitendra Bhivare set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
98850a4b824SJitendra Bhivare ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
98950a4b824SJitendra Bhivare
99050a4b824SJitendra Bhivare be_mcc_notify(phba, tag);
99150a4b824SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
99250a4b824SJitendra Bhivare return tag;
99350a4b824SJitendra Bhivare }
99450a4b824SJitendra Bhivare
99550a4b824SJitendra Bhivare
99650a4b824SJitendra Bhivare /**
99750a4b824SJitendra Bhivare * beiscsi_boot_get_sinfo()- Get boot session info
99850a4b824SJitendra Bhivare * @phba: device priv structure instance
99950a4b824SJitendra Bhivare *
100050a4b824SJitendra Bhivare * Fetches the boot_struct.s_handle info from FW.
100150a4b824SJitendra Bhivare * return
100250a4b824SJitendra Bhivare * the TAG used for MBOX Command
100350a4b824SJitendra Bhivare *
100450a4b824SJitendra Bhivare **/
beiscsi_boot_get_sinfo(struct beiscsi_hba * phba)100550a4b824SJitendra Bhivare unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
100650a4b824SJitendra Bhivare {
100750a4b824SJitendra Bhivare struct be_ctrl_info *ctrl = &phba->ctrl;
100850a4b824SJitendra Bhivare struct be_cmd_get_session_req *req;
100950a4b824SJitendra Bhivare struct be_dma_mem *nonemb_cmd;
101050a4b824SJitendra Bhivare struct be_mcc_wrb *wrb;
101150a4b824SJitendra Bhivare struct be_sge *sge;
101250a4b824SJitendra Bhivare unsigned int tag;
101350a4b824SJitendra Bhivare
101450a4b824SJitendra Bhivare mutex_lock(&ctrl->mbox_lock);
101550a4b824SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
101650a4b824SJitendra Bhivare if (!wrb) {
101750a4b824SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
101850a4b824SJitendra Bhivare return 0;
101950a4b824SJitendra Bhivare }
102050a4b824SJitendra Bhivare
102150a4b824SJitendra Bhivare nonemb_cmd = &phba->boot_struct.nonemb_cmd;
1022fa1261c4SJitendra Bhivare nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp);
102326a4c991SChristoph Hellwig nonemb_cmd->va = dma_alloc_coherent(&phba->ctrl.pdev->dev,
102423b98e4bSDan Carpenter nonemb_cmd->size,
102526a4c991SChristoph Hellwig &nonemb_cmd->dma,
102626a4c991SChristoph Hellwig GFP_KERNEL);
1027658f18d1SJitendra Bhivare if (!nonemb_cmd->va) {
1028658f18d1SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
102950a4b824SJitendra Bhivare return 0;
1030658f18d1SJitendra Bhivare }
103150a4b824SJitendra Bhivare
103250a4b824SJitendra Bhivare req = nonemb_cmd->va;
103350a4b824SJitendra Bhivare memset(req, 0, sizeof(*req));
103450a4b824SJitendra Bhivare sge = nonembedded_sgl(wrb);
103550a4b824SJitendra Bhivare be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
103650a4b824SJitendra Bhivare be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
103750a4b824SJitendra Bhivare OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
1038fa1261c4SJitendra Bhivare sizeof(struct be_cmd_get_session_resp));
103950a4b824SJitendra Bhivare req->session_handle = phba->boot_struct.s_handle;
104050a4b824SJitendra Bhivare sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
104150a4b824SJitendra Bhivare sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
104250a4b824SJitendra Bhivare sge->len = cpu_to_le32(nonemb_cmd->size);
104350a4b824SJitendra Bhivare
104450a4b824SJitendra Bhivare phba->boot_struct.tag = tag;
104550a4b824SJitendra Bhivare set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
104650a4b824SJitendra Bhivare ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
104750a4b824SJitendra Bhivare
104850a4b824SJitendra Bhivare be_mcc_notify(phba, tag);
104950a4b824SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
105050a4b824SJitendra Bhivare return tag;
105150a4b824SJitendra Bhivare }
105250a4b824SJitendra Bhivare
__beiscsi_boot_get_shandle(struct beiscsi_hba * phba,int async)105350a4b824SJitendra Bhivare unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
105450a4b824SJitendra Bhivare {
105550a4b824SJitendra Bhivare struct be_ctrl_info *ctrl = &phba->ctrl;
105650a4b824SJitendra Bhivare struct be_mcc_wrb *wrb;
105750a4b824SJitendra Bhivare struct be_cmd_get_boot_target_req *req;
105850a4b824SJitendra Bhivare unsigned int tag;
105950a4b824SJitendra Bhivare
106050a4b824SJitendra Bhivare mutex_lock(&ctrl->mbox_lock);
106150a4b824SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
106250a4b824SJitendra Bhivare if (!wrb) {
106350a4b824SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
106450a4b824SJitendra Bhivare return 0;
106550a4b824SJitendra Bhivare }
106650a4b824SJitendra Bhivare
106750a4b824SJitendra Bhivare req = embedded_payload(wrb);
106850a4b824SJitendra Bhivare be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
106950a4b824SJitendra Bhivare be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
107050a4b824SJitendra Bhivare OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
107150a4b824SJitendra Bhivare sizeof(struct be_cmd_get_boot_target_resp));
107250a4b824SJitendra Bhivare
107350a4b824SJitendra Bhivare if (async) {
107450a4b824SJitendra Bhivare phba->boot_struct.tag = tag;
107550a4b824SJitendra Bhivare set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
107650a4b824SJitendra Bhivare ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
107750a4b824SJitendra Bhivare }
107850a4b824SJitendra Bhivare
107950a4b824SJitendra Bhivare be_mcc_notify(phba, tag);
108050a4b824SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
108150a4b824SJitendra Bhivare return tag;
108250a4b824SJitendra Bhivare }
108350a4b824SJitendra Bhivare
108450a4b824SJitendra Bhivare /**
108550a4b824SJitendra Bhivare * beiscsi_boot_get_shandle()- Get boot session handle
10869aef4200SJohn Soni Jose * @phba: device priv structure instance
10879aef4200SJohn Soni Jose * @s_handle: session handle returned for boot session.
10889aef4200SJohn Soni Jose *
10899aef4200SJohn Soni Jose * return
109050a4b824SJitendra Bhivare * Success: 1
109150a4b824SJitendra Bhivare * Failure: negative
10929aef4200SJohn Soni Jose *
10939aef4200SJohn Soni Jose **/
beiscsi_boot_get_shandle(struct beiscsi_hba * phba,unsigned int * s_handle)109450a4b824SJitendra Bhivare int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
10959aef4200SJohn Soni Jose {
10969aef4200SJohn Soni Jose struct be_cmd_get_boot_target_resp *boot_resp;
10979aef4200SJohn Soni Jose struct be_mcc_wrb *wrb;
1098e175defeSJohn Soni Jose unsigned int tag;
1099e175defeSJohn Soni Jose int rc;
11009aef4200SJohn Soni Jose
110150a4b824SJitendra Bhivare *s_handle = BE_BOOT_INVALID_SHANDLE;
110250a4b824SJitendra Bhivare /* get configured boot session count and handle */
110350a4b824SJitendra Bhivare tag = __beiscsi_boot_get_shandle(phba, 0);
11049aef4200SJohn Soni Jose if (!tag) {
110599bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR,
110699bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
110799bc5d55SJohn Soni Jose "BG_%d : Getting Boot Target Info Failed\n");
11089aef4200SJohn Soni Jose return -EAGAIN;
1109e175defeSJohn Soni Jose }
11109aef4200SJohn Soni Jose
111188840332SJitendra Bhivare rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1112e175defeSJohn Soni Jose if (rc) {
111399bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR,
111499bc5d55SJohn Soni Jose BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1115e175defeSJohn Soni Jose "BG_%d : MBX CMD get_boot_target Failed\n");
11169aef4200SJohn Soni Jose return -EBUSY;
11179aef4200SJohn Soni Jose }
1118e175defeSJohn Soni Jose
11199aef4200SJohn Soni Jose boot_resp = embedded_payload(wrb);
112050a4b824SJitendra Bhivare /* check if there are any boot targets configured */
11219aef4200SJohn Soni Jose if (!boot_resp->boot_session_count) {
112250a4b824SJitendra Bhivare __beiscsi_log(phba, KERN_INFO,
112350a4b824SJitendra Bhivare "BG_%d : No boot targets configured\n");
11249aef4200SJohn Soni Jose return -ENXIO;
11259aef4200SJohn Soni Jose }
11269aef4200SJohn Soni Jose
112750a4b824SJitendra Bhivare /* only if FW has logged in to the boot target, s_handle is valid */
11289aef4200SJohn Soni Jose *s_handle = boot_resp->boot_session_handle;
112950a4b824SJitendra Bhivare return 1;
11309aef4200SJohn Soni Jose }
11316f72238eSJohn Soni Jose
11326f72238eSJohn Soni Jose /**
11335cac7596SJohn Soni Jose * beiscsi_drvr_ver_disp()- Display the driver Name and Version
11345cac7596SJohn Soni Jose * @dev: ptr to device not used.
11355cac7596SJohn Soni Jose * @attr: device attribute, not used.
11365cac7596SJohn Soni Jose * @buf: contains formatted text driver name and version
11375cac7596SJohn Soni Jose *
11385cac7596SJohn Soni Jose * return
11395cac7596SJohn Soni Jose * size of the formatted string
11405cac7596SJohn Soni Jose **/
11415cac7596SJohn Soni Jose ssize_t
beiscsi_drvr_ver_disp(struct device * dev,struct device_attribute * attr,char * buf)11425cac7596SJohn Soni Jose beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
11435cac7596SJohn Soni Jose char *buf)
11445cac7596SJohn Soni Jose {
11455cac7596SJohn Soni Jose return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
11465cac7596SJohn Soni Jose }
1147acb9693cSJohn Soni Jose
114826000db7SJohn Soni Jose /**
114922661e25SJayamohan Kallickal * beiscsi_fw_ver_disp()- Display Firmware Version
115022661e25SJayamohan Kallickal * @dev: ptr to device not used.
115122661e25SJayamohan Kallickal * @attr: device attribute, not used.
115222661e25SJayamohan Kallickal * @buf: contains formatted text Firmware version
115322661e25SJayamohan Kallickal *
115422661e25SJayamohan Kallickal * return
115522661e25SJayamohan Kallickal * size of the formatted string
115622661e25SJayamohan Kallickal **/
115722661e25SJayamohan Kallickal ssize_t
beiscsi_fw_ver_disp(struct device * dev,struct device_attribute * attr,char * buf)115822661e25SJayamohan Kallickal beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
115922661e25SJayamohan Kallickal char *buf)
116022661e25SJayamohan Kallickal {
116122661e25SJayamohan Kallickal struct Scsi_Host *shost = class_to_shost(dev);
116222661e25SJayamohan Kallickal struct beiscsi_hba *phba = iscsi_host_priv(shost);
116322661e25SJayamohan Kallickal
116422661e25SJayamohan Kallickal return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
116522661e25SJayamohan Kallickal }
116622661e25SJayamohan Kallickal
116722661e25SJayamohan Kallickal /**
11686103c1f7SJayamohan Kallickal * beiscsi_active_session_disp()- Display Sessions Active
11697ad4dfe1SJayamohan Kallickal * @dev: ptr to device not used.
11707ad4dfe1SJayamohan Kallickal * @attr: device attribute, not used.
11717ad4dfe1SJayamohan Kallickal * @buf: contains formatted text Session Count
11727ad4dfe1SJayamohan Kallickal *
11737ad4dfe1SJayamohan Kallickal * return
11747ad4dfe1SJayamohan Kallickal * size of the formatted string
11757ad4dfe1SJayamohan Kallickal **/
11767ad4dfe1SJayamohan Kallickal ssize_t
beiscsi_active_session_disp(struct device * dev,struct device_attribute * attr,char * buf)11776103c1f7SJayamohan Kallickal beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
11787ad4dfe1SJayamohan Kallickal char *buf)
11797ad4dfe1SJayamohan Kallickal {
11807ad4dfe1SJayamohan Kallickal struct Scsi_Host *shost = class_to_shost(dev);
11817ad4dfe1SJayamohan Kallickal struct beiscsi_hba *phba = iscsi_host_priv(shost);
11820a3db7c0SJayamohan Kallickal uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
11837ad4dfe1SJayamohan Kallickal
11840a3db7c0SJayamohan Kallickal for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
11850a3db7c0SJayamohan Kallickal if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
11860a3db7c0SJayamohan Kallickal avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
11870a3db7c0SJayamohan Kallickal total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
11887cd1615eSTakashi Iwai len += scnprintf(buf+len, PAGE_SIZE - len,
11890a3db7c0SJayamohan Kallickal "ULP%d : %d\n", ulp_num,
11900a3db7c0SJayamohan Kallickal (total_cids - avlbl_cids));
11910a3db7c0SJayamohan Kallickal } else
11927cd1615eSTakashi Iwai len += scnprintf(buf+len, PAGE_SIZE - len,
11930a3db7c0SJayamohan Kallickal "ULP%d : %d\n", ulp_num, 0);
11940a3db7c0SJayamohan Kallickal }
11950a3db7c0SJayamohan Kallickal
11960a3db7c0SJayamohan Kallickal return len;
11977ad4dfe1SJayamohan Kallickal }
11987ad4dfe1SJayamohan Kallickal
11997ad4dfe1SJayamohan Kallickal /**
12006103c1f7SJayamohan Kallickal * beiscsi_free_session_disp()- Display Avaliable Session
12016103c1f7SJayamohan Kallickal * @dev: ptr to device not used.
12026103c1f7SJayamohan Kallickal * @attr: device attribute, not used.
12036103c1f7SJayamohan Kallickal * @buf: contains formatted text Session Count
12046103c1f7SJayamohan Kallickal *
12056103c1f7SJayamohan Kallickal * return
12066103c1f7SJayamohan Kallickal * size of the formatted string
12076103c1f7SJayamohan Kallickal **/
12086103c1f7SJayamohan Kallickal ssize_t
beiscsi_free_session_disp(struct device * dev,struct device_attribute * attr,char * buf)12096103c1f7SJayamohan Kallickal beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
12106103c1f7SJayamohan Kallickal char *buf)
12116103c1f7SJayamohan Kallickal {
12126103c1f7SJayamohan Kallickal struct Scsi_Host *shost = class_to_shost(dev);
12136103c1f7SJayamohan Kallickal struct beiscsi_hba *phba = iscsi_host_priv(shost);
12146103c1f7SJayamohan Kallickal uint16_t ulp_num, len = 0;
12156103c1f7SJayamohan Kallickal
12166103c1f7SJayamohan Kallickal for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
12176103c1f7SJayamohan Kallickal if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
12187cd1615eSTakashi Iwai len += scnprintf(buf+len, PAGE_SIZE - len,
12196103c1f7SJayamohan Kallickal "ULP%d : %d\n", ulp_num,
12206103c1f7SJayamohan Kallickal BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
12216103c1f7SJayamohan Kallickal else
12227cd1615eSTakashi Iwai len += scnprintf(buf+len, PAGE_SIZE - len,
12236103c1f7SJayamohan Kallickal "ULP%d : %d\n", ulp_num, 0);
12246103c1f7SJayamohan Kallickal }
12256103c1f7SJayamohan Kallickal
12266103c1f7SJayamohan Kallickal return len;
12276103c1f7SJayamohan Kallickal }
12286103c1f7SJayamohan Kallickal
12296103c1f7SJayamohan Kallickal /**
123026000db7SJohn Soni Jose * beiscsi_adap_family_disp()- Display adapter family.
123126000db7SJohn Soni Jose * @dev: ptr to device to get priv structure
123226000db7SJohn Soni Jose * @attr: device attribute, not used.
123326000db7SJohn Soni Jose * @buf: contains formatted text driver name and version
123426000db7SJohn Soni Jose *
123526000db7SJohn Soni Jose * return
123626000db7SJohn Soni Jose * size of the formatted string
123726000db7SJohn Soni Jose **/
123826000db7SJohn Soni Jose ssize_t
beiscsi_adap_family_disp(struct device * dev,struct device_attribute * attr,char * buf)123926000db7SJohn Soni Jose beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
124026000db7SJohn Soni Jose char *buf)
124126000db7SJohn Soni Jose {
124226000db7SJohn Soni Jose uint16_t dev_id = 0;
124326000db7SJohn Soni Jose struct Scsi_Host *shost = class_to_shost(dev);
124426000db7SJohn Soni Jose struct beiscsi_hba *phba = iscsi_host_priv(shost);
124526000db7SJohn Soni Jose
124626000db7SJohn Soni Jose dev_id = phba->pcidev->device;
124726000db7SJohn Soni Jose switch (dev_id) {
124826000db7SJohn Soni Jose case BE_DEVICE_ID1:
124926000db7SJohn Soni Jose case OC_DEVICE_ID1:
125026000db7SJohn Soni Jose case OC_DEVICE_ID2:
12515fa7db21SKetan Mukadam return snprintf(buf, PAGE_SIZE,
12525fa7db21SKetan Mukadam "Obsolete/Unsupported BE2 Adapter Family\n");
125326000db7SJohn Soni Jose case BE_DEVICE_ID2:
125426000db7SJohn Soni Jose case OC_DEVICE_ID3:
125526000db7SJohn Soni Jose return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
125626000db7SJohn Soni Jose case OC_SKH_ID1:
125726000db7SJohn Soni Jose return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
125826000db7SJohn Soni Jose default:
125926000db7SJohn Soni Jose return snprintf(buf, PAGE_SIZE,
1260b23f7a09SMasanari Iida "Unknown Adapter Family: 0x%x\n", dev_id);
126126000db7SJohn Soni Jose }
126226000db7SJohn Soni Jose }
126326000db7SJohn Soni Jose
1264d3fea9afSJayamohan Kallickal /**
1265ab4bab7aSLee Jones * beiscsi_phys_port_disp()- Display Physical Port Identifier
1266d3fea9afSJayamohan Kallickal * @dev: ptr to device not used.
1267d3fea9afSJayamohan Kallickal * @attr: device attribute, not used.
1268d3fea9afSJayamohan Kallickal * @buf: contains formatted text port identifier
1269d3fea9afSJayamohan Kallickal *
1270d3fea9afSJayamohan Kallickal * return
1271d3fea9afSJayamohan Kallickal * size of the formatted string
1272d3fea9afSJayamohan Kallickal **/
1273d3fea9afSJayamohan Kallickal ssize_t
beiscsi_phys_port_disp(struct device * dev,struct device_attribute * attr,char * buf)1274d3fea9afSJayamohan Kallickal beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1275d3fea9afSJayamohan Kallickal char *buf)
1276d3fea9afSJayamohan Kallickal {
1277d3fea9afSJayamohan Kallickal struct Scsi_Host *shost = class_to_shost(dev);
1278d3fea9afSJayamohan Kallickal struct beiscsi_hba *phba = iscsi_host_priv(shost);
1279d3fea9afSJayamohan Kallickal
1280fa1261c4SJitendra Bhivare return snprintf(buf, PAGE_SIZE, "Port Identifier : %u\n",
1281d3fea9afSJayamohan Kallickal phba->fw_config.phys_port);
1282d3fea9afSJayamohan Kallickal }
128326000db7SJohn Soni Jose
beiscsi_offload_cxn_v0(struct beiscsi_offload_params * params,struct wrb_handle * pwrb_handle,struct be_mem_descriptor * mem_descr,struct hwi_wrb_context * pwrb_context)1284acb9693cSJohn Soni Jose void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1285acb9693cSJohn Soni Jose struct wrb_handle *pwrb_handle,
1286340c99e9SJohn Soni Jose struct be_mem_descriptor *mem_descr,
1287340c99e9SJohn Soni Jose struct hwi_wrb_context *pwrb_context)
1288acb9693cSJohn Soni Jose {
1289acb9693cSJohn Soni Jose struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1290acb9693cSJohn Soni Jose
1291acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1292acb9693cSJohn Soni Jose max_send_data_segment_length, pwrb,
1293acb9693cSJohn Soni Jose params->dw[offsetof(struct amap_beiscsi_offload_params,
1294acb9693cSJohn Soni Jose max_send_data_segment_length) / 32]);
1295acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1296acb9693cSJohn Soni Jose BE_TGT_CTX_UPDT_CMD);
1297acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1298acb9693cSJohn Soni Jose first_burst_length,
1299acb9693cSJohn Soni Jose pwrb,
1300acb9693cSJohn Soni Jose params->dw[offsetof(struct amap_beiscsi_offload_params,
1301acb9693cSJohn Soni Jose first_burst_length) / 32]);
1302acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1303acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1304acb9693cSJohn Soni Jose erl) / 32] & OFFLD_PARAMS_ERL));
1305acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1306acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1307acb9693cSJohn Soni Jose dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1308acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1309acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1310acb9693cSJohn Soni Jose hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1311acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1312acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1313acb9693cSJohn Soni Jose ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1314acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1315acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1316acb9693cSJohn Soni Jose imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1317acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1318acb9693cSJohn Soni Jose pwrb,
1319acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1320acb9693cSJohn Soni Jose exp_statsn) / 32] + 1));
1321acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1322acb9693cSJohn Soni Jose pwrb, pwrb_handle->wrb_index);
1323acb9693cSJohn Soni Jose
1324acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1325acb9693cSJohn Soni Jose max_burst_length, pwrb, params->dw[offsetof
1326acb9693cSJohn Soni Jose (struct amap_beiscsi_offload_params,
1327acb9693cSJohn Soni Jose max_burst_length) / 32]);
1328acb9693cSJohn Soni Jose
1329acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1330340c99e9SJohn Soni Jose pwrb, pwrb_handle->wrb_index);
1331340c99e9SJohn Soni Jose if (pwrb_context->plast_wrb)
1332340c99e9SJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1333340c99e9SJohn Soni Jose ptr2nextwrb,
1334340c99e9SJohn Soni Jose pwrb_context->plast_wrb,
1335340c99e9SJohn Soni Jose pwrb_handle->wrb_index);
1336340c99e9SJohn Soni Jose pwrb_context->plast_wrb = pwrb;
1337340c99e9SJohn Soni Jose
1338acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1339acb9693cSJohn Soni Jose session_state, pwrb, 0);
1340acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1341acb9693cSJohn Soni Jose pwrb, 1);
1342acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1343acb9693cSJohn Soni Jose pwrb, 0);
1344acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1345acb9693cSJohn Soni Jose 0);
1346acb9693cSJohn Soni Jose
1347acb9693cSJohn Soni Jose mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1348acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1349acb9693cSJohn Soni Jose pad_buffer_addr_hi, pwrb,
1350acb9693cSJohn Soni Jose mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1351acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1352acb9693cSJohn Soni Jose pad_buffer_addr_lo, pwrb,
1353acb9693cSJohn Soni Jose mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1354acb9693cSJohn Soni Jose }
1355acb9693cSJohn Soni Jose
beiscsi_offload_cxn_v2(struct beiscsi_offload_params * params,struct wrb_handle * pwrb_handle,struct hwi_wrb_context * pwrb_context)1356acb9693cSJohn Soni Jose void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1357340c99e9SJohn Soni Jose struct wrb_handle *pwrb_handle,
1358340c99e9SJohn Soni Jose struct hwi_wrb_context *pwrb_context)
1359acb9693cSJohn Soni Jose {
1360acb9693cSJohn Soni Jose struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1361acb9693cSJohn Soni Jose
1362acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1363acb9693cSJohn Soni Jose max_burst_length, pwrb, params->dw[offsetof
1364acb9693cSJohn Soni Jose (struct amap_beiscsi_offload_params,
1365acb9693cSJohn Soni Jose max_burst_length) / 32]);
1366acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1367acb9693cSJohn Soni Jose type, pwrb,
1368acb9693cSJohn Soni Jose BE_TGT_CTX_UPDT_CMD);
1369acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1370acb9693cSJohn Soni Jose ptr2nextwrb,
1371340c99e9SJohn Soni Jose pwrb, pwrb_handle->wrb_index);
1372340c99e9SJohn Soni Jose if (pwrb_context->plast_wrb)
1373340c99e9SJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1374340c99e9SJohn Soni Jose ptr2nextwrb,
1375340c99e9SJohn Soni Jose pwrb_context->plast_wrb,
1376340c99e9SJohn Soni Jose pwrb_handle->wrb_index);
1377340c99e9SJohn Soni Jose pwrb_context->plast_wrb = pwrb;
1378340c99e9SJohn Soni Jose
1379acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1380acb9693cSJohn Soni Jose pwrb, pwrb_handle->wrb_index);
1381acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1382acb9693cSJohn Soni Jose max_send_data_segment_length, pwrb,
1383acb9693cSJohn Soni Jose params->dw[offsetof(struct amap_beiscsi_offload_params,
1384acb9693cSJohn Soni Jose max_send_data_segment_length) / 32]);
1385acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1386acb9693cSJohn Soni Jose first_burst_length, pwrb,
1387acb9693cSJohn Soni Jose params->dw[offsetof(struct amap_beiscsi_offload_params,
1388acb9693cSJohn Soni Jose first_burst_length) / 32]);
1389acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
13907331613eSJayamohan Kallickal max_recv_dataseg_len, pwrb,
13917331613eSJayamohan Kallickal params->dw[offsetof(struct amap_beiscsi_offload_params,
13927331613eSJayamohan Kallickal max_recv_data_segment_length) / 32]);
1393acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1394acb9693cSJohn Soni Jose max_cxns, pwrb, BEISCSI_MAX_CXNS);
1395acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1396acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1397acb9693cSJohn Soni Jose erl) / 32] & OFFLD_PARAMS_ERL));
1398acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1399acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1400acb9693cSJohn Soni Jose dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1401acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1402acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1403acb9693cSJohn Soni Jose hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1404acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1405acb9693cSJohn Soni Jose ir2t, pwrb,
1406acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1407acb9693cSJohn Soni Jose ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1408acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1409acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1410acb9693cSJohn Soni Jose imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1411acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1412acb9693cSJohn Soni Jose data_seq_inorder,
1413acb9693cSJohn Soni Jose pwrb,
1414acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1415acb9693cSJohn Soni Jose data_seq_inorder) / 32] &
1416acb9693cSJohn Soni Jose OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1417acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1418acb9693cSJohn Soni Jose pdu_seq_inorder,
1419acb9693cSJohn Soni Jose pwrb,
1420acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1421acb9693cSJohn Soni Jose pdu_seq_inorder) / 32] &
1422acb9693cSJohn Soni Jose OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1423acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1424acb9693cSJohn Soni Jose pwrb,
1425acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1426acb9693cSJohn Soni Jose max_r2t) / 32] &
1427acb9693cSJohn Soni Jose OFFLD_PARAMS_MAX_R2T) >> 8);
1428acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1429acb9693cSJohn Soni Jose pwrb,
1430acb9693cSJohn Soni Jose (params->dw[offsetof(struct amap_beiscsi_offload_params,
1431acb9693cSJohn Soni Jose exp_statsn) / 32] + 1));
1432acb9693cSJohn Soni Jose }
143398713216SJitendra Bhivare
beiscsi_invalidate_cxn(struct beiscsi_hba * phba,struct beiscsi_endpoint * beiscsi_ep)143449fc5152SJitendra Bhivare unsigned int beiscsi_invalidate_cxn(struct beiscsi_hba *phba,
143549fc5152SJitendra Bhivare struct beiscsi_endpoint *beiscsi_ep)
143649fc5152SJitendra Bhivare {
143749fc5152SJitendra Bhivare struct be_invalidate_connection_params_in *req;
143849fc5152SJitendra Bhivare struct be_ctrl_info *ctrl = &phba->ctrl;
143949fc5152SJitendra Bhivare struct be_mcc_wrb *wrb;
144049fc5152SJitendra Bhivare unsigned int tag = 0;
144149fc5152SJitendra Bhivare
144249fc5152SJitendra Bhivare mutex_lock(&ctrl->mbox_lock);
144349fc5152SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
144449fc5152SJitendra Bhivare if (!wrb) {
144549fc5152SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
144649fc5152SJitendra Bhivare return 0;
144749fc5152SJitendra Bhivare }
144849fc5152SJitendra Bhivare
144949fc5152SJitendra Bhivare req = embedded_payload(wrb);
145049fc5152SJitendra Bhivare be_wrb_hdr_prepare(wrb, sizeof(union be_invalidate_connection_params),
145149fc5152SJitendra Bhivare true, 0);
145249fc5152SJitendra Bhivare be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
145349fc5152SJitendra Bhivare OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
145449fc5152SJitendra Bhivare sizeof(*req));
145549fc5152SJitendra Bhivare req->session_handle = beiscsi_ep->fw_handle;
145649fc5152SJitendra Bhivare req->cid = beiscsi_ep->ep_cid;
145749fc5152SJitendra Bhivare if (beiscsi_ep->conn)
145849fc5152SJitendra Bhivare req->cleanup_type = BE_CLEANUP_TYPE_INVALIDATE;
145949fc5152SJitendra Bhivare else
146049fc5152SJitendra Bhivare req->cleanup_type = BE_CLEANUP_TYPE_ISSUE_TCP_RST;
146149fc5152SJitendra Bhivare /**
146249fc5152SJitendra Bhivare * 0 - non-persistent targets
146349fc5152SJitendra Bhivare * 1 - save session info on flash
146449fc5152SJitendra Bhivare */
146549fc5152SJitendra Bhivare req->save_cfg = 0;
146649fc5152SJitendra Bhivare be_mcc_notify(phba, tag);
146749fc5152SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
146849fc5152SJitendra Bhivare return tag;
146949fc5152SJitendra Bhivare }
147049fc5152SJitendra Bhivare
beiscsi_upload_cxn(struct beiscsi_hba * phba,struct beiscsi_endpoint * beiscsi_ep)147149fc5152SJitendra Bhivare unsigned int beiscsi_upload_cxn(struct beiscsi_hba *phba,
147249fc5152SJitendra Bhivare struct beiscsi_endpoint *beiscsi_ep)
147349fc5152SJitendra Bhivare {
147449fc5152SJitendra Bhivare struct be_ctrl_info *ctrl = &phba->ctrl;
147549fc5152SJitendra Bhivare struct be_mcc_wrb *wrb;
147649fc5152SJitendra Bhivare struct be_tcp_upload_params_in *req;
147749fc5152SJitendra Bhivare unsigned int tag;
147849fc5152SJitendra Bhivare
147949fc5152SJitendra Bhivare mutex_lock(&ctrl->mbox_lock);
148049fc5152SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
148149fc5152SJitendra Bhivare if (!wrb) {
148249fc5152SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
148349fc5152SJitendra Bhivare return 0;
148449fc5152SJitendra Bhivare }
148549fc5152SJitendra Bhivare
148649fc5152SJitendra Bhivare req = embedded_payload(wrb);
148749fc5152SJitendra Bhivare be_wrb_hdr_prepare(wrb, sizeof(union be_tcp_upload_params), true, 0);
148849fc5152SJitendra Bhivare be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
148949fc5152SJitendra Bhivare OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
149049fc5152SJitendra Bhivare req->id = beiscsi_ep->ep_cid;
149149fc5152SJitendra Bhivare if (beiscsi_ep->conn)
149249fc5152SJitendra Bhivare req->upload_type = BE_UPLOAD_TYPE_GRACEFUL;
149349fc5152SJitendra Bhivare else
149449fc5152SJitendra Bhivare req->upload_type = BE_UPLOAD_TYPE_ABORT;
149549fc5152SJitendra Bhivare be_mcc_notify(phba, tag);
149649fc5152SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
149749fc5152SJitendra Bhivare return tag;
149849fc5152SJitendra Bhivare }
149949fc5152SJitendra Bhivare
beiscsi_mgmt_invalidate_icds(struct beiscsi_hba * phba,struct invldt_cmd_tbl * inv_tbl,unsigned int nents)150098713216SJitendra Bhivare int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba,
150198713216SJitendra Bhivare struct invldt_cmd_tbl *inv_tbl,
150298713216SJitendra Bhivare unsigned int nents)
150398713216SJitendra Bhivare {
150498713216SJitendra Bhivare struct be_ctrl_info *ctrl = &phba->ctrl;
150598713216SJitendra Bhivare struct invldt_cmds_params_in *req;
150698713216SJitendra Bhivare struct be_dma_mem nonemb_cmd;
150798713216SJitendra Bhivare struct be_mcc_wrb *wrb;
150898713216SJitendra Bhivare unsigned int i, tag;
150998713216SJitendra Bhivare struct be_sge *sge;
151098713216SJitendra Bhivare int rc;
151198713216SJitendra Bhivare
151298713216SJitendra Bhivare if (!nents || nents > BE_INVLDT_CMD_TBL_SZ)
151398713216SJitendra Bhivare return -EINVAL;
151498713216SJitendra Bhivare
151598713216SJitendra Bhivare nonemb_cmd.size = sizeof(union be_invldt_cmds_params);
1516750afb08SLuis Chamberlain nonemb_cmd.va = dma_alloc_coherent(&phba->ctrl.pdev->dev,
1517750afb08SLuis Chamberlain nonemb_cmd.size, &nonemb_cmd.dma,
151826a4c991SChristoph Hellwig GFP_KERNEL);
151998713216SJitendra Bhivare if (!nonemb_cmd.va) {
152098713216SJitendra Bhivare beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
152198713216SJitendra Bhivare "BM_%d : invldt_cmds_params alloc failed\n");
152298713216SJitendra Bhivare return -ENOMEM;
152398713216SJitendra Bhivare }
152498713216SJitendra Bhivare
152598713216SJitendra Bhivare mutex_lock(&ctrl->mbox_lock);
152698713216SJitendra Bhivare wrb = alloc_mcc_wrb(phba, &tag);
152798713216SJitendra Bhivare if (!wrb) {
152898713216SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
152926a4c991SChristoph Hellwig dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
153098713216SJitendra Bhivare nonemb_cmd.va, nonemb_cmd.dma);
153198713216SJitendra Bhivare return -ENOMEM;
153298713216SJitendra Bhivare }
153398713216SJitendra Bhivare
153498713216SJitendra Bhivare req = nonemb_cmd.va;
153598713216SJitendra Bhivare be_wrb_hdr_prepare(wrb, nonemb_cmd.size, false, 1);
153698713216SJitendra Bhivare be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
153798713216SJitendra Bhivare OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
153898713216SJitendra Bhivare sizeof(*req));
153998713216SJitendra Bhivare req->ref_handle = 0;
154098713216SJitendra Bhivare req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
154198713216SJitendra Bhivare for (i = 0; i < nents; i++) {
154298713216SJitendra Bhivare req->table[i].icd = inv_tbl[i].icd;
154398713216SJitendra Bhivare req->table[i].cid = inv_tbl[i].cid;
154498713216SJitendra Bhivare req->icd_count++;
154598713216SJitendra Bhivare }
154698713216SJitendra Bhivare sge = nonembedded_sgl(wrb);
154798713216SJitendra Bhivare sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
154898713216SJitendra Bhivare sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd.dma));
154998713216SJitendra Bhivare sge->len = cpu_to_le32(nonemb_cmd.size);
155098713216SJitendra Bhivare
155198713216SJitendra Bhivare be_mcc_notify(phba, tag);
155298713216SJitendra Bhivare mutex_unlock(&ctrl->mbox_lock);
155398713216SJitendra Bhivare
155498713216SJitendra Bhivare rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
155598713216SJitendra Bhivare if (rc != -EBUSY)
155626a4c991SChristoph Hellwig dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
155798713216SJitendra Bhivare nonemb_cmd.va, nonemb_cmd.dma);
155898713216SJitendra Bhivare return rc;
155998713216SJitendra Bhivare }
1560