xref: /openbmc/linux/drivers/scsi/be2iscsi/be_mgmt.c (revision 861e10be)
1 /**
2  * Copyright (C) 2005 - 2012 Emulex
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License version 2
7  * as published by the Free Software Foundation.  The full GNU General
8  * Public License is included in this distribution in the file called COPYING.
9  *
10  * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
11  *
12  * Contact Information:
13  * linux-drivers@emulex.com
14  *
15  * Emulex
16  * 3333 Susan Street
17  * Costa Mesa, CA 92626
18  */
19 
20 #include <linux/bsg-lib.h>
21 #include <scsi/scsi_transport_iscsi.h>
22 #include <scsi/scsi_bsg_iscsi.h>
23 #include "be_mgmt.h"
24 #include "be_iscsi.h"
25 #include "be_main.h"
26 
27 /* UE Status Low CSR */
28 static const char * const desc_ue_status_low[] = {
29 	"CEV",
30 	"CTX",
31 	"DBUF",
32 	"ERX",
33 	"Host",
34 	"MPU",
35 	"NDMA",
36 	"PTC ",
37 	"RDMA ",
38 	"RXF ",
39 	"RXIPS ",
40 	"RXULP0 ",
41 	"RXULP1 ",
42 	"RXULP2 ",
43 	"TIM ",
44 	"TPOST ",
45 	"TPRE ",
46 	"TXIPS ",
47 	"TXULP0 ",
48 	"TXULP1 ",
49 	"UC ",
50 	"WDMA ",
51 	"TXULP2 ",
52 	"HOST1 ",
53 	"P0_OB_LINK ",
54 	"P1_OB_LINK ",
55 	"HOST_GPIO ",
56 	"MBOX ",
57 	"AXGMAC0",
58 	"AXGMAC1",
59 	"JTAG",
60 	"MPU_INTPEND"
61 };
62 
63 /* UE Status High CSR */
64 static const char * const desc_ue_status_hi[] = {
65 	"LPCMEMHOST",
66 	"MGMT_MAC",
67 	"PCS0ONLINE",
68 	"MPU_IRAM",
69 	"PCS1ONLINE",
70 	"PCTL0",
71 	"PCTL1",
72 	"PMEM",
73 	"RR",
74 	"TXPB",
75 	"RXPP",
76 	"XAUI",
77 	"TXP",
78 	"ARM",
79 	"IPC",
80 	"HOST2",
81 	"HOST3",
82 	"HOST4",
83 	"HOST5",
84 	"HOST6",
85 	"HOST7",
86 	"HOST8",
87 	"HOST9",
88 	"NETC",
89 	"Unknown",
90 	"Unknown",
91 	"Unknown",
92 	"Unknown",
93 	"Unknown",
94 	"Unknown",
95 	"Unknown",
96 	"Unknown"
97 };
98 
99 /*
100  * beiscsi_ue_detec()- Detect Unrecoverable Error on adapter
101  * @phba: Driver priv structure
102  *
103  * Read registers linked to UE and check for the UE status
104  **/
105 void beiscsi_ue_detect(struct beiscsi_hba *phba)
106 {
107 	uint32_t ue_hi = 0, ue_lo = 0;
108 	uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
109 	uint8_t i = 0;
110 
111 	if (phba->ue_detected)
112 		return;
113 
114 	pci_read_config_dword(phba->pcidev,
115 			      PCICFG_UE_STATUS_LOW, &ue_lo);
116 	pci_read_config_dword(phba->pcidev,
117 			      PCICFG_UE_STATUS_MASK_LOW,
118 			      &ue_mask_lo);
119 	pci_read_config_dword(phba->pcidev,
120 			      PCICFG_UE_STATUS_HIGH,
121 			      &ue_hi);
122 	pci_read_config_dword(phba->pcidev,
123 			      PCICFG_UE_STATUS_MASK_HI,
124 			      &ue_mask_hi);
125 
126 	ue_lo = (ue_lo & ~ue_mask_lo);
127 	ue_hi = (ue_hi & ~ue_mask_hi);
128 
129 
130 	if (ue_lo || ue_hi) {
131 		phba->ue_detected = true;
132 		beiscsi_log(phba, KERN_ERR,
133 			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
134 			    "BG_%d : Error detected on the adapter\n");
135 	}
136 
137 	if (ue_lo) {
138 		for (i = 0; ue_lo; ue_lo >>= 1, i++) {
139 			if (ue_lo & 1)
140 				beiscsi_log(phba, KERN_ERR,
141 					    BEISCSI_LOG_CONFIG,
142 					    "BG_%d : UE_LOW %s bit set\n",
143 					    desc_ue_status_low[i]);
144 		}
145 	}
146 
147 	if (ue_hi) {
148 		for (i = 0; ue_hi; ue_hi >>= 1, i++) {
149 			if (ue_hi & 1)
150 				beiscsi_log(phba, KERN_ERR,
151 					    BEISCSI_LOG_CONFIG,
152 					    "BG_%d : UE_HIGH %s bit set\n",
153 					    desc_ue_status_hi[i]);
154 		}
155 	}
156 }
157 
158 /**
159  * mgmt_reopen_session()- Reopen a session based on reopen_type
160  * @phba: Device priv structure instance
161  * @reopen_type: Type of reopen_session FW should do.
162  * @sess_handle: Session Handle of the session to be re-opened
163  *
164  * return
165  *	the TAG used for MBOX Command
166  *
167  **/
168 unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
169 				  unsigned int reopen_type,
170 				  unsigned int sess_handle)
171 {
172 	struct be_ctrl_info *ctrl = &phba->ctrl;
173 	struct be_mcc_wrb *wrb;
174 	struct be_cmd_reopen_session_req *req;
175 	unsigned int tag = 0;
176 
177 	beiscsi_log(phba, KERN_INFO,
178 		    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
179 		    "BG_%d : In bescsi_get_boot_target\n");
180 
181 	spin_lock(&ctrl->mbox_lock);
182 	tag = alloc_mcc_tag(phba);
183 	if (!tag) {
184 		spin_unlock(&ctrl->mbox_lock);
185 		return tag;
186 	}
187 
188 	wrb = wrb_from_mccq(phba);
189 	req = embedded_payload(wrb);
190 	wrb->tag0 |= tag;
191 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
192 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
193 			   OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
194 			   sizeof(struct be_cmd_reopen_session_resp));
195 
196 	/* set the reopen_type,sess_handle */
197 	req->reopen_type = reopen_type;
198 	req->session_handle = sess_handle;
199 
200 	be_mcc_notify(phba);
201 	spin_unlock(&ctrl->mbox_lock);
202 	return tag;
203 }
204 
205 unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
206 {
207 	struct be_ctrl_info *ctrl = &phba->ctrl;
208 	struct be_mcc_wrb *wrb;
209 	struct be_cmd_get_boot_target_req *req;
210 	unsigned int tag = 0;
211 
212 	beiscsi_log(phba, KERN_INFO,
213 		    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
214 		    "BG_%d : In bescsi_get_boot_target\n");
215 
216 	spin_lock(&ctrl->mbox_lock);
217 	tag = alloc_mcc_tag(phba);
218 	if (!tag) {
219 		spin_unlock(&ctrl->mbox_lock);
220 		return tag;
221 	}
222 
223 	wrb = wrb_from_mccq(phba);
224 	req = embedded_payload(wrb);
225 	wrb->tag0 |= tag;
226 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
227 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
228 			   OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
229 			   sizeof(struct be_cmd_get_boot_target_resp));
230 
231 	be_mcc_notify(phba);
232 	spin_unlock(&ctrl->mbox_lock);
233 	return tag;
234 }
235 
236 unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
237 				   u32 boot_session_handle,
238 				   struct be_dma_mem *nonemb_cmd)
239 {
240 	struct be_ctrl_info *ctrl = &phba->ctrl;
241 	struct be_mcc_wrb *wrb;
242 	unsigned int tag = 0;
243 	struct  be_cmd_get_session_req *req;
244 	struct be_cmd_get_session_resp *resp;
245 	struct be_sge *sge;
246 
247 	beiscsi_log(phba, KERN_INFO,
248 		    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
249 		    "BG_%d : In beiscsi_get_session_info\n");
250 
251 	spin_lock(&ctrl->mbox_lock);
252 	tag = alloc_mcc_tag(phba);
253 	if (!tag) {
254 		spin_unlock(&ctrl->mbox_lock);
255 		return tag;
256 	}
257 
258 	nonemb_cmd->size = sizeof(*resp);
259 	req = nonemb_cmd->va;
260 	memset(req, 0, sizeof(*req));
261 	wrb = wrb_from_mccq(phba);
262 	sge = nonembedded_sgl(wrb);
263 	wrb->tag0 |= tag;
264 
265 
266 	wrb->tag0 |= tag;
267 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
268 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
269 			   OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
270 			   sizeof(*resp));
271 	req->session_handle = boot_session_handle;
272 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
273 	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
274 	sge->len = cpu_to_le32(nonemb_cmd->size);
275 
276 	be_mcc_notify(phba);
277 	spin_unlock(&ctrl->mbox_lock);
278 	return tag;
279 }
280 
281 int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
282 				struct beiscsi_hba *phba)
283 {
284 	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
285 	struct be_fw_cfg *req = embedded_payload(wrb);
286 	int status = 0;
287 
288 	spin_lock(&ctrl->mbox_lock);
289 	memset(wrb, 0, sizeof(*wrb));
290 
291 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
292 
293 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
294 			   OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
295 	status = be_mbox_notify(ctrl);
296 	if (!status) {
297 		struct be_fw_cfg *pfw_cfg;
298 		pfw_cfg = req;
299 		phba->fw_config.phys_port = pfw_cfg->phys_port;
300 		phba->fw_config.iscsi_icd_start =
301 					pfw_cfg->ulp[0].icd_base;
302 		phba->fw_config.iscsi_icd_count =
303 					pfw_cfg->ulp[0].icd_count;
304 		phba->fw_config.iscsi_cid_start =
305 					pfw_cfg->ulp[0].sq_base;
306 		phba->fw_config.iscsi_cid_count =
307 					pfw_cfg->ulp[0].sq_count;
308 		if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) {
309 			beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
310 				    "BG_%d : FW reported MAX CXNS as %d\t"
311 				    "Max Supported = %d.\n",
312 				    phba->fw_config.iscsi_cid_count,
313 				    BE2_MAX_SESSIONS);
314 			phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2;
315 		}
316 	} else {
317 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
318 			    "BG_%d : Failed in mgmt_get_fw_config\n");
319 	}
320 
321 	spin_unlock(&ctrl->mbox_lock);
322 	return status;
323 }
324 
325 int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
326 				      struct beiscsi_hba *phba)
327 {
328 	struct be_dma_mem nonemb_cmd;
329 	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
330 	struct be_mgmt_controller_attributes *req;
331 	struct be_sge *sge = nonembedded_sgl(wrb);
332 	int status = 0;
333 
334 	nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
335 				sizeof(struct be_mgmt_controller_attributes),
336 				&nonemb_cmd.dma);
337 	if (nonemb_cmd.va == NULL) {
338 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
339 			    "BG_%d : Failed to allocate memory for "
340 			    "mgmt_check_supported_fw\n");
341 		return -ENOMEM;
342 	}
343 	nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
344 	req = nonemb_cmd.va;
345 	memset(req, 0, sizeof(*req));
346 	spin_lock(&ctrl->mbox_lock);
347 	memset(wrb, 0, sizeof(*wrb));
348 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
349 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
350 			   OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
351 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
352 	sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
353 	sge->len = cpu_to_le32(nonemb_cmd.size);
354 	status = be_mbox_notify(ctrl);
355 	if (!status) {
356 		struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
357 		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
358 			    "BG_%d : Firmware Version of CMD : %s\n"
359 			    "Firmware Version is : %s\n"
360 			    "Developer Build, not performing version check...\n",
361 			    resp->params.hba_attribs
362 			    .flashrom_version_string,
363 			    resp->params.hba_attribs.
364 			    firmware_version_string);
365 
366 		phba->fw_config.iscsi_features =
367 				resp->params.hba_attribs.iscsi_features;
368 		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
369 			    "BM_%d : phba->fw_config.iscsi_features = %d\n",
370 			    phba->fw_config.iscsi_features);
371 	} else
372 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
373 			    "BG_%d :  Failed in mgmt_check_supported_fw\n");
374 	spin_unlock(&ctrl->mbox_lock);
375 	if (nonemb_cmd.va)
376 		pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
377 				    nonemb_cmd.va, nonemb_cmd.dma);
378 
379 	return status;
380 }
381 
382 unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
383 					 struct beiscsi_hba *phba,
384 					 struct bsg_job *job,
385 					 struct be_dma_mem *nonemb_cmd)
386 {
387 	struct be_cmd_resp_hdr *resp;
388 	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
389 	struct be_sge *mcc_sge = nonembedded_sgl(wrb);
390 	unsigned int tag = 0;
391 	struct iscsi_bsg_request *bsg_req = job->request;
392 	struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
393 	unsigned short region, sector_size, sector, offset;
394 
395 	nonemb_cmd->size = job->request_payload.payload_len;
396 	memset(nonemb_cmd->va, 0, nonemb_cmd->size);
397 	resp = nonemb_cmd->va;
398 	region =  bsg_req->rqst_data.h_vendor.vendor_cmd[1];
399 	sector_size =  bsg_req->rqst_data.h_vendor.vendor_cmd[2];
400 	sector =  bsg_req->rqst_data.h_vendor.vendor_cmd[3];
401 	offset =  bsg_req->rqst_data.h_vendor.vendor_cmd[4];
402 	req->region = region;
403 	req->sector = sector;
404 	req->offset = offset;
405 	spin_lock(&ctrl->mbox_lock);
406 	memset(wrb, 0, sizeof(*wrb));
407 
408 	switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
409 	case BEISCSI_WRITE_FLASH:
410 		offset = sector * sector_size + offset;
411 		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
412 				   OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
413 		sg_copy_to_buffer(job->request_payload.sg_list,
414 				  job->request_payload.sg_cnt,
415 				  nonemb_cmd->va + offset, job->request_len);
416 		break;
417 	case BEISCSI_READ_FLASH:
418 		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
419 			   OPCODE_COMMON_READ_FLASH, sizeof(*req));
420 		break;
421 	default:
422 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
423 			    "BG_%d : Unsupported cmd = 0x%x\n\n",
424 			    bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
425 
426 		spin_unlock(&ctrl->mbox_lock);
427 		return -ENOSYS;
428 	}
429 
430 	tag = alloc_mcc_tag(phba);
431 	if (!tag) {
432 		spin_unlock(&ctrl->mbox_lock);
433 		return tag;
434 	}
435 
436 	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
437 			   job->request_payload.sg_cnt);
438 	mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
439 	mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
440 	mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
441 	wrb->tag0 |= tag;
442 
443 	be_mcc_notify(phba);
444 
445 	spin_unlock(&ctrl->mbox_lock);
446 	return tag;
447 }
448 
449 int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
450 {
451 	struct be_ctrl_info *ctrl = &phba->ctrl;
452 	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
453 	struct iscsi_cleanup_req *req = embedded_payload(wrb);
454 	int status = 0;
455 
456 	spin_lock(&ctrl->mbox_lock);
457 	memset(wrb, 0, sizeof(*wrb));
458 
459 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
460 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
461 			   OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
462 
463 	req->chute = chute;
464 	req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba));
465 	req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba));
466 
467 	status =  be_mcc_notify_wait(phba);
468 	if (status)
469 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
470 			    "BG_%d : mgmt_epfw_cleanup , FAILED\n");
471 	spin_unlock(&ctrl->mbox_lock);
472 	return status;
473 }
474 
475 unsigned int  mgmt_invalidate_icds(struct beiscsi_hba *phba,
476 				struct invalidate_command_table *inv_tbl,
477 				unsigned int num_invalidate, unsigned int cid,
478 				struct be_dma_mem *nonemb_cmd)
479 
480 {
481 	struct be_ctrl_info *ctrl = &phba->ctrl;
482 	struct be_mcc_wrb *wrb;
483 	struct be_sge *sge;
484 	struct invalidate_commands_params_in *req;
485 	unsigned int i, tag = 0;
486 
487 	spin_lock(&ctrl->mbox_lock);
488 	tag = alloc_mcc_tag(phba);
489 	if (!tag) {
490 		spin_unlock(&ctrl->mbox_lock);
491 		return tag;
492 	}
493 
494 	req = nonemb_cmd->va;
495 	memset(req, 0, sizeof(*req));
496 	wrb = wrb_from_mccq(phba);
497 	sge = nonembedded_sgl(wrb);
498 	wrb->tag0 |= tag;
499 
500 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
501 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
502 			OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
503 			sizeof(*req));
504 	req->ref_handle = 0;
505 	req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
506 	for (i = 0; i < num_invalidate; i++) {
507 		req->table[i].icd = inv_tbl->icd;
508 		req->table[i].cid = inv_tbl->cid;
509 		req->icd_count++;
510 		inv_tbl++;
511 	}
512 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
513 	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
514 	sge->len = cpu_to_le32(nonemb_cmd->size);
515 
516 	be_mcc_notify(phba);
517 	spin_unlock(&ctrl->mbox_lock);
518 	return tag;
519 }
520 
521 unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
522 					 struct beiscsi_endpoint *beiscsi_ep,
523 					 unsigned short cid,
524 					 unsigned short issue_reset,
525 					 unsigned short savecfg_flag)
526 {
527 	struct be_ctrl_info *ctrl = &phba->ctrl;
528 	struct be_mcc_wrb *wrb;
529 	struct iscsi_invalidate_connection_params_in *req;
530 	unsigned int tag = 0;
531 
532 	spin_lock(&ctrl->mbox_lock);
533 	tag = alloc_mcc_tag(phba);
534 	if (!tag) {
535 		spin_unlock(&ctrl->mbox_lock);
536 		return tag;
537 	}
538 	wrb = wrb_from_mccq(phba);
539 	wrb->tag0 |= tag;
540 	req = embedded_payload(wrb);
541 
542 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
543 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
544 			   OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
545 			   sizeof(*req));
546 	req->session_handle = beiscsi_ep->fw_handle;
547 	req->cid = cid;
548 	if (issue_reset)
549 		req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST;
550 	else
551 		req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
552 	req->save_cfg = savecfg_flag;
553 	be_mcc_notify(phba);
554 	spin_unlock(&ctrl->mbox_lock);
555 	return tag;
556 }
557 
558 unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
559 				unsigned short cid, unsigned int upload_flag)
560 {
561 	struct be_ctrl_info *ctrl = &phba->ctrl;
562 	struct be_mcc_wrb *wrb;
563 	struct tcp_upload_params_in *req;
564 	unsigned int tag = 0;
565 
566 	spin_lock(&ctrl->mbox_lock);
567 	tag = alloc_mcc_tag(phba);
568 	if (!tag) {
569 		spin_unlock(&ctrl->mbox_lock);
570 		return tag;
571 	}
572 	wrb = wrb_from_mccq(phba);
573 	req = embedded_payload(wrb);
574 	wrb->tag0 |= tag;
575 
576 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
577 	be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
578 			   OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
579 	req->id = (unsigned short)cid;
580 	req->upload_type = (unsigned char)upload_flag;
581 	be_mcc_notify(phba);
582 	spin_unlock(&ctrl->mbox_lock);
583 	return tag;
584 }
585 
586 int mgmt_open_connection(struct beiscsi_hba *phba,
587 			 struct sockaddr *dst_addr,
588 			 struct beiscsi_endpoint *beiscsi_ep,
589 			 struct be_dma_mem *nonemb_cmd)
590 {
591 	struct hwi_controller *phwi_ctrlr;
592 	struct hwi_context_memory *phwi_context;
593 	struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
594 	struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
595 	struct be_ctrl_info *ctrl = &phba->ctrl;
596 	struct be_mcc_wrb *wrb;
597 	struct tcp_connect_and_offload_in *req;
598 	unsigned short def_hdr_id;
599 	unsigned short def_data_id;
600 	struct phys_addr template_address = { 0, 0 };
601 	struct phys_addr *ptemplate_address;
602 	unsigned int tag = 0;
603 	unsigned int i;
604 	unsigned short cid = beiscsi_ep->ep_cid;
605 	struct be_sge *sge;
606 
607 	phwi_ctrlr = phba->phwi_ctrlr;
608 	phwi_context = phwi_ctrlr->phwi_ctxt;
609 	def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba);
610 	def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba);
611 
612 	ptemplate_address = &template_address;
613 	ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
614 	spin_lock(&ctrl->mbox_lock);
615 	tag = alloc_mcc_tag(phba);
616 	if (!tag) {
617 		spin_unlock(&ctrl->mbox_lock);
618 		return tag;
619 	}
620 	wrb = wrb_from_mccq(phba);
621 	memset(wrb, 0, sizeof(*wrb));
622 	sge = nonembedded_sgl(wrb);
623 
624 	req = nonemb_cmd->va;
625 	memset(req, 0, sizeof(*req));
626 	wrb->tag0 |= tag;
627 
628 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
629 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
630 			   OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
631 			   sizeof(*req));
632 	if (dst_addr->sa_family == PF_INET) {
633 		__be32 s_addr = daddr_in->sin_addr.s_addr;
634 		req->ip_address.ip_type = BE2_IPV4;
635 		req->ip_address.addr[0] = s_addr & 0x000000ff;
636 		req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
637 		req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
638 		req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
639 		req->tcp_port = ntohs(daddr_in->sin_port);
640 		beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
641 		beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
642 		beiscsi_ep->ip_type = BE2_IPV4;
643 	} else if (dst_addr->sa_family == PF_INET6) {
644 		req->ip_address.ip_type = BE2_IPV6;
645 		memcpy(&req->ip_address.addr,
646 		       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
647 		req->tcp_port = ntohs(daddr_in6->sin6_port);
648 		beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
649 		memcpy(&beiscsi_ep->dst6_addr,
650 		       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
651 		beiscsi_ep->ip_type = BE2_IPV6;
652 	} else{
653 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
654 			    "BG_%d : unknown addr family %d\n",
655 			    dst_addr->sa_family);
656 		spin_unlock(&ctrl->mbox_lock);
657 		free_mcc_tag(&phba->ctrl, tag);
658 		return -EINVAL;
659 
660 	}
661 	req->cid = cid;
662 	i = phba->nxt_cqid++;
663 	if (phba->nxt_cqid == phba->num_cpus)
664 		phba->nxt_cqid = 0;
665 	req->cq_id = phwi_context->be_cq[i].id;
666 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
667 		    "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
668 	req->defq_id = def_hdr_id;
669 	req->hdr_ring_id = def_hdr_id;
670 	req->data_ring_id = def_data_id;
671 	req->do_offload = 1;
672 	req->dataout_template_pa.lo = ptemplate_address->lo;
673 	req->dataout_template_pa.hi = ptemplate_address->hi;
674 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
675 	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
676 	sge->len = cpu_to_le32(nonemb_cmd->size);
677 	be_mcc_notify(phba);
678 	spin_unlock(&ctrl->mbox_lock);
679 	return tag;
680 }
681 
682 unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
683 {
684 	struct be_ctrl_info *ctrl = &phba->ctrl;
685 	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
686 	struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
687 	struct be_cmd_get_all_if_id_req *pbe_allid = req;
688 	int status = 0;
689 
690 	memset(wrb, 0, sizeof(*wrb));
691 
692 	spin_lock(&ctrl->mbox_lock);
693 
694 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
695 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
696 			   OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
697 			   sizeof(*req));
698 	status = be_mbox_notify(ctrl);
699 	if (!status)
700 		phba->interface_handle = pbe_allid->if_hndl_list[0];
701 	else {
702 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
703 			    "BG_%d : Failed in mgmt_get_all_if_id\n");
704 	}
705 	spin_unlock(&ctrl->mbox_lock);
706 
707 	return status;
708 }
709 
710 /*
711  * mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
712  * @phba: Driver priv structure
713  * @nonemb_cmd: Address of the MBX command issued
714  * @resp_buf: Buffer to copy the MBX cmd response
715  * @resp_buf_len: respone lenght to be copied
716  *
717  **/
718 static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
719 				struct be_dma_mem *nonemb_cmd, void *resp_buf,
720 				int resp_buf_len)
721 {
722 	struct be_ctrl_info *ctrl = &phba->ctrl;
723 	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
724 	struct be_sge *sge;
725 	unsigned int tag;
726 	int rc = 0;
727 
728 	spin_lock(&ctrl->mbox_lock);
729 	tag = alloc_mcc_tag(phba);
730 	if (!tag) {
731 		spin_unlock(&ctrl->mbox_lock);
732 		rc = -ENOMEM;
733 		goto free_cmd;
734 	}
735 	memset(wrb, 0, sizeof(*wrb));
736 	wrb->tag0 |= tag;
737 	sge = nonembedded_sgl(wrb);
738 
739 	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
740 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
741 	sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
742 	sge->len = cpu_to_le32(nonemb_cmd->size);
743 
744 	be_mcc_notify(phba);
745 	spin_unlock(&ctrl->mbox_lock);
746 
747 	rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va);
748 	if (rc) {
749 		beiscsi_log(phba, KERN_ERR,
750 			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
751 			    "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
752 
753 		rc = -EIO;
754 		goto free_cmd;
755 	}
756 
757 	if (resp_buf)
758 		memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
759 
760 free_cmd:
761 	pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
762 			    nonemb_cmd->va, nonemb_cmd->dma);
763 	return rc;
764 }
765 
766 static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
767 			       int iscsi_cmd, int size)
768 {
769 	cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
770 	if (!cmd->va) {
771 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
772 			    "BG_%d : Failed to allocate memory for if info\n");
773 		return -ENOMEM;
774 	}
775 	memset(cmd->va, 0, size);
776 	cmd->size = size;
777 	be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
778 	return 0;
779 }
780 
781 static int
782 mgmt_static_ip_modify(struct beiscsi_hba *phba,
783 		      struct be_cmd_get_if_info_resp *if_info,
784 		      struct iscsi_iface_param_info *ip_param,
785 		      struct iscsi_iface_param_info *subnet_param,
786 		      uint32_t ip_action)
787 {
788 	struct be_cmd_set_ip_addr_req *req;
789 	struct be_dma_mem nonemb_cmd;
790 	uint32_t ip_type;
791 	int rc;
792 
793 	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
794 				 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
795 				 sizeof(*req));
796 	if (rc)
797 		return rc;
798 
799 	ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
800 		BE2_IPV6 : BE2_IPV4 ;
801 
802 	req = nonemb_cmd.va;
803 	req->ip_params.record_entry_count = 1;
804 	req->ip_params.ip_record.action = ip_action;
805 	req->ip_params.ip_record.interface_hndl =
806 		phba->interface_handle;
807 	req->ip_params.ip_record.ip_addr.size_of_structure =
808 		sizeof(struct be_ip_addr_subnet_format);
809 	req->ip_params.ip_record.ip_addr.ip_type = ip_type;
810 
811 	if (ip_action == IP_ACTION_ADD) {
812 		memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
813 		       ip_param->len);
814 
815 		if (subnet_param)
816 			memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
817 			       subnet_param->value, subnet_param->len);
818 	} else {
819 		memcpy(req->ip_params.ip_record.ip_addr.addr,
820 		       if_info->ip_addr.addr, ip_param->len);
821 
822 		memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
823 		       if_info->ip_addr.subnet_mask, ip_param->len);
824 	}
825 
826 	rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
827 	if (rc < 0)
828 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
829 			    "BG_%d : Failed to Modify existing IP Address\n");
830 	return rc;
831 }
832 
833 static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
834 			       uint32_t gtway_action, uint32_t param_len)
835 {
836 	struct be_cmd_set_def_gateway_req *req;
837 	struct be_dma_mem nonemb_cmd;
838 	int rt_val;
839 
840 
841 	rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
842 				OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
843 				sizeof(*req));
844 	if (rt_val)
845 		return rt_val;
846 
847 	req = nonemb_cmd.va;
848 	req->action = gtway_action;
849 	req->ip_addr.ip_type = BE2_IPV4;
850 
851 	memcpy(req->ip_addr.addr, gt_addr, param_len);
852 
853 	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
854 }
855 
856 int mgmt_set_ip(struct beiscsi_hba *phba,
857 		struct iscsi_iface_param_info *ip_param,
858 		struct iscsi_iface_param_info *subnet_param,
859 		uint32_t boot_proto)
860 {
861 	struct be_cmd_get_def_gateway_resp gtway_addr_set;
862 	struct be_cmd_get_if_info_resp if_info;
863 	struct be_cmd_set_dhcp_req *dhcpreq;
864 	struct be_cmd_rel_dhcp_req *reldhcp;
865 	struct be_dma_mem nonemb_cmd;
866 	uint8_t *gtway_addr;
867 	uint32_t ip_type;
868 	int rc;
869 
870 	if (mgmt_get_all_if_id(phba))
871 		return -EIO;
872 
873 	memset(&if_info, 0, sizeof(if_info));
874 	ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
875 		BE2_IPV6 : BE2_IPV4 ;
876 
877 	rc = mgmt_get_if_info(phba, ip_type, &if_info);
878 	if (rc)
879 		return rc;
880 
881 	if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
882 		if (if_info.dhcp_state) {
883 			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
884 				    "BG_%d : DHCP Already Enabled\n");
885 			return 0;
886 		}
887 		/* The ip_param->len is 1 in DHCP case. Setting
888 		   proper IP len as this it is used while
889 		   freeing the Static IP.
890 		 */
891 		ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
892 				IP_V6_LEN : IP_V4_LEN;
893 
894 	} else {
895 		if (if_info.dhcp_state) {
896 
897 			memset(&if_info, 0, sizeof(if_info));
898 			rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
899 				OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
900 				sizeof(*reldhcp));
901 
902 			if (rc)
903 				return rc;
904 
905 			reldhcp = nonemb_cmd.va;
906 			reldhcp->interface_hndl = phba->interface_handle;
907 			reldhcp->ip_type = ip_type;
908 
909 			rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
910 			if (rc < 0) {
911 				beiscsi_log(phba, KERN_WARNING,
912 					    BEISCSI_LOG_CONFIG,
913 					    "BG_%d : Failed to Delete existing dhcp\n");
914 				return rc;
915 			}
916 		}
917 	}
918 
919 	/* Delete the Static IP Set */
920 	if (if_info.ip_addr.addr[0]) {
921 		rc = mgmt_static_ip_modify(phba, &if_info, ip_param, NULL,
922 					   IP_ACTION_DEL);
923 		if (rc)
924 			return rc;
925 	}
926 
927 	/* Delete the Gateway settings if mode change is to DHCP */
928 	if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
929 		memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
930 		rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
931 		if (rc) {
932 			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
933 				    "BG_%d : Failed to Get Gateway Addr\n");
934 			return rc;
935 		}
936 
937 		if (gtway_addr_set.ip_addr.addr[0]) {
938 			gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
939 			rc = mgmt_modify_gateway(phba, gtway_addr,
940 						 IP_ACTION_DEL, IP_V4_LEN);
941 
942 			if (rc) {
943 				beiscsi_log(phba, KERN_WARNING,
944 					    BEISCSI_LOG_CONFIG,
945 					    "BG_%d : Failed to clear Gateway Addr Set\n");
946 				return rc;
947 			}
948 		}
949 	}
950 
951 	/* Set Adapter to DHCP/Static Mode */
952 	if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
953 		rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
954 			OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
955 			sizeof(*dhcpreq));
956 		if (rc)
957 			return rc;
958 
959 		dhcpreq = nonemb_cmd.va;
960 		dhcpreq->flags = BLOCKING;
961 		dhcpreq->retry_count = 1;
962 		dhcpreq->interface_hndl = phba->interface_handle;
963 		dhcpreq->ip_type = BE2_DHCP_V4;
964 
965 		return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
966 	} else {
967 		return mgmt_static_ip_modify(phba, &if_info, ip_param,
968 					     subnet_param, IP_ACTION_ADD);
969 	}
970 
971 	return rc;
972 }
973 
974 int mgmt_set_gateway(struct beiscsi_hba *phba,
975 		     struct iscsi_iface_param_info *gateway_param)
976 {
977 	struct be_cmd_get_def_gateway_resp gtway_addr_set;
978 	uint8_t *gtway_addr;
979 	int rt_val;
980 
981 	memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
982 	rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
983 	if (rt_val) {
984 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
985 			    "BG_%d : Failed to Get Gateway Addr\n");
986 		return rt_val;
987 	}
988 
989 	if (gtway_addr_set.ip_addr.addr[0]) {
990 		gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
991 		rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
992 					     gateway_param->len);
993 		if (rt_val) {
994 			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
995 				    "BG_%d : Failed to clear Gateway Addr Set\n");
996 			return rt_val;
997 		}
998 	}
999 
1000 	gtway_addr = (uint8_t *)&gateway_param->value;
1001 	rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
1002 				     gateway_param->len);
1003 
1004 	if (rt_val)
1005 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1006 			    "BG_%d : Failed to Set Gateway Addr\n");
1007 
1008 	return rt_val;
1009 }
1010 
1011 int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
1012 		     struct be_cmd_get_def_gateway_resp *gateway)
1013 {
1014 	struct be_cmd_get_def_gateway_req *req;
1015 	struct be_dma_mem nonemb_cmd;
1016 	int rc;
1017 
1018 	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1019 				 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
1020 				 sizeof(*gateway));
1021 	if (rc)
1022 		return rc;
1023 
1024 	req = nonemb_cmd.va;
1025 	req->ip_type = ip_type;
1026 
1027 	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
1028 				    sizeof(*gateway));
1029 }
1030 
1031 int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
1032 		     struct be_cmd_get_if_info_resp *if_info)
1033 {
1034 	struct be_cmd_get_if_info_req *req;
1035 	struct be_dma_mem nonemb_cmd;
1036 	int rc;
1037 
1038 	if (mgmt_get_all_if_id(phba))
1039 		return -EIO;
1040 
1041 	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1042 				 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
1043 				 sizeof(*if_info));
1044 	if (rc)
1045 		return rc;
1046 
1047 	req = nonemb_cmd.va;
1048 	req->interface_hndl = phba->interface_handle;
1049 	req->ip_type = ip_type;
1050 
1051 	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, if_info,
1052 				    sizeof(*if_info));
1053 }
1054 
1055 int mgmt_get_nic_conf(struct beiscsi_hba *phba,
1056 		      struct be_cmd_get_nic_conf_resp *nic)
1057 {
1058 	struct be_dma_mem nonemb_cmd;
1059 	int rc;
1060 
1061 	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1062 				 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
1063 				 sizeof(*nic));
1064 	if (rc)
1065 		return rc;
1066 
1067 	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
1068 }
1069 
1070 
1071 
1072 unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1073 {
1074 	unsigned int tag = 0;
1075 	struct be_mcc_wrb *wrb;
1076 	struct be_cmd_hba_name *req;
1077 	struct be_ctrl_info *ctrl = &phba->ctrl;
1078 
1079 	spin_lock(&ctrl->mbox_lock);
1080 	tag = alloc_mcc_tag(phba);
1081 	if (!tag) {
1082 		spin_unlock(&ctrl->mbox_lock);
1083 		return tag;
1084 	}
1085 
1086 	wrb = wrb_from_mccq(phba);
1087 	req = embedded_payload(wrb);
1088 	wrb->tag0 |= tag;
1089 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1090 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1091 			OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
1092 			sizeof(*req));
1093 
1094 	be_mcc_notify(phba);
1095 	spin_unlock(&ctrl->mbox_lock);
1096 	return tag;
1097 }
1098 
1099 unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
1100 {
1101 	unsigned int tag = 0;
1102 	struct be_mcc_wrb *wrb;
1103 	struct be_cmd_ntwk_link_status_req *req;
1104 	struct be_ctrl_info *ctrl = &phba->ctrl;
1105 
1106 	spin_lock(&ctrl->mbox_lock);
1107 	tag = alloc_mcc_tag(phba);
1108 	if (!tag) {
1109 		spin_unlock(&ctrl->mbox_lock);
1110 		return tag;
1111 	}
1112 
1113 	wrb = wrb_from_mccq(phba);
1114 	req = embedded_payload(wrb);
1115 	wrb->tag0 |= tag;
1116 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1117 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1118 			OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1119 			sizeof(*req));
1120 
1121 	be_mcc_notify(phba);
1122 	spin_unlock(&ctrl->mbox_lock);
1123 	return tag;
1124 }
1125 
1126 /**
1127  * be_mgmt_get_boot_shandle()- Get the session handle
1128  * @phba: device priv structure instance
1129  * @s_handle: session handle returned for boot session.
1130  *
1131  * Get the boot target session handle. In case of
1132  * crashdump mode driver has to issue and MBX Cmd
1133  * for FW to login to boot target
1134  *
1135  * return
1136  *	Success: 0
1137  *	Failure: Non-Zero value
1138  *
1139  **/
1140 int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
1141 			      unsigned int *s_handle)
1142 {
1143 	struct be_cmd_get_boot_target_resp *boot_resp;
1144 	struct be_mcc_wrb *wrb;
1145 	unsigned int tag;
1146 	uint8_t boot_retry = 3;
1147 	int rc;
1148 
1149 	do {
1150 		/* Get the Boot Target Session Handle and Count*/
1151 		tag = mgmt_get_boot_target(phba);
1152 		if (!tag) {
1153 			beiscsi_log(phba, KERN_ERR,
1154 				    BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1155 				    "BG_%d : Getting Boot Target Info Failed\n");
1156 			return -EAGAIN;
1157 		}
1158 
1159 		rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1160 		if (rc) {
1161 			beiscsi_log(phba, KERN_ERR,
1162 				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1163 				    "BG_%d : MBX CMD get_boot_target Failed\n");
1164 			return -EBUSY;
1165 		}
1166 
1167 		boot_resp = embedded_payload(wrb);
1168 
1169 		/* Check if the there are any Boot targets configured */
1170 		if (!boot_resp->boot_session_count) {
1171 			beiscsi_log(phba, KERN_INFO,
1172 				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1173 				    "BG_%d  ;No boot targets configured\n");
1174 			return -ENXIO;
1175 		}
1176 
1177 		/* FW returns the session handle of the boot session */
1178 		if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1179 			*s_handle = boot_resp->boot_session_handle;
1180 			return 0;
1181 		}
1182 
1183 		/* Issue MBX Cmd to FW to login to the boot target */
1184 		tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
1185 					  INVALID_SESS_HANDLE);
1186 		if (!tag) {
1187 			beiscsi_log(phba, KERN_ERR,
1188 				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1189 				    "BG_%d : mgmt_reopen_session Failed\n");
1190 			return -EAGAIN;
1191 		}
1192 
1193 		rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1194 		if (rc) {
1195 			beiscsi_log(phba, KERN_ERR,
1196 				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1197 				    "BG_%d : mgmt_reopen_session Failed");
1198 			return rc;
1199 		}
1200 	} while (--boot_retry);
1201 
1202 	/* Couldn't log into the boot target */
1203 	beiscsi_log(phba, KERN_ERR,
1204 		    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1205 		    "BG_%d : Login to Boot Target Failed\n");
1206 	return -ENXIO;
1207 }
1208 
1209 /**
1210  * mgmt_set_vlan()- Issue and wait for CMD completion
1211  * @phba: device private structure instance
1212  * @vlan_tag: VLAN tag
1213  *
1214  * Issue the MBX Cmd and wait for the completion of the
1215  * command.
1216  *
1217  * returns
1218  *	Success: 0
1219  *	Failure: Non-Xero Value
1220  **/
1221 int mgmt_set_vlan(struct beiscsi_hba *phba,
1222 		   uint16_t vlan_tag)
1223 {
1224 	int rc;
1225 	unsigned int tag;
1226 	struct be_mcc_wrb *wrb = NULL;
1227 
1228 	tag = be_cmd_set_vlan(phba, vlan_tag);
1229 	if (!tag) {
1230 		beiscsi_log(phba, KERN_ERR,
1231 			    (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1232 			    "BG_%d : VLAN Setting Failed\n");
1233 		return -EBUSY;
1234 	}
1235 
1236 	rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1237 	if (rc) {
1238 		beiscsi_log(phba, KERN_ERR,
1239 			    (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1240 			    "BS_%d : VLAN MBX Cmd Failed\n");
1241 		return rc;
1242 	}
1243 	return rc;
1244 }
1245 
1246 /**
1247  * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1248  * @dev: ptr to device not used.
1249  * @attr: device attribute, not used.
1250  * @buf: contains formatted text driver name and version
1251  *
1252  * return
1253  * size of the formatted string
1254  **/
1255 ssize_t
1256 beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1257 		       char *buf)
1258 {
1259 	return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1260 }
1261 
1262 /**
1263  * beiscsi_adap_family_disp()- Display adapter family.
1264  * @dev: ptr to device to get priv structure
1265  * @attr: device attribute, not used.
1266  * @buf: contains formatted text driver name and version
1267  *
1268  * return
1269  * size of the formatted string
1270  **/
1271 ssize_t
1272 beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1273 			  char *buf)
1274 {
1275 	uint16_t dev_id = 0;
1276 	struct Scsi_Host *shost = class_to_shost(dev);
1277 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1278 
1279 	dev_id = phba->pcidev->device;
1280 	switch (dev_id) {
1281 	case BE_DEVICE_ID1:
1282 	case OC_DEVICE_ID1:
1283 	case OC_DEVICE_ID2:
1284 		return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
1285 		break;
1286 	case BE_DEVICE_ID2:
1287 	case OC_DEVICE_ID3:
1288 		return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1289 		break;
1290 	case OC_SKH_ID1:
1291 		return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1292 		break;
1293 	default:
1294 		return snprintf(buf, PAGE_SIZE,
1295 				"Unkown Adapter Family: 0x%x\n", dev_id);
1296 		break;
1297 	}
1298 }
1299 
1300 
1301 void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1302 			     struct wrb_handle *pwrb_handle,
1303 			     struct be_mem_descriptor *mem_descr)
1304 {
1305 	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1306 
1307 	memset(pwrb, 0, sizeof(*pwrb));
1308 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1309 		      max_send_data_segment_length, pwrb,
1310 		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1311 		      max_send_data_segment_length) / 32]);
1312 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1313 		      BE_TGT_CTX_UPDT_CMD);
1314 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1315 		      first_burst_length,
1316 		      pwrb,
1317 		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1318 		      first_burst_length) / 32]);
1319 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1320 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1321 		      erl) / 32] & OFFLD_PARAMS_ERL));
1322 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1323 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1324 		       dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1325 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1326 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1327 		      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1328 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1329 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1330 		      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1331 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1332 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1333 		      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1334 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1335 		      pwrb,
1336 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1337 		      exp_statsn) / 32] + 1));
1338 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1339 		      pwrb, pwrb_handle->wrb_index);
1340 
1341 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1342 		      max_burst_length, pwrb, params->dw[offsetof
1343 		      (struct amap_beiscsi_offload_params,
1344 		      max_burst_length) / 32]);
1345 
1346 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1347 		      pwrb, pwrb_handle->nxt_wrb_index);
1348 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1349 		      session_state, pwrb, 0);
1350 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1351 		      pwrb, 1);
1352 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1353 		      pwrb, 0);
1354 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1355 		      0);
1356 
1357 	mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1358 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1359 		      pad_buffer_addr_hi, pwrb,
1360 		      mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1361 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1362 		      pad_buffer_addr_lo, pwrb,
1363 		      mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1364 }
1365 
1366 void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1367 			     struct wrb_handle *pwrb_handle)
1368 {
1369 	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1370 
1371 	memset(pwrb, 0, sizeof(*pwrb));
1372 
1373 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1374 		      max_burst_length, pwrb, params->dw[offsetof
1375 		      (struct amap_beiscsi_offload_params,
1376 		      max_burst_length) / 32]);
1377 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1378 		      max_burst_length, pwrb, params->dw[offsetof
1379 		      (struct amap_beiscsi_offload_params,
1380 		      max_burst_length) / 32]);
1381 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1382 		      type, pwrb,
1383 		      BE_TGT_CTX_UPDT_CMD);
1384 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1385 		      ptr2nextwrb,
1386 		      pwrb, pwrb_handle->nxt_wrb_index);
1387 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1388 		      pwrb, pwrb_handle->wrb_index);
1389 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1390 		      max_send_data_segment_length, pwrb,
1391 		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1392 		      max_send_data_segment_length) / 32]);
1393 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1394 		      first_burst_length, pwrb,
1395 		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1396 		      first_burst_length) / 32]);
1397 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1398 		      max_recv_dataseg_len, pwrb, BEISCSI_MAX_RECV_DATASEG_LEN);
1399 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1400 		      max_cxns, pwrb, BEISCSI_MAX_CXNS);
1401 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1402 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1403 		      erl) / 32] & OFFLD_PARAMS_ERL));
1404 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1405 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1406 		      dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1407 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1408 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1409 		      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1410 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1411 		      ir2t, pwrb,
1412 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1413 		      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1414 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1415 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1416 		      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1417 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1418 		      data_seq_inorder,
1419 		      pwrb,
1420 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1421 		      data_seq_inorder) / 32] &
1422 		      OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1423 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1424 		      pdu_seq_inorder,
1425 		      pwrb,
1426 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1427 		      pdu_seq_inorder) / 32] &
1428 		      OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1429 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1430 		      pwrb,
1431 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1432 		      max_r2t) / 32] &
1433 		      OFFLD_PARAMS_MAX_R2T) >> 8);
1434 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1435 		      pwrb,
1436 		     (params->dw[offsetof(struct amap_beiscsi_offload_params,
1437 		      exp_statsn) / 32] + 1));
1438 }
1439