xref: /linux/drivers/scsi/be2iscsi/be_mgmt.c (revision acb9693cb007e126fd313cb696dfbf5c214514cd)
16733b39aSJayamohan Kallickal /**
2255fa9a3SJayamohan Kallickal  * Copyright (C) 2005 - 2011 Emulex
36733b39aSJayamohan Kallickal  * All rights reserved.
46733b39aSJayamohan Kallickal  *
56733b39aSJayamohan Kallickal  * This program is free software; you can redistribute it and/or
66733b39aSJayamohan Kallickal  * modify it under the terms of the GNU General Public License version 2
76733b39aSJayamohan Kallickal  * as published by the Free Software Foundation.  The full GNU General
86733b39aSJayamohan Kallickal  * Public License is included in this distribution in the file called COPYING.
96733b39aSJayamohan Kallickal  *
10255fa9a3SJayamohan Kallickal  * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
116733b39aSJayamohan Kallickal  *
126733b39aSJayamohan Kallickal  * Contact Information:
13255fa9a3SJayamohan Kallickal  * linux-drivers@emulex.com
146733b39aSJayamohan Kallickal  *
15255fa9a3SJayamohan Kallickal  * Emulex
16255fa9a3SJayamohan Kallickal  * 3333 Susan Street
17255fa9a3SJayamohan Kallickal  * Costa Mesa, CA 92626
186733b39aSJayamohan Kallickal  */
196733b39aSJayamohan Kallickal 
20ffce3e2eSJayamohan Kallickal #include <linux/bsg-lib.h>
21ffce3e2eSJayamohan Kallickal #include <scsi/scsi_transport_iscsi.h>
22ffce3e2eSJayamohan Kallickal #include <scsi/scsi_bsg_iscsi.h>
236733b39aSJayamohan Kallickal #include "be_mgmt.h"
246733b39aSJayamohan Kallickal #include "be_iscsi.h"
25c7acc5b8SJayamohan Kallickal 
269aef4200SJohn Soni Jose /**
279aef4200SJohn Soni Jose  * mgmt_reopen_session()- Reopen a session based on reopen_type
289aef4200SJohn Soni Jose  * @phba: Device priv structure instance
299aef4200SJohn Soni Jose  * @reopen_type: Type of reopen_session FW should do.
309aef4200SJohn Soni Jose  * @sess_handle: Session Handle of the session to be re-opened
319aef4200SJohn Soni Jose  *
329aef4200SJohn Soni Jose  * return
339aef4200SJohn Soni Jose  *	the TAG used for MBOX Command
349aef4200SJohn Soni Jose  *
359aef4200SJohn Soni Jose  **/
369aef4200SJohn Soni Jose unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
379aef4200SJohn Soni Jose 				  unsigned int reopen_type,
389aef4200SJohn Soni Jose 				  unsigned int sess_handle)
399aef4200SJohn Soni Jose {
409aef4200SJohn Soni Jose 	struct be_ctrl_info *ctrl = &phba->ctrl;
419aef4200SJohn Soni Jose 	struct be_mcc_wrb *wrb;
429aef4200SJohn Soni Jose 	struct be_cmd_reopen_session_req *req;
439aef4200SJohn Soni Jose 	unsigned int tag = 0;
449aef4200SJohn Soni Jose 
4599bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO,
4699bc5d55SJohn Soni Jose 		    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
4799bc5d55SJohn Soni Jose 		    "BG_%d : In bescsi_get_boot_target\n");
4899bc5d55SJohn Soni Jose 
499aef4200SJohn Soni Jose 	spin_lock(&ctrl->mbox_lock);
509aef4200SJohn Soni Jose 	tag = alloc_mcc_tag(phba);
519aef4200SJohn Soni Jose 	if (!tag) {
529aef4200SJohn Soni Jose 		spin_unlock(&ctrl->mbox_lock);
539aef4200SJohn Soni Jose 		return tag;
549aef4200SJohn Soni Jose 	}
559aef4200SJohn Soni Jose 
569aef4200SJohn Soni Jose 	wrb = wrb_from_mccq(phba);
579aef4200SJohn Soni Jose 	req = embedded_payload(wrb);
589aef4200SJohn Soni Jose 	wrb->tag0 |= tag;
599aef4200SJohn Soni Jose 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
609aef4200SJohn Soni Jose 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
619aef4200SJohn Soni Jose 			   OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
629aef4200SJohn Soni Jose 			   sizeof(struct be_cmd_reopen_session_resp));
639aef4200SJohn Soni Jose 
649aef4200SJohn Soni Jose 	/* set the reopen_type,sess_handle */
659aef4200SJohn Soni Jose 	req->reopen_type = reopen_type;
669aef4200SJohn Soni Jose 	req->session_handle = sess_handle;
679aef4200SJohn Soni Jose 
689aef4200SJohn Soni Jose 	be_mcc_notify(phba);
699aef4200SJohn Soni Jose 	spin_unlock(&ctrl->mbox_lock);
709aef4200SJohn Soni Jose 	return tag;
719aef4200SJohn Soni Jose }
729aef4200SJohn Soni Jose 
730e43895eSMike Christie unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
74c7acc5b8SJayamohan Kallickal {
75c7acc5b8SJayamohan Kallickal 	struct be_ctrl_info *ctrl = &phba->ctrl;
76c7acc5b8SJayamohan Kallickal 	struct be_mcc_wrb *wrb;
770e43895eSMike Christie 	struct be_cmd_get_boot_target_req *req;
78c7acc5b8SJayamohan Kallickal 	unsigned int tag = 0;
79c7acc5b8SJayamohan Kallickal 
8099bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO,
8199bc5d55SJohn Soni Jose 		    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
8299bc5d55SJohn Soni Jose 		    "BG_%d : In bescsi_get_boot_target\n");
8399bc5d55SJohn Soni Jose 
84c7acc5b8SJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
85c7acc5b8SJayamohan Kallickal 	tag = alloc_mcc_tag(phba);
86c7acc5b8SJayamohan Kallickal 	if (!tag) {
87c7acc5b8SJayamohan Kallickal 		spin_unlock(&ctrl->mbox_lock);
88c7acc5b8SJayamohan Kallickal 		return tag;
89c7acc5b8SJayamohan Kallickal 	}
90c7acc5b8SJayamohan Kallickal 
91c7acc5b8SJayamohan Kallickal 	wrb = wrb_from_mccq(phba);
92c7acc5b8SJayamohan Kallickal 	req = embedded_payload(wrb);
93c7acc5b8SJayamohan Kallickal 	wrb->tag0 |= tag;
94c7acc5b8SJayamohan Kallickal 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
95c7acc5b8SJayamohan Kallickal 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
96c7acc5b8SJayamohan Kallickal 			   OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
970e43895eSMike Christie 			   sizeof(struct be_cmd_get_boot_target_resp));
98c7acc5b8SJayamohan Kallickal 
99c7acc5b8SJayamohan Kallickal 	be_mcc_notify(phba);
100c7acc5b8SJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
101c7acc5b8SJayamohan Kallickal 	return tag;
102c7acc5b8SJayamohan Kallickal }
103c7acc5b8SJayamohan Kallickal 
1040e43895eSMike Christie unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
105c7acc5b8SJayamohan Kallickal 				   u32 boot_session_handle,
106c7acc5b8SJayamohan Kallickal 				   struct be_dma_mem *nonemb_cmd)
107c7acc5b8SJayamohan Kallickal {
108c7acc5b8SJayamohan Kallickal 	struct be_ctrl_info *ctrl = &phba->ctrl;
109c7acc5b8SJayamohan Kallickal 	struct be_mcc_wrb *wrb;
110c7acc5b8SJayamohan Kallickal 	unsigned int tag = 0;
1110e43895eSMike Christie 	struct  be_cmd_get_session_req *req;
1120e43895eSMike Christie 	struct be_cmd_get_session_resp *resp;
113c7acc5b8SJayamohan Kallickal 	struct be_sge *sge;
114c7acc5b8SJayamohan Kallickal 
11599bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO,
11699bc5d55SJohn Soni Jose 		    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
11799bc5d55SJohn Soni Jose 		    "BG_%d : In beiscsi_get_session_info\n");
11899bc5d55SJohn Soni Jose 
119c7acc5b8SJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
120c7acc5b8SJayamohan Kallickal 	tag = alloc_mcc_tag(phba);
121c7acc5b8SJayamohan Kallickal 	if (!tag) {
122c7acc5b8SJayamohan Kallickal 		spin_unlock(&ctrl->mbox_lock);
123c7acc5b8SJayamohan Kallickal 		return tag;
124c7acc5b8SJayamohan Kallickal 	}
125c7acc5b8SJayamohan Kallickal 
126c7acc5b8SJayamohan Kallickal 	nonemb_cmd->size = sizeof(*resp);
127c7acc5b8SJayamohan Kallickal 	req = nonemb_cmd->va;
128c7acc5b8SJayamohan Kallickal 	memset(req, 0, sizeof(*req));
129c7acc5b8SJayamohan Kallickal 	wrb = wrb_from_mccq(phba);
130c7acc5b8SJayamohan Kallickal 	sge = nonembedded_sgl(wrb);
131c7acc5b8SJayamohan Kallickal 	wrb->tag0 |= tag;
132c7acc5b8SJayamohan Kallickal 
133c7acc5b8SJayamohan Kallickal 
134c7acc5b8SJayamohan Kallickal 	wrb->tag0 |= tag;
135c7acc5b8SJayamohan Kallickal 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
136c7acc5b8SJayamohan Kallickal 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
137c7acc5b8SJayamohan Kallickal 			   OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
138c7acc5b8SJayamohan Kallickal 			   sizeof(*resp));
139c7acc5b8SJayamohan Kallickal 	req->session_handle = boot_session_handle;
140c7acc5b8SJayamohan Kallickal 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
141c7acc5b8SJayamohan Kallickal 	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
142c7acc5b8SJayamohan Kallickal 	sge->len = cpu_to_le32(nonemb_cmd->size);
143c7acc5b8SJayamohan Kallickal 
144c7acc5b8SJayamohan Kallickal 	be_mcc_notify(phba);
145c7acc5b8SJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
146c7acc5b8SJayamohan Kallickal 	return tag;
147c7acc5b8SJayamohan Kallickal }
1486733b39aSJayamohan Kallickal 
14903a12310SJayamohan Kallickal int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
1506733b39aSJayamohan Kallickal 				struct beiscsi_hba *phba)
1516733b39aSJayamohan Kallickal {
1526733b39aSJayamohan Kallickal 	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1536733b39aSJayamohan Kallickal 	struct be_fw_cfg *req = embedded_payload(wrb);
1546733b39aSJayamohan Kallickal 	int status = 0;
1556733b39aSJayamohan Kallickal 
1566733b39aSJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
1576733b39aSJayamohan Kallickal 	memset(wrb, 0, sizeof(*wrb));
1586733b39aSJayamohan Kallickal 
1596733b39aSJayamohan Kallickal 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1606733b39aSJayamohan Kallickal 
1616733b39aSJayamohan Kallickal 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1626733b39aSJayamohan Kallickal 			   OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
1636733b39aSJayamohan Kallickal 	status = be_mbox_notify(ctrl);
1646733b39aSJayamohan Kallickal 	if (!status) {
1656733b39aSJayamohan Kallickal 		struct be_fw_cfg *pfw_cfg;
1666733b39aSJayamohan Kallickal 		pfw_cfg = req;
1676733b39aSJayamohan Kallickal 		phba->fw_config.phys_port = pfw_cfg->phys_port;
1686733b39aSJayamohan Kallickal 		phba->fw_config.iscsi_icd_start =
1696733b39aSJayamohan Kallickal 					pfw_cfg->ulp[0].icd_base;
1706733b39aSJayamohan Kallickal 		phba->fw_config.iscsi_icd_count =
1716733b39aSJayamohan Kallickal 					pfw_cfg->ulp[0].icd_count;
1726733b39aSJayamohan Kallickal 		phba->fw_config.iscsi_cid_start =
1736733b39aSJayamohan Kallickal 					pfw_cfg->ulp[0].sq_base;
1746733b39aSJayamohan Kallickal 		phba->fw_config.iscsi_cid_count =
1756733b39aSJayamohan Kallickal 					pfw_cfg->ulp[0].sq_count;
1767da50879SJayamohan Kallickal 		if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) {
17799bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
17899bc5d55SJohn Soni Jose 				    "BG_%d : FW reported MAX CXNS as %d\t"
179a3babda5SJayamohan Kallickal 				    "Max Supported = %d.\n",
1807da50879SJayamohan Kallickal 				    phba->fw_config.iscsi_cid_count,
1817da50879SJayamohan Kallickal 				    BE2_MAX_SESSIONS);
182a3babda5SJayamohan Kallickal 			phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2;
1837da50879SJayamohan Kallickal 		}
1846733b39aSJayamohan Kallickal 	} else {
18599bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
18699bc5d55SJohn Soni Jose 			    "BG_%d : Failed in mgmt_get_fw_config\n");
1876733b39aSJayamohan Kallickal 	}
1886733b39aSJayamohan Kallickal 
1896733b39aSJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
1906733b39aSJayamohan Kallickal 	return status;
1916733b39aSJayamohan Kallickal }
1926733b39aSJayamohan Kallickal 
19303a12310SJayamohan Kallickal int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
194bfead3b2SJayamohan Kallickal 				      struct beiscsi_hba *phba)
1956733b39aSJayamohan Kallickal {
1966733b39aSJayamohan Kallickal 	struct be_dma_mem nonemb_cmd;
1976733b39aSJayamohan Kallickal 	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
1986733b39aSJayamohan Kallickal 	struct be_mgmt_controller_attributes *req;
1996733b39aSJayamohan Kallickal 	struct be_sge *sge = nonembedded_sgl(wrb);
2006733b39aSJayamohan Kallickal 	int status = 0;
2016733b39aSJayamohan Kallickal 
2026733b39aSJayamohan Kallickal 	nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
2036733b39aSJayamohan Kallickal 				sizeof(struct be_mgmt_controller_attributes),
2046733b39aSJayamohan Kallickal 				&nonemb_cmd.dma);
2056733b39aSJayamohan Kallickal 	if (nonemb_cmd.va == NULL) {
20699bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
20799bc5d55SJohn Soni Jose 			    "BG_%d : Failed to allocate memory for "
20899bc5d55SJohn Soni Jose 			    "mgmt_check_supported_fw\n");
209d3ad2bb3SJayamohan Kallickal 		return -ENOMEM;
2106733b39aSJayamohan Kallickal 	}
2116733b39aSJayamohan Kallickal 	nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
2126733b39aSJayamohan Kallickal 	req = nonemb_cmd.va;
213f98c96b0SJayamohan Kallickal 	memset(req, 0, sizeof(*req));
2146733b39aSJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
2156733b39aSJayamohan Kallickal 	memset(wrb, 0, sizeof(*wrb));
2166733b39aSJayamohan Kallickal 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
2176733b39aSJayamohan Kallickal 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
2186733b39aSJayamohan Kallickal 			   OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
2196733b39aSJayamohan Kallickal 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
2206733b39aSJayamohan Kallickal 	sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
2216733b39aSJayamohan Kallickal 	sge->len = cpu_to_le32(nonemb_cmd.size);
2226733b39aSJayamohan Kallickal 	status = be_mbox_notify(ctrl);
2236733b39aSJayamohan Kallickal 	if (!status) {
2246733b39aSJayamohan Kallickal 		struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
22599bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
22699bc5d55SJohn Soni Jose 			    "BG_%d : Firmware Version of CMD : %s\n"
22799bc5d55SJohn Soni Jose 			    "Firmware Version is : %s\n"
22899bc5d55SJohn Soni Jose 			    "Developer Build, not performing version check...\n",
22999bc5d55SJohn Soni Jose 			    resp->params.hba_attribs
23099bc5d55SJohn Soni Jose 			    .flashrom_version_string,
23199bc5d55SJohn Soni Jose 			    resp->params.hba_attribs.
23299bc5d55SJohn Soni Jose 			    firmware_version_string);
23399bc5d55SJohn Soni Jose 
234bfead3b2SJayamohan Kallickal 		phba->fw_config.iscsi_features =
235bfead3b2SJayamohan Kallickal 				resp->params.hba_attribs.iscsi_features;
23699bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
23799bc5d55SJohn Soni Jose 			    "BM_%d : phba->fw_config.iscsi_features = %d\n",
238bfead3b2SJayamohan Kallickal 			    phba->fw_config.iscsi_features);
2396733b39aSJayamohan Kallickal 	} else
24099bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
24199bc5d55SJohn Soni Jose 			    "BG_%d :  Failed in mgmt_check_supported_fw\n");
242bfead3b2SJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
2436733b39aSJayamohan Kallickal 	if (nonemb_cmd.va)
2446733b39aSJayamohan Kallickal 		pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
2456733b39aSJayamohan Kallickal 				    nonemb_cmd.va, nonemb_cmd.dma);
2466733b39aSJayamohan Kallickal 
2476733b39aSJayamohan Kallickal 	return status;
2486733b39aSJayamohan Kallickal }
2496733b39aSJayamohan Kallickal 
250ffce3e2eSJayamohan Kallickal unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
251ffce3e2eSJayamohan Kallickal 					 struct beiscsi_hba *phba,
252ffce3e2eSJayamohan Kallickal 					 struct bsg_job *job,
253ffce3e2eSJayamohan Kallickal 					 struct be_dma_mem *nonemb_cmd)
254ffce3e2eSJayamohan Kallickal {
255ffce3e2eSJayamohan Kallickal 	struct be_cmd_resp_hdr *resp;
256ffce3e2eSJayamohan Kallickal 	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
257ffce3e2eSJayamohan Kallickal 	struct be_sge *mcc_sge = nonembedded_sgl(wrb);
258ffce3e2eSJayamohan Kallickal 	unsigned int tag = 0;
259ffce3e2eSJayamohan Kallickal 	struct iscsi_bsg_request *bsg_req = job->request;
260ffce3e2eSJayamohan Kallickal 	struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
261ffce3e2eSJayamohan Kallickal 	unsigned short region, sector_size, sector, offset;
262ffce3e2eSJayamohan Kallickal 
263ffce3e2eSJayamohan Kallickal 	nonemb_cmd->size = job->request_payload.payload_len;
264ffce3e2eSJayamohan Kallickal 	memset(nonemb_cmd->va, 0, nonemb_cmd->size);
265ffce3e2eSJayamohan Kallickal 	resp = nonemb_cmd->va;
266ffce3e2eSJayamohan Kallickal 	region =  bsg_req->rqst_data.h_vendor.vendor_cmd[1];
267ffce3e2eSJayamohan Kallickal 	sector_size =  bsg_req->rqst_data.h_vendor.vendor_cmd[2];
268ffce3e2eSJayamohan Kallickal 	sector =  bsg_req->rqst_data.h_vendor.vendor_cmd[3];
269ffce3e2eSJayamohan Kallickal 	offset =  bsg_req->rqst_data.h_vendor.vendor_cmd[4];
270ffce3e2eSJayamohan Kallickal 	req->region = region;
271ffce3e2eSJayamohan Kallickal 	req->sector = sector;
272ffce3e2eSJayamohan Kallickal 	req->offset = offset;
273ffce3e2eSJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
274ffce3e2eSJayamohan Kallickal 	memset(wrb, 0, sizeof(*wrb));
275ffce3e2eSJayamohan Kallickal 
276ffce3e2eSJayamohan Kallickal 	switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
277ffce3e2eSJayamohan Kallickal 	case BEISCSI_WRITE_FLASH:
278ffce3e2eSJayamohan Kallickal 		offset = sector * sector_size + offset;
279ffce3e2eSJayamohan Kallickal 		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
280ffce3e2eSJayamohan Kallickal 				   OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
281ffce3e2eSJayamohan Kallickal 		sg_copy_to_buffer(job->request_payload.sg_list,
282ffce3e2eSJayamohan Kallickal 				  job->request_payload.sg_cnt,
283ffce3e2eSJayamohan Kallickal 				  nonemb_cmd->va + offset, job->request_len);
284ffce3e2eSJayamohan Kallickal 		break;
285ffce3e2eSJayamohan Kallickal 	case BEISCSI_READ_FLASH:
286ffce3e2eSJayamohan Kallickal 		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
287ffce3e2eSJayamohan Kallickal 			   OPCODE_COMMON_READ_FLASH, sizeof(*req));
288ffce3e2eSJayamohan Kallickal 		break;
289ffce3e2eSJayamohan Kallickal 	default:
29099bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
29199bc5d55SJohn Soni Jose 			    "BG_%d : Unsupported cmd = 0x%x\n\n",
29299bc5d55SJohn Soni Jose 			    bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
29399bc5d55SJohn Soni Jose 
294ffce3e2eSJayamohan Kallickal 		spin_unlock(&ctrl->mbox_lock);
295ffce3e2eSJayamohan Kallickal 		return -ENOSYS;
296ffce3e2eSJayamohan Kallickal 	}
297ffce3e2eSJayamohan Kallickal 
298ffce3e2eSJayamohan Kallickal 	tag = alloc_mcc_tag(phba);
299ffce3e2eSJayamohan Kallickal 	if (!tag) {
300ffce3e2eSJayamohan Kallickal 		spin_unlock(&ctrl->mbox_lock);
301ffce3e2eSJayamohan Kallickal 		return tag;
302ffce3e2eSJayamohan Kallickal 	}
303ffce3e2eSJayamohan Kallickal 
304ffce3e2eSJayamohan Kallickal 	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
305ffce3e2eSJayamohan Kallickal 			   job->request_payload.sg_cnt);
306ffce3e2eSJayamohan Kallickal 	mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
307ffce3e2eSJayamohan Kallickal 	mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
308ffce3e2eSJayamohan Kallickal 	mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
309ffce3e2eSJayamohan Kallickal 	wrb->tag0 |= tag;
310ffce3e2eSJayamohan Kallickal 
311ffce3e2eSJayamohan Kallickal 	be_mcc_notify(phba);
312ffce3e2eSJayamohan Kallickal 
313ffce3e2eSJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
314ffce3e2eSJayamohan Kallickal 	return tag;
315ffce3e2eSJayamohan Kallickal }
316ffce3e2eSJayamohan Kallickal 
31703a12310SJayamohan Kallickal int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
3186733b39aSJayamohan Kallickal {
3196733b39aSJayamohan Kallickal 	struct be_ctrl_info *ctrl = &phba->ctrl;
320bfead3b2SJayamohan Kallickal 	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
3216733b39aSJayamohan Kallickal 	struct iscsi_cleanup_req *req = embedded_payload(wrb);
3226733b39aSJayamohan Kallickal 	int status = 0;
3236733b39aSJayamohan Kallickal 
3246733b39aSJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
3256733b39aSJayamohan Kallickal 	memset(wrb, 0, sizeof(*wrb));
3266733b39aSJayamohan Kallickal 
3276733b39aSJayamohan Kallickal 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
3286733b39aSJayamohan Kallickal 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
3296733b39aSJayamohan Kallickal 			   OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
3306733b39aSJayamohan Kallickal 
3316733b39aSJayamohan Kallickal 	req->chute = chute;
332069adc7bSJayamohan Kallickal 	req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba));
333069adc7bSJayamohan Kallickal 	req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba));
3346733b39aSJayamohan Kallickal 
335bfead3b2SJayamohan Kallickal 	status =  be_mcc_notify_wait(phba);
3366733b39aSJayamohan Kallickal 	if (status)
33799bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
33899bc5d55SJohn Soni Jose 			    "BG_%d : mgmt_epfw_cleanup , FAILED\n");
3396733b39aSJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
3406733b39aSJayamohan Kallickal 	return status;
3416733b39aSJayamohan Kallickal }
3426733b39aSJayamohan Kallickal 
34303a12310SJayamohan Kallickal unsigned int  mgmt_invalidate_icds(struct beiscsi_hba *phba,
3444183122dSJayamohan Kallickal 				struct invalidate_command_table *inv_tbl,
3453cbb7a74SJayamohan Kallickal 				unsigned int num_invalidate, unsigned int cid,
3463cbb7a74SJayamohan Kallickal 				struct be_dma_mem *nonemb_cmd)
3473cbb7a74SJayamohan Kallickal 
3486733b39aSJayamohan Kallickal {
3496733b39aSJayamohan Kallickal 	struct be_ctrl_info *ctrl = &phba->ctrl;
350756d29c8SJayamohan Kallickal 	struct be_mcc_wrb *wrb;
351756d29c8SJayamohan Kallickal 	struct be_sge *sge;
3526733b39aSJayamohan Kallickal 	struct invalidate_commands_params_in *req;
3534183122dSJayamohan Kallickal 	unsigned int i, tag = 0;
354756d29c8SJayamohan Kallickal 
355756d29c8SJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
356756d29c8SJayamohan Kallickal 	tag = alloc_mcc_tag(phba);
357756d29c8SJayamohan Kallickal 	if (!tag) {
358756d29c8SJayamohan Kallickal 		spin_unlock(&ctrl->mbox_lock);
359756d29c8SJayamohan Kallickal 		return tag;
360756d29c8SJayamohan Kallickal 	}
3616733b39aSJayamohan Kallickal 
3623cbb7a74SJayamohan Kallickal 	req = nonemb_cmd->va;
363f98c96b0SJayamohan Kallickal 	memset(req, 0, sizeof(*req));
364756d29c8SJayamohan Kallickal 	wrb = wrb_from_mccq(phba);
365756d29c8SJayamohan Kallickal 	sge = nonembedded_sgl(wrb);
366756d29c8SJayamohan Kallickal 	wrb->tag0 |= tag;
3676733b39aSJayamohan Kallickal 
3686733b39aSJayamohan Kallickal 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
3696733b39aSJayamohan Kallickal 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
3706733b39aSJayamohan Kallickal 			OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
3716733b39aSJayamohan Kallickal 			sizeof(*req));
3726733b39aSJayamohan Kallickal 	req->ref_handle = 0;
3736733b39aSJayamohan Kallickal 	req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
3744183122dSJayamohan Kallickal 	for (i = 0; i < num_invalidate; i++) {
3754183122dSJayamohan Kallickal 		req->table[i].icd = inv_tbl->icd;
3764183122dSJayamohan Kallickal 		req->table[i].cid = inv_tbl->cid;
3774183122dSJayamohan Kallickal 		req->icd_count++;
3784183122dSJayamohan Kallickal 		inv_tbl++;
3794183122dSJayamohan Kallickal 	}
3803cbb7a74SJayamohan Kallickal 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
3813cbb7a74SJayamohan Kallickal 	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
3823cbb7a74SJayamohan Kallickal 	sge->len = cpu_to_le32(nonemb_cmd->size);
3836733b39aSJayamohan Kallickal 
384756d29c8SJayamohan Kallickal 	be_mcc_notify(phba);
3856733b39aSJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
386756d29c8SJayamohan Kallickal 	return tag;
3876733b39aSJayamohan Kallickal }
3886733b39aSJayamohan Kallickal 
38903a12310SJayamohan Kallickal unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
3906733b39aSJayamohan Kallickal 					 struct beiscsi_endpoint *beiscsi_ep,
3916733b39aSJayamohan Kallickal 					 unsigned short cid,
3926733b39aSJayamohan Kallickal 					 unsigned short issue_reset,
3936733b39aSJayamohan Kallickal 					 unsigned short savecfg_flag)
3946733b39aSJayamohan Kallickal {
3956733b39aSJayamohan Kallickal 	struct be_ctrl_info *ctrl = &phba->ctrl;
396756d29c8SJayamohan Kallickal 	struct be_mcc_wrb *wrb;
397756d29c8SJayamohan Kallickal 	struct iscsi_invalidate_connection_params_in *req;
398756d29c8SJayamohan Kallickal 	unsigned int tag = 0;
3996733b39aSJayamohan Kallickal 
4006733b39aSJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
401756d29c8SJayamohan Kallickal 	tag = alloc_mcc_tag(phba);
402756d29c8SJayamohan Kallickal 	if (!tag) {
403756d29c8SJayamohan Kallickal 		spin_unlock(&ctrl->mbox_lock);
404756d29c8SJayamohan Kallickal 		return tag;
405756d29c8SJayamohan Kallickal 	}
406756d29c8SJayamohan Kallickal 	wrb = wrb_from_mccq(phba);
407756d29c8SJayamohan Kallickal 	wrb->tag0 |= tag;
408756d29c8SJayamohan Kallickal 	req = embedded_payload(wrb);
4096733b39aSJayamohan Kallickal 
4106733b39aSJayamohan Kallickal 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
4116733b39aSJayamohan Kallickal 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
4126733b39aSJayamohan Kallickal 			   OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
4136733b39aSJayamohan Kallickal 			   sizeof(*req));
4146733b39aSJayamohan Kallickal 	req->session_handle = beiscsi_ep->fw_handle;
4156733b39aSJayamohan Kallickal 	req->cid = cid;
4166733b39aSJayamohan Kallickal 	if (issue_reset)
4176733b39aSJayamohan Kallickal 		req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST;
4186733b39aSJayamohan Kallickal 	else
4196733b39aSJayamohan Kallickal 		req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
4206733b39aSJayamohan Kallickal 	req->save_cfg = savecfg_flag;
421756d29c8SJayamohan Kallickal 	be_mcc_notify(phba);
4226733b39aSJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
423756d29c8SJayamohan Kallickal 	return tag;
4246733b39aSJayamohan Kallickal }
4256733b39aSJayamohan Kallickal 
42603a12310SJayamohan Kallickal unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
4276733b39aSJayamohan Kallickal 				unsigned short cid, unsigned int upload_flag)
4286733b39aSJayamohan Kallickal {
4296733b39aSJayamohan Kallickal 	struct be_ctrl_info *ctrl = &phba->ctrl;
430756d29c8SJayamohan Kallickal 	struct be_mcc_wrb *wrb;
431756d29c8SJayamohan Kallickal 	struct tcp_upload_params_in *req;
432756d29c8SJayamohan Kallickal 	unsigned int tag = 0;
4336733b39aSJayamohan Kallickal 
4346733b39aSJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
435756d29c8SJayamohan Kallickal 	tag = alloc_mcc_tag(phba);
436756d29c8SJayamohan Kallickal 	if (!tag) {
437756d29c8SJayamohan Kallickal 		spin_unlock(&ctrl->mbox_lock);
438756d29c8SJayamohan Kallickal 		return tag;
439756d29c8SJayamohan Kallickal 	}
440756d29c8SJayamohan Kallickal 	wrb = wrb_from_mccq(phba);
441756d29c8SJayamohan Kallickal 	req = embedded_payload(wrb);
442756d29c8SJayamohan Kallickal 	wrb->tag0 |= tag;
4436733b39aSJayamohan Kallickal 
4446733b39aSJayamohan Kallickal 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
4456733b39aSJayamohan Kallickal 	be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
4466733b39aSJayamohan Kallickal 			   OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
4476733b39aSJayamohan Kallickal 	req->id = (unsigned short)cid;
4486733b39aSJayamohan Kallickal 	req->upload_type = (unsigned char)upload_flag;
449756d29c8SJayamohan Kallickal 	be_mcc_notify(phba);
4506733b39aSJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
451756d29c8SJayamohan Kallickal 	return tag;
4526733b39aSJayamohan Kallickal }
4536733b39aSJayamohan Kallickal 
4546733b39aSJayamohan Kallickal int mgmt_open_connection(struct beiscsi_hba *phba,
4556733b39aSJayamohan Kallickal 			 struct sockaddr *dst_addr,
4563cbb7a74SJayamohan Kallickal 			 struct beiscsi_endpoint *beiscsi_ep,
4573cbb7a74SJayamohan Kallickal 			 struct be_dma_mem *nonemb_cmd)
4586733b39aSJayamohan Kallickal {
4596733b39aSJayamohan Kallickal 	struct hwi_controller *phwi_ctrlr;
4606733b39aSJayamohan Kallickal 	struct hwi_context_memory *phwi_context;
4616733b39aSJayamohan Kallickal 	struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
4626733b39aSJayamohan Kallickal 	struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
4636733b39aSJayamohan Kallickal 	struct be_ctrl_info *ctrl = &phba->ctrl;
464756d29c8SJayamohan Kallickal 	struct be_mcc_wrb *wrb;
465756d29c8SJayamohan Kallickal 	struct tcp_connect_and_offload_in *req;
4666733b39aSJayamohan Kallickal 	unsigned short def_hdr_id;
4676733b39aSJayamohan Kallickal 	unsigned short def_data_id;
4686733b39aSJayamohan Kallickal 	struct phys_addr template_address = { 0, 0 };
4696733b39aSJayamohan Kallickal 	struct phys_addr *ptemplate_address;
470756d29c8SJayamohan Kallickal 	unsigned int tag = 0;
471bfead3b2SJayamohan Kallickal 	unsigned int i;
4726733b39aSJayamohan Kallickal 	unsigned short cid = beiscsi_ep->ep_cid;
4733cbb7a74SJayamohan Kallickal 	struct be_sge *sge;
4746733b39aSJayamohan Kallickal 
4756733b39aSJayamohan Kallickal 	phwi_ctrlr = phba->phwi_ctrlr;
4766733b39aSJayamohan Kallickal 	phwi_context = phwi_ctrlr->phwi_ctxt;
4776733b39aSJayamohan Kallickal 	def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba);
4786733b39aSJayamohan Kallickal 	def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba);
4796733b39aSJayamohan Kallickal 
4806733b39aSJayamohan Kallickal 	ptemplate_address = &template_address;
4816733b39aSJayamohan Kallickal 	ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
4826733b39aSJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
483756d29c8SJayamohan Kallickal 	tag = alloc_mcc_tag(phba);
484756d29c8SJayamohan Kallickal 	if (!tag) {
485756d29c8SJayamohan Kallickal 		spin_unlock(&ctrl->mbox_lock);
486756d29c8SJayamohan Kallickal 		return tag;
487756d29c8SJayamohan Kallickal 	}
488756d29c8SJayamohan Kallickal 	wrb = wrb_from_mccq(phba);
4893cbb7a74SJayamohan Kallickal 	memset(wrb, 0, sizeof(*wrb));
4903cbb7a74SJayamohan Kallickal 	sge = nonembedded_sgl(wrb);
4913cbb7a74SJayamohan Kallickal 
4923cbb7a74SJayamohan Kallickal 	req = nonemb_cmd->va;
4933cbb7a74SJayamohan Kallickal 	memset(req, 0, sizeof(*req));
494756d29c8SJayamohan Kallickal 	wrb->tag0 |= tag;
4956733b39aSJayamohan Kallickal 
496b15d05b0SJayamohan Kallickal 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
4976733b39aSJayamohan Kallickal 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
4986733b39aSJayamohan Kallickal 			   OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
4996733b39aSJayamohan Kallickal 			   sizeof(*req));
5006733b39aSJayamohan Kallickal 	if (dst_addr->sa_family == PF_INET) {
5016733b39aSJayamohan Kallickal 		__be32 s_addr = daddr_in->sin_addr.s_addr;
5026733b39aSJayamohan Kallickal 		req->ip_address.ip_type = BE2_IPV4;
5030e43895eSMike Christie 		req->ip_address.addr[0] = s_addr & 0x000000ff;
5040e43895eSMike Christie 		req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
5050e43895eSMike Christie 		req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
5060e43895eSMike Christie 		req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
5076733b39aSJayamohan Kallickal 		req->tcp_port = ntohs(daddr_in->sin_port);
5086733b39aSJayamohan Kallickal 		beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
5096733b39aSJayamohan Kallickal 		beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
5106733b39aSJayamohan Kallickal 		beiscsi_ep->ip_type = BE2_IPV4;
5116733b39aSJayamohan Kallickal 	} else if (dst_addr->sa_family == PF_INET6) {
5126733b39aSJayamohan Kallickal 		req->ip_address.ip_type = BE2_IPV6;
5130e43895eSMike Christie 		memcpy(&req->ip_address.addr,
5146733b39aSJayamohan Kallickal 		       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
5156733b39aSJayamohan Kallickal 		req->tcp_port = ntohs(daddr_in6->sin6_port);
5166733b39aSJayamohan Kallickal 		beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
5176733b39aSJayamohan Kallickal 		memcpy(&beiscsi_ep->dst6_addr,
5186733b39aSJayamohan Kallickal 		       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
5196733b39aSJayamohan Kallickal 		beiscsi_ep->ip_type = BE2_IPV6;
5206733b39aSJayamohan Kallickal 	} else{
52199bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
52299bc5d55SJohn Soni Jose 			    "BG_%d : unknown addr family %d\n",
5236733b39aSJayamohan Kallickal 			    dst_addr->sa_family);
5246733b39aSJayamohan Kallickal 		spin_unlock(&ctrl->mbox_lock);
5255db3f33dSJayamohan Kallickal 		free_mcc_tag(&phba->ctrl, tag);
5266733b39aSJayamohan Kallickal 		return -EINVAL;
5276733b39aSJayamohan Kallickal 
5286733b39aSJayamohan Kallickal 	}
5296733b39aSJayamohan Kallickal 	req->cid = cid;
530bfead3b2SJayamohan Kallickal 	i = phba->nxt_cqid++;
531bfead3b2SJayamohan Kallickal 	if (phba->nxt_cqid == phba->num_cpus)
532bfead3b2SJayamohan Kallickal 		phba->nxt_cqid = 0;
533bfead3b2SJayamohan Kallickal 	req->cq_id = phwi_context->be_cq[i].id;
53499bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
53599bc5d55SJohn Soni Jose 		    "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
5366733b39aSJayamohan Kallickal 	req->defq_id = def_hdr_id;
5376733b39aSJayamohan Kallickal 	req->hdr_ring_id = def_hdr_id;
5386733b39aSJayamohan Kallickal 	req->data_ring_id = def_data_id;
5396733b39aSJayamohan Kallickal 	req->do_offload = 1;
5406733b39aSJayamohan Kallickal 	req->dataout_template_pa.lo = ptemplate_address->lo;
5416733b39aSJayamohan Kallickal 	req->dataout_template_pa.hi = ptemplate_address->hi;
5423cbb7a74SJayamohan Kallickal 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
5433cbb7a74SJayamohan Kallickal 	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
5443cbb7a74SJayamohan Kallickal 	sge->len = cpu_to_le32(nonemb_cmd->size);
545756d29c8SJayamohan Kallickal 	be_mcc_notify(phba);
5466733b39aSJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
547756d29c8SJayamohan Kallickal 	return tag;
5486733b39aSJayamohan Kallickal }
549bfead3b2SJayamohan Kallickal 
5500e43895eSMike Christie unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
551bfead3b2SJayamohan Kallickal {
552bfead3b2SJayamohan Kallickal 	struct be_ctrl_info *ctrl = &phba->ctrl;
5530e43895eSMike Christie 	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
5540e43895eSMike Christie 	struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
5550e43895eSMike Christie 	struct be_cmd_get_all_if_id_req *pbe_allid = req;
5560e43895eSMike Christie 	int status = 0;
557bfead3b2SJayamohan Kallickal 
5580e43895eSMike Christie 	memset(wrb, 0, sizeof(*wrb));
5590e43895eSMike Christie 
5600e43895eSMike Christie 	spin_lock(&ctrl->mbox_lock);
5610e43895eSMike Christie 
5620e43895eSMike Christie 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
5630e43895eSMike Christie 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
5640e43895eSMike Christie 			   OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
5650e43895eSMike Christie 			   sizeof(*req));
5660e43895eSMike Christie 	status = be_mbox_notify(ctrl);
5670e43895eSMike Christie 	if (!status)
5680e43895eSMike Christie 		phba->interface_handle = pbe_allid->if_hndl_list[0];
5690e43895eSMike Christie 	else {
57099bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
57199bc5d55SJohn Soni Jose 			    "BG_%d : Failed in mgmt_get_all_if_id\n");
5720e43895eSMike Christie 	}
5730e43895eSMike Christie 	spin_unlock(&ctrl->mbox_lock);
5740e43895eSMike Christie 
5750e43895eSMike Christie 	return status;
5760e43895eSMike Christie }
5770e43895eSMike Christie 
5780e43895eSMike Christie static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
5790e43895eSMike Christie 				struct be_dma_mem *nonemb_cmd, void *resp_buf,
5800e43895eSMike Christie 				int resp_buf_len)
5810e43895eSMike Christie {
5820e43895eSMike Christie 	struct be_ctrl_info *ctrl = &phba->ctrl;
5830e43895eSMike Christie 	struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
5840e43895eSMike Christie 	unsigned short status, extd_status;
5850e43895eSMike Christie 	struct be_sge *sge;
5860e43895eSMike Christie 	unsigned int tag;
5870e43895eSMike Christie 	int rc = 0;
5880e43895eSMike Christie 
589bfead3b2SJayamohan Kallickal 	spin_lock(&ctrl->mbox_lock);
590756d29c8SJayamohan Kallickal 	tag = alloc_mcc_tag(phba);
591756d29c8SJayamohan Kallickal 	if (!tag) {
592756d29c8SJayamohan Kallickal 		spin_unlock(&ctrl->mbox_lock);
5930e43895eSMike Christie 		rc = -ENOMEM;
5940e43895eSMike Christie 		goto free_cmd;
595756d29c8SJayamohan Kallickal 	}
5960e43895eSMike Christie 	memset(wrb, 0, sizeof(*wrb));
597756d29c8SJayamohan Kallickal 	wrb->tag0 |= tag;
5980e43895eSMike Christie 	sge = nonembedded_sgl(wrb);
5990e43895eSMike Christie 
6000e43895eSMike Christie 	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
6010e43895eSMike Christie 	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
6020e43895eSMike Christie 	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
6030e43895eSMike Christie 	sge->len = cpu_to_le32(nonemb_cmd->size);
604bfead3b2SJayamohan Kallickal 
605756d29c8SJayamohan Kallickal 	be_mcc_notify(phba);
606bfead3b2SJayamohan Kallickal 	spin_unlock(&ctrl->mbox_lock);
6070e43895eSMike Christie 
6080e43895eSMike Christie 	wait_event_interruptible(phba->ctrl.mcc_wait[tag],
6090e43895eSMike Christie 				 phba->ctrl.mcc_numtag[tag]);
6100e43895eSMike Christie 
6110e43895eSMike Christie 	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
6120e43895eSMike Christie 	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
6130e43895eSMike Christie 	if (status || extd_status) {
61499bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR,
61599bc5d55SJohn Soni Jose 			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
61699bc5d55SJohn Soni Jose 			    "BG_%d : mgmt_exec_nonemb_cmd Failed status = %d"
6170e43895eSMike Christie 			    "extd_status = %d\n", status, extd_status);
6180e43895eSMike Christie 		rc = -EIO;
6190e43895eSMike Christie 		goto free_tag;
620bfead3b2SJayamohan Kallickal 	}
621bfead3b2SJayamohan Kallickal 
6220e43895eSMike Christie 	if (resp_buf)
6230e43895eSMike Christie 		memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
6240e43895eSMike Christie 
6250e43895eSMike Christie free_tag:
6260e43895eSMike Christie 	free_mcc_tag(&phba->ctrl, tag);
6270e43895eSMike Christie free_cmd:
6280e43895eSMike Christie 	pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
6290e43895eSMike Christie 			    nonemb_cmd->va, nonemb_cmd->dma);
6300e43895eSMike Christie 	return rc;
6310e43895eSMike Christie }
6320e43895eSMike Christie 
6330e43895eSMike Christie static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
6340e43895eSMike Christie 			       int iscsi_cmd, int size)
6350e43895eSMike Christie {
636b83d543fSMike Christie 	cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
6370e43895eSMike Christie 	if (!cmd->va) {
63899bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
63999bc5d55SJohn Soni Jose 			    "BG_%d : Failed to allocate memory for if info\n");
6400e43895eSMike Christie 		return -ENOMEM;
6410e43895eSMike Christie 	}
642b83d543fSMike Christie 	memset(cmd->va, 0, size);
6430e43895eSMike Christie 	cmd->size = size;
6440e43895eSMike Christie 	be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
6450e43895eSMike Christie 	return 0;
6460e43895eSMike Christie }
6470e43895eSMike Christie 
6480e43895eSMike Christie static int
6490e43895eSMike Christie mgmt_static_ip_modify(struct beiscsi_hba *phba,
6500e43895eSMike Christie 		      struct be_cmd_get_if_info_resp *if_info,
6510e43895eSMike Christie 		      struct iscsi_iface_param_info *ip_param,
6520e43895eSMike Christie 		      struct iscsi_iface_param_info *subnet_param,
6530e43895eSMike Christie 		      uint32_t ip_action)
6540e43895eSMike Christie {
6550e43895eSMike Christie 	struct be_cmd_set_ip_addr_req *req;
6560e43895eSMike Christie 	struct be_dma_mem nonemb_cmd;
6570e43895eSMike Christie 	uint32_t ip_type;
6580e43895eSMike Christie 	int rc;
6590e43895eSMike Christie 
6600e43895eSMike Christie 	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
6610e43895eSMike Christie 				 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
6620e43895eSMike Christie 				 sizeof(*req));
6630e43895eSMike Christie 	if (rc)
6640e43895eSMike Christie 		return rc;
6650e43895eSMike Christie 
6660e43895eSMike Christie 	ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
6670e43895eSMike Christie 		BE2_IPV6 : BE2_IPV4 ;
6680e43895eSMike Christie 
6690e43895eSMike Christie 	req = nonemb_cmd.va;
6700e43895eSMike Christie 	req->ip_params.record_entry_count = 1;
6710e43895eSMike Christie 	req->ip_params.ip_record.action = ip_action;
6720e43895eSMike Christie 	req->ip_params.ip_record.interface_hndl =
6730e43895eSMike Christie 		phba->interface_handle;
6740e43895eSMike Christie 	req->ip_params.ip_record.ip_addr.size_of_structure =
6750e43895eSMike Christie 		sizeof(struct be_ip_addr_subnet_format);
6760e43895eSMike Christie 	req->ip_params.ip_record.ip_addr.ip_type = ip_type;
6770e43895eSMike Christie 
6780e43895eSMike Christie 	if (ip_action == IP_ACTION_ADD) {
6790e43895eSMike Christie 		memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
6800e43895eSMike Christie 		       ip_param->len);
6810e43895eSMike Christie 
6820e43895eSMike Christie 		if (subnet_param)
6830e43895eSMike Christie 			memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
6840e43895eSMike Christie 			       subnet_param->value, subnet_param->len);
6850e43895eSMike Christie 	} else {
6860e43895eSMike Christie 		memcpy(req->ip_params.ip_record.ip_addr.addr,
6870e43895eSMike Christie 		       if_info->ip_addr.addr, ip_param->len);
6880e43895eSMike Christie 
6890e43895eSMike Christie 		memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
6900e43895eSMike Christie 		       if_info->ip_addr.subnet_mask, ip_param->len);
6910e43895eSMike Christie 	}
6920e43895eSMike Christie 
6930e43895eSMike Christie 	rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
6940e43895eSMike Christie 	if (rc < 0)
69599bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
69699bc5d55SJohn Soni Jose 			    "BG_%d : Failed to Modify existing IP Address\n");
6970e43895eSMike Christie 	return rc;
6980e43895eSMike Christie }
6990e43895eSMike Christie 
7000e43895eSMike Christie static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
7010e43895eSMike Christie 			       uint32_t gtway_action, uint32_t param_len)
7020e43895eSMike Christie {
7030e43895eSMike Christie 	struct be_cmd_set_def_gateway_req *req;
7040e43895eSMike Christie 	struct be_dma_mem nonemb_cmd;
7050e43895eSMike Christie 	int rt_val;
7060e43895eSMike Christie 
7070e43895eSMike Christie 
7080e43895eSMike Christie 	rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
7090e43895eSMike Christie 				OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
7100e43895eSMike Christie 				sizeof(*req));
7110e43895eSMike Christie 	if (rt_val)
7120e43895eSMike Christie 		return rt_val;
7130e43895eSMike Christie 
7140e43895eSMike Christie 	req = nonemb_cmd.va;
7150e43895eSMike Christie 	req->action = gtway_action;
7160e43895eSMike Christie 	req->ip_addr.ip_type = BE2_IPV4;
7170e43895eSMike Christie 
7180e43895eSMike Christie 	memcpy(req->ip_addr.addr, gt_addr, param_len);
7190e43895eSMike Christie 
7200e43895eSMike Christie 	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
7210e43895eSMike Christie }
7220e43895eSMike Christie 
7230e43895eSMike Christie int mgmt_set_ip(struct beiscsi_hba *phba,
7240e43895eSMike Christie 		struct iscsi_iface_param_info *ip_param,
7250e43895eSMike Christie 		struct iscsi_iface_param_info *subnet_param,
7260e43895eSMike Christie 		uint32_t boot_proto)
7270e43895eSMike Christie {
7280e43895eSMike Christie 	struct be_cmd_get_def_gateway_resp gtway_addr_set;
7290e43895eSMike Christie 	struct be_cmd_get_if_info_resp if_info;
7300e43895eSMike Christie 	struct be_cmd_set_dhcp_req *dhcpreq;
7310e43895eSMike Christie 	struct be_cmd_rel_dhcp_req *reldhcp;
7320e43895eSMike Christie 	struct be_dma_mem nonemb_cmd;
7330e43895eSMike Christie 	uint8_t *gtway_addr;
7340e43895eSMike Christie 	uint32_t ip_type;
7350e43895eSMike Christie 	int rc;
7360e43895eSMike Christie 
7370e43895eSMike Christie 	if (mgmt_get_all_if_id(phba))
7380e43895eSMike Christie 		return -EIO;
7390e43895eSMike Christie 
7400e43895eSMike Christie 	memset(&if_info, 0, sizeof(if_info));
7410e43895eSMike Christie 	ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
7420e43895eSMike Christie 		BE2_IPV6 : BE2_IPV4 ;
7430e43895eSMike Christie 
7440e43895eSMike Christie 	rc = mgmt_get_if_info(phba, ip_type, &if_info);
7450e43895eSMike Christie 	if (rc)
7460e43895eSMike Christie 		return rc;
7470e43895eSMike Christie 
7480e43895eSMike Christie 	if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
7490e43895eSMike Christie 		if (if_info.dhcp_state) {
75099bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
75199bc5d55SJohn Soni Jose 				    "BG_%d : DHCP Already Enabled\n");
7520e43895eSMike Christie 			return 0;
7530e43895eSMike Christie 		}
7540e43895eSMike Christie 		/* The ip_param->len is 1 in DHCP case. Setting
7550e43895eSMike Christie 		   proper IP len as this it is used while
7560e43895eSMike Christie 		   freeing the Static IP.
7570e43895eSMike Christie 		 */
7580e43895eSMike Christie 		ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
7590e43895eSMike Christie 				IP_V6_LEN : IP_V4_LEN;
7600e43895eSMike Christie 
7610e43895eSMike Christie 	} else {
7620e43895eSMike Christie 		if (if_info.dhcp_state) {
7630e43895eSMike Christie 
7640e43895eSMike Christie 			memset(&if_info, 0, sizeof(if_info));
7650e43895eSMike Christie 			rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
7660e43895eSMike Christie 				OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
7670e43895eSMike Christie 				sizeof(*reldhcp));
7680e43895eSMike Christie 
7690e43895eSMike Christie 			if (rc)
7700e43895eSMike Christie 				return rc;
7710e43895eSMike Christie 
7720e43895eSMike Christie 			reldhcp = nonemb_cmd.va;
7730e43895eSMike Christie 			reldhcp->interface_hndl = phba->interface_handle;
7740e43895eSMike Christie 			reldhcp->ip_type = ip_type;
7750e43895eSMike Christie 
7760e43895eSMike Christie 			rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
7770e43895eSMike Christie 			if (rc < 0) {
77899bc5d55SJohn Soni Jose 				beiscsi_log(phba, KERN_WARNING,
77999bc5d55SJohn Soni Jose 					    BEISCSI_LOG_CONFIG,
78099bc5d55SJohn Soni Jose 					    "BG_%d : Failed to Delete existing dhcp\n");
7810e43895eSMike Christie 				return rc;
7820e43895eSMike Christie 			}
7830e43895eSMike Christie 		}
7840e43895eSMike Christie 	}
7850e43895eSMike Christie 
7860e43895eSMike Christie 	/* Delete the Static IP Set */
7870e43895eSMike Christie 	if (if_info.ip_addr.addr[0]) {
7880e43895eSMike Christie 		rc = mgmt_static_ip_modify(phba, &if_info, ip_param, NULL,
7890e43895eSMike Christie 					   IP_ACTION_DEL);
7900e43895eSMike Christie 		if (rc)
7910e43895eSMike Christie 			return rc;
7920e43895eSMike Christie 	}
7930e43895eSMike Christie 
7940e43895eSMike Christie 	/* Delete the Gateway settings if mode change is to DHCP */
7950e43895eSMike Christie 	if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
7960e43895eSMike Christie 		memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
7970e43895eSMike Christie 		rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
7980e43895eSMike Christie 		if (rc) {
79999bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
80099bc5d55SJohn Soni Jose 				    "BG_%d : Failed to Get Gateway Addr\n");
8010e43895eSMike Christie 			return rc;
8020e43895eSMike Christie 		}
8030e43895eSMike Christie 
8040e43895eSMike Christie 		if (gtway_addr_set.ip_addr.addr[0]) {
8050e43895eSMike Christie 			gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
8060e43895eSMike Christie 			rc = mgmt_modify_gateway(phba, gtway_addr,
8070e43895eSMike Christie 						 IP_ACTION_DEL, IP_V4_LEN);
8080e43895eSMike Christie 
8090e43895eSMike Christie 			if (rc) {
81099bc5d55SJohn Soni Jose 				beiscsi_log(phba, KERN_WARNING,
81199bc5d55SJohn Soni Jose 					    BEISCSI_LOG_CONFIG,
81299bc5d55SJohn Soni Jose 					    "BG_%d : Failed to clear Gateway Addr Set\n");
8130e43895eSMike Christie 				return rc;
8140e43895eSMike Christie 			}
8150e43895eSMike Christie 		}
8160e43895eSMike Christie 	}
8170e43895eSMike Christie 
8180e43895eSMike Christie 	/* Set Adapter to DHCP/Static Mode */
8190e43895eSMike Christie 	if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
8200e43895eSMike Christie 		rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
8210e43895eSMike Christie 			OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
8220e43895eSMike Christie 			sizeof(*dhcpreq));
8230e43895eSMike Christie 		if (rc)
8240e43895eSMike Christie 			return rc;
8250e43895eSMike Christie 
8260e43895eSMike Christie 		dhcpreq = nonemb_cmd.va;
8270e43895eSMike Christie 		dhcpreq->flags = BLOCKING;
8280e43895eSMike Christie 		dhcpreq->retry_count = 1;
8290e43895eSMike Christie 		dhcpreq->interface_hndl = phba->interface_handle;
8300e43895eSMike Christie 		dhcpreq->ip_type = BE2_DHCP_V4;
8310e43895eSMike Christie 
8320e43895eSMike Christie 		return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
8330e43895eSMike Christie 	} else {
8340e43895eSMike Christie 		return mgmt_static_ip_modify(phba, &if_info, ip_param,
8350e43895eSMike Christie 					     subnet_param, IP_ACTION_ADD);
8360e43895eSMike Christie 	}
8370e43895eSMike Christie 
8380e43895eSMike Christie 	return rc;
8390e43895eSMike Christie }
8400e43895eSMike Christie 
8410e43895eSMike Christie int mgmt_set_gateway(struct beiscsi_hba *phba,
8420e43895eSMike Christie 		     struct iscsi_iface_param_info *gateway_param)
8430e43895eSMike Christie {
8440e43895eSMike Christie 	struct be_cmd_get_def_gateway_resp gtway_addr_set;
8450e43895eSMike Christie 	uint8_t *gtway_addr;
8460e43895eSMike Christie 	int rt_val;
8470e43895eSMike Christie 
8480e43895eSMike Christie 	memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
8490e43895eSMike Christie 	rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
8500e43895eSMike Christie 	if (rt_val) {
85199bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
85299bc5d55SJohn Soni Jose 			    "BG_%d : Failed to Get Gateway Addr\n");
8530e43895eSMike Christie 		return rt_val;
8540e43895eSMike Christie 	}
8550e43895eSMike Christie 
8560e43895eSMike Christie 	if (gtway_addr_set.ip_addr.addr[0]) {
8570e43895eSMike Christie 		gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
8580e43895eSMike Christie 		rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
8590e43895eSMike Christie 					     gateway_param->len);
8600e43895eSMike Christie 		if (rt_val) {
86199bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
86299bc5d55SJohn Soni Jose 				    "BG_%d : Failed to clear Gateway Addr Set\n");
8630e43895eSMike Christie 			return rt_val;
8640e43895eSMike Christie 		}
8650e43895eSMike Christie 	}
8660e43895eSMike Christie 
8670e43895eSMike Christie 	gtway_addr = (uint8_t *)&gateway_param->value;
8680e43895eSMike Christie 	rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
8690e43895eSMike Christie 				     gateway_param->len);
8700e43895eSMike Christie 
8710e43895eSMike Christie 	if (rt_val)
87299bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
87399bc5d55SJohn Soni Jose 			    "BG_%d : Failed to Set Gateway Addr\n");
8740e43895eSMike Christie 
8750e43895eSMike Christie 	return rt_val;
8760e43895eSMike Christie }
8770e43895eSMike Christie 
8780e43895eSMike Christie int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
8790e43895eSMike Christie 		     struct be_cmd_get_def_gateway_resp *gateway)
8800e43895eSMike Christie {
8810e43895eSMike Christie 	struct be_cmd_get_def_gateway_req *req;
8820e43895eSMike Christie 	struct be_dma_mem nonemb_cmd;
8830e43895eSMike Christie 	int rc;
8840e43895eSMike Christie 
8850e43895eSMike Christie 	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
8860e43895eSMike Christie 				 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
8870e43895eSMike Christie 				 sizeof(*gateway));
8880e43895eSMike Christie 	if (rc)
8890e43895eSMike Christie 		return rc;
8900e43895eSMike Christie 
8910e43895eSMike Christie 	req = nonemb_cmd.va;
8920e43895eSMike Christie 	req->ip_type = ip_type;
8930e43895eSMike Christie 
8940e43895eSMike Christie 	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
8950e43895eSMike Christie 				    sizeof(*gateway));
8960e43895eSMike Christie }
8970e43895eSMike Christie 
8980e43895eSMike Christie int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
8990e43895eSMike Christie 		     struct be_cmd_get_if_info_resp *if_info)
9000e43895eSMike Christie {
9010e43895eSMike Christie 	struct be_cmd_get_if_info_req *req;
9020e43895eSMike Christie 	struct be_dma_mem nonemb_cmd;
9030e43895eSMike Christie 	int rc;
9040e43895eSMike Christie 
9050e43895eSMike Christie 	if (mgmt_get_all_if_id(phba))
9060e43895eSMike Christie 		return -EIO;
9070e43895eSMike Christie 
9080e43895eSMike Christie 	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
9090e43895eSMike Christie 				 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
9100e43895eSMike Christie 				 sizeof(*if_info));
9110e43895eSMike Christie 	if (rc)
9120e43895eSMike Christie 		return rc;
9130e43895eSMike Christie 
9140e43895eSMike Christie 	req = nonemb_cmd.va;
9150e43895eSMike Christie 	req->interface_hndl = phba->interface_handle;
9160e43895eSMike Christie 	req->ip_type = ip_type;
9170e43895eSMike Christie 
9180e43895eSMike Christie 	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, if_info,
9190e43895eSMike Christie 				    sizeof(*if_info));
9200e43895eSMike Christie }
9210e43895eSMike Christie 
9220e43895eSMike Christie int mgmt_get_nic_conf(struct beiscsi_hba *phba,
9230e43895eSMike Christie 		      struct be_cmd_get_nic_conf_resp *nic)
9240e43895eSMike Christie {
9250e43895eSMike Christie 	struct be_dma_mem nonemb_cmd;
9260e43895eSMike Christie 	int rc;
9270e43895eSMike Christie 
9280e43895eSMike Christie 	rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
9290e43895eSMike Christie 				 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
9300e43895eSMike Christie 				 sizeof(*nic));
9310e43895eSMike Christie 	if (rc)
9320e43895eSMike Christie 		return rc;
9330e43895eSMike Christie 
9340e43895eSMike Christie 	return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
9350e43895eSMike Christie }
9360e43895eSMike Christie 
9370e43895eSMike Christie 
9380e43895eSMike Christie 
9392177199dSJohn Soni Jose unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
9402177199dSJohn Soni Jose {
9412177199dSJohn Soni Jose 	unsigned int tag = 0;
9422177199dSJohn Soni Jose 	struct be_mcc_wrb *wrb;
9432177199dSJohn Soni Jose 	struct be_cmd_hba_name *req;
9442177199dSJohn Soni Jose 	struct be_ctrl_info *ctrl = &phba->ctrl;
9452177199dSJohn Soni Jose 
9462177199dSJohn Soni Jose 	spin_lock(&ctrl->mbox_lock);
9472177199dSJohn Soni Jose 	tag = alloc_mcc_tag(phba);
9482177199dSJohn Soni Jose 	if (!tag) {
9492177199dSJohn Soni Jose 		spin_unlock(&ctrl->mbox_lock);
9502177199dSJohn Soni Jose 		return tag;
9512177199dSJohn Soni Jose 	}
9522177199dSJohn Soni Jose 
9532177199dSJohn Soni Jose 	wrb = wrb_from_mccq(phba);
9542177199dSJohn Soni Jose 	req = embedded_payload(wrb);
9552177199dSJohn Soni Jose 	wrb->tag0 |= tag;
9562177199dSJohn Soni Jose 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
9572177199dSJohn Soni Jose 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
9582177199dSJohn Soni Jose 			OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
9592177199dSJohn Soni Jose 			sizeof(*req));
9602177199dSJohn Soni Jose 
9612177199dSJohn Soni Jose 	be_mcc_notify(phba);
9622177199dSJohn Soni Jose 	spin_unlock(&ctrl->mbox_lock);
9632177199dSJohn Soni Jose 	return tag;
9642177199dSJohn Soni Jose }
965c62eef0dSJohn Soni Jose 
966c62eef0dSJohn Soni Jose unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
967c62eef0dSJohn Soni Jose {
968c62eef0dSJohn Soni Jose 	unsigned int tag = 0;
969c62eef0dSJohn Soni Jose 	struct be_mcc_wrb *wrb;
970c62eef0dSJohn Soni Jose 	struct be_cmd_ntwk_link_status_req *req;
971c62eef0dSJohn Soni Jose 	struct be_ctrl_info *ctrl = &phba->ctrl;
972c62eef0dSJohn Soni Jose 
973c62eef0dSJohn Soni Jose 	spin_lock(&ctrl->mbox_lock);
974c62eef0dSJohn Soni Jose 	tag = alloc_mcc_tag(phba);
975c62eef0dSJohn Soni Jose 	if (!tag) {
976c62eef0dSJohn Soni Jose 		spin_unlock(&ctrl->mbox_lock);
977c62eef0dSJohn Soni Jose 		return tag;
978c62eef0dSJohn Soni Jose 	}
979c62eef0dSJohn Soni Jose 
980c62eef0dSJohn Soni Jose 	wrb = wrb_from_mccq(phba);
981c62eef0dSJohn Soni Jose 	req = embedded_payload(wrb);
982c62eef0dSJohn Soni Jose 	wrb->tag0 |= tag;
983c62eef0dSJohn Soni Jose 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
984c62eef0dSJohn Soni Jose 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
985c62eef0dSJohn Soni Jose 			OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
986c62eef0dSJohn Soni Jose 			sizeof(*req));
987c62eef0dSJohn Soni Jose 
988c62eef0dSJohn Soni Jose 	be_mcc_notify(phba);
989c62eef0dSJohn Soni Jose 	spin_unlock(&ctrl->mbox_lock);
990c62eef0dSJohn Soni Jose 	return tag;
991c62eef0dSJohn Soni Jose }
9929aef4200SJohn Soni Jose 
9939aef4200SJohn Soni Jose /**
9949aef4200SJohn Soni Jose  * be_mgmt_get_boot_shandle()- Get the session handle
9959aef4200SJohn Soni Jose  * @phba: device priv structure instance
9969aef4200SJohn Soni Jose  * @s_handle: session handle returned for boot session.
9979aef4200SJohn Soni Jose  *
9989aef4200SJohn Soni Jose  * Get the boot target session handle. In case of
9999aef4200SJohn Soni Jose  * crashdump mode driver has to issue and MBX Cmd
10009aef4200SJohn Soni Jose  * for FW to login to boot target
10019aef4200SJohn Soni Jose  *
10029aef4200SJohn Soni Jose  * return
10039aef4200SJohn Soni Jose  *	Success: 0
10049aef4200SJohn Soni Jose  *	Failure: Non-Zero value
10059aef4200SJohn Soni Jose  *
10069aef4200SJohn Soni Jose  **/
10079aef4200SJohn Soni Jose int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
10089aef4200SJohn Soni Jose 			      unsigned int *s_handle)
10099aef4200SJohn Soni Jose {
10109aef4200SJohn Soni Jose 	struct be_cmd_get_boot_target_resp *boot_resp;
10119aef4200SJohn Soni Jose 	struct be_mcc_wrb *wrb;
10129aef4200SJohn Soni Jose 	unsigned int tag, wrb_num;
10139aef4200SJohn Soni Jose 	uint8_t boot_retry = 3;
10149aef4200SJohn Soni Jose 	unsigned short status, extd_status;
10159aef4200SJohn Soni Jose 	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
10169aef4200SJohn Soni Jose 
10179aef4200SJohn Soni Jose 	do {
10189aef4200SJohn Soni Jose 		/* Get the Boot Target Session Handle and Count*/
10199aef4200SJohn Soni Jose 		tag = mgmt_get_boot_target(phba);
10209aef4200SJohn Soni Jose 		if (!tag) {
102199bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_ERR,
102299bc5d55SJohn Soni Jose 				    BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
102399bc5d55SJohn Soni Jose 				    "BG_%d : Getting Boot Target Info Failed\n");
10249aef4200SJohn Soni Jose 			return -EAGAIN;
10259aef4200SJohn Soni Jose 		} else
10269aef4200SJohn Soni Jose 			wait_event_interruptible(phba->ctrl.mcc_wait[tag],
10279aef4200SJohn Soni Jose 						 phba->ctrl.mcc_numtag[tag]);
10289aef4200SJohn Soni Jose 
10299aef4200SJohn Soni Jose 		wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
10309aef4200SJohn Soni Jose 		extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
10319aef4200SJohn Soni Jose 		status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
10329aef4200SJohn Soni Jose 		if (status || extd_status) {
103399bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_ERR,
103499bc5d55SJohn Soni Jose 				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
103599bc5d55SJohn Soni Jose 				    "BG_%d : mgmt_get_boot_target Failed"
10369aef4200SJohn Soni Jose 				    " status = %d extd_status = %d\n",
10379aef4200SJohn Soni Jose 				    status, extd_status);
10389aef4200SJohn Soni Jose 			free_mcc_tag(&phba->ctrl, tag);
10399aef4200SJohn Soni Jose 			return -EBUSY;
10409aef4200SJohn Soni Jose 		}
10419aef4200SJohn Soni Jose 		wrb = queue_get_wrb(mccq, wrb_num);
10429aef4200SJohn Soni Jose 		free_mcc_tag(&phba->ctrl, tag);
10439aef4200SJohn Soni Jose 		boot_resp = embedded_payload(wrb);
10449aef4200SJohn Soni Jose 
10459aef4200SJohn Soni Jose 		/* Check if the there are any Boot targets configured */
10469aef4200SJohn Soni Jose 		if (!boot_resp->boot_session_count) {
104799bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_INFO,
104899bc5d55SJohn Soni Jose 				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
104999bc5d55SJohn Soni Jose 				    "BG_%d  ;No boot targets configured\n");
10509aef4200SJohn Soni Jose 			return -ENXIO;
10519aef4200SJohn Soni Jose 		}
10529aef4200SJohn Soni Jose 
10539aef4200SJohn Soni Jose 		/* FW returns the session handle of the boot session */
10549aef4200SJohn Soni Jose 		if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
10559aef4200SJohn Soni Jose 			*s_handle = boot_resp->boot_session_handle;
10569aef4200SJohn Soni Jose 			return 0;
10579aef4200SJohn Soni Jose 		}
10589aef4200SJohn Soni Jose 
10599aef4200SJohn Soni Jose 		/* Issue MBX Cmd to FW to login to the boot target */
10609aef4200SJohn Soni Jose 		tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
10619aef4200SJohn Soni Jose 					  INVALID_SESS_HANDLE);
10629aef4200SJohn Soni Jose 		if (!tag) {
106399bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_ERR,
106499bc5d55SJohn Soni Jose 				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
106599bc5d55SJohn Soni Jose 				    "BG_%d : mgmt_reopen_session Failed\n");
10669aef4200SJohn Soni Jose 			return -EAGAIN;
10679aef4200SJohn Soni Jose 		} else
10689aef4200SJohn Soni Jose 			wait_event_interruptible(phba->ctrl.mcc_wait[tag],
10699aef4200SJohn Soni Jose 						 phba->ctrl.mcc_numtag[tag]);
10709aef4200SJohn Soni Jose 
10719aef4200SJohn Soni Jose 		wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
10729aef4200SJohn Soni Jose 		extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
10739aef4200SJohn Soni Jose 		status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
10749aef4200SJohn Soni Jose 		if (status || extd_status) {
107599bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_ERR,
107699bc5d55SJohn Soni Jose 				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
107799bc5d55SJohn Soni Jose 				    "BG_%d : mgmt_reopen_session Failed"
10789aef4200SJohn Soni Jose 				    " status = %d extd_status = %d\n",
10799aef4200SJohn Soni Jose 				    status, extd_status);
10809aef4200SJohn Soni Jose 			free_mcc_tag(&phba->ctrl, tag);
10819aef4200SJohn Soni Jose 			return -EBUSY;
10829aef4200SJohn Soni Jose 		}
10839aef4200SJohn Soni Jose 		free_mcc_tag(&phba->ctrl, tag);
10849aef4200SJohn Soni Jose 
10859aef4200SJohn Soni Jose 	} while (--boot_retry);
10869aef4200SJohn Soni Jose 
10879aef4200SJohn Soni Jose 	/* Couldn't log into the boot target */
108899bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_ERR,
108999bc5d55SJohn Soni Jose 		    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
109099bc5d55SJohn Soni Jose 		    "BG_%d : Login to Boot Target Failed\n");
10919aef4200SJohn Soni Jose 	return -ENXIO;
10929aef4200SJohn Soni Jose }
10936f72238eSJohn Soni Jose 
10946f72238eSJohn Soni Jose /**
10956f72238eSJohn Soni Jose  * mgmt_set_vlan()- Issue and wait for CMD completion
10966f72238eSJohn Soni Jose  * @phba: device private structure instance
10976f72238eSJohn Soni Jose  * @vlan_tag: VLAN tag
10986f72238eSJohn Soni Jose  *
10996f72238eSJohn Soni Jose  * Issue the MBX Cmd and wait for the completion of the
11006f72238eSJohn Soni Jose  * command.
11016f72238eSJohn Soni Jose  *
11026f72238eSJohn Soni Jose  * returns
11036f72238eSJohn Soni Jose  *	Success: 0
11046f72238eSJohn Soni Jose  *	Failure: Non-Xero Value
11056f72238eSJohn Soni Jose  **/
11066f72238eSJohn Soni Jose int mgmt_set_vlan(struct beiscsi_hba *phba,
11076f72238eSJohn Soni Jose 		   uint16_t vlan_tag)
11086f72238eSJohn Soni Jose {
11096f72238eSJohn Soni Jose 	unsigned int tag, wrb_num;
11106f72238eSJohn Soni Jose 	unsigned short status, extd_status;
11116f72238eSJohn Soni Jose 
11126f72238eSJohn Soni Jose 	tag = be_cmd_set_vlan(phba, vlan_tag);
11136f72238eSJohn Soni Jose 	if (!tag) {
11146f72238eSJohn Soni Jose 		beiscsi_log(phba, KERN_ERR,
11156f72238eSJohn Soni Jose 			    (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
11166f72238eSJohn Soni Jose 			    "BG_%d : VLAN Setting Failed\n");
11176f72238eSJohn Soni Jose 		return -EBUSY;
11186f72238eSJohn Soni Jose 	} else
11196f72238eSJohn Soni Jose 		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
11206f72238eSJohn Soni Jose 					 phba->ctrl.mcc_numtag[tag]);
11216f72238eSJohn Soni Jose 
11226f72238eSJohn Soni Jose 	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
11236f72238eSJohn Soni Jose 	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
11246f72238eSJohn Soni Jose 	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
11256f72238eSJohn Soni Jose 
11266f72238eSJohn Soni Jose 	if (status || extd_status) {
11276f72238eSJohn Soni Jose 		beiscsi_log(phba, KERN_ERR,
11286f72238eSJohn Soni Jose 			    (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
11296f72238eSJohn Soni Jose 			    "BS_%d : status : %d extd_status : %d\n",
11306f72238eSJohn Soni Jose 			    status, extd_status);
11316f72238eSJohn Soni Jose 
11326f72238eSJohn Soni Jose 		free_mcc_tag(&phba->ctrl, tag);
11336f72238eSJohn Soni Jose 		return -EAGAIN;
11346f72238eSJohn Soni Jose 	}
11356f72238eSJohn Soni Jose 
11366f72238eSJohn Soni Jose 	free_mcc_tag(&phba->ctrl, tag);
11376f72238eSJohn Soni Jose 	return 0;
11386f72238eSJohn Soni Jose }
11395cac7596SJohn Soni Jose 
11405cac7596SJohn Soni Jose /**
11415cac7596SJohn Soni Jose  * beiscsi_drvr_ver_disp()- Display the driver Name and Version
11425cac7596SJohn Soni Jose  * @dev: ptr to device not used.
11435cac7596SJohn Soni Jose  * @attr: device attribute, not used.
11445cac7596SJohn Soni Jose  * @buf: contains formatted text driver name and version
11455cac7596SJohn Soni Jose  *
11465cac7596SJohn Soni Jose  * return
11475cac7596SJohn Soni Jose  * size of the formatted string
11485cac7596SJohn Soni Jose  **/
11495cac7596SJohn Soni Jose ssize_t
11505cac7596SJohn Soni Jose beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
11515cac7596SJohn Soni Jose 		       char *buf)
11525cac7596SJohn Soni Jose {
11535cac7596SJohn Soni Jose 	return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
11545cac7596SJohn Soni Jose }
1155*acb9693cSJohn Soni Jose 
1156*acb9693cSJohn Soni Jose void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1157*acb9693cSJohn Soni Jose 			     struct wrb_handle *pwrb_handle,
1158*acb9693cSJohn Soni Jose 			     struct be_mem_descriptor *mem_descr)
1159*acb9693cSJohn Soni Jose {
1160*acb9693cSJohn Soni Jose 	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1161*acb9693cSJohn Soni Jose 
1162*acb9693cSJohn Soni Jose 	memset(pwrb, 0, sizeof(*pwrb));
1163*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1164*acb9693cSJohn Soni Jose 		      max_send_data_segment_length, pwrb,
1165*acb9693cSJohn Soni Jose 		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1166*acb9693cSJohn Soni Jose 		      max_send_data_segment_length) / 32]);
1167*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1168*acb9693cSJohn Soni Jose 		      BE_TGT_CTX_UPDT_CMD);
1169*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1170*acb9693cSJohn Soni Jose 		      first_burst_length,
1171*acb9693cSJohn Soni Jose 		      pwrb,
1172*acb9693cSJohn Soni Jose 		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1173*acb9693cSJohn Soni Jose 		      first_burst_length) / 32]);
1174*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1175*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1176*acb9693cSJohn Soni Jose 		      erl) / 32] & OFFLD_PARAMS_ERL));
1177*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1178*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1179*acb9693cSJohn Soni Jose 		       dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1180*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1181*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1182*acb9693cSJohn Soni Jose 		      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1183*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1184*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1185*acb9693cSJohn Soni Jose 		      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1186*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1187*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1188*acb9693cSJohn Soni Jose 		      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1189*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1190*acb9693cSJohn Soni Jose 		      pwrb,
1191*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1192*acb9693cSJohn Soni Jose 		      exp_statsn) / 32] + 1));
1193*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1194*acb9693cSJohn Soni Jose 		      pwrb, pwrb_handle->wrb_index);
1195*acb9693cSJohn Soni Jose 
1196*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1197*acb9693cSJohn Soni Jose 		      max_burst_length, pwrb, params->dw[offsetof
1198*acb9693cSJohn Soni Jose 		      (struct amap_beiscsi_offload_params,
1199*acb9693cSJohn Soni Jose 		      max_burst_length) / 32]);
1200*acb9693cSJohn Soni Jose 
1201*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1202*acb9693cSJohn Soni Jose 		      pwrb, pwrb_handle->nxt_wrb_index);
1203*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1204*acb9693cSJohn Soni Jose 		      session_state, pwrb, 0);
1205*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1206*acb9693cSJohn Soni Jose 		      pwrb, 1);
1207*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1208*acb9693cSJohn Soni Jose 		      pwrb, 0);
1209*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1210*acb9693cSJohn Soni Jose 		      0);
1211*acb9693cSJohn Soni Jose 
1212*acb9693cSJohn Soni Jose 	mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1213*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1214*acb9693cSJohn Soni Jose 		      pad_buffer_addr_hi, pwrb,
1215*acb9693cSJohn Soni Jose 		      mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1216*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1217*acb9693cSJohn Soni Jose 		      pad_buffer_addr_lo, pwrb,
1218*acb9693cSJohn Soni Jose 		      mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1219*acb9693cSJohn Soni Jose }
1220*acb9693cSJohn Soni Jose 
1221*acb9693cSJohn Soni Jose void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1222*acb9693cSJohn Soni Jose 			     struct wrb_handle *pwrb_handle)
1223*acb9693cSJohn Soni Jose {
1224*acb9693cSJohn Soni Jose 	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1225*acb9693cSJohn Soni Jose 
1226*acb9693cSJohn Soni Jose 	memset(pwrb, 0, sizeof(*pwrb));
1227*acb9693cSJohn Soni Jose 
1228*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1229*acb9693cSJohn Soni Jose 		      max_burst_length, pwrb, params->dw[offsetof
1230*acb9693cSJohn Soni Jose 		      (struct amap_beiscsi_offload_params,
1231*acb9693cSJohn Soni Jose 		      max_burst_length) / 32]);
1232*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1233*acb9693cSJohn Soni Jose 		      max_burst_length, pwrb, params->dw[offsetof
1234*acb9693cSJohn Soni Jose 		      (struct amap_beiscsi_offload_params,
1235*acb9693cSJohn Soni Jose 		      max_burst_length) / 32]);
1236*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1237*acb9693cSJohn Soni Jose 		      type, pwrb,
1238*acb9693cSJohn Soni Jose 		      BE_TGT_CTX_UPDT_CMD);
1239*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1240*acb9693cSJohn Soni Jose 		      ptr2nextwrb,
1241*acb9693cSJohn Soni Jose 		      pwrb, pwrb_handle->nxt_wrb_index);
1242*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1243*acb9693cSJohn Soni Jose 		      pwrb, pwrb_handle->wrb_index);
1244*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1245*acb9693cSJohn Soni Jose 		      max_send_data_segment_length, pwrb,
1246*acb9693cSJohn Soni Jose 		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1247*acb9693cSJohn Soni Jose 		      max_send_data_segment_length) / 32]);
1248*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1249*acb9693cSJohn Soni Jose 		      first_burst_length, pwrb,
1250*acb9693cSJohn Soni Jose 		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1251*acb9693cSJohn Soni Jose 		      first_burst_length) / 32]);
1252*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1253*acb9693cSJohn Soni Jose 		      max_recv_dataseg_len, pwrb, BEISCSI_MAX_RECV_DATASEG_LEN);
1254*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1255*acb9693cSJohn Soni Jose 		      max_cxns, pwrb, BEISCSI_MAX_CXNS);
1256*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1257*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1258*acb9693cSJohn Soni Jose 		      erl) / 32] & OFFLD_PARAMS_ERL));
1259*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1260*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1261*acb9693cSJohn Soni Jose 		      dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1262*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1263*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1264*acb9693cSJohn Soni Jose 		      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1265*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1266*acb9693cSJohn Soni Jose 		      ir2t, pwrb,
1267*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1268*acb9693cSJohn Soni Jose 		      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1269*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1270*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1271*acb9693cSJohn Soni Jose 		      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1272*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1273*acb9693cSJohn Soni Jose 		      data_seq_inorder,
1274*acb9693cSJohn Soni Jose 		      pwrb,
1275*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1276*acb9693cSJohn Soni Jose 		      data_seq_inorder) / 32] &
1277*acb9693cSJohn Soni Jose 		      OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1278*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1279*acb9693cSJohn Soni Jose 		      pdu_seq_inorder,
1280*acb9693cSJohn Soni Jose 		      pwrb,
1281*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1282*acb9693cSJohn Soni Jose 		      pdu_seq_inorder) / 32] &
1283*acb9693cSJohn Soni Jose 		      OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1284*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1285*acb9693cSJohn Soni Jose 		      pwrb,
1286*acb9693cSJohn Soni Jose 		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1287*acb9693cSJohn Soni Jose 		      max_r2t) / 32] &
1288*acb9693cSJohn Soni Jose 		      OFFLD_PARAMS_MAX_R2T) >> 8);
1289*acb9693cSJohn Soni Jose 	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1290*acb9693cSJohn Soni Jose 		      pwrb,
1291*acb9693cSJohn Soni Jose 		     (params->dw[offsetof(struct amap_beiscsi_offload_params,
1292*acb9693cSJohn Soni Jose 		      exp_statsn) / 32] + 1));
1293*acb9693cSJohn Soni Jose }
1294