xref: /openbmc/linux/drivers/scsi/be2iscsi/be_mgmt.c (revision f7d84fa7)
1 /*
2  * Copyright 2017 Broadcom. All Rights Reserved.
3  * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License version 2
7  * as published by the Free Software Foundation. The full GNU General
8  * Public License is included in this distribution in the file called COPYING.
9  *
10  * Contact Information:
11  * linux-drivers@broadcom.com
12  *
13  */
14 
15 #include <linux/bsg-lib.h>
16 #include <scsi/scsi_transport_iscsi.h>
17 #include <scsi/scsi_bsg_iscsi.h>
18 #include "be_mgmt.h"
19 #include "be_iscsi.h"
20 #include "be_main.h"
21 
22 int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
23 			    struct be_set_eqd *set_eqd,
24 			    int num)
25 {
26 	struct be_ctrl_info *ctrl = &phba->ctrl;
27 	struct be_mcc_wrb *wrb;
28 	struct be_cmd_req_modify_eq_delay *req;
29 	unsigned int tag;
30 	int i;
31 
32 	mutex_lock(&ctrl->mbox_lock);
33 	wrb = alloc_mcc_wrb(phba, &tag);
34 	if (!wrb) {
35 		mutex_unlock(&ctrl->mbox_lock);
36 		return 0;
37 	}
38 
39 	req = embedded_payload(wrb);
40 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
41 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
42 			   OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
43 
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 
52 	/* ignore the completion of this mbox command */
53 	set_bit(MCC_TAG_STATE_IGNORE, &ctrl->ptag_state[tag].tag_state);
54 	be_mcc_notify(phba, tag);
55 	mutex_unlock(&ctrl->mbox_lock);
56 	return tag;
57 }
58 
59 unsigned 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 {
64 	struct be_mcc_wrb *wrb;
65 	struct be_sge *mcc_sge;
66 	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);
73 	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;
80 
81 	if (mutex_lock_interruptible(&ctrl->mbox_lock))
82 		return 0;
83 	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:
97 		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 
101 		mutex_unlock(&ctrl->mbox_lock);
102 		return -EPERM;
103 	}
104 
105 	wrb = alloc_mcc_wrb(phba, &tag);
106 	if (!wrb) {
107 		mutex_unlock(&ctrl->mbox_lock);
108 		return 0;
109 	}
110 
111 	mcc_sge = nonembedded_sgl(wrb);
112 	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);
117 
118 	be_mcc_notify(phba, tag);
119 
120 	mutex_unlock(&ctrl->mbox_lock);
121 	return tag;
122 }
123 
124 /**
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  **/
134 int mgmt_open_connection(struct beiscsi_hba *phba,
135 			 struct sockaddr *dst_addr,
136 			 struct beiscsi_endpoint *beiscsi_ep,
137 			 struct be_dma_mem *nonemb_cmd)
138 {
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;
144 	struct be_mcc_wrb *wrb;
145 	struct tcp_connect_and_offload_in_v1 *req;
146 	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;
150 	unsigned int tag = 0;
151 	unsigned int i, ulp_num;
152 	unsigned short cid = beiscsi_ep->ep_cid;
153 	struct be_sge *sge;
154 
155 	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 
162 	phwi_ctrlr = phba->phwi_ctrlr;
163 	phwi_context = phwi_ctrlr->phwi_ctxt;
164 
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);
169 
170 	ptemplate_address = &template_address;
171 	ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
172 	if (mutex_lock_interruptible(&ctrl->mbox_lock))
173 		return 0;
174 	wrb = alloc_mcc_wrb(phba, &tag);
175 	if (!wrb) {
176 		mutex_unlock(&ctrl->mbox_lock);
177 		return 0;
178 	}
179 
180 	sge = nonembedded_sgl(wrb);
181 	req = nonemb_cmd->va;
182 	memset(req, 0, sizeof(*req));
183 
184 	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
185 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
186 			   OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
187 			   nonemb_cmd->size);
188 	if (dst_addr->sa_family == PF_INET) {
189 		__be32 s_addr = daddr_in->sin_addr.s_addr;
190 		req->ip_address.ip_type = BEISCSI_IP_TYPE_V4;
191 		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;
195 		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);
198 		beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4;
199 	} else {
200 		/* else its PF_INET6 family */
201 		req->ip_address.ip_type = BEISCSI_IP_TYPE_V6;
202 		memcpy(&req->ip_address.addr,
203 		       &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);
208 		beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6;
209 	}
210 	req->cid = cid;
211 	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;
215 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
216 		    "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
217 	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;
223 	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);
226 
227 	if (!is_chip_be2_be3r(phba)) {
228 		req->hdr.version = MBX_CMD_VER1;
229 		req->tcp_window_size = 0x8000;
230 		req->tcp_window_scale_count = 2;
231 	}
232 
233 	be_mcc_notify(phba, tag);
234 	mutex_unlock(&ctrl->mbox_lock);
235 	return tag;
236 }
237 
238 /*
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  **/
246 static 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;
251 	struct be_mcc_wrb *wrb;
252 	struct be_sge *sge;
253 	unsigned int tag;
254 	int rc = 0;
255 
256 	mutex_lock(&ctrl->mbox_lock);
257 	wrb = alloc_mcc_wrb(phba, &tag);
258 	if (!wrb) {
259 		mutex_unlock(&ctrl->mbox_lock);
260 		rc = -ENOMEM;
261 		goto free_cmd;
262 	}
263 
264 	sge = nonembedded_sgl(wrb);
265 	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
266 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
267 	sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
268 	sge->len = cpu_to_le32(nonemb_cmd->size);
269 
270 	be_mcc_notify(phba, tag);
271 	mutex_unlock(&ctrl->mbox_lock);
272 
273 	rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd);
274 
275 	if (resp_buf)
276 		memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
277 
278 	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 	}
292 free_cmd:
293 	pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
294 			    nonemb_cmd->va, nonemb_cmd->dma);
295 	return rc;
296 }
297 
298 static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
299 			       int iscsi_cmd, int size)
300 {
301 	cmd->va = pci_zalloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
302 	if (!cmd->va) {
303 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
304 			    "BG_%d : Failed to allocate memory for if info\n");
305 		return -ENOMEM;
306 	}
307 	cmd->size = size;
308 	be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
309 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
310 		    "BG_%d : subsystem iSCSI cmd %d size %d\n",
311 		    iscsi_cmd, size);
312 	return 0;
313 }
314 
315 unsigned 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 
354 static 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 
364 static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
365 			     u32 action, u32 ip_type, u8 *gw)
366 {
367 	struct be_cmd_set_def_gateway_req *req;
368 	struct be_dma_mem nonemb_cmd;
369 	int rt_val;
370 
371 	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;
378 	req->action = action;
379 	req->ip_addr.ip_type = ip_type;
380 	memcpy(req->ip_addr.addr, gw,
381 	       (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
382 	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
383 }
384 
385 int 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 
398 	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 		}
406 	}
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 
416 int 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 
436 static int
437 beiscsi_if_clr_ip(struct beiscsi_hba *phba,
438 		  struct be_cmd_get_if_info_resp *if_info)
439 {
440 	struct be_cmd_set_ip_addr_req *req;
441 	struct be_dma_mem nonemb_cmd;
442 	int rc;
443 
444 	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
445 				 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
446 				 sizeof(*req));
447 	if (rc)
448 		return rc;
449 
450 	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 
473 static int
474 beiscsi_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;
496 	ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
497 	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 
517 int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
518 			 u8 *ip, u8 *subnet)
519 {
520 	struct be_cmd_get_if_info_resp *if_info;
521 	struct be_cmd_rel_dhcp_req *reldhcp;
522 	struct be_dma_mem nonemb_cmd;
523 	int rc;
524 
525 	rc = beiscsi_if_get_info(phba, ip_type, &if_info);
526 	if (rc)
527 		return rc;
528 
529 	if (if_info->dhcp_state) {
530 		rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
531 				OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
532 				sizeof(*reldhcp));
533 		if (rc)
534 			goto exit;
535 
536 		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) {
541 			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
542 				    "BG_%d : failed to release existing DHCP: %d\n",
543 				    rc);
544 			goto exit;
545 		}
546 	}
547 
548 	/* 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 	}
554 
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);
558 exit:
559 	kfree(if_info);
560 	return rc;
561 }
562 
563 int 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 
572 	rc = beiscsi_if_get_info(phba, ip_type, &if_info);
573 	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 
582 	/* first delete any IP set */
583 	if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
584 		rc = beiscsi_if_clr_ip(phba, if_info);
585 		if (rc)
586 			goto exit;
587 	}
588 
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;
599 	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 		}
607 	}
608 
609 	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
610 			OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
611 			sizeof(*dhcpreq));
612 	if (rc)
613 		goto exit;
614 
615 	dhcpreq = nonemb_cmd.va;
616 	dhcpreq->flags = 1; /* 1 - blocking; 0 - non-blocking */
617 	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);
621 
622 exit:
623 	kfree(if_info);
624 	return rc;
625 }
626 
627 /**
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  **/
639 int 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 
663 int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
664 			struct be_cmd_get_if_info_resp **if_info)
665 {
666 	struct be_cmd_get_if_info_req *req;
667 	struct be_dma_mem nonemb_cmd;
668 	uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
669 	int rc;
670 
671 	rc = beiscsi_if_get_handle(phba);
672 	if (rc)
673 		return rc;
674 
675 	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;
681 
682 		req = nonemb_cmd.va;
683 		req->interface_hndl = phba->interface_handle;
684 		req->ip_type = ip_type;
685 
686 		/* 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;
723 }
724 
725 int 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 
742 unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
743 {
744 	unsigned int tag;
745 	struct be_mcc_wrb *wrb;
746 	struct be_cmd_hba_name *req;
747 	struct be_ctrl_info *ctrl = &phba->ctrl;
748 
749 	if (mutex_lock_interruptible(&ctrl->mbox_lock))
750 		return 0;
751 	wrb = alloc_mcc_wrb(phba, &tag);
752 	if (!wrb) {
753 		mutex_unlock(&ctrl->mbox_lock);
754 		return 0;
755 	}
756 
757 	req = embedded_payload(wrb);
758 	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 
763 	be_mcc_notify(phba, tag);
764 	mutex_unlock(&ctrl->mbox_lock);
765 	return tag;
766 }
767 
768 static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
769 				       unsigned int tag)
770 {
771 	struct be_cmd_get_boot_target_resp *boot_resp;
772 	struct be_cmd_resp_logout_fw_sess *logo_resp;
773 	struct be_cmd_get_session_resp *sess_resp;
774 	struct be_mcc_wrb *wrb;
775 	struct boot_struct *bs;
776 	int boot_work, status;
777 
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 
866 /**
867  * 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  */
874 unsigned 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  **/
913 unsigned 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  **/
954 unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
955 {
956 	struct be_ctrl_info *ctrl = &phba->ctrl;
957 	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;
971 	nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp);
972 	nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
973 					      nonemb_cmd->size,
974 					      &nonemb_cmd->dma);
975 	if (!nonemb_cmd->va) {
976 		mutex_unlock(&ctrl->mbox_lock);
977 		return 0;
978 	}
979 
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,
986 			   sizeof(struct be_cmd_get_session_resp));
987 	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 
1001 unsigned 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
1034  * @phba: device priv structure instance
1035  * @s_handle: session handle returned for boot session.
1036  *
1037  * return
1038  *	Success: 1
1039  *	Failure: negative
1040  *
1041  **/
1042 int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
1043 {
1044 	struct be_cmd_get_boot_target_resp *boot_resp;
1045 	struct be_mcc_wrb *wrb;
1046 	unsigned int tag;
1047 	int rc;
1048 
1049 	*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 	}
1058 
1059 	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 	}
1066 
1067 	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 	}
1074 
1075 	/* 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;
1078 }
1079 
1080 /**
1081  * 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  **/
1089 ssize_t
1090 beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1091 		       char *buf)
1092 {
1093 	return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1094 }
1095 
1096 /**
1097  * 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  **/
1105 ssize_t
1106 beiscsi_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 /**
1116  * beiscsi_active_session_disp()- Display Sessions Active
1117  * @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  **/
1124 ssize_t
1125 beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1126 			 char *buf)
1127 {
1128 	struct Scsi_Host *shost = class_to_shost(dev);
1129 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1130 	uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1131 
1132 	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;
1145 }
1146 
1147 /**
1148  * 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  **/
1156 ssize_t
1157 beiscsi_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 /**
1178  * 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  **/
1186 ssize_t
1187 beiscsi_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:
1199 		return snprintf(buf, PAGE_SIZE,
1200 				"Obsolete/Unsupported BE2 Adapter Family\n");
1201 		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,
1211 				"Unknown Adapter Family: 0x%x\n", dev_id);
1212 		break;
1213 	}
1214 }
1215 
1216 /**
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  **/
1225 ssize_t
1226 beiscsi_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 
1232 	return snprintf(buf, PAGE_SIZE, "Port Identifier : %u\n",
1233 			phba->fw_config.phys_port);
1234 }
1235 
1236 void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1237 			     struct wrb_handle *pwrb_handle,
1238 			     struct be_mem_descriptor *mem_descr,
1239 			     struct hwi_wrb_context *pwrb_context)
1240 {
1241 	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1242 
1243 	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,
1282 		      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 
1290 	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 
1308 void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1309 			     struct wrb_handle *pwrb_handle,
1310 			     struct hwi_wrb_context *pwrb_context)
1311 {
1312 	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1313 
1314 	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,
1323 		      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 
1331 	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,
1342 		      max_recv_dataseg_len, pwrb,
1343 		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1344 		      max_recv_data_segment_length) / 32]);
1345 	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 }
1385 
1386 unsigned 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 
1423 unsigned 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 
1452 int 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 }
1512