blob: c73775368d0913805270ae874f54ab1822e332a6 [file] [log] [blame]
Jitendra Bhivare942b7652017-03-24 14:11:48 +05301/*
2 * Copyright 2017 Broadcom. All Rights Reserved.
3 * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05304 *
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
Jitendra Bhivare942b7652017-03-24 14:11:48 +05307 * as published by the Free Software Foundation. The full GNU General
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05308 * Public License is included in this distribution in the file called COPYING.
9 *
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053010 * Contact Information:
Jitendra Bhivare60f36e02016-08-19 15:20:24 +053011 * linux-drivers@broadcom.com
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053012 *
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053013 */
14
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -050015#include <linux/bsg-lib.h>
16#include <scsi/scsi_transport_iscsi.h>
17#include <scsi/scsi_bsg_iscsi.h>
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053018#include "be_mgmt.h"
19#include "be_iscsi.h"
John Soni Jose7a158002012-10-20 04:45:51 +053020#include "be_main.h"
21
Jitendra Bhivare10bcd472016-08-19 15:20:13 +053022int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
23 struct be_set_eqd *set_eqd,
24 int num)
Jayamohan Kallickal73af08e2014-05-05 21:41:26 -040025{
26 struct be_ctrl_info *ctrl = &phba->ctrl;
27 struct be_mcc_wrb *wrb;
28 struct be_cmd_req_modify_eq_delay *req;
Jitendra Bhivare090e2182016-02-04 15:49:17 +053029 unsigned int tag;
Jayamohan Kallickal73af08e2014-05-05 21:41:26 -040030 int i;
31
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +053032 mutex_lock(&ctrl->mbox_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +053033 wrb = alloc_mcc_wrb(phba, &tag);
34 if (!wrb) {
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +053035 mutex_unlock(&ctrl->mbox_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +053036 return 0;
Jayamohan Kallickal73af08e2014-05-05 21:41:26 -040037 }
38
Jayamohan Kallickal73af08e2014-05-05 21:41:26 -040039 req = embedded_payload(wrb);
Jayamohan Kallickal73af08e2014-05-05 21:41:26 -040040 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
41 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Jitendra Bhivare10bcd472016-08-19 15:20:13 +053042 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
Jayamohan Kallickal73af08e2014-05-05 21:41:26 -040043
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
Jitendra Bhivare10bcd472016-08-19 15:20:13 +053052 /* ignore the completion of this mbox command */
53 set_bit(MCC_TAG_STATE_IGNORE, &ctrl->ptag_state[tag].tag_state);
Jitendra Bhivarecdde6682016-01-20 14:10:47 +053054 be_mcc_notify(phba, tag);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +053055 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal73af08e2014-05-05 21:41:26 -040056 return tag;
57}
58
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -050059unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
60 struct beiscsi_hba *phba,
61 struct bsg_job *job,
62 struct be_dma_mem *nonemb_cmd)
63{
Jayamohan Kallickaldaa8dc02014-05-05 21:41:24 -040064 struct be_mcc_wrb *wrb;
65 struct be_sge *mcc_sge;
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -050066 unsigned int tag = 0;
67 struct iscsi_bsg_request *bsg_req = job->request;
68 struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
69 unsigned short region, sector_size, sector, offset;
70
71 nonemb_cmd->size = job->request_payload.payload_len;
72 memset(nonemb_cmd->va, 0, nonemb_cmd->size);
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -050073 region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
74 sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
75 sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
76 offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4];
77 req->region = region;
78 req->sector = sector;
79 req->offset = offset;
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -050080
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +053081 if (mutex_lock_interruptible(&ctrl->mbox_lock))
82 return 0;
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -050083 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
84 case BEISCSI_WRITE_FLASH:
85 offset = sector * sector_size + offset;
86 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
87 OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
88 sg_copy_to_buffer(job->request_payload.sg_list,
89 job->request_payload.sg_cnt,
90 nonemb_cmd->va + offset, job->request_len);
91 break;
92 case BEISCSI_READ_FLASH:
93 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
94 OPCODE_COMMON_READ_FLASH, sizeof(*req));
95 break;
96 default:
John Soni Jose99bc5d52012-08-20 23:00:18 +053097 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
98 "BG_%d : Unsupported cmd = 0x%x\n\n",
99 bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
100
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530101 mutex_unlock(&ctrl->mbox_lock);
Jitendra Bhivarec5bf8882016-08-19 15:20:05 +0530102 return -EPERM;
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500103 }
104
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530105 wrb = alloc_mcc_wrb(phba, &tag);
106 if (!wrb) {
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530107 mutex_unlock(&ctrl->mbox_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530108 return 0;
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500109 }
110
Jayamohan Kallickaldaa8dc02014-05-05 21:41:24 -0400111 mcc_sge = nonembedded_sgl(wrb);
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500112 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
113 job->request_payload.sg_cnt);
114 mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
115 mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
116 mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500117
Jitendra Bhivarecdde6682016-01-20 14:10:47 +0530118 be_mcc_notify(phba, tag);
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500119
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530120 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500121 return tag;
122}
123
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700124/**
125 * mgmt_open_connection()- Establish a TCP CXN
126 * @dst_addr: Destination Address
127 * @beiscsi_ep: ptr to device endpoint struct
128 * @nonemb_cmd: ptr to memory allocated for command
129 *
130 * return
131 * Success: Tag number of the MBX Command issued
132 * Failure: Error code
133 **/
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530134int mgmt_open_connection(struct beiscsi_hba *phba,
135 struct sockaddr *dst_addr,
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530136 struct beiscsi_endpoint *beiscsi_ep,
137 struct be_dma_mem *nonemb_cmd)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530138{
139 struct hwi_controller *phwi_ctrlr;
140 struct hwi_context_memory *phwi_context;
141 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
142 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
143 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530144 struct be_mcc_wrb *wrb;
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -0400145 struct tcp_connect_and_offload_in_v1 *req;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530146 unsigned short def_hdr_id;
147 unsigned short def_data_id;
148 struct phys_addr template_address = { 0, 0 };
149 struct phys_addr *ptemplate_address;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530150 unsigned int tag = 0;
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700151 unsigned int i, ulp_num;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530152 unsigned short cid = beiscsi_ep->ep_cid;
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530153 struct be_sge *sge;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530154
Jitendra Bhivare291fef22016-02-04 15:49:16 +0530155 if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
156 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
157 "BG_%d : unknown addr family %d\n",
158 dst_addr->sa_family);
159 return -EINVAL;
160 }
161
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530162 phwi_ctrlr = phba->phwi_ctrlr;
163 phwi_context = phwi_ctrlr->phwi_ctxt;
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700164
165 ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
166
167 def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
168 def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530169
170 ptemplate_address = &template_address;
171 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530172 if (mutex_lock_interruptible(&ctrl->mbox_lock))
173 return 0;
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530174 wrb = alloc_mcc_wrb(phba, &tag);
175 if (!wrb) {
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530176 mutex_unlock(&ctrl->mbox_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530177 return 0;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530178 }
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530179
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530180 sge = nonembedded_sgl(wrb);
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530181 req = nonemb_cmd->va;
182 memset(req, 0, sizeof(*req));
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530183
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -0400184 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530185 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
186 OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -0400187 nonemb_cmd->size);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530188 if (dst_addr->sa_family == PF_INET) {
189 __be32 s_addr = daddr_in->sin_addr.s_addr;
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530190 req->ip_address.ip_type = BEISCSI_IP_TYPE_V4;
Mike Christie0e438952012-04-03 23:41:51 -0500191 req->ip_address.addr[0] = s_addr & 0x000000ff;
192 req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
193 req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
194 req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530195 req->tcp_port = ntohs(daddr_in->sin_port);
196 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
197 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530198 beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4;
Jitendra Bhivare291fef22016-02-04 15:49:16 +0530199 } else {
200 /* else its PF_INET6 family */
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530201 req->ip_address.ip_type = BEISCSI_IP_TYPE_V6;
Mike Christie0e438952012-04-03 23:41:51 -0500202 memcpy(&req->ip_address.addr,
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530203 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
204 req->tcp_port = ntohs(daddr_in6->sin6_port);
205 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
206 memcpy(&beiscsi_ep->dst6_addr,
207 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530208 beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530209 }
210 req->cid = cid;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530211 i = phba->nxt_cqid++;
212 if (phba->nxt_cqid == phba->num_cpus)
213 phba->nxt_cqid = 0;
214 req->cq_id = phwi_context->be_cq[i].id;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530215 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
216 "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530217 req->defq_id = def_hdr_id;
218 req->hdr_ring_id = def_hdr_id;
219 req->data_ring_id = def_data_id;
220 req->do_offload = 1;
221 req->dataout_template_pa.lo = ptemplate_address->lo;
222 req->dataout_template_pa.hi = ptemplate_address->hi;
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530223 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
224 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
225 sge->len = cpu_to_le32(nonemb_cmd->size);
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -0400226
227 if (!is_chip_be2_be3r(phba)) {
228 req->hdr.version = MBX_CMD_VER1;
Jitendra Bhivare1b7a7dd2016-08-19 15:20:23 +0530229 req->tcp_window_size = 0x8000;
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -0400230 req->tcp_window_scale_count = 2;
231 }
232
Jitendra Bhivarecdde6682016-01-20 14:10:47 +0530233 be_mcc_notify(phba, tag);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530234 mutex_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530235 return tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530236}
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530237
John Soni Josee175def2012-10-20 04:45:40 +0530238/*
239 * mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
240 * @phba: Driver priv structure
241 * @nonemb_cmd: Address of the MBX command issued
242 * @resp_buf: Buffer to copy the MBX cmd response
243 * @resp_buf_len: respone lenght to be copied
244 *
245 **/
Mike Christie0e438952012-04-03 23:41:51 -0500246static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
247 struct be_dma_mem *nonemb_cmd, void *resp_buf,
248 int resp_buf_len)
249{
250 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickaldaa8dc02014-05-05 21:41:24 -0400251 struct be_mcc_wrb *wrb;
Mike Christie0e438952012-04-03 23:41:51 -0500252 struct be_sge *sge;
253 unsigned int tag;
254 int rc = 0;
255
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530256 mutex_lock(&ctrl->mbox_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530257 wrb = alloc_mcc_wrb(phba, &tag);
258 if (!wrb) {
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530259 mutex_unlock(&ctrl->mbox_lock);
Mike Christie0e438952012-04-03 23:41:51 -0500260 rc = -ENOMEM;
261 goto free_cmd;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530262 }
Jayamohan Kallickaldaa8dc02014-05-05 21:41:24 -0400263
Mike Christie0e438952012-04-03 23:41:51 -0500264 sge = nonembedded_sgl(wrb);
Mike Christie0e438952012-04-03 23:41:51 -0500265 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
266 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
John Soni Josee175def2012-10-20 04:45:40 +0530267 sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
Mike Christie0e438952012-04-03 23:41:51 -0500268 sge->len = cpu_to_le32(nonemb_cmd->size);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530269
Jitendra Bhivarecdde6682016-01-20 14:10:47 +0530270 be_mcc_notify(phba, tag);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530271 mutex_unlock(&ctrl->mbox_lock);
Mike Christie0e438952012-04-03 23:41:51 -0500272
Jitendra Bhivare88840332016-02-04 15:49:12 +0530273 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd);
Mike Christie0e438952012-04-03 23:41:51 -0500274
275 if (resp_buf)
276 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
277
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500278 if (rc) {
279 /* Check if the MBX Cmd needs to be re-issued */
280 if (rc == -EAGAIN)
281 return rc;
282
283 beiscsi_log(phba, KERN_WARNING,
284 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
285 "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
286
287 if (rc != -EBUSY)
288 goto free_cmd;
289 else
290 return rc;
291 }
Mike Christie0e438952012-04-03 23:41:51 -0500292free_cmd:
293 pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
294 nonemb_cmd->va, nonemb_cmd->dma);
295 return rc;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530296}
297
Mike Christie0e438952012-04-03 23:41:51 -0500298static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
299 int iscsi_cmd, int size)
300{
Joe Perches7c845eb2014-08-08 14:24:46 -0700301 cmd->va = pci_zalloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
Mike Christie0e438952012-04-03 23:41:51 -0500302 if (!cmd->va) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530303 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
304 "BG_%d : Failed to allocate memory for if info\n");
Mike Christie0e438952012-04-03 23:41:51 -0500305 return -ENOMEM;
306 }
Mike Christie0e438952012-04-03 23:41:51 -0500307 cmd->size = size;
308 be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530309 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
310 "BG_%d : subsystem iSCSI cmd %d size %d\n",
311 iscsi_cmd, size);
Mike Christie0e438952012-04-03 23:41:51 -0500312 return 0;
313}
314
Jitendra Bhivarec5bf8882016-08-19 15:20:05 +0530315unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba)
316{
317 struct be_ctrl_info *ctrl = &phba->ctrl;
318 struct be_mcc_wrb *wrb;
319 struct be_cmd_get_all_if_id_req *req;
320 struct be_cmd_get_all_if_id_req *pbe_allid;
321 unsigned int tag;
322 int status = 0;
323
324 if (mutex_lock_interruptible(&ctrl->mbox_lock))
325 return -EINTR;
326 wrb = alloc_mcc_wrb(phba, &tag);
327 if (!wrb) {
328 mutex_unlock(&ctrl->mbox_lock);
329 return -ENOMEM;
330 }
331
332 req = embedded_payload(wrb);
333 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
334 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
335 OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
336 sizeof(*req));
337 be_mcc_notify(phba, tag);
338 mutex_unlock(&ctrl->mbox_lock);
339
340 status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
341 if (status) {
342 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
343 "BG_%d : %s failed: %d\n", __func__, status);
344 return -EBUSY;
345 }
346
347 pbe_allid = embedded_payload(wrb);
348 /* we now support only one interface per function */
349 phba->interface_handle = pbe_allid->if_hndl_list[0];
350
351 return status;
352}
353
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530354static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type)
355{
356 u32 len;
357
358 len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
359 while (len && !ip[len - 1])
360 len--;
361 return (len == 0);
362}
363
Jitendra Bhivare37f21642016-08-19 15:20:02 +0530364static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
365 u32 action, u32 ip_type, u8 *gw)
Mike Christie0e438952012-04-03 23:41:51 -0500366{
367 struct be_cmd_set_def_gateway_req *req;
368 struct be_dma_mem nonemb_cmd;
369 int rt_val;
370
Mike Christie0e438952012-04-03 23:41:51 -0500371 rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
372 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
373 sizeof(*req));
374 if (rt_val)
375 return rt_val;
376
377 req = nonemb_cmd.va;
Jitendra Bhivare37f21642016-08-19 15:20:02 +0530378 req->action = action;
379 req->ip_addr.ip_type = ip_type;
380 memcpy(req->ip_addr.addr, gw,
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530381 (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
Mike Christie0e438952012-04-03 23:41:51 -0500382 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
383}
384
Jitendra Bhivare37f21642016-08-19 15:20:02 +0530385int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw)
386{
387 struct be_cmd_get_def_gateway_resp gw_resp;
388 int rt_val;
389
390 memset(&gw_resp, 0, sizeof(gw_resp));
391 rt_val = beiscsi_if_get_gw(phba, ip_type, &gw_resp);
392 if (rt_val) {
393 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
394 "BG_%d : Failed to Get Gateway Addr\n");
395 return rt_val;
396 }
397
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530398 if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) {
399 rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type,
400 gw_resp.ip_addr.addr);
401 if (rt_val) {
402 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
403 "BG_%d : Failed to clear Gateway Addr Set\n");
404 return rt_val;
405 }
Jitendra Bhivare37f21642016-08-19 15:20:02 +0530406 }
407
408 rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw);
409 if (rt_val)
410 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
411 "BG_%d : Failed to Set Gateway Addr\n");
412
413 return rt_val;
414}
415
416int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
417 struct be_cmd_get_def_gateway_resp *resp)
418{
419 struct be_cmd_get_def_gateway_req *req;
420 struct be_dma_mem nonemb_cmd;
421 int rc;
422
423 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
424 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
425 sizeof(*resp));
426 if (rc)
427 return rc;
428
429 req = nonemb_cmd.va;
430 req->ip_type = ip_type;
431
432 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, resp,
433 sizeof(*resp));
434}
435
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530436static int
437beiscsi_if_clr_ip(struct beiscsi_hba *phba,
438 struct be_cmd_get_if_info_resp *if_info)
Mike Christie0e438952012-04-03 23:41:51 -0500439{
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530440 struct be_cmd_set_ip_addr_req *req;
Mike Christie0e438952012-04-03 23:41:51 -0500441 struct be_dma_mem nonemb_cmd;
Mike Christie0e438952012-04-03 23:41:51 -0500442 int rc;
443
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530444 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
445 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
446 sizeof(*req));
Jitendra Bhivare3c9d9032016-01-20 14:10:50 +0530447 if (rc)
448 return rc;
Mike Christie0e438952012-04-03 23:41:51 -0500449
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530450 req = nonemb_cmd.va;
451 req->ip_params.record_entry_count = 1;
452 req->ip_params.ip_record.action = IP_ACTION_DEL;
453 req->ip_params.ip_record.interface_hndl =
454 phba->interface_handle;
455 req->ip_params.ip_record.ip_addr.size_of_structure =
456 sizeof(struct be_ip_addr_subnet_format);
457 req->ip_params.ip_record.ip_addr.ip_type = if_info->ip_addr.ip_type;
458 memcpy(req->ip_params.ip_record.ip_addr.addr,
459 if_info->ip_addr.addr,
460 sizeof(if_info->ip_addr.addr));
461 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
462 if_info->ip_addr.subnet_mask,
463 sizeof(if_info->ip_addr.subnet_mask));
464 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
465 if (rc < 0 || req->ip_params.ip_record.status) {
466 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
467 "BG_%d : failed to clear IP: rc %d status %d\n",
468 rc, req->ip_params.ip_record.status);
469 }
470 return rc;
471}
472
473static int
474beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip,
475 u8 *subnet, u32 ip_type)
476{
477 struct be_cmd_set_ip_addr_req *req;
478 struct be_dma_mem nonemb_cmd;
479 uint32_t ip_len;
480 int rc;
481
482 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
483 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
484 sizeof(*req));
485 if (rc)
486 return rc;
487
488 req = nonemb_cmd.va;
489 req->ip_params.record_entry_count = 1;
490 req->ip_params.ip_record.action = IP_ACTION_ADD;
491 req->ip_params.ip_record.interface_hndl =
492 phba->interface_handle;
493 req->ip_params.ip_record.ip_addr.size_of_structure =
494 sizeof(struct be_ip_addr_subnet_format);
495 req->ip_params.ip_record.ip_addr.ip_type = ip_type;
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530496 ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530497 memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len);
498 if (subnet)
499 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
500 subnet, ip_len);
501
502 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
503 /**
504 * In some cases, host needs to look into individual record status
505 * even though FW reported success for that IOCTL.
506 */
507 if (rc < 0 || req->ip_params.ip_record.status) {
508 __beiscsi_log(phba, KERN_ERR,
509 "BG_%d : failed to set IP: rc %d status %d\n",
510 rc, req->ip_params.ip_record.status);
511 if (req->ip_params.ip_record.status)
512 rc = -EINVAL;
513 }
514 return rc;
515}
516
517int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
518 u8 *ip, u8 *subnet)
519{
520 struct be_cmd_get_if_info_resp *if_info;
521 struct be_cmd_rel_dhcp_req *reldhcp;
522 struct be_dma_mem nonemb_cmd;
523 int rc;
Mike Christie0e438952012-04-03 23:41:51 -0500524
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530525 rc = beiscsi_if_get_info(phba, ip_type, &if_info);
Tomas Henzlbeff6542014-06-06 14:22:44 +0200526 if (rc)
Mike Christie0e438952012-04-03 23:41:51 -0500527 return rc;
528
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530529 if (if_info->dhcp_state) {
530 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
Mike Christie0e438952012-04-03 23:41:51 -0500531 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
532 sizeof(*reldhcp));
Mike Christie0e438952012-04-03 23:41:51 -0500533 if (rc)
Maurizio Lombardi6d677262014-06-27 14:55:20 +0200534 goto exit;
Mike Christie0e438952012-04-03 23:41:51 -0500535
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530536 reldhcp = nonemb_cmd.va;
537 reldhcp->interface_hndl = phba->interface_handle;
538 reldhcp->ip_type = ip_type;
539 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
540 if (rc < 0) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530541 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530542 "BG_%d : failed to release existing DHCP: %d\n",
543 rc);
Maurizio Lombardi6d677262014-06-27 14:55:20 +0200544 goto exit;
Mike Christie0e438952012-04-03 23:41:51 -0500545 }
Mike Christie0e438952012-04-03 23:41:51 -0500546 }
547
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530548 /* first delete any IP set */
549 if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
550 rc = beiscsi_if_clr_ip(phba, if_info);
551 if (rc)
552 goto exit;
553 }
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530554
555 /* if ip == NULL then this is called just to release DHCP IP */
556 if (ip)
557 rc = beiscsi_if_set_ip(phba, ip, subnet, ip_type);
558exit:
559 kfree(if_info);
560 return rc;
561}
562
563int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type)
564{
565 struct be_cmd_get_def_gateway_resp gw_resp;
566 struct be_cmd_get_if_info_resp *if_info;
567 struct be_cmd_set_dhcp_req *dhcpreq;
568 struct be_dma_mem nonemb_cmd;
569 u8 *gw;
570 int rc;
571
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530572 rc = beiscsi_if_get_info(phba, ip_type, &if_info);
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530573 if (rc)
574 return rc;
575
576 if (if_info->dhcp_state) {
577 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
578 "BG_%d : DHCP Already Enabled\n");
579 goto exit;
580 }
581
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530582 /* 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 }
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530588
589 /* delete gateway settings if mode change is to DHCP */
590 memset(&gw_resp, 0, sizeof(gw_resp));
591 /* use ip_type provided in if_info */
592 rc = beiscsi_if_get_gw(phba, if_info->ip_addr.ip_type, &gw_resp);
593 if (rc) {
594 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
595 "BG_%d : Failed to Get Gateway Addr\n");
596 goto exit;
597 }
598 gw = (u8 *)&gw_resp.ip_addr.addr;
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530599 if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) {
600 rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL,
601 if_info->ip_addr.ip_type, gw);
602 if (rc) {
603 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
604 "BG_%d : Failed to clear Gateway Addr Set\n");
605 goto exit;
606 }
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530607 }
608
609 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
Mike Christie0e438952012-04-03 23:41:51 -0500610 OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
611 sizeof(*dhcpreq));
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530612 if (rc)
613 goto exit;
Mike Christie0e438952012-04-03 23:41:51 -0500614
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530615 dhcpreq = nonemb_cmd.va;
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530616 dhcpreq->flags = 1; /* 1 - blocking; 0 - non-blocking */
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530617 dhcpreq->retry_count = 1;
618 dhcpreq->interface_hndl = phba->interface_handle;
619 dhcpreq->ip_type = ip_type;
620 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
Mike Christie0e438952012-04-03 23:41:51 -0500621
Maurizio Lombardi6d677262014-06-27 14:55:20 +0200622exit:
623 kfree(if_info);
Mike Christie0e438952012-04-03 23:41:51 -0500624 return rc;
625}
626
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530627/**
628 * beiscsi_if_set_vlan()- Issue and wait for CMD completion
629 * @phba: device private structure instance
630 * @vlan_tag: VLAN tag
631 *
632 * Issue the MBX Cmd and wait for the completion of the
633 * command.
634 *
635 * returns
636 * Success: 0
637 * Failure: Non-Xero Value
638 **/
639int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag)
640{
641 int rc;
642 unsigned int tag;
643
644 tag = be_cmd_set_vlan(phba, vlan_tag);
645 if (!tag) {
646 beiscsi_log(phba, KERN_ERR,
647 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
648 "BG_%d : VLAN Setting Failed\n");
649 return -EBUSY;
650 }
651
652 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
653 if (rc) {
654 beiscsi_log(phba, KERN_ERR,
655 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
656 "BS_%d : VLAN MBX Cmd Failed\n");
657 return rc;
658 }
659 return rc;
660}
661
662
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530663int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
664 struct be_cmd_get_if_info_resp **if_info)
Mike Christie0e438952012-04-03 23:41:51 -0500665{
666 struct be_cmd_get_if_info_req *req;
667 struct be_dma_mem nonemb_cmd;
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700668 uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
Mike Christie0e438952012-04-03 23:41:51 -0500669 int rc;
670
Jitendra Bhivarec5bf8882016-08-19 15:20:05 +0530671 rc = beiscsi_if_get_handle(phba);
Jitendra Bhivare3c9d9032016-01-20 14:10:50 +0530672 if (rc)
673 return rc;
Mike Christie0e438952012-04-03 23:41:51 -0500674
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700675 do {
676 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
677 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
678 ioctl_size);
679 if (rc)
680 return rc;
Mike Christie0e438952012-04-03 23:41:51 -0500681
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700682 req = nonemb_cmd.va;
683 req->interface_hndl = phba->interface_handle;
684 req->ip_type = ip_type;
Mike Christie0e438952012-04-03 23:41:51 -0500685
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700686 /* Allocate memory for if_info */
687 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
688 if (!*if_info) {
689 beiscsi_log(phba, KERN_ERR,
690 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
691 "BG_%d : Memory Allocation Failure\n");
692
693 /* Free the DMA memory for the IOCTL issuing */
694 pci_free_consistent(phba->ctrl.pdev,
695 nonemb_cmd.size,
696 nonemb_cmd.va,
697 nonemb_cmd.dma);
698 return -ENOMEM;
699 }
700
701 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
702 ioctl_size);
703
704 /* Check if the error is because of Insufficent_Buffer */
705 if (rc == -EAGAIN) {
706
707 /* Get the new memory size */
708 ioctl_size = ((struct be_cmd_resp_hdr *)
709 nonemb_cmd.va)->actual_resp_len;
710 ioctl_size += sizeof(struct be_cmd_req_hdr);
711
712 /* Free the previous allocated DMA memory */
713 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
714 nonemb_cmd.va,
715 nonemb_cmd.dma);
716
717 /* Free the virtual memory */
718 kfree(*if_info);
719 } else
720 break;
721 } while (true);
722 return rc;
Mike Christie0e438952012-04-03 23:41:51 -0500723}
724
725int mgmt_get_nic_conf(struct beiscsi_hba *phba,
726 struct be_cmd_get_nic_conf_resp *nic)
727{
728 struct be_dma_mem nonemb_cmd;
729 int rc;
730
731 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
732 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
733 sizeof(*nic));
734 if (rc)
735 return rc;
736
737 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
738}
739
740
741
John Soni Jose21771992012-04-03 23:41:49 -0500742unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
743{
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530744 unsigned int tag;
John Soni Jose21771992012-04-03 23:41:49 -0500745 struct be_mcc_wrb *wrb;
746 struct be_cmd_hba_name *req;
747 struct be_ctrl_info *ctrl = &phba->ctrl;
748
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530749 if (mutex_lock_interruptible(&ctrl->mbox_lock))
750 return 0;
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530751 wrb = alloc_mcc_wrb(phba, &tag);
752 if (!wrb) {
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530753 mutex_unlock(&ctrl->mbox_lock);
Jitendra Bhivare090e2182016-02-04 15:49:17 +0530754 return 0;
John Soni Jose21771992012-04-03 23:41:49 -0500755 }
756
John Soni Jose21771992012-04-03 23:41:49 -0500757 req = embedded_payload(wrb);
John Soni Jose21771992012-04-03 23:41:49 -0500758 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
759 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
760 OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
761 sizeof(*req));
762
Jitendra Bhivarecdde6682016-01-20 14:10:47 +0530763 be_mcc_notify(phba, tag);
Jitendra Bhivarec03a50f2016-01-20 14:10:46 +0530764 mutex_unlock(&ctrl->mbox_lock);
John Soni Jose21771992012-04-03 23:41:49 -0500765 return tag;
766}
John Soni Josec62eef02012-04-03 23:41:52 -0500767
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530768static 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
778 if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
779 __beiscsi_log(phba, KERN_ERR,
780 "BG_%d : %s no boot work %lx\n",
781 __func__, phba->state);
782 return;
783 }
784
785 if (phba->boot_struct.tag != tag) {
786 __beiscsi_log(phba, KERN_ERR,
787 "BG_%d : %s tag mismatch %d:%d\n",
788 __func__, tag, phba->boot_struct.tag);
789 return;
790 }
791 bs = &phba->boot_struct;
792 boot_work = 1;
793 status = 0;
794 switch (bs->action) {
795 case BEISCSI_BOOT_REOPEN_SESS:
796 status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
797 if (!status)
798 bs->action = BEISCSI_BOOT_GET_SHANDLE;
799 else
800 bs->retry--;
801 break;
802 case BEISCSI_BOOT_GET_SHANDLE:
803 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
804 if (!status) {
805 boot_resp = embedded_payload(wrb);
806 bs->s_handle = boot_resp->boot_session_handle;
807 }
808 if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
809 bs->action = BEISCSI_BOOT_REOPEN_SESS;
810 bs->retry--;
811 } else {
812 bs->action = BEISCSI_BOOT_GET_SINFO;
813 }
814 break;
815 case BEISCSI_BOOT_GET_SINFO:
816 status = __beiscsi_mcc_compl_status(phba, tag, NULL,
817 &bs->nonemb_cmd);
818 if (!status) {
819 sess_resp = bs->nonemb_cmd.va;
820 memcpy(&bs->boot_sess, &sess_resp->session_info,
821 sizeof(struct mgmt_session_info));
822 bs->action = BEISCSI_BOOT_LOGOUT_SESS;
823 } else {
824 __beiscsi_log(phba, KERN_ERR,
825 "BG_%d : get boot session info error : 0x%x\n",
826 status);
827 boot_work = 0;
828 }
829 pci_free_consistent(phba->ctrl.pdev, bs->nonemb_cmd.size,
830 bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
831 bs->nonemb_cmd.va = NULL;
832 break;
833 case BEISCSI_BOOT_LOGOUT_SESS:
834 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
835 if (!status) {
836 logo_resp = embedded_payload(wrb);
837 if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
838 __beiscsi_log(phba, KERN_ERR,
839 "BG_%d : FW boot session logout error : 0x%x\n",
840 logo_resp->session_status);
841 }
842 }
843 /* continue to create boot_kset even if logout failed? */
844 bs->action = BEISCSI_BOOT_CREATE_KSET;
845 break;
846 default:
847 break;
848 }
849
850 /* clear the tag so no other completion matches this tag */
851 bs->tag = 0;
852 if (!bs->retry) {
853 boot_work = 0;
854 __beiscsi_log(phba, KERN_ERR,
855 "BG_%d : failed to setup boot target: status %d action %d\n",
856 status, bs->action);
857 }
858 if (!boot_work) {
859 /* wait for next event to start boot_work */
860 clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
861 return;
862 }
863 schedule_work(&phba->boot_work);
864}
865
John Soni Jose9aef4202012-08-20 23:00:08 +0530866/**
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530867 * beiscsi_boot_logout_sess()- Logout from boot FW session
868 * @phba: Device priv structure instance
869 *
870 * return
871 * the TAG used for MBOX Command
872 *
873 */
874unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
875{
876 struct be_ctrl_info *ctrl = &phba->ctrl;
877 struct be_mcc_wrb *wrb;
878 struct be_cmd_req_logout_fw_sess *req;
879 unsigned int tag;
880
881 mutex_lock(&ctrl->mbox_lock);
882 wrb = alloc_mcc_wrb(phba, &tag);
883 if (!wrb) {
884 mutex_unlock(&ctrl->mbox_lock);
885 return 0;
886 }
887
888 req = embedded_payload(wrb);
889 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
890 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
891 OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
892 sizeof(struct be_cmd_req_logout_fw_sess));
893 /* Use the session handle copied into boot_sess */
894 req->session_handle = phba->boot_struct.boot_sess.session_handle;
895
896 phba->boot_struct.tag = tag;
897 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
898 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
899
900 be_mcc_notify(phba, tag);
901 mutex_unlock(&ctrl->mbox_lock);
902
903 return tag;
904}
905/**
906 * beiscsi_boot_reopen_sess()- Reopen boot session
907 * @phba: Device priv structure instance
908 *
909 * return
910 * the TAG used for MBOX Command
911 *
912 **/
913unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
914{
915 struct be_ctrl_info *ctrl = &phba->ctrl;
916 struct be_mcc_wrb *wrb;
917 struct be_cmd_reopen_session_req *req;
918 unsigned int tag;
919
920 mutex_lock(&ctrl->mbox_lock);
921 wrb = alloc_mcc_wrb(phba, &tag);
922 if (!wrb) {
923 mutex_unlock(&ctrl->mbox_lock);
924 return 0;
925 }
926
927 req = embedded_payload(wrb);
928 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
929 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
930 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
931 sizeof(struct be_cmd_reopen_session_resp));
932 req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
933 req->session_handle = BE_BOOT_INVALID_SHANDLE;
934
935 phba->boot_struct.tag = tag;
936 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
937 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
938
939 be_mcc_notify(phba, tag);
940 mutex_unlock(&ctrl->mbox_lock);
941 return tag;
942}
943
944
945/**
946 * beiscsi_boot_get_sinfo()- Get boot session info
947 * @phba: device priv structure instance
948 *
949 * Fetches the boot_struct.s_handle info from FW.
950 * return
951 * the TAG used for MBOX Command
952 *
953 **/
954unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
955{
956 struct be_ctrl_info *ctrl = &phba->ctrl;
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530957 struct be_cmd_get_session_req *req;
958 struct be_dma_mem *nonemb_cmd;
959 struct be_mcc_wrb *wrb;
960 struct be_sge *sge;
961 unsigned int tag;
962
963 mutex_lock(&ctrl->mbox_lock);
964 wrb = alloc_mcc_wrb(phba, &tag);
965 if (!wrb) {
966 mutex_unlock(&ctrl->mbox_lock);
967 return 0;
968 }
969
970 nonemb_cmd = &phba->boot_struct.nonemb_cmd;
Jitendra Bhivarefa1261c2016-12-13 15:56:01 +0530971 nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp);
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530972 nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
Dan Carpenter23b98e42016-11-18 14:53:39 +0300973 nonemb_cmd->size,
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530974 &nonemb_cmd->dma);
Jitendra Bhivare658f18d2016-08-26 15:09:08 +0530975 if (!nonemb_cmd->va) {
976 mutex_unlock(&ctrl->mbox_lock);
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530977 return 0;
Jitendra Bhivare658f18d2016-08-26 15:09:08 +0530978 }
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530979
980 req = nonemb_cmd->va;
981 memset(req, 0, sizeof(*req));
982 sge = nonembedded_sgl(wrb);
983 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
984 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
985 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
Jitendra Bhivarefa1261c2016-12-13 15:56:01 +0530986 sizeof(struct be_cmd_get_session_resp));
Jitendra Bhivare50a4b822016-08-19 15:20:12 +0530987 req->session_handle = phba->boot_struct.s_handle;
988 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
989 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
990 sge->len = cpu_to_le32(nonemb_cmd->size);
991
992 phba->boot_struct.tag = tag;
993 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
994 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
995
996 be_mcc_notify(phba, tag);
997 mutex_unlock(&ctrl->mbox_lock);
998 return tag;
999}
1000
1001unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
1002{
1003 struct be_ctrl_info *ctrl = &phba->ctrl;
1004 struct be_mcc_wrb *wrb;
1005 struct be_cmd_get_boot_target_req *req;
1006 unsigned int tag;
1007
1008 mutex_lock(&ctrl->mbox_lock);
1009 wrb = alloc_mcc_wrb(phba, &tag);
1010 if (!wrb) {
1011 mutex_unlock(&ctrl->mbox_lock);
1012 return 0;
1013 }
1014
1015 req = embedded_payload(wrb);
1016 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1017 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1018 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
1019 sizeof(struct be_cmd_get_boot_target_resp));
1020
1021 if (async) {
1022 phba->boot_struct.tag = tag;
1023 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1024 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1025 }
1026
1027 be_mcc_notify(phba, tag);
1028 mutex_unlock(&ctrl->mbox_lock);
1029 return tag;
1030}
1031
1032/**
1033 * beiscsi_boot_get_shandle()- Get boot session handle
John Soni Jose9aef4202012-08-20 23:00:08 +05301034 * @phba: device priv structure instance
1035 * @s_handle: session handle returned for boot session.
1036 *
John Soni Jose9aef4202012-08-20 23:00:08 +05301037 * return
Jitendra Bhivare50a4b822016-08-19 15:20:12 +05301038 * Success: 1
1039 * Failure: negative
John Soni Jose9aef4202012-08-20 23:00:08 +05301040 *
1041 **/
Jitendra Bhivare50a4b822016-08-19 15:20:12 +05301042int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
John Soni Jose9aef4202012-08-20 23:00:08 +05301043{
1044 struct be_cmd_get_boot_target_resp *boot_resp;
1045 struct be_mcc_wrb *wrb;
John Soni Josee175def2012-10-20 04:45:40 +05301046 unsigned int tag;
John Soni Josee175def2012-10-20 04:45:40 +05301047 int rc;
John Soni Jose9aef4202012-08-20 23:00:08 +05301048
Jitendra Bhivare50a4b822016-08-19 15:20:12 +05301049 *s_handle = BE_BOOT_INVALID_SHANDLE;
1050 /* get configured boot session count and handle */
1051 tag = __beiscsi_boot_get_shandle(phba, 0);
1052 if (!tag) {
1053 beiscsi_log(phba, KERN_ERR,
1054 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1055 "BG_%d : Getting Boot Target Info Failed\n");
1056 return -EAGAIN;
1057 }
John Soni Jose9aef4202012-08-20 23:00:08 +05301058
Jitendra Bhivare50a4b822016-08-19 15:20:12 +05301059 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1060 if (rc) {
1061 beiscsi_log(phba, KERN_ERR,
1062 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1063 "BG_%d : MBX CMD get_boot_target Failed\n");
1064 return -EBUSY;
1065 }
John Soni Josee175def2012-10-20 04:45:40 +05301066
Jitendra Bhivare50a4b822016-08-19 15:20:12 +05301067 boot_resp = embedded_payload(wrb);
1068 /* check if there are any boot targets configured */
1069 if (!boot_resp->boot_session_count) {
1070 __beiscsi_log(phba, KERN_INFO,
1071 "BG_%d : No boot targets configured\n");
1072 return -ENXIO;
1073 }
John Soni Jose9aef4202012-08-20 23:00:08 +05301074
Jitendra Bhivare50a4b822016-08-19 15:20:12 +05301075 /* only if FW has logged in to the boot target, s_handle is valid */
1076 *s_handle = boot_resp->boot_session_handle;
1077 return 1;
John Soni Jose9aef4202012-08-20 23:00:08 +05301078}
John Soni Jose6f722382012-08-20 23:00:43 +05301079
1080/**
John Soni Jose5cac7592012-10-20 04:42:25 +05301081 * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1082 * @dev: ptr to device not used.
1083 * @attr: device attribute, not used.
1084 * @buf: contains formatted text driver name and version
1085 *
1086 * return
1087 * size of the formatted string
1088 **/
1089ssize_t
1090beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1091 char *buf)
1092{
1093 return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1094}
John Soni Joseacb96932012-10-20 04:44:35 +05301095
John Soni Jose26000db2012-10-20 04:45:06 +05301096/**
Jayamohan Kallickal22661e22013-04-05 20:38:28 -07001097 * beiscsi_fw_ver_disp()- Display Firmware Version
1098 * @dev: ptr to device not used.
1099 * @attr: device attribute, not used.
1100 * @buf: contains formatted text Firmware version
1101 *
1102 * return
1103 * size of the formatted string
1104 **/
1105ssize_t
1106beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1107 char *buf)
1108{
1109 struct Scsi_Host *shost = class_to_shost(dev);
1110 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1111
1112 return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1113}
1114
1115/**
Jayamohan Kallickal6103c1f2013-09-28 15:35:52 -07001116 * beiscsi_active_session_disp()- Display Sessions Active
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001117 * @dev: ptr to device not used.
1118 * @attr: device attribute, not used.
1119 * @buf: contains formatted text Session Count
1120 *
1121 * return
1122 * size of the formatted string
1123 **/
1124ssize_t
Jayamohan Kallickal6103c1f2013-09-28 15:35:52 -07001125beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001126 char *buf)
1127{
1128 struct Scsi_Host *shost = class_to_shost(dev);
1129 struct beiscsi_hba *phba = iscsi_host_priv(shost);
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -07001130 uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001131
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -07001132 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1133 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1134 avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1135 total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1136 len += snprintf(buf+len, PAGE_SIZE - len,
1137 "ULP%d : %d\n", ulp_num,
1138 (total_cids - avlbl_cids));
1139 } else
1140 len += snprintf(buf+len, PAGE_SIZE - len,
1141 "ULP%d : %d\n", ulp_num, 0);
1142 }
1143
1144 return len;
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001145}
1146
1147/**
Jayamohan Kallickal6103c1f2013-09-28 15:35:52 -07001148 * beiscsi_free_session_disp()- Display Avaliable Session
1149 * @dev: ptr to device not used.
1150 * @attr: device attribute, not used.
1151 * @buf: contains formatted text Session Count
1152 *
1153 * return
1154 * size of the formatted string
1155 **/
1156ssize_t
1157beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1158 char *buf)
1159{
1160 struct Scsi_Host *shost = class_to_shost(dev);
1161 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1162 uint16_t ulp_num, len = 0;
1163
1164 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1165 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1166 len += snprintf(buf+len, PAGE_SIZE - len,
1167 "ULP%d : %d\n", ulp_num,
1168 BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1169 else
1170 len += snprintf(buf+len, PAGE_SIZE - len,
1171 "ULP%d : %d\n", ulp_num, 0);
1172 }
1173
1174 return len;
1175}
1176
1177/**
John Soni Jose26000db2012-10-20 04:45:06 +05301178 * beiscsi_adap_family_disp()- Display adapter family.
1179 * @dev: ptr to device to get priv structure
1180 * @attr: device attribute, not used.
1181 * @buf: contains formatted text driver name and version
1182 *
1183 * return
1184 * size of the formatted string
1185 **/
1186ssize_t
1187beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1188 char *buf)
1189{
1190 uint16_t dev_id = 0;
1191 struct Scsi_Host *shost = class_to_shost(dev);
1192 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1193
1194 dev_id = phba->pcidev->device;
1195 switch (dev_id) {
1196 case BE_DEVICE_ID1:
1197 case OC_DEVICE_ID1:
1198 case OC_DEVICE_ID2:
Ketan Mukadam5fa7db22016-12-13 15:56:05 +05301199 return snprintf(buf, PAGE_SIZE,
1200 "Obsolete/Unsupported BE2 Adapter Family\n");
John Soni Jose26000db2012-10-20 04:45:06 +05301201 break;
1202 case BE_DEVICE_ID2:
1203 case OC_DEVICE_ID3:
1204 return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1205 break;
1206 case OC_SKH_ID1:
1207 return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1208 break;
1209 default:
1210 return snprintf(buf, PAGE_SIZE,
Masanari Iidab23f7a02013-04-18 00:12:55 +09001211 "Unknown Adapter Family: 0x%x\n", dev_id);
John Soni Jose26000db2012-10-20 04:45:06 +05301212 break;
1213 }
1214}
1215
Jayamohan Kallickald3fea9a2013-09-28 15:35:53 -07001216/**
1217 * beiscsi_phys_port()- Display Physical Port Identifier
1218 * @dev: ptr to device not used.
1219 * @attr: device attribute, not used.
1220 * @buf: contains formatted text port identifier
1221 *
1222 * return
1223 * size of the formatted string
1224 **/
1225ssize_t
1226beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1227 char *buf)
1228{
1229 struct Scsi_Host *shost = class_to_shost(dev);
1230 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1231
Jitendra Bhivarefa1261c2016-12-13 15:56:01 +05301232 return snprintf(buf, PAGE_SIZE, "Port Identifier : %u\n",
Jayamohan Kallickald3fea9a2013-09-28 15:35:53 -07001233 phba->fw_config.phys_port);
1234}
John Soni Jose26000db2012-10-20 04:45:06 +05301235
John Soni Joseacb96932012-10-20 04:44:35 +05301236void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1237 struct wrb_handle *pwrb_handle,
John Soni Jose340c99e2015-08-20 04:44:30 +05301238 struct be_mem_descriptor *mem_descr,
1239 struct hwi_wrb_context *pwrb_context)
John Soni Joseacb96932012-10-20 04:44:35 +05301240{
1241 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1242
John Soni Joseacb96932012-10-20 04:44:35 +05301243 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1244 max_send_data_segment_length, pwrb,
1245 params->dw[offsetof(struct amap_beiscsi_offload_params,
1246 max_send_data_segment_length) / 32]);
1247 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1248 BE_TGT_CTX_UPDT_CMD);
1249 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1250 first_burst_length,
1251 pwrb,
1252 params->dw[offsetof(struct amap_beiscsi_offload_params,
1253 first_burst_length) / 32]);
1254 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1255 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1256 erl) / 32] & OFFLD_PARAMS_ERL));
1257 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1258 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1259 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1260 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1261 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1262 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1263 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1264 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1265 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1266 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1267 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1268 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1269 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1270 pwrb,
1271 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1272 exp_statsn) / 32] + 1));
1273 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1274 pwrb, pwrb_handle->wrb_index);
1275
1276 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1277 max_burst_length, pwrb, params->dw[offsetof
1278 (struct amap_beiscsi_offload_params,
1279 max_burst_length) / 32]);
1280
1281 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
John Soni Jose340c99e2015-08-20 04:44:30 +05301282 pwrb, pwrb_handle->wrb_index);
1283 if (pwrb_context->plast_wrb)
1284 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1285 ptr2nextwrb,
1286 pwrb_context->plast_wrb,
1287 pwrb_handle->wrb_index);
1288 pwrb_context->plast_wrb = pwrb;
1289
John Soni Joseacb96932012-10-20 04:44:35 +05301290 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1291 session_state, pwrb, 0);
1292 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1293 pwrb, 1);
1294 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1295 pwrb, 0);
1296 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1297 0);
1298
1299 mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1300 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1301 pad_buffer_addr_hi, pwrb,
1302 mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1303 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1304 pad_buffer_addr_lo, pwrb,
1305 mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1306}
1307
1308void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
John Soni Jose340c99e2015-08-20 04:44:30 +05301309 struct wrb_handle *pwrb_handle,
1310 struct hwi_wrb_context *pwrb_context)
John Soni Joseacb96932012-10-20 04:44:35 +05301311{
1312 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1313
John Soni Joseacb96932012-10-20 04:44:35 +05301314 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1315 max_burst_length, pwrb, params->dw[offsetof
1316 (struct amap_beiscsi_offload_params,
1317 max_burst_length) / 32]);
1318 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1319 type, pwrb,
1320 BE_TGT_CTX_UPDT_CMD);
1321 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1322 ptr2nextwrb,
John Soni Jose340c99e2015-08-20 04:44:30 +05301323 pwrb, pwrb_handle->wrb_index);
1324 if (pwrb_context->plast_wrb)
1325 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1326 ptr2nextwrb,
1327 pwrb_context->plast_wrb,
1328 pwrb_handle->wrb_index);
1329 pwrb_context->plast_wrb = pwrb;
1330
John Soni Joseacb96932012-10-20 04:44:35 +05301331 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1332 pwrb, pwrb_handle->wrb_index);
1333 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1334 max_send_data_segment_length, pwrb,
1335 params->dw[offsetof(struct amap_beiscsi_offload_params,
1336 max_send_data_segment_length) / 32]);
1337 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1338 first_burst_length, pwrb,
1339 params->dw[offsetof(struct amap_beiscsi_offload_params,
1340 first_burst_length) / 32]);
1341 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
Jayamohan Kallickal73316132013-09-28 15:35:41 -07001342 max_recv_dataseg_len, pwrb,
1343 params->dw[offsetof(struct amap_beiscsi_offload_params,
1344 max_recv_data_segment_length) / 32]);
John Soni Joseacb96932012-10-20 04:44:35 +05301345 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1346 max_cxns, pwrb, BEISCSI_MAX_CXNS);
1347 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1348 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1349 erl) / 32] & OFFLD_PARAMS_ERL));
1350 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1351 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1352 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1353 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1354 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1355 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1356 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1357 ir2t, pwrb,
1358 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1359 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1360 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1361 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1362 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1363 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1364 data_seq_inorder,
1365 pwrb,
1366 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1367 data_seq_inorder) / 32] &
1368 OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1369 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1370 pdu_seq_inorder,
1371 pwrb,
1372 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1373 pdu_seq_inorder) / 32] &
1374 OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1375 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1376 pwrb,
1377 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1378 max_r2t) / 32] &
1379 OFFLD_PARAMS_MAX_R2T) >> 8);
1380 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1381 pwrb,
1382 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1383 exp_statsn) / 32] + 1));
1384}
Jitendra Bhivare98713212016-12-13 15:55:55 +05301385
Jitendra Bhivare49fc5152017-03-24 14:11:41 +05301386unsigned int beiscsi_invalidate_cxn(struct beiscsi_hba *phba,
1387 struct beiscsi_endpoint *beiscsi_ep)
1388{
1389 struct be_invalidate_connection_params_in *req;
1390 struct be_ctrl_info *ctrl = &phba->ctrl;
1391 struct be_mcc_wrb *wrb;
1392 unsigned int tag = 0;
1393
1394 mutex_lock(&ctrl->mbox_lock);
1395 wrb = alloc_mcc_wrb(phba, &tag);
1396 if (!wrb) {
1397 mutex_unlock(&ctrl->mbox_lock);
1398 return 0;
1399 }
1400
1401 req = embedded_payload(wrb);
1402 be_wrb_hdr_prepare(wrb, sizeof(union be_invalidate_connection_params),
1403 true, 0);
1404 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1405 OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
1406 sizeof(*req));
1407 req->session_handle = beiscsi_ep->fw_handle;
1408 req->cid = beiscsi_ep->ep_cid;
1409 if (beiscsi_ep->conn)
1410 req->cleanup_type = BE_CLEANUP_TYPE_INVALIDATE;
1411 else
1412 req->cleanup_type = BE_CLEANUP_TYPE_ISSUE_TCP_RST;
1413 /**
1414 * 0 - non-persistent targets
1415 * 1 - save session info on flash
1416 */
1417 req->save_cfg = 0;
1418 be_mcc_notify(phba, tag);
1419 mutex_unlock(&ctrl->mbox_lock);
1420 return tag;
1421}
1422
1423unsigned int beiscsi_upload_cxn(struct beiscsi_hba *phba,
1424 struct beiscsi_endpoint *beiscsi_ep)
1425{
1426 struct be_ctrl_info *ctrl = &phba->ctrl;
1427 struct be_mcc_wrb *wrb;
1428 struct be_tcp_upload_params_in *req;
1429 unsigned int tag;
1430
1431 mutex_lock(&ctrl->mbox_lock);
1432 wrb = alloc_mcc_wrb(phba, &tag);
1433 if (!wrb) {
1434 mutex_unlock(&ctrl->mbox_lock);
1435 return 0;
1436 }
1437
1438 req = embedded_payload(wrb);
1439 be_wrb_hdr_prepare(wrb, sizeof(union be_tcp_upload_params), true, 0);
1440 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
1441 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
1442 req->id = beiscsi_ep->ep_cid;
1443 if (beiscsi_ep->conn)
1444 req->upload_type = BE_UPLOAD_TYPE_GRACEFUL;
1445 else
1446 req->upload_type = BE_UPLOAD_TYPE_ABORT;
1447 be_mcc_notify(phba, tag);
1448 mutex_unlock(&ctrl->mbox_lock);
1449 return tag;
1450}
1451
Jitendra Bhivare98713212016-12-13 15:55:55 +05301452int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba,
1453 struct invldt_cmd_tbl *inv_tbl,
1454 unsigned int nents)
1455{
1456 struct be_ctrl_info *ctrl = &phba->ctrl;
1457 struct invldt_cmds_params_in *req;
1458 struct be_dma_mem nonemb_cmd;
1459 struct be_mcc_wrb *wrb;
1460 unsigned int i, tag;
1461 struct be_sge *sge;
1462 int rc;
1463
1464 if (!nents || nents > BE_INVLDT_CMD_TBL_SZ)
1465 return -EINVAL;
1466
1467 nonemb_cmd.size = sizeof(union be_invldt_cmds_params);
1468 nonemb_cmd.va = pci_zalloc_consistent(phba->ctrl.pdev,
1469 nonemb_cmd.size,
1470 &nonemb_cmd.dma);
1471 if (!nonemb_cmd.va) {
1472 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
1473 "BM_%d : invldt_cmds_params alloc failed\n");
1474 return -ENOMEM;
1475 }
1476
1477 mutex_lock(&ctrl->mbox_lock);
1478 wrb = alloc_mcc_wrb(phba, &tag);
1479 if (!wrb) {
1480 mutex_unlock(&ctrl->mbox_lock);
1481 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1482 nonemb_cmd.va, nonemb_cmd.dma);
1483 return -ENOMEM;
1484 }
1485
1486 req = nonemb_cmd.va;
1487 be_wrb_hdr_prepare(wrb, nonemb_cmd.size, false, 1);
1488 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1489 OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
1490 sizeof(*req));
1491 req->ref_handle = 0;
1492 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
1493 for (i = 0; i < nents; i++) {
1494 req->table[i].icd = inv_tbl[i].icd;
1495 req->table[i].cid = inv_tbl[i].cid;
1496 req->icd_count++;
1497 }
1498 sge = nonembedded_sgl(wrb);
1499 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
1500 sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd.dma));
1501 sge->len = cpu_to_le32(nonemb_cmd.size);
1502
1503 be_mcc_notify(phba, tag);
1504 mutex_unlock(&ctrl->mbox_lock);
1505
1506 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
1507 if (rc != -EBUSY)
1508 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1509 nonemb_cmd.va, nonemb_cmd.dma);
1510 return rc;
1511}