1/**
2 * Copyright (C) 2005 - 2015 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@avagotech.com)
11 *
12 * Contact Information:
13 * linux-drivers@avagotech.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 */
28static 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 */
64static 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 **/
105void 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
158int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
159		 struct be_set_eqd *set_eqd, int num)
160{
161	struct be_ctrl_info *ctrl = &phba->ctrl;
162	struct be_mcc_wrb *wrb;
163	struct be_cmd_req_modify_eq_delay *req;
164	unsigned int tag = 0;
165	int i;
166
167	spin_lock(&ctrl->mbox_lock);
168	tag = alloc_mcc_tag(phba);
169	if (!tag) {
170		spin_unlock(&ctrl->mbox_lock);
171		return tag;
172	}
173
174	wrb = wrb_from_mccq(phba);
175	req = embedded_payload(wrb);
176
177	wrb->tag0 |= tag;
178	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
179	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
180		OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
181
182	req->num_eq = cpu_to_le32(num);
183	for (i = 0; i < num; i++) {
184		req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
185		req->delay[i].phase = 0;
186		req->delay[i].delay_multiplier =
187				cpu_to_le32(set_eqd[i].delay_multiplier);
188	}
189
190	be_mcc_notify(phba);
191	spin_unlock(&ctrl->mbox_lock);
192	return tag;
193}
194
195/**
196 * mgmt_reopen_session()- Reopen a session based on reopen_type
197 * @phba: Device priv structure instance
198 * @reopen_type: Type of reopen_session FW should do.
199 * @sess_handle: Session Handle of the session to be re-opened
200 *
201 * return
202 *	the TAG used for MBOX Command
203 *
204 **/
205unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
206				  unsigned int reopen_type,
207				  unsigned int sess_handle)
208{
209	struct be_ctrl_info *ctrl = &phba->ctrl;
210	struct be_mcc_wrb *wrb;
211	struct be_cmd_reopen_session_req *req;
212	unsigned int tag = 0;
213
214	beiscsi_log(phba, KERN_INFO,
215		    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
216		    "BG_%d : In bescsi_get_boot_target\n");
217
218	spin_lock(&ctrl->mbox_lock);
219	tag = alloc_mcc_tag(phba);
220	if (!tag) {
221		spin_unlock(&ctrl->mbox_lock);
222		return tag;
223	}
224
225	wrb = wrb_from_mccq(phba);
226	req = embedded_payload(wrb);
227	wrb->tag0 |= tag;
228	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
229	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
230			   OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
231			   sizeof(struct be_cmd_reopen_session_resp));
232
233	/* set the reopen_type,sess_handle */
234	req->reopen_type = reopen_type;
235	req->session_handle = sess_handle;
236
237	be_mcc_notify(phba);
238	spin_unlock(&ctrl->mbox_lock);
239	return tag;
240}
241
242unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
243{
244	struct be_ctrl_info *ctrl = &phba->ctrl;
245	struct be_mcc_wrb *wrb;
246	struct be_cmd_get_boot_target_req *req;
247	unsigned int tag = 0;
248
249	beiscsi_log(phba, KERN_INFO,
250		    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
251		    "BG_%d : In bescsi_get_boot_target\n");
252
253	spin_lock(&ctrl->mbox_lock);
254	tag = alloc_mcc_tag(phba);
255	if (!tag) {
256		spin_unlock(&ctrl->mbox_lock);
257		return tag;
258	}
259
260	wrb = wrb_from_mccq(phba);
261	req = embedded_payload(wrb);
262	wrb->tag0 |= tag;
263	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
264	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
265			   OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
266			   sizeof(struct be_cmd_get_boot_target_resp));
267
268	be_mcc_notify(phba);
269	spin_unlock(&ctrl->mbox_lock);
270	return tag;
271}
272
273unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
274				   u32 boot_session_handle,
275				   struct be_dma_mem *nonemb_cmd)
276{
277	struct be_ctrl_info *ctrl = &phba->ctrl;
278	struct be_mcc_wrb *wrb;
279	unsigned int tag = 0;
280	struct  be_cmd_get_session_req *req;
281	struct be_cmd_get_session_resp *resp;
282	struct be_sge *sge;
283
284	beiscsi_log(phba, KERN_INFO,
285		    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
286		    "BG_%d : In beiscsi_get_session_info\n");
287
288	spin_lock(&ctrl->mbox_lock);
289	tag = alloc_mcc_tag(phba);
290	if (!tag) {
291		spin_unlock(&ctrl->mbox_lock);
292		return tag;
293	}
294
295	nonemb_cmd->size = sizeof(*resp);
296	req = nonemb_cmd->va;
297	memset(req, 0, sizeof(*req));
298	wrb = wrb_from_mccq(phba);
299	sge = nonembedded_sgl(wrb);
300	wrb->tag0 |= tag;
301
302
303	wrb->tag0 |= tag;
304	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
305	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
306			   OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
307			   sizeof(*resp));
308	req->session_handle = boot_session_handle;
309	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
310	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
311	sge->len = cpu_to_le32(nonemb_cmd->size);
312
313	be_mcc_notify(phba);
314	spin_unlock(&ctrl->mbox_lock);
315	return tag;
316}
317
318/**
319 * mgmt_get_fw_config()- Get the FW config for the function
320 * @ctrl: ptr to Ctrl Info
321 * @phba: ptr to the dev priv structure
322 *
323 * Get the FW config and resources available for the function.
324 * The resources are created based on the count received here.
325 *
326 * return
327 *	Success: 0
328 *	Failure: Non-Zero Value
329 **/
330int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
331				struct beiscsi_hba *phba)
332{
333	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
334	struct be_fw_cfg *req = embedded_payload(wrb);
335	int status = 0;
336
337	spin_lock(&ctrl->mbox_lock);
338	memset(wrb, 0, sizeof(*wrb));
339
340	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
341
342	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
343			   OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
344			   EMBED_MBX_MAX_PAYLOAD_SIZE);
345	status = be_mbox_notify(ctrl);
346	if (!status) {
347		uint8_t ulp_num = 0;
348		struct be_fw_cfg *pfw_cfg;
349		pfw_cfg = req;
350
351		if (!is_chip_be2_be3r(phba)) {
352			phba->fw_config.eqid_count = pfw_cfg->eqid_count;
353			phba->fw_config.cqid_count = pfw_cfg->cqid_count;
354
355			beiscsi_log(phba, KERN_INFO,
356				    BEISCSI_LOG_INIT,
357				    "BG_%d : EQ_Count : %d CQ_Count : %d\n",
358				    phba->fw_config.eqid_count,
359				    phba->fw_config.cqid_count);
360		}
361
362		for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
363			if (pfw_cfg->ulp[ulp_num].ulp_mode &
364			    BEISCSI_ULP_ISCSI_INI_MODE)
365				set_bit(ulp_num,
366				&phba->fw_config.ulp_supported);
367
368		phba->fw_config.phys_port = pfw_cfg->phys_port;
369		for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
370			if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
371
372				phba->fw_config.iscsi_cid_start[ulp_num] =
373					pfw_cfg->ulp[ulp_num].sq_base;
374				phba->fw_config.iscsi_cid_count[ulp_num] =
375					pfw_cfg->ulp[ulp_num].sq_count;
376
377				phba->fw_config.iscsi_icd_start[ulp_num] =
378					pfw_cfg->ulp[ulp_num].icd_base;
379				phba->fw_config.iscsi_icd_count[ulp_num] =
380					pfw_cfg->ulp[ulp_num].icd_count;
381
382				phba->fw_config.iscsi_chain_start[ulp_num] =
383					pfw_cfg->chain_icd[ulp_num].chain_base;
384				phba->fw_config.iscsi_chain_count[ulp_num] =
385					pfw_cfg->chain_icd[ulp_num].chain_count;
386
387				beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
388					    "BG_%d : Function loaded on ULP : %d\n"
389					    "\tiscsi_cid_count : %d\n"
390					    "\tiscsi_cid_start : %d\n"
391					    "\t iscsi_icd_count : %d\n"
392					    "\t iscsi_icd_start : %d\n",
393					    ulp_num,
394					    phba->fw_config.
395					    iscsi_cid_count[ulp_num],
396					    phba->fw_config.
397					    iscsi_cid_start[ulp_num],
398					    phba->fw_config.
399					    iscsi_icd_count[ulp_num],
400					    phba->fw_config.
401					    iscsi_icd_start[ulp_num]);
402			}
403		}
404
405		phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
406						  BEISCSI_FUNC_DUA_MODE);
407
408		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
409			    "BG_%d : DUA Mode : 0x%x\n",
410			    phba->fw_config.dual_ulp_aware);
411
412	} else {
413		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
414			    "BG_%d : Failed in mgmt_get_fw_config\n");
415		status = -EINVAL;
416	}
417
418	spin_unlock(&ctrl->mbox_lock);
419	return status;
420}
421
422int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
423				      struct beiscsi_hba *phba)
424{
425	struct be_dma_mem nonemb_cmd;
426	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
427	struct be_mgmt_controller_attributes *req;
428	struct be_sge *sge = nonembedded_sgl(wrb);
429	int status = 0;
430
431	nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
432				sizeof(struct be_mgmt_controller_attributes),
433				&nonemb_cmd.dma);
434	if (nonemb_cmd.va == NULL) {
435		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
436			    "BG_%d : Failed to allocate memory for "
437			    "mgmt_check_supported_fw\n");
438		return -ENOMEM;
439	}
440	nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
441	req = nonemb_cmd.va;
442	memset(req, 0, sizeof(*req));
443	spin_lock(&ctrl->mbox_lock);
444	memset(wrb, 0, sizeof(*wrb));
445	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
446	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
447			   OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
448	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
449	sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
450	sge->len = cpu_to_le32(nonemb_cmd.size);
451	status = be_mbox_notify(ctrl);
452	if (!status) {
453		struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
454		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
455			    "BG_%d : Firmware Version of CMD : %s\n"
456			    "Firmware Version is : %s\n"
457			    "Developer Build, not performing version check...\n",
458			    resp->params.hba_attribs
459			    .flashrom_version_string,
460			    resp->params.hba_attribs.
461			    firmware_version_string);
462
463		phba->fw_config.iscsi_features =
464				resp->params.hba_attribs.iscsi_features;
465		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
466			    "BM_%d : phba->fw_config.iscsi_features = %d\n",
467			    phba->fw_config.iscsi_features);
468		memcpy(phba->fw_ver_str, resp->params.hba_attribs.
469		       firmware_version_string, BEISCSI_VER_STRLEN);
470	} else
471		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
472			    "BG_%d :  Failed in mgmt_check_supported_fw\n");
473	spin_unlock(&ctrl->mbox_lock);
474	if (nonemb_cmd.va)
475		pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
476				    nonemb_cmd.va, nonemb_cmd.dma);
477
478	return status;
479}
480
481unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
482					 struct beiscsi_hba *phba,
483					 struct bsg_job *job,
484					 struct be_dma_mem *nonemb_cmd)
485{
486	struct be_cmd_resp_hdr *resp;
487	struct be_mcc_wrb *wrb;
488	struct be_sge *mcc_sge;
489	unsigned int tag = 0;
490	struct iscsi_bsg_request *bsg_req = job->request;
491	struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
492	unsigned short region, sector_size, sector, offset;
493
494	nonemb_cmd->size = job->request_payload.payload_len;
495	memset(nonemb_cmd->va, 0, nonemb_cmd->size);
496	resp = nonemb_cmd->va;
497	region =  bsg_req->rqst_data.h_vendor.vendor_cmd[1];
498	sector_size =  bsg_req->rqst_data.h_vendor.vendor_cmd[2];
499	sector =  bsg_req->rqst_data.h_vendor.vendor_cmd[3];
500	offset =  bsg_req->rqst_data.h_vendor.vendor_cmd[4];
501	req->region = region;
502	req->sector = sector;
503	req->offset = offset;
504	spin_lock(&ctrl->mbox_lock);
505
506	switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
507	case BEISCSI_WRITE_FLASH:
508		offset = sector * sector_size + offset;
509		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
510				   OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
511		sg_copy_to_buffer(job->request_payload.sg_list,
512				  job->request_payload.sg_cnt,
513				  nonemb_cmd->va + offset, job->request_len);
514		break;
515	case BEISCSI_READ_FLASH:
516		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
517			   OPCODE_COMMON_READ_FLASH, sizeof(*req));
518		break;
519	default:
520		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
521			    "BG_%d : Unsupported cmd = 0x%x\n\n",
522			    bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
523
524		spin_unlock(&ctrl->mbox_lock);
525		return -ENOSYS;
526	}
527
528	tag = alloc_mcc_tag(phba);
529	if (!tag) {
530		spin_unlock(&ctrl->mbox_lock);
531		return tag;
532	}
533
534	wrb = wrb_from_mccq(phba);
535	mcc_sge = nonembedded_sgl(wrb);
536	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
537			   job->request_payload.sg_cnt);
538	mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
539	mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
540	mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
541	wrb->tag0 |= tag;
542
543	be_mcc_notify(phba);
544
545	spin_unlock(&ctrl->mbox_lock);
546	return tag;
547}
548
549/**
550 * mgmt_epfw_cleanup()- Inform FW to cleanup data structures.
551 * @phba: pointer to dev priv structure
552 * @ulp_num: ULP number.
553 *
554 * return
555 *	Success: 0
556 *	Failure: Non-Zero Value
557 **/
558int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
559{
560	struct be_ctrl_info *ctrl = &phba->ctrl;
561	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
562	struct iscsi_cleanup_req *req = embedded_payload(wrb);
563	int status = 0;
564
565	spin_lock(&ctrl->mbox_lock);
566
567	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
568	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
569			   OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
570
571	req->chute = (1 << ulp_num);
572	req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, ulp_num));
573	req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, ulp_num));
574
575	status =  be_mcc_notify_wait(phba);
576	if (status)
577		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
578			    "BG_%d : mgmt_epfw_cleanup , FAILED\n");
579	spin_unlock(&ctrl->mbox_lock);
580	return status;
581}
582
583unsigned int  mgmt_invalidate_icds(struct beiscsi_hba *phba,
584				struct invalidate_command_table *inv_tbl,
585				unsigned int num_invalidate, unsigned int cid,
586				struct be_dma_mem *nonemb_cmd)
587
588{
589	struct be_ctrl_info *ctrl = &phba->ctrl;
590	struct be_mcc_wrb *wrb;
591	struct be_sge *sge;
592	struct invalidate_commands_params_in *req;
593	unsigned int i, tag = 0;
594
595	spin_lock(&ctrl->mbox_lock);
596	tag = alloc_mcc_tag(phba);
597	if (!tag) {
598		spin_unlock(&ctrl->mbox_lock);
599		return tag;
600	}
601
602	req = nonemb_cmd->va;
603	memset(req, 0, sizeof(*req));
604	wrb = wrb_from_mccq(phba);
605	sge = nonembedded_sgl(wrb);
606	wrb->tag0 |= tag;
607
608	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
609	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
610			OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
611			sizeof(*req));
612	req->ref_handle = 0;
613	req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
614	for (i = 0; i < num_invalidate; i++) {
615		req->table[i].icd = inv_tbl->icd;
616		req->table[i].cid = inv_tbl->cid;
617		req->icd_count++;
618		inv_tbl++;
619	}
620	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
621	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
622	sge->len = cpu_to_le32(nonemb_cmd->size);
623
624	be_mcc_notify(phba);
625	spin_unlock(&ctrl->mbox_lock);
626	return tag;
627}
628
629unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
630					 struct beiscsi_endpoint *beiscsi_ep,
631					 unsigned short cid,
632					 unsigned short issue_reset,
633					 unsigned short savecfg_flag)
634{
635	struct be_ctrl_info *ctrl = &phba->ctrl;
636	struct be_mcc_wrb *wrb;
637	struct iscsi_invalidate_connection_params_in *req;
638	unsigned int tag = 0;
639
640	spin_lock(&ctrl->mbox_lock);
641	tag = alloc_mcc_tag(phba);
642	if (!tag) {
643		spin_unlock(&ctrl->mbox_lock);
644		return tag;
645	}
646	wrb = wrb_from_mccq(phba);
647	wrb->tag0 |= tag;
648	req = embedded_payload(wrb);
649
650	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
651	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
652			   OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
653			   sizeof(*req));
654	req->session_handle = beiscsi_ep->fw_handle;
655	req->cid = cid;
656	if (issue_reset)
657		req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST;
658	else
659		req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
660	req->save_cfg = savecfg_flag;
661	be_mcc_notify(phba);
662	spin_unlock(&ctrl->mbox_lock);
663	return tag;
664}
665
666unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
667				unsigned short cid, unsigned int upload_flag)
668{
669	struct be_ctrl_info *ctrl = &phba->ctrl;
670	struct be_mcc_wrb *wrb;
671	struct tcp_upload_params_in *req;
672	unsigned int tag = 0;
673
674	spin_lock(&ctrl->mbox_lock);
675	tag = alloc_mcc_tag(phba);
676	if (!tag) {
677		spin_unlock(&ctrl->mbox_lock);
678		return tag;
679	}
680	wrb = wrb_from_mccq(phba);
681	req = embedded_payload(wrb);
682	wrb->tag0 |= tag;
683
684	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
685	be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
686			   OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
687	req->id = (unsigned short)cid;
688	req->upload_type = (unsigned char)upload_flag;
689	be_mcc_notify(phba);
690	spin_unlock(&ctrl->mbox_lock);
691	return tag;
692}
693
694/**
695 * mgmt_open_connection()- Establish a TCP CXN
696 * @dst_addr: Destination Address
697 * @beiscsi_ep: ptr to device endpoint struct
698 * @nonemb_cmd: ptr to memory allocated for command
699 *
700 * return
701 *	Success: Tag number of the MBX Command issued
702 *	Failure: Error code
703 **/
704int mgmt_open_connection(struct beiscsi_hba *phba,
705			 struct sockaddr *dst_addr,
706			 struct beiscsi_endpoint *beiscsi_ep,
707			 struct be_dma_mem *nonemb_cmd)
708{
709	struct hwi_controller *phwi_ctrlr;
710	struct hwi_context_memory *phwi_context;
711	struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
712	struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
713	struct be_ctrl_info *ctrl = &phba->ctrl;
714	struct be_mcc_wrb *wrb;
715	struct tcp_connect_and_offload_in_v1 *req;
716	unsigned short def_hdr_id;
717	unsigned short def_data_id;
718	struct phys_addr template_address = { 0, 0 };
719	struct phys_addr *ptemplate_address;
720	unsigned int tag = 0;
721	unsigned int i, ulp_num;
722	unsigned short cid = beiscsi_ep->ep_cid;
723	struct be_sge *sge;
724
725	phwi_ctrlr = phba->phwi_ctrlr;
726	phwi_context = phwi_ctrlr->phwi_ctxt;
727
728	ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
729
730	def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
731	def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
732
733	ptemplate_address = &template_address;
734	ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
735	spin_lock(&ctrl->mbox_lock);
736	tag = alloc_mcc_tag(phba);
737	if (!tag) {
738		spin_unlock(&ctrl->mbox_lock);
739		return tag;
740	}
741	wrb = wrb_from_mccq(phba);
742	sge = nonembedded_sgl(wrb);
743
744	req = nonemb_cmd->va;
745	memset(req, 0, sizeof(*req));
746	wrb->tag0 |= tag;
747
748	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
749	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
750			   OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
751			   nonemb_cmd->size);
752	if (dst_addr->sa_family == PF_INET) {
753		__be32 s_addr = daddr_in->sin_addr.s_addr;
754		req->ip_address.ip_type = BE2_IPV4;
755		req->ip_address.addr[0] = s_addr & 0x000000ff;
756		req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
757		req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
758		req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
759		req->tcp_port = ntohs(daddr_in->sin_port);
760		beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
761		beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
762		beiscsi_ep->ip_type = BE2_IPV4;
763	} else if (dst_addr->sa_family == PF_INET6) {
764		req->ip_address.ip_type = BE2_IPV6;
765		memcpy(&req->ip_address.addr,
766		       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
767		req->tcp_port = ntohs(daddr_in6->sin6_port);
768		beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
769		memcpy(&beiscsi_ep->dst6_addr,
770		       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
771		beiscsi_ep->ip_type = BE2_IPV6;
772	} else{
773		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
774			    "BG_%d : unknown addr family %d\n",
775			    dst_addr->sa_family);
776		spin_unlock(&ctrl->mbox_lock);
777		free_mcc_tag(&phba->ctrl, tag);
778		return -EINVAL;
779
780	}
781	req->cid = cid;
782	i = phba->nxt_cqid++;
783	if (phba->nxt_cqid == phba->num_cpus)
784		phba->nxt_cqid = 0;
785	req->cq_id = phwi_context->be_cq[i].id;
786	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
787		    "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
788	req->defq_id = def_hdr_id;
789	req->hdr_ring_id = def_hdr_id;
790	req->data_ring_id = def_data_id;
791	req->do_offload = 1;
792	req->dataout_template_pa.lo = ptemplate_address->lo;
793	req->dataout_template_pa.hi = ptemplate_address->hi;
794	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
795	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
796	sge->len = cpu_to_le32(nonemb_cmd->size);
797
798	if (!is_chip_be2_be3r(phba)) {
799		req->hdr.version = MBX_CMD_VER1;
800		req->tcp_window_size = 0;
801		req->tcp_window_scale_count = 2;
802	}
803
804	be_mcc_notify(phba);
805	spin_unlock(&ctrl->mbox_lock);
806	return tag;
807}
808
809unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
810{
811	struct be_ctrl_info *ctrl = &phba->ctrl;
812	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
813	struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
814	struct be_cmd_get_all_if_id_req *pbe_allid = req;
815	int status = 0;
816
817	memset(wrb, 0, sizeof(*wrb));
818
819	spin_lock(&ctrl->mbox_lock);
820
821	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
822	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
823			   OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
824			   sizeof(*req));
825	status = be_mbox_notify(ctrl);
826	if (!status)
827		phba->interface_handle = pbe_allid->if_hndl_list[0];
828	else {
829		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
830			    "BG_%d : Failed in mgmt_get_all_if_id\n");
831	}
832	spin_unlock(&ctrl->mbox_lock);
833
834	return status;
835}
836
837/*
838 * mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
839 * @phba: Driver priv structure
840 * @nonemb_cmd: Address of the MBX command issued
841 * @resp_buf: Buffer to copy the MBX cmd response
842 * @resp_buf_len: respone lenght to be copied
843 *
844 **/
845static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
846				struct be_dma_mem *nonemb_cmd, void *resp_buf,
847				int resp_buf_len)
848{
849	struct be_ctrl_info *ctrl = &phba->ctrl;
850	struct be_mcc_wrb *wrb;
851	struct be_sge *sge;
852	unsigned int tag;
853	int rc = 0;
854
855	spin_lock(&ctrl->mbox_lock);
856	tag = alloc_mcc_tag(phba);
857	if (!tag) {
858		spin_unlock(&ctrl->mbox_lock);
859		rc = -ENOMEM;
860		goto free_cmd;
861	}
862
863	wrb = wrb_from_mccq(phba);
864	wrb->tag0 |= tag;
865	sge = nonembedded_sgl(wrb);
866
867	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
868	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
869	sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
870	sge->len = cpu_to_le32(nonemb_cmd->size);
871
872	be_mcc_notify(phba);
873	spin_unlock(&ctrl->mbox_lock);
874
875	rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd);
876
877	if (resp_buf)
878		memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
879
880	if (rc) {
881		/* Check if the MBX Cmd needs to be re-issued */
882		if (rc == -EAGAIN)
883			return rc;
884
885		beiscsi_log(phba, KERN_WARNING,
886			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
887			    "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
888
889		if (rc != -EBUSY)
890			goto free_cmd;
891		else
892			return rc;
893	}
894free_cmd:
895	pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
896			    nonemb_cmd->va, nonemb_cmd->dma);
897	return rc;
898}
899
900static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
901			       int iscsi_cmd, int size)
902{
903	cmd->va = pci_zalloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
904	if (!cmd->va) {
905		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
906			    "BG_%d : Failed to allocate memory for if info\n");
907		return -ENOMEM;
908	}
909	cmd->size = size;
910	be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
911	return 0;
912}
913
914static int
915mgmt_static_ip_modify(struct beiscsi_hba *phba,
916		      struct be_cmd_get_if_info_resp *if_info,
917		      struct iscsi_iface_param_info *ip_param,
918		      struct iscsi_iface_param_info *subnet_param,
919		      uint32_t ip_action)
920{
921	struct be_cmd_set_ip_addr_req *req;
922	struct be_dma_mem nonemb_cmd;
923	uint32_t ip_type;
924	int rc;
925
926	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
927				 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
928				 sizeof(*req));
929	if (rc)
930		return rc;
931
932	ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
933		BE2_IPV6 : BE2_IPV4 ;
934
935	req = nonemb_cmd.va;
936	req->ip_params.record_entry_count = 1;
937	req->ip_params.ip_record.action = ip_action;
938	req->ip_params.ip_record.interface_hndl =
939		phba->interface_handle;
940	req->ip_params.ip_record.ip_addr.size_of_structure =
941		sizeof(struct be_ip_addr_subnet_format);
942	req->ip_params.ip_record.ip_addr.ip_type = ip_type;
943
944	if (ip_action == IP_ACTION_ADD) {
945		memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
946		       sizeof(req->ip_params.ip_record.ip_addr.addr));
947
948		if (subnet_param)
949			memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
950			       subnet_param->value,
951			       sizeof(req->ip_params.ip_record.ip_addr.subnet_mask));
952	} else {
953		memcpy(req->ip_params.ip_record.ip_addr.addr,
954		       if_info->ip_addr.addr,
955		       sizeof(req->ip_params.ip_record.ip_addr.addr));
956
957		memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
958		       if_info->ip_addr.subnet_mask,
959		       sizeof(req->ip_params.ip_record.ip_addr.subnet_mask));
960	}
961
962	rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
963	if (rc < 0)
964		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
965			    "BG_%d : Failed to Modify existing IP Address\n");
966	return rc;
967}
968
969static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
970			       uint32_t gtway_action, uint32_t param_len)
971{
972	struct be_cmd_set_def_gateway_req *req;
973	struct be_dma_mem nonemb_cmd;
974	int rt_val;
975
976
977	rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
978				OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
979				sizeof(*req));
980	if (rt_val)
981		return rt_val;
982
983	req = nonemb_cmd.va;
984	req->action = gtway_action;
985	req->ip_addr.ip_type = BE2_IPV4;
986
987	memcpy(req->ip_addr.addr, gt_addr, sizeof(req->ip_addr.addr));
988
989	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
990}
991
992int mgmt_set_ip(struct beiscsi_hba *phba,
993		struct iscsi_iface_param_info *ip_param,
994		struct iscsi_iface_param_info *subnet_param,
995		uint32_t boot_proto)
996{
997	struct be_cmd_get_def_gateway_resp gtway_addr_set;
998	struct be_cmd_get_if_info_resp *if_info;
999	struct be_cmd_set_dhcp_req *dhcpreq;
1000	struct be_cmd_rel_dhcp_req *reldhcp;
1001	struct be_dma_mem nonemb_cmd;
1002	uint8_t *gtway_addr;
1003	uint32_t ip_type;
1004	int rc;
1005
1006	if (mgmt_get_all_if_id(phba))
1007		return -EIO;
1008
1009	ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1010		BE2_IPV6 : BE2_IPV4 ;
1011
1012	rc = mgmt_get_if_info(phba, ip_type, &if_info);
1013	if (rc)
1014		return rc;
1015
1016	if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1017		if (if_info->dhcp_state) {
1018			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1019				    "BG_%d : DHCP Already Enabled\n");
1020			goto exit;
1021		}
1022		/* The ip_param->len is 1 in DHCP case. Setting
1023		   proper IP len as this it is used while
1024		   freeing the Static IP.
1025		 */
1026		ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1027				IP_V6_LEN : IP_V4_LEN;
1028
1029	} else {
1030		if (if_info->dhcp_state) {
1031
1032			memset(if_info, 0, sizeof(*if_info));
1033			rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1034				OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
1035				sizeof(*reldhcp));
1036
1037			if (rc)
1038				goto exit;
1039
1040			reldhcp = nonemb_cmd.va;
1041			reldhcp->interface_hndl = phba->interface_handle;
1042			reldhcp->ip_type = ip_type;
1043
1044			rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1045			if (rc < 0) {
1046				beiscsi_log(phba, KERN_WARNING,
1047					    BEISCSI_LOG_CONFIG,
1048					    "BG_%d : Failed to Delete existing dhcp\n");
1049				goto exit;
1050			}
1051		}
1052	}
1053
1054	/* Delete the Static IP Set */
1055	if (if_info->ip_addr.addr[0]) {
1056		rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
1057					   IP_ACTION_DEL);
1058		if (rc)
1059			goto exit;
1060	}
1061
1062	/* Delete the Gateway settings if mode change is to DHCP */
1063	if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1064		memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1065		rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1066		if (rc) {
1067			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1068				    "BG_%d : Failed to Get Gateway Addr\n");
1069			goto exit;
1070		}
1071
1072		if (gtway_addr_set.ip_addr.addr[0]) {
1073			gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1074			rc = mgmt_modify_gateway(phba, gtway_addr,
1075						 IP_ACTION_DEL, IP_V4_LEN);
1076
1077			if (rc) {
1078				beiscsi_log(phba, KERN_WARNING,
1079					    BEISCSI_LOG_CONFIG,
1080					    "BG_%d : Failed to clear Gateway Addr Set\n");
1081				goto exit;
1082			}
1083		}
1084	}
1085
1086	/* Set Adapter to DHCP/Static Mode */
1087	if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1088		rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1089			OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
1090			sizeof(*dhcpreq));
1091		if (rc)
1092			goto exit;
1093
1094		dhcpreq = nonemb_cmd.va;
1095		dhcpreq->flags = BLOCKING;
1096		dhcpreq->retry_count = 1;
1097		dhcpreq->interface_hndl = phba->interface_handle;
1098		dhcpreq->ip_type = BE2_DHCP_V4;
1099
1100		rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1101	} else {
1102		rc = mgmt_static_ip_modify(phba, if_info, ip_param,
1103					     subnet_param, IP_ACTION_ADD);
1104	}
1105
1106exit:
1107	kfree(if_info);
1108	return rc;
1109}
1110
1111int mgmt_set_gateway(struct beiscsi_hba *phba,
1112		     struct iscsi_iface_param_info *gateway_param)
1113{
1114	struct be_cmd_get_def_gateway_resp gtway_addr_set;
1115	uint8_t *gtway_addr;
1116	int rt_val;
1117
1118	memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1119	rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1120	if (rt_val) {
1121		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1122			    "BG_%d : Failed to Get Gateway Addr\n");
1123		return rt_val;
1124	}
1125
1126	if (gtway_addr_set.ip_addr.addr[0]) {
1127		gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1128		rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
1129					     gateway_param->len);
1130		if (rt_val) {
1131			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1132				    "BG_%d : Failed to clear Gateway Addr Set\n");
1133			return rt_val;
1134		}
1135	}
1136
1137	gtway_addr = (uint8_t *)&gateway_param->value;
1138	rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
1139				     gateway_param->len);
1140
1141	if (rt_val)
1142		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1143			    "BG_%d : Failed to Set Gateway Addr\n");
1144
1145	return rt_val;
1146}
1147
1148int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
1149		     struct be_cmd_get_def_gateway_resp *gateway)
1150{
1151	struct be_cmd_get_def_gateway_req *req;
1152	struct be_dma_mem nonemb_cmd;
1153	int rc;
1154
1155	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1156				 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
1157				 sizeof(*gateway));
1158	if (rc)
1159		return rc;
1160
1161	req = nonemb_cmd.va;
1162	req->ip_type = ip_type;
1163
1164	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
1165				    sizeof(*gateway));
1166}
1167
1168int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
1169		     struct be_cmd_get_if_info_resp **if_info)
1170{
1171	struct be_cmd_get_if_info_req *req;
1172	struct be_dma_mem nonemb_cmd;
1173	uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
1174	int rc;
1175
1176	if (mgmt_get_all_if_id(phba))
1177		return -EIO;
1178
1179	do {
1180		rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1181					 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
1182					 ioctl_size);
1183		if (rc)
1184			return rc;
1185
1186		req = nonemb_cmd.va;
1187		req->interface_hndl = phba->interface_handle;
1188		req->ip_type = ip_type;
1189
1190		/* Allocate memory for if_info */
1191		*if_info = kzalloc(ioctl_size, GFP_KERNEL);
1192		if (!*if_info) {
1193			beiscsi_log(phba, KERN_ERR,
1194				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1195				    "BG_%d : Memory Allocation Failure\n");
1196
1197				/* Free the DMA memory for the IOCTL issuing */
1198				pci_free_consistent(phba->ctrl.pdev,
1199						    nonemb_cmd.size,
1200						    nonemb_cmd.va,
1201						    nonemb_cmd.dma);
1202				return -ENOMEM;
1203		}
1204
1205		rc =  mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
1206					   ioctl_size);
1207
1208		/* Check if the error is because of Insufficent_Buffer */
1209		if (rc == -EAGAIN) {
1210
1211			/* Get the new memory size */
1212			ioctl_size = ((struct be_cmd_resp_hdr *)
1213				      nonemb_cmd.va)->actual_resp_len;
1214			ioctl_size += sizeof(struct be_cmd_req_hdr);
1215
1216			/* Free the previous allocated DMA memory */
1217			pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1218					    nonemb_cmd.va,
1219					    nonemb_cmd.dma);
1220
1221			/* Free the virtual memory */
1222			kfree(*if_info);
1223		} else
1224			break;
1225	} while (true);
1226	return rc;
1227}
1228
1229int mgmt_get_nic_conf(struct beiscsi_hba *phba,
1230		      struct be_cmd_get_nic_conf_resp *nic)
1231{
1232	struct be_dma_mem nonemb_cmd;
1233	int rc;
1234
1235	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1236				 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
1237				 sizeof(*nic));
1238	if (rc)
1239		return rc;
1240
1241	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
1242}
1243
1244
1245
1246unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1247{
1248	unsigned int tag = 0;
1249	struct be_mcc_wrb *wrb;
1250	struct be_cmd_hba_name *req;
1251	struct be_ctrl_info *ctrl = &phba->ctrl;
1252
1253	spin_lock(&ctrl->mbox_lock);
1254	tag = alloc_mcc_tag(phba);
1255	if (!tag) {
1256		spin_unlock(&ctrl->mbox_lock);
1257		return tag;
1258	}
1259
1260	wrb = wrb_from_mccq(phba);
1261	req = embedded_payload(wrb);
1262	wrb->tag0 |= tag;
1263	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1264	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1265			OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
1266			sizeof(*req));
1267
1268	be_mcc_notify(phba);
1269	spin_unlock(&ctrl->mbox_lock);
1270	return tag;
1271}
1272
1273unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
1274{
1275	unsigned int tag = 0;
1276	struct be_mcc_wrb *wrb;
1277	struct be_cmd_ntwk_link_status_req *req;
1278	struct be_ctrl_info *ctrl = &phba->ctrl;
1279
1280	spin_lock(&ctrl->mbox_lock);
1281	tag = alloc_mcc_tag(phba);
1282	if (!tag) {
1283		spin_unlock(&ctrl->mbox_lock);
1284		return tag;
1285	}
1286
1287	wrb = wrb_from_mccq(phba);
1288	req = embedded_payload(wrb);
1289	wrb->tag0 |= tag;
1290	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1291	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1292			OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1293			sizeof(*req));
1294
1295	be_mcc_notify(phba);
1296	spin_unlock(&ctrl->mbox_lock);
1297	return tag;
1298}
1299
1300/**
1301 * be_mgmt_get_boot_shandle()- Get the session handle
1302 * @phba: device priv structure instance
1303 * @s_handle: session handle returned for boot session.
1304 *
1305 * Get the boot target session handle. In case of
1306 * crashdump mode driver has to issue and MBX Cmd
1307 * for FW to login to boot target
1308 *
1309 * return
1310 *	Success: 0
1311 *	Failure: Non-Zero value
1312 *
1313 **/
1314int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
1315			      unsigned int *s_handle)
1316{
1317	struct be_cmd_get_boot_target_resp *boot_resp;
1318	struct be_mcc_wrb *wrb;
1319	unsigned int tag;
1320	uint8_t boot_retry = 3;
1321	int rc;
1322
1323	do {
1324		/* Get the Boot Target Session Handle and Count*/
1325		tag = mgmt_get_boot_target(phba);
1326		if (!tag) {
1327			beiscsi_log(phba, KERN_ERR,
1328				    BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1329				    "BG_%d : Getting Boot Target Info Failed\n");
1330			return -EAGAIN;
1331		}
1332
1333		rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1334		if (rc) {
1335			beiscsi_log(phba, KERN_ERR,
1336				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1337				    "BG_%d : MBX CMD get_boot_target Failed\n");
1338			return -EBUSY;
1339		}
1340
1341		boot_resp = embedded_payload(wrb);
1342
1343		/* Check if the there are any Boot targets configured */
1344		if (!boot_resp->boot_session_count) {
1345			beiscsi_log(phba, KERN_INFO,
1346				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1347				    "BG_%d  ;No boot targets configured\n");
1348			return -ENXIO;
1349		}
1350
1351		/* FW returns the session handle of the boot session */
1352		if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1353			*s_handle = boot_resp->boot_session_handle;
1354			return 0;
1355		}
1356
1357		/* Issue MBX Cmd to FW to login to the boot target */
1358		tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
1359					  INVALID_SESS_HANDLE);
1360		if (!tag) {
1361			beiscsi_log(phba, KERN_ERR,
1362				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1363				    "BG_%d : mgmt_reopen_session Failed\n");
1364			return -EAGAIN;
1365		}
1366
1367		rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1368		if (rc) {
1369			beiscsi_log(phba, KERN_ERR,
1370				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1371				    "BG_%d : mgmt_reopen_session Failed");
1372			return rc;
1373		}
1374	} while (--boot_retry);
1375
1376	/* Couldn't log into the boot target */
1377	beiscsi_log(phba, KERN_ERR,
1378		    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1379		    "BG_%d : Login to Boot Target Failed\n");
1380	return -ENXIO;
1381}
1382
1383/**
1384 * mgmt_set_vlan()- Issue and wait for CMD completion
1385 * @phba: device private structure instance
1386 * @vlan_tag: VLAN tag
1387 *
1388 * Issue the MBX Cmd and wait for the completion of the
1389 * command.
1390 *
1391 * returns
1392 *	Success: 0
1393 *	Failure: Non-Xero Value
1394 **/
1395int mgmt_set_vlan(struct beiscsi_hba *phba,
1396		   uint16_t vlan_tag)
1397{
1398	int rc;
1399	unsigned int tag;
1400
1401	tag = be_cmd_set_vlan(phba, vlan_tag);
1402	if (!tag) {
1403		beiscsi_log(phba, KERN_ERR,
1404			    (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1405			    "BG_%d : VLAN Setting Failed\n");
1406		return -EBUSY;
1407	}
1408
1409	rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1410	if (rc) {
1411		beiscsi_log(phba, KERN_ERR,
1412			    (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1413			    "BS_%d : VLAN MBX Cmd Failed\n");
1414		return rc;
1415	}
1416	return rc;
1417}
1418
1419/**
1420 * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1421 * @dev: ptr to device not used.
1422 * @attr: device attribute, not used.
1423 * @buf: contains formatted text driver name and version
1424 *
1425 * return
1426 * size of the formatted string
1427 **/
1428ssize_t
1429beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1430		       char *buf)
1431{
1432	return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1433}
1434
1435/**
1436 * beiscsi_fw_ver_disp()- Display Firmware Version
1437 * @dev: ptr to device not used.
1438 * @attr: device attribute, not used.
1439 * @buf: contains formatted text Firmware version
1440 *
1441 * return
1442 * size of the formatted string
1443 **/
1444ssize_t
1445beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1446		     char *buf)
1447{
1448	struct Scsi_Host *shost = class_to_shost(dev);
1449	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1450
1451	return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1452}
1453
1454/**
1455 * beiscsi_active_session_disp()- Display Sessions Active
1456 * @dev: ptr to device not used.
1457 * @attr: device attribute, not used.
1458 * @buf: contains formatted text Session Count
1459 *
1460 * return
1461 * size of the formatted string
1462 **/
1463ssize_t
1464beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1465			 char *buf)
1466{
1467	struct Scsi_Host *shost = class_to_shost(dev);
1468	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1469	uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1470
1471	for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1472		if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1473			avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1474			total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1475			len += snprintf(buf+len, PAGE_SIZE - len,
1476					"ULP%d : %d\n", ulp_num,
1477					(total_cids - avlbl_cids));
1478		} else
1479			len += snprintf(buf+len, PAGE_SIZE - len,
1480					"ULP%d : %d\n", ulp_num, 0);
1481	}
1482
1483	return len;
1484}
1485
1486/**
1487 * beiscsi_free_session_disp()- Display Avaliable Session
1488 * @dev: ptr to device not used.
1489 * @attr: device attribute, not used.
1490 * @buf: contains formatted text Session Count
1491 *
1492 * return
1493 * size of the formatted string
1494 **/
1495ssize_t
1496beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1497		       char *buf)
1498{
1499	struct Scsi_Host *shost = class_to_shost(dev);
1500	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1501	uint16_t ulp_num, len = 0;
1502
1503	for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1504		if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1505			len += snprintf(buf+len, PAGE_SIZE - len,
1506					"ULP%d : %d\n", ulp_num,
1507					BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1508		else
1509			len += snprintf(buf+len, PAGE_SIZE - len,
1510					"ULP%d : %d\n", ulp_num, 0);
1511	}
1512
1513	return len;
1514}
1515
1516/**
1517 * beiscsi_adap_family_disp()- Display adapter family.
1518 * @dev: ptr to device to get priv structure
1519 * @attr: device attribute, not used.
1520 * @buf: contains formatted text driver name and version
1521 *
1522 * return
1523 * size of the formatted string
1524 **/
1525ssize_t
1526beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1527			  char *buf)
1528{
1529	uint16_t dev_id = 0;
1530	struct Scsi_Host *shost = class_to_shost(dev);
1531	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1532
1533	dev_id = phba->pcidev->device;
1534	switch (dev_id) {
1535	case BE_DEVICE_ID1:
1536	case OC_DEVICE_ID1:
1537	case OC_DEVICE_ID2:
1538		return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
1539		break;
1540	case BE_DEVICE_ID2:
1541	case OC_DEVICE_ID3:
1542		return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1543		break;
1544	case OC_SKH_ID1:
1545		return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1546		break;
1547	default:
1548		return snprintf(buf, PAGE_SIZE,
1549				"Unknown Adapter Family: 0x%x\n", dev_id);
1550		break;
1551	}
1552}
1553
1554/**
1555 * beiscsi_phys_port()- Display Physical Port Identifier
1556 * @dev: ptr to device not used.
1557 * @attr: device attribute, not used.
1558 * @buf: contains formatted text port identifier
1559 *
1560 * return
1561 * size of the formatted string
1562 **/
1563ssize_t
1564beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1565			 char *buf)
1566{
1567	struct Scsi_Host *shost = class_to_shost(dev);
1568	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1569
1570	return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n",
1571			phba->fw_config.phys_port);
1572}
1573
1574void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1575			     struct wrb_handle *pwrb_handle,
1576			     struct be_mem_descriptor *mem_descr,
1577			     struct hwi_wrb_context *pwrb_context)
1578{
1579	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1580
1581	memset(pwrb, 0, sizeof(*pwrb));
1582	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1583		      max_send_data_segment_length, pwrb,
1584		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1585		      max_send_data_segment_length) / 32]);
1586	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1587		      BE_TGT_CTX_UPDT_CMD);
1588	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1589		      first_burst_length,
1590		      pwrb,
1591		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1592		      first_burst_length) / 32]);
1593	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1594		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1595		      erl) / 32] & OFFLD_PARAMS_ERL));
1596	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1597		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1598		       dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1599	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1600		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1601		      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1602	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1603		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1604		      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1605	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1606		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1607		      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1608	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1609		      pwrb,
1610		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1611		      exp_statsn) / 32] + 1));
1612	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1613		      pwrb, pwrb_handle->wrb_index);
1614
1615	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1616		      max_burst_length, pwrb, params->dw[offsetof
1617		      (struct amap_beiscsi_offload_params,
1618		      max_burst_length) / 32]);
1619
1620	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1621		      pwrb, pwrb_handle->wrb_index);
1622	if (pwrb_context->plast_wrb)
1623		AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1624			      ptr2nextwrb,
1625			      pwrb_context->plast_wrb,
1626			      pwrb_handle->wrb_index);
1627	pwrb_context->plast_wrb = pwrb;
1628
1629	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1630		      session_state, pwrb, 0);
1631	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1632		      pwrb, 1);
1633	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1634		      pwrb, 0);
1635	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1636		      0);
1637
1638	mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1639	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1640		      pad_buffer_addr_hi, pwrb,
1641		      mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1642	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1643		      pad_buffer_addr_lo, pwrb,
1644		      mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1645}
1646
1647void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1648			     struct wrb_handle *pwrb_handle,
1649			     struct hwi_wrb_context *pwrb_context)
1650{
1651	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1652
1653	memset(pwrb, 0, sizeof(*pwrb));
1654
1655	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1656		      max_burst_length, pwrb, params->dw[offsetof
1657		      (struct amap_beiscsi_offload_params,
1658		      max_burst_length) / 32]);
1659	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1660		      type, pwrb,
1661		      BE_TGT_CTX_UPDT_CMD);
1662	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1663		      ptr2nextwrb,
1664		      pwrb, pwrb_handle->wrb_index);
1665	if (pwrb_context->plast_wrb)
1666		AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1667			      ptr2nextwrb,
1668			      pwrb_context->plast_wrb,
1669			      pwrb_handle->wrb_index);
1670	pwrb_context->plast_wrb = pwrb;
1671
1672	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1673		      pwrb, pwrb_handle->wrb_index);
1674	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1675		      max_send_data_segment_length, pwrb,
1676		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1677		      max_send_data_segment_length) / 32]);
1678	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1679		      first_burst_length, pwrb,
1680		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1681		      first_burst_length) / 32]);
1682	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1683		      max_recv_dataseg_len, pwrb,
1684		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1685		      max_recv_data_segment_length) / 32]);
1686	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1687		      max_cxns, pwrb, BEISCSI_MAX_CXNS);
1688	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1689		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1690		      erl) / 32] & OFFLD_PARAMS_ERL));
1691	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1692		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1693		      dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1694	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1695		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1696		      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1697	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1698		      ir2t, pwrb,
1699		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1700		      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1701	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1702		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1703		      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1704	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1705		      data_seq_inorder,
1706		      pwrb,
1707		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1708		      data_seq_inorder) / 32] &
1709		      OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1710	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1711		      pdu_seq_inorder,
1712		      pwrb,
1713		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1714		      pdu_seq_inorder) / 32] &
1715		      OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1716	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1717		      pwrb,
1718		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1719		      max_r2t) / 32] &
1720		      OFFLD_PARAMS_MAX_R2T) >> 8);
1721	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1722		      pwrb,
1723		     (params->dw[offsetof(struct amap_beiscsi_offload_params,
1724		      exp_statsn) / 32] + 1));
1725}
1726
1727/**
1728 * beiscsi_logout_fw_sess()- Firmware Session Logout
1729 * @phba: Device priv structure instance
1730 * @fw_sess_handle: FW session handle
1731 *
1732 * Logout from the FW established sessions.
1733 * returns
1734 *  Success: 0
1735 *  Failure: Non-Zero Value
1736 *
1737 */
1738int beiscsi_logout_fw_sess(struct beiscsi_hba *phba,
1739		uint32_t fw_sess_handle)
1740{
1741	struct be_ctrl_info *ctrl = &phba->ctrl;
1742	struct be_mcc_wrb *wrb;
1743	struct be_cmd_req_logout_fw_sess *req;
1744	struct be_cmd_resp_logout_fw_sess *resp;
1745	unsigned int tag;
1746	int rc;
1747
1748	beiscsi_log(phba, KERN_INFO,
1749		    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1750		    "BG_%d : In bescsi_logout_fwboot_sess\n");
1751
1752	spin_lock(&ctrl->mbox_lock);
1753	tag = alloc_mcc_tag(phba);
1754	if (!tag) {
1755		spin_unlock(&ctrl->mbox_lock);
1756		beiscsi_log(phba, KERN_INFO,
1757			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1758			    "BG_%d : MBX Tag Failure\n");
1759		return -EINVAL;
1760	}
1761
1762	wrb = wrb_from_mccq(phba);
1763	req = embedded_payload(wrb);
1764	wrb->tag0 |= tag;
1765	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1766	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1767			   OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
1768			   sizeof(struct be_cmd_req_logout_fw_sess));
1769
1770	/* Set the session handle */
1771	req->session_handle = fw_sess_handle;
1772	be_mcc_notify(phba);
1773	spin_unlock(&ctrl->mbox_lock);
1774
1775	rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1776	if (rc) {
1777		beiscsi_log(phba, KERN_ERR,
1778			    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1779			    "BG_%d : MBX CMD FW_SESSION_LOGOUT_TARGET Failed\n");
1780		return -EBUSY;
1781	}
1782
1783	resp = embedded_payload(wrb);
1784	if (resp->session_status !=
1785		BEISCSI_MGMT_SESSION_CLOSE) {
1786		beiscsi_log(phba, KERN_ERR,
1787			    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1788			    "BG_%d : FW_SESSION_LOGOUT_TARGET resp : 0x%x\n",
1789			    resp->session_status);
1790		rc = -EINVAL;
1791	}
1792
1793	return rc;
1794}
1795