File Index
Files and directories
Sign in
FILE

be_mgmt.c

File preview with syntax highlighting.

linux-6.19.14/drivers/scsi/be2iscsi/be_mgmt.c C
   1/*
   2 * This file is part of the Emulex Linux Device Driver for Enterprise iSCSI
   3 * Host Bus Adapters. Refer to the README file included with this package
   4 * for driver version and adapter compatibility.
   5 *
   6 * Copyright (c) 2018 Broadcom. All Rights Reserved.
   7 * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
   8 *
   9 * This program is free software; you can redistribute it and/or modify it
  10 * under the terms of version 2 of the GNU General Public License as published
  11 * by the Free Software Foundation.
  12 *
  13 * This program is distributed in the hope that it will be useful. ALL EXPRESS
  14 * OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
  15 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
  16 * OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
  17 * DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
  18 * See the GNU General Public License for more details, a copy of which
  19 * can be found in the file COPYING included with this package.
  20 *
  21 * Contact Information:
  22 * linux-drivers@broadcom.com
  23 *
  24 */
  25
  26#include <linux/bsg-lib.h>
  27#include <scsi/scsi_transport_iscsi.h>
  28#include <scsi/scsi_bsg_iscsi.h>
  29#include "be_mgmt.h"
  30#include "be_iscsi.h"
  31#include "be_main.h"
  32
  33unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
  34					 struct beiscsi_hba *phba,
  35					 struct bsg_job *job,
  36					 struct be_dma_mem *nonemb_cmd)
  37{
  38	struct be_mcc_wrb *wrb;
  39	struct be_sge *mcc_sge;
  40	unsigned int tag = 0;
  41	struct iscsi_bsg_request *bsg_req = job->request;
  42	struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
  43	unsigned short region, sector_size, sector, offset;
  44
  45	nonemb_cmd->size = job->request_payload.payload_len;
  46	memset(nonemb_cmd->va, 0, nonemb_cmd->size);
  47	region =  bsg_req->rqst_data.h_vendor.vendor_cmd[1];
  48	sector_size =  bsg_req->rqst_data.h_vendor.vendor_cmd[2];
  49	sector =  bsg_req->rqst_data.h_vendor.vendor_cmd[3];
  50	offset =  bsg_req->rqst_data.h_vendor.vendor_cmd[4];
  51	req->region = region;
  52	req->sector = sector;
  53	req->offset = offset;
  54
  55	if (mutex_lock_interruptible(&ctrl->mbox_lock))
  56		return 0;
  57	switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
  58	case BEISCSI_WRITE_FLASH:
  59		offset = sector * sector_size + offset;
  60		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  61				   OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
  62		sg_copy_to_buffer(job->request_payload.sg_list,
  63				  job->request_payload.sg_cnt,
  64				  nonemb_cmd->va + offset, job->request_len);
  65		break;
  66	case BEISCSI_READ_FLASH:
  67		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
  68			   OPCODE_COMMON_READ_FLASH, sizeof(*req));
  69		break;
  70	default:
  71		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
  72			    "BG_%d : Unsupported cmd = 0x%x\n\n",
  73			    bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
  74
  75		mutex_unlock(&ctrl->mbox_lock);
  76		return -EPERM;
  77	}
  78
  79	wrb = alloc_mcc_wrb(phba, &tag);
  80	if (!wrb) {
  81		mutex_unlock(&ctrl->mbox_lock);
  82		return 0;
  83	}
  84
  85	mcc_sge = nonembedded_sgl(wrb);
  86	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
  87			   job->request_payload.sg_cnt);
  88	mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
  89	mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
  90	mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
  91
  92	be_mcc_notify(phba, tag);
  93
  94	mutex_unlock(&ctrl->mbox_lock);
  95	return tag;
  96}
  97
  98/**
  99 * mgmt_open_connection()- Establish a TCP CXN
 100 * @phba: driver priv structure
 101 * @dst_addr: Destination Address
 102 * @beiscsi_ep: ptr to device endpoint struct
 103 * @nonemb_cmd: ptr to memory allocated for command
 104 *
 105 * return
 106 *	Success: Tag number of the MBX Command issued
 107 *	Failure: Error code
 108 **/
 109int mgmt_open_connection(struct beiscsi_hba *phba,
 110			 struct sockaddr *dst_addr,
 111			 struct beiscsi_endpoint *beiscsi_ep,
 112			 struct be_dma_mem *nonemb_cmd)
 113{
 114	struct hwi_controller *phwi_ctrlr;
 115	struct hwi_context_memory *phwi_context;
 116	struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
 117	struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
 118	struct be_ctrl_info *ctrl = &phba->ctrl;
 119	struct be_mcc_wrb *wrb;
 120	struct tcp_connect_and_offload_in_v1 *req;
 121	unsigned short def_hdr_id;
 122	unsigned short def_data_id;
 123	struct phys_addr template_address = { 0, 0 };
 124	struct phys_addr *ptemplate_address;
 125	unsigned int tag = 0;
 126	unsigned int i, ulp_num;
 127	unsigned short cid = beiscsi_ep->ep_cid;
 128	struct be_sge *sge;
 129
 130	if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
 131		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 132			    "BG_%d : unknown addr family %d\n",
 133			    dst_addr->sa_family);
 134		return 0;
 135	}
 136
 137	phwi_ctrlr = phba->phwi_ctrlr;
 138	phwi_context = phwi_ctrlr->phwi_ctxt;
 139
 140	ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
 141
 142	def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
 143	def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
 144
 145	ptemplate_address = &template_address;
 146	ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
 147	if (mutex_lock_interruptible(&ctrl->mbox_lock))
 148		return 0;
 149	wrb = alloc_mcc_wrb(phba, &tag);
 150	if (!wrb) {
 151		mutex_unlock(&ctrl->mbox_lock);
 152		return 0;
 153	}
 154
 155	sge = nonembedded_sgl(wrb);
 156	req = nonemb_cmd->va;
 157	memset(req, 0, sizeof(*req));
 158
 159	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
 160	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
 161			   OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
 162			   nonemb_cmd->size);
 163	if (dst_addr->sa_family == PF_INET) {
 164		__be32 s_addr = daddr_in->sin_addr.s_addr;
 165		req->ip_address.ip_type = BEISCSI_IP_TYPE_V4;
 166		req->ip_address.addr[0] = s_addr & 0x000000ff;
 167		req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
 168		req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
 169		req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
 170		req->tcp_port = ntohs(daddr_in->sin_port);
 171		beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
 172		beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
 173		beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4;
 174	} else {
 175		/* else its PF_INET6 family */
 176		req->ip_address.ip_type = BEISCSI_IP_TYPE_V6;
 177		memcpy(&req->ip_address.addr,
 178		       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
 179		req->tcp_port = ntohs(daddr_in6->sin6_port);
 180		beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
 181		memcpy(&beiscsi_ep->dst6_addr,
 182		       &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
 183		beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6;
 184	}
 185	req->cid = cid;
 186	i = phba->nxt_cqid++;
 187	if (phba->nxt_cqid == phba->num_cpus)
 188		phba->nxt_cqid = 0;
 189	req->cq_id = phwi_context->be_cq[i].id;
 190	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 191		    "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
 192	req->defq_id = def_hdr_id;
 193	req->hdr_ring_id = def_hdr_id;
 194	req->data_ring_id = def_data_id;
 195	req->do_offload = 1;
 196	req->dataout_template_pa.lo = ptemplate_address->lo;
 197	req->dataout_template_pa.hi = ptemplate_address->hi;
 198	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
 199	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
 200	sge->len = cpu_to_le32(nonemb_cmd->size);
 201
 202	if (!is_chip_be2_be3r(phba)) {
 203		req->hdr.version = MBX_CMD_VER1;
 204		req->tcp_window_size = 0x8000;
 205		req->tcp_window_scale_count = 2;
 206	}
 207
 208	be_mcc_notify(phba, tag);
 209	mutex_unlock(&ctrl->mbox_lock);
 210	return tag;
 211}
 212
 213/**
 214 * beiscsi_exec_nemb_cmd()- execute non-embedded MBX cmd
 215 * @phba: driver priv structure
 216 * @nonemb_cmd: DMA address of the MBX command to be issued
 217 * @cbfn: callback func on MCC completion
 218 * @resp_buf: buffer to copy the MBX cmd response
 219 * @resp_buf_len: response length to be copied
 220 *
 221 **/
 222static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba,
 223				 struct be_dma_mem *nonemb_cmd,
 224				 void (*cbfn)(struct beiscsi_hba *,
 225					      unsigned int),
 226				 void *resp_buf, u32 resp_buf_len)
 227{
 228	struct be_ctrl_info *ctrl = &phba->ctrl;
 229	struct be_mcc_wrb *wrb;
 230	struct be_sge *sge;
 231	unsigned int tag;
 232	int rc = 0;
 233
 234	mutex_lock(&ctrl->mbox_lock);
 235	wrb = alloc_mcc_wrb(phba, &tag);
 236	if (!wrb) {
 237		mutex_unlock(&ctrl->mbox_lock);
 238		return -ENOMEM;
 239	}
 240
 241	sge = nonembedded_sgl(wrb);
 242	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
 243	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
 244	sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
 245	sge->len = cpu_to_le32(nonemb_cmd->size);
 246
 247	if (cbfn) {
 248		struct be_dma_mem *tag_mem;
 249
 250		set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
 251		ctrl->ptag_state[tag].cbfn = cbfn;
 252		tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
 253
 254		/* store DMA mem to be freed in callback */
 255		tag_mem->size = nonemb_cmd->size;
 256		tag_mem->va = nonemb_cmd->va;
 257		tag_mem->dma = nonemb_cmd->dma;
 258	}
 259	be_mcc_notify(phba, tag);
 260	mutex_unlock(&ctrl->mbox_lock);
 261
 262	/* with cbfn set, its async cmd, don't wait */
 263	if (cbfn)
 264		return 0;
 265
 266	rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd);
 267
 268	/* copy the response, if any */
 269	if (resp_buf)
 270		memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
 271	return rc;
 272}
 273
 274static int beiscsi_prep_nemb_cmd(struct beiscsi_hba *phba,
 275				 struct be_dma_mem *cmd,
 276				 u8 subsystem, u8 opcode, u32 size)
 277{
 278	cmd->va = dma_alloc_coherent(&phba->ctrl.pdev->dev, size, &cmd->dma,
 279				     GFP_KERNEL);
 280	if (!cmd->va) {
 281		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 282			    "BG_%d : Failed to allocate memory for if info\n");
 283		return -ENOMEM;
 284	}
 285	cmd->size = size;
 286	be_cmd_hdr_prepare(cmd->va, subsystem, opcode, size);
 287	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 288		    "BG_%d : subsystem %u cmd %u size %u\n",
 289		    subsystem, opcode, size);
 290	return 0;
 291}
 292
 293static void beiscsi_free_nemb_cmd(struct beiscsi_hba *phba,
 294				  struct be_dma_mem *cmd, int rc)
 295{
 296	/*
 297	 * If FW is busy the DMA buffer is saved with the tag. When the cmd
 298	 * completes this buffer is freed.
 299	 */
 300	if (rc == -EBUSY)
 301		return;
 302
 303	dma_free_coherent(&phba->ctrl.pdev->dev, cmd->size, cmd->va, cmd->dma);
 304}
 305
 306static void __beiscsi_eq_delay_compl(struct beiscsi_hba *phba, unsigned int tag)
 307{
 308	struct be_dma_mem *tag_mem;
 309
 310	/* status is ignored */
 311	__beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
 312	tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
 313	if (tag_mem->size) {
 314		dma_free_coherent(&phba->pcidev->dev, tag_mem->size,
 315				    tag_mem->va, tag_mem->dma);
 316		tag_mem->size = 0;
 317	}
 318}
 319
 320int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
 321			    struct be_set_eqd *set_eqd, int num)
 322{
 323	struct be_cmd_req_modify_eq_delay *req;
 324	struct be_dma_mem nonemb_cmd;
 325	int i, rc;
 326
 327	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_COMMON,
 328			OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
 329	if (rc)
 330		return rc;
 331
 332	req = nonemb_cmd.va;
 333	req->num_eq = cpu_to_le32(num);
 334	for (i = 0; i < num; i++) {
 335		req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
 336		req->delay[i].phase = 0;
 337		req->delay[i].delay_multiplier =
 338				cpu_to_le32(set_eqd[i].delay_multiplier);
 339	}
 340
 341	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, __beiscsi_eq_delay_compl,
 342				   NULL, 0);
 343	if (rc) {
 344		/*
 345		 * Only free on failure. Async cmds are handled like -EBUSY
 346		 * where it's handled for us.
 347		 */
 348		beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 349	}
 350	return rc;
 351}
 352
 353/**
 354 * beiscsi_get_initiator_name - read initiator name from flash
 355 * @phba: device priv structure
 356 * @name: buffer pointer
 357 * @cfg: fetch user configured
 358 *
 359 */
 360int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name, bool cfg)
 361{
 362	struct be_dma_mem nonemb_cmd;
 363	struct be_cmd_hba_name resp;
 364	struct be_cmd_hba_name *req;
 365	int rc;
 366
 367	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI_INI,
 368			OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, sizeof(resp));
 369	if (rc)
 370		return rc;
 371
 372	req = nonemb_cmd.va;
 373	if (cfg)
 374		req->hdr.version = 1;
 375	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
 376				   &resp, sizeof(resp));
 377	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 378	if (rc) {
 379		beiscsi_log(phba, KERN_ERR,
 380			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
 381			    "BS_%d : Initiator Name MBX Failed\n");
 382		return rc;
 383	}
 384	rc = sprintf(name, "%s\n", resp.initiator_name);
 385	return rc;
 386}
 387
 388unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba)
 389{
 390	struct be_ctrl_info *ctrl = &phba->ctrl;
 391	struct be_mcc_wrb *wrb;
 392	struct be_cmd_get_all_if_id_req *req;
 393	struct be_cmd_get_all_if_id_req *pbe_allid;
 394	unsigned int tag;
 395	int status = 0;
 396
 397	if (mutex_lock_interruptible(&ctrl->mbox_lock))
 398		return -EINTR;
 399	wrb = alloc_mcc_wrb(phba, &tag);
 400	if (!wrb) {
 401		mutex_unlock(&ctrl->mbox_lock);
 402		return -ENOMEM;
 403	}
 404
 405	req = embedded_payload(wrb);
 406	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 407	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
 408			   OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
 409			   sizeof(*req));
 410	be_mcc_notify(phba, tag);
 411	mutex_unlock(&ctrl->mbox_lock);
 412
 413	status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
 414	if (status) {
 415		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 416			    "BG_%d : %s failed: %d\n", __func__, status);
 417		return -EBUSY;
 418	}
 419
 420	pbe_allid = embedded_payload(wrb);
 421	/* we now support only one interface per function */
 422	phba->interface_handle = pbe_allid->if_hndl_list[0];
 423
 424	return status;
 425}
 426
 427static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type)
 428{
 429	u32 len;
 430
 431	len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
 432	while (len && !ip[len - 1])
 433		len--;
 434	return (len == 0);
 435}
 436
 437static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
 438			     u32 action, u32 ip_type, u8 *gw)
 439{
 440	struct be_cmd_set_def_gateway_req *req;
 441	struct be_dma_mem nonemb_cmd;
 442	int rt_val;
 443
 444	rt_val = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 445			OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
 446			sizeof(*req));
 447	if (rt_val)
 448		return rt_val;
 449
 450	req = nonemb_cmd.va;
 451	req->action = action;
 452	req->ip_addr.ip_type = ip_type;
 453	memcpy(req->ip_addr.addr, gw,
 454	       (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
 455	rt_val = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
 456	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rt_val);
 457	return rt_val;
 458}
 459
 460int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw)
 461{
 462	struct be_cmd_get_def_gateway_resp gw_resp;
 463	int rt_val;
 464
 465	memset(&gw_resp, 0, sizeof(gw_resp));
 466	rt_val = beiscsi_if_get_gw(phba, ip_type, &gw_resp);
 467	if (rt_val) {
 468		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 469			    "BG_%d : Failed to Get Gateway Addr\n");
 470		return rt_val;
 471	}
 472
 473	if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) {
 474		rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type,
 475					   gw_resp.ip_addr.addr);
 476		if (rt_val) {
 477			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 478				    "BG_%d : Failed to clear Gateway Addr Set\n");
 479			return rt_val;
 480		}
 481	}
 482
 483	rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw);
 484	if (rt_val)
 485		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 486			    "BG_%d : Failed to Set Gateway Addr\n");
 487
 488	return rt_val;
 489}
 490
 491int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
 492		      struct be_cmd_get_def_gateway_resp *resp)
 493{
 494	struct be_cmd_get_def_gateway_req *req;
 495	struct be_dma_mem nonemb_cmd;
 496	int rc;
 497
 498	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 499			OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
 500			sizeof(*resp));
 501	if (rc)
 502		return rc;
 503
 504	req = nonemb_cmd.va;
 505	req->ip_type = ip_type;
 506
 507	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, resp,
 508				   sizeof(*resp));
 509	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 510	return rc;
 511}
 512
 513static int
 514beiscsi_if_clr_ip(struct beiscsi_hba *phba,
 515		  struct be_cmd_get_if_info_resp *if_info)
 516{
 517	struct be_cmd_set_ip_addr_req *req;
 518	struct be_dma_mem nonemb_cmd;
 519	int rc;
 520
 521	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 522			OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
 523			sizeof(*req));
 524	if (rc)
 525		return rc;
 526
 527	req = nonemb_cmd.va;
 528	req->ip_params.record_entry_count = 1;
 529	req->ip_params.ip_record.action = IP_ACTION_DEL;
 530	req->ip_params.ip_record.interface_hndl =
 531		phba->interface_handle;
 532	req->ip_params.ip_record.ip_addr.size_of_structure =
 533		sizeof(struct be_ip_addr_subnet_format);
 534	req->ip_params.ip_record.ip_addr.ip_type = if_info->ip_addr.ip_type;
 535	memcpy(req->ip_params.ip_record.ip_addr.addr,
 536	       if_info->ip_addr.addr,
 537	       sizeof(if_info->ip_addr.addr));
 538	memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
 539	       if_info->ip_addr.subnet_mask,
 540	       sizeof(if_info->ip_addr.subnet_mask));
 541	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
 542	if (rc < 0 || req->ip_params.ip_record.status) {
 543		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 544			    "BG_%d : failed to clear IP: rc %d status %d\n",
 545			    rc, req->ip_params.ip_record.status);
 546	}
 547	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 548	return rc;
 549}
 550
 551static int
 552beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip,
 553		  u8 *subnet, u32 ip_type)
 554{
 555	struct be_cmd_set_ip_addr_req *req;
 556	struct be_dma_mem nonemb_cmd;
 557	uint32_t ip_len;
 558	int rc;
 559
 560	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 561			OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
 562			sizeof(*req));
 563	if (rc)
 564		return rc;
 565
 566	req = nonemb_cmd.va;
 567	req->ip_params.record_entry_count = 1;
 568	req->ip_params.ip_record.action = IP_ACTION_ADD;
 569	req->ip_params.ip_record.interface_hndl =
 570		phba->interface_handle;
 571	req->ip_params.ip_record.ip_addr.size_of_structure =
 572		sizeof(struct be_ip_addr_subnet_format);
 573	req->ip_params.ip_record.ip_addr.ip_type = ip_type;
 574	ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
 575	memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len);
 576	if (subnet)
 577		memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
 578		       subnet, ip_len);
 579
 580	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
 581	/**
 582	 * In some cases, host needs to look into individual record status
 583	 * even though FW reported success for that IOCTL.
 584	 */
 585	if (rc < 0 || req->ip_params.ip_record.status) {
 586		__beiscsi_log(phba, KERN_ERR,
 587			    "BG_%d : failed to set IP: rc %d status %d\n",
 588			    rc, req->ip_params.ip_record.status);
 589		if (req->ip_params.ip_record.status)
 590			rc = -EINVAL;
 591	}
 592	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 593	return rc;
 594}
 595
 596int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
 597			 u8 *ip, u8 *subnet)
 598{
 599	struct be_cmd_get_if_info_resp *if_info;
 600	struct be_cmd_rel_dhcp_req *reldhcp;
 601	struct be_dma_mem nonemb_cmd;
 602	int rc;
 603
 604	rc = beiscsi_if_get_info(phba, ip_type, &if_info);
 605	if (rc)
 606		return rc;
 607
 608	if (if_info->dhcp_state) {
 609		rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
 610				CMD_SUBSYSTEM_ISCSI,
 611				OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
 612				sizeof(*reldhcp));
 613		if (rc)
 614			goto exit;
 615
 616		reldhcp = nonemb_cmd.va;
 617		reldhcp->interface_hndl = phba->interface_handle;
 618		reldhcp->ip_type = ip_type;
 619		rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
 620		beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 621		if (rc < 0) {
 622			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 623				    "BG_%d : failed to release existing DHCP: %d\n",
 624				    rc);
 625			goto exit;
 626		}
 627	}
 628
 629	/* first delete any IP set */
 630	if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
 631		rc = beiscsi_if_clr_ip(phba, if_info);
 632		if (rc)
 633			goto exit;
 634	}
 635
 636	/* if ip == NULL then this is called just to release DHCP IP */
 637	if (ip)
 638		rc = beiscsi_if_set_ip(phba, ip, subnet, ip_type);
 639exit:
 640	kfree(if_info);
 641	return rc;
 642}
 643
 644int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type)
 645{
 646	struct be_cmd_get_def_gateway_resp gw_resp;
 647	struct be_cmd_get_if_info_resp *if_info;
 648	struct be_cmd_set_dhcp_req *dhcpreq;
 649	struct be_dma_mem nonemb_cmd;
 650	u8 *gw;
 651	int rc;
 652
 653	rc = beiscsi_if_get_info(phba, ip_type, &if_info);
 654	if (rc)
 655		return rc;
 656
 657	if (if_info->dhcp_state) {
 658		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 659				"BG_%d : DHCP Already Enabled\n");
 660		goto exit;
 661	}
 662
 663	/* first delete any IP set */
 664	if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
 665		rc = beiscsi_if_clr_ip(phba, if_info);
 666		if (rc)
 667			goto exit;
 668	}
 669
 670	/* delete gateway settings if mode change is to DHCP */
 671	memset(&gw_resp, 0, sizeof(gw_resp));
 672	/* use ip_type provided in if_info */
 673	rc = beiscsi_if_get_gw(phba, if_info->ip_addr.ip_type, &gw_resp);
 674	if (rc) {
 675		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 676			    "BG_%d : Failed to Get Gateway Addr\n");
 677		goto exit;
 678	}
 679	gw = (u8 *)&gw_resp.ip_addr.addr;
 680	if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) {
 681		rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL,
 682				       if_info->ip_addr.ip_type, gw);
 683		if (rc) {
 684			beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
 685				    "BG_%d : Failed to clear Gateway Addr Set\n");
 686			goto exit;
 687		}
 688	}
 689
 690	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 691			OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
 692			sizeof(*dhcpreq));
 693	if (rc)
 694		goto exit;
 695
 696	dhcpreq = nonemb_cmd.va;
 697	dhcpreq->flags = 1; /* 1 - blocking; 0 - non-blocking */
 698	dhcpreq->retry_count = 1;
 699	dhcpreq->interface_hndl = phba->interface_handle;
 700	dhcpreq->ip_type = ip_type;
 701	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
 702	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 703exit:
 704	kfree(if_info);
 705	return rc;
 706}
 707
 708/**
 709 * beiscsi_if_set_vlan()- Issue and wait for CMD completion
 710 * @phba: device private structure instance
 711 * @vlan_tag: VLAN tag
 712 *
 713 * Issue the MBX Cmd and wait for the completion of the
 714 * command.
 715 *
 716 * returns
 717 *	Success: 0
 718 *	Failure: Non-Xero Value
 719 **/
 720int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag)
 721{
 722	int rc;
 723	unsigned int tag;
 724
 725	tag = be_cmd_set_vlan(phba, vlan_tag);
 726	if (!tag) {
 727		beiscsi_log(phba, KERN_ERR,
 728			    (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
 729			    "BG_%d : VLAN Setting Failed\n");
 730		return -EBUSY;
 731	}
 732
 733	rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
 734	if (rc) {
 735		beiscsi_log(phba, KERN_ERR,
 736			    (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
 737			    "BS_%d : VLAN MBX Cmd Failed\n");
 738		return rc;
 739	}
 740	return rc;
 741}
 742
 743
 744int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
 745			struct be_cmd_get_if_info_resp **if_info)
 746{
 747	struct be_cmd_get_if_info_req *req;
 748	struct be_dma_mem nonemb_cmd;
 749	uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
 750	int rc;
 751
 752	rc = beiscsi_if_get_handle(phba);
 753	if (rc)
 754		return rc;
 755
 756	do {
 757		rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
 758				CMD_SUBSYSTEM_ISCSI,
 759				OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
 760				ioctl_size);
 761		if (rc)
 762			return rc;
 763
 764		req = nonemb_cmd.va;
 765		req->interface_hndl = phba->interface_handle;
 766		req->ip_type = ip_type;
 767
 768		/* Allocate memory for if_info */
 769		*if_info = kzalloc(ioctl_size, GFP_KERNEL);
 770		if (!*if_info) {
 771			beiscsi_log(phba, KERN_ERR,
 772				    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
 773				    "BG_%d : Memory Allocation Failure\n");
 774
 775				beiscsi_free_nemb_cmd(phba, &nonemb_cmd,
 776						      -ENOMEM);
 777				return -ENOMEM;
 778		}
 779
 780		rc =  beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, *if_info,
 781					    ioctl_size);
 782
 783		/* Check if the error is because of Insufficent_Buffer */
 784		if (rc == -EAGAIN) {
 785
 786			/* Get the new memory size */
 787			ioctl_size = ((struct be_cmd_resp_hdr *)
 788				      nonemb_cmd.va)->actual_resp_len;
 789			ioctl_size += sizeof(struct be_cmd_req_hdr);
 790
 791			beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 792			/* Free the virtual memory */
 793			kfree(*if_info);
 794		} else {
 795			beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 796			break;
 797		}
 798	} while (true);
 799	return rc;
 800}
 801
 802int mgmt_get_nic_conf(struct beiscsi_hba *phba,
 803		      struct be_cmd_get_nic_conf_resp *nic)
 804{
 805	struct be_dma_mem nonemb_cmd;
 806	int rc;
 807
 808	rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
 809			OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
 810			sizeof(*nic));
 811	if (rc)
 812		return rc;
 813
 814	rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, nic, sizeof(*nic));
 815	beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc);
 816	return rc;
 817}
 818
 819static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
 820				       unsigned int tag)
 821{
 822	struct be_cmd_get_boot_target_resp *boot_resp;
 823	struct be_cmd_resp_logout_fw_sess *logo_resp;
 824	struct be_cmd_get_session_resp *sess_resp;
 825	struct be_mcc_wrb *wrb;
 826	struct boot_struct *bs;
 827	int boot_work, status;
 828
 829	if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
 830		__beiscsi_log(phba, KERN_ERR,
 831			      "BG_%d : %s no boot work %lx\n",
 832			      __func__, phba->state);
 833		return;
 834	}
 835
 836	if (phba->boot_struct.tag != tag) {
 837		__beiscsi_log(phba, KERN_ERR,
 838			      "BG_%d : %s tag mismatch %d:%d\n",
 839			      __func__, tag, phba->boot_struct.tag);
 840		return;
 841	}
 842	bs = &phba->boot_struct;
 843	boot_work = 1;
 844	status = 0;
 845	switch (bs->action) {
 846	case BEISCSI_BOOT_REOPEN_SESS:
 847		status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
 848		if (!status)
 849			bs->action = BEISCSI_BOOT_GET_SHANDLE;
 850		else
 851			bs->retry--;
 852		break;
 853	case BEISCSI_BOOT_GET_SHANDLE:
 854		status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
 855		if (!status) {
 856			boot_resp = embedded_payload(wrb);
 857			bs->s_handle = boot_resp->boot_session_handle;
 858		}
 859		if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
 860			bs->action = BEISCSI_BOOT_REOPEN_SESS;
 861			bs->retry--;
 862		} else {
 863			bs->action = BEISCSI_BOOT_GET_SINFO;
 864		}
 865		break;
 866	case BEISCSI_BOOT_GET_SINFO:
 867		status = __beiscsi_mcc_compl_status(phba, tag, NULL,
 868						    &bs->nonemb_cmd);
 869		if (!status) {
 870			sess_resp = bs->nonemb_cmd.va;
 871			memcpy(&bs->boot_sess, &sess_resp->session_info,
 872			       sizeof(struct mgmt_session_info));
 873			bs->action = BEISCSI_BOOT_LOGOUT_SESS;
 874		} else {
 875			__beiscsi_log(phba, KERN_ERR,
 876				      "BG_%d : get boot session info error : 0x%x\n",
 877				      status);
 878			boot_work = 0;
 879		}
 880		dma_free_coherent(&phba->ctrl.pdev->dev, bs->nonemb_cmd.size,
 881				    bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
 882		bs->nonemb_cmd.va = NULL;
 883		break;
 884	case BEISCSI_BOOT_LOGOUT_SESS:
 885		status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
 886		if (!status) {
 887			logo_resp = embedded_payload(wrb);
 888			if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
 889				__beiscsi_log(phba, KERN_ERR,
 890					      "BG_%d : FW boot session logout error : 0x%x\n",
 891					      logo_resp->session_status);
 892			}
 893		}
 894		/* continue to create boot_kset even if logout failed? */
 895		bs->action = BEISCSI_BOOT_CREATE_KSET;
 896		break;
 897	default:
 898		break;
 899	}
 900
 901	/* clear the tag so no other completion matches this tag */
 902	bs->tag = 0;
 903	if (!bs->retry) {
 904		boot_work = 0;
 905		__beiscsi_log(phba, KERN_ERR,
 906			      "BG_%d : failed to setup boot target: status %d action %d\n",
 907			      status, bs->action);
 908	}
 909	if (!boot_work) {
 910		/* wait for next event to start boot_work */
 911		clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
 912		return;
 913	}
 914	schedule_work(&phba->boot_work);
 915}
 916
 917/**
 918 * beiscsi_boot_logout_sess()- Logout from boot FW session
 919 * @phba: Device priv structure instance
 920 *
 921 * return
 922 *	the TAG used for MBOX Command
 923 *
 924 */
 925unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
 926{
 927	struct be_ctrl_info *ctrl = &phba->ctrl;
 928	struct be_mcc_wrb *wrb;
 929	struct be_cmd_req_logout_fw_sess *req;
 930	unsigned int tag;
 931
 932	mutex_lock(&ctrl->mbox_lock);
 933	wrb = alloc_mcc_wrb(phba, &tag);
 934	if (!wrb) {
 935		mutex_unlock(&ctrl->mbox_lock);
 936		return 0;
 937	}
 938
 939	req = embedded_payload(wrb);
 940	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 941	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
 942			   OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
 943			   sizeof(struct be_cmd_req_logout_fw_sess));
 944	/* Use the session handle copied into boot_sess */
 945	req->session_handle = phba->boot_struct.boot_sess.session_handle;
 946
 947	phba->boot_struct.tag = tag;
 948	set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
 949	ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
 950
 951	be_mcc_notify(phba, tag);
 952	mutex_unlock(&ctrl->mbox_lock);
 953
 954	return tag;
 955}
 956/**
 957 * beiscsi_boot_reopen_sess()- Reopen boot session
 958 * @phba: Device priv structure instance
 959 *
 960 * return
 961 *	the TAG used for MBOX Command
 962 *
 963 **/
 964unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
 965{
 966	struct be_ctrl_info *ctrl = &phba->ctrl;
 967	struct be_mcc_wrb *wrb;
 968	struct be_cmd_reopen_session_req *req;
 969	unsigned int tag;
 970
 971	mutex_lock(&ctrl->mbox_lock);
 972	wrb = alloc_mcc_wrb(phba, &tag);
 973	if (!wrb) {
 974		mutex_unlock(&ctrl->mbox_lock);
 975		return 0;
 976	}
 977
 978	req = embedded_payload(wrb);
 979	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 980	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
 981			   OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
 982			   sizeof(struct be_cmd_reopen_session_resp));
 983	req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
 984	req->session_handle = BE_BOOT_INVALID_SHANDLE;
 985
 986	phba->boot_struct.tag = tag;
 987	set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
 988	ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
 989
 990	be_mcc_notify(phba, tag);
 991	mutex_unlock(&ctrl->mbox_lock);
 992	return tag;
 993}
 994
 995
 996/**
 997 * beiscsi_boot_get_sinfo()- Get boot session info
 998 * @phba: device priv structure instance
 999 *
1000 * Fetches the boot_struct.s_handle info from FW.
1001 * return
1002 *	the TAG used for MBOX Command
1003 *
1004 **/
1005unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
1006{
1007	struct be_ctrl_info *ctrl = &phba->ctrl;
1008	struct be_cmd_get_session_req *req;
1009	struct be_dma_mem *nonemb_cmd;
1010	struct be_mcc_wrb *wrb;
1011	struct be_sge *sge;
1012	unsigned int tag;
1013
1014	mutex_lock(&ctrl->mbox_lock);
1015	wrb = alloc_mcc_wrb(phba, &tag);
1016	if (!wrb) {
1017		mutex_unlock(&ctrl->mbox_lock);
1018		return 0;
1019	}
1020
1021	nonemb_cmd = &phba->boot_struct.nonemb_cmd;
1022	nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp);
1023	nonemb_cmd->va = dma_alloc_coherent(&phba->ctrl.pdev->dev,
1024					      nonemb_cmd->size,
1025					      &nonemb_cmd->dma,
1026					      GFP_KERNEL);
1027	if (!nonemb_cmd->va) {
1028		free_mcc_wrb(ctrl, tag);
1029		mutex_unlock(&ctrl->mbox_lock);
1030		return 0;
1031	}
1032
1033	req = nonemb_cmd->va;
1034	memset(req, 0, sizeof(*req));
1035	sge = nonembedded_sgl(wrb);
1036	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
1037	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1038			   OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
1039			   sizeof(struct be_cmd_get_session_resp));
1040	req->session_handle = phba->boot_struct.s_handle;
1041	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
1042	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
1043	sge->len = cpu_to_le32(nonemb_cmd->size);
1044
1045	phba->boot_struct.tag = tag;
1046	set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1047	ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1048
1049	be_mcc_notify(phba, tag);
1050	mutex_unlock(&ctrl->mbox_lock);
1051	return tag;
1052}
1053
1054unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
1055{
1056	struct be_ctrl_info *ctrl = &phba->ctrl;
1057	struct be_mcc_wrb *wrb;
1058	struct be_cmd_get_boot_target_req *req;
1059	unsigned int tag;
1060
1061	mutex_lock(&ctrl->mbox_lock);
1062	wrb = alloc_mcc_wrb(phba, &tag);
1063	if (!wrb) {
1064		mutex_unlock(&ctrl->mbox_lock);
1065		return 0;
1066	}
1067
1068	req = embedded_payload(wrb);
1069	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1070	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1071			   OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
1072			   sizeof(struct be_cmd_get_boot_target_resp));
1073
1074	if (async) {
1075		phba->boot_struct.tag = tag;
1076		set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1077		ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1078	}
1079
1080	be_mcc_notify(phba, tag);
1081	mutex_unlock(&ctrl->mbox_lock);
1082	return tag;
1083}
1084
1085/**
1086 * beiscsi_boot_get_shandle()- Get boot session handle
1087 * @phba: device priv structure instance
1088 * @s_handle: session handle returned for boot session.
1089 *
1090 * return
1091 *	Success: 1
1092 *	Failure: negative
1093 *
1094 **/
1095int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
1096{
1097	struct be_cmd_get_boot_target_resp *boot_resp;
1098	struct be_mcc_wrb *wrb;
1099	unsigned int tag;
1100	int rc;
1101
1102	*s_handle = BE_BOOT_INVALID_SHANDLE;
1103	/* get configured boot session count and handle */
1104	tag = __beiscsi_boot_get_shandle(phba, 0);
1105	if (!tag) {
1106		beiscsi_log(phba, KERN_ERR,
1107			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1108			    "BG_%d : Getting Boot Target Info Failed\n");
1109		return -EAGAIN;
1110	}
1111
1112	rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1113	if (rc) {
1114		beiscsi_log(phba, KERN_ERR,
1115			    BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1116			    "BG_%d : MBX CMD get_boot_target Failed\n");
1117		return -EBUSY;
1118	}
1119
1120	boot_resp = embedded_payload(wrb);
1121	/* check if there are any boot targets configured */
1122	if (!boot_resp->boot_session_count) {
1123		__beiscsi_log(phba, KERN_INFO,
1124			      "BG_%d : No boot targets configured\n");
1125		return -ENXIO;
1126	}
1127
1128	/* only if FW has logged in to the boot target, s_handle is valid */
1129	*s_handle = boot_resp->boot_session_handle;
1130	return 1;
1131}
1132
1133/**
1134 * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1135 * @dev: ptr to device not used.
1136 * @attr: device attribute, not used.
1137 * @buf: contains formatted text driver name and version
1138 *
1139 * return
1140 * size of the formatted string
1141 **/
1142ssize_t
1143beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1144		       char *buf)
1145{
1146	return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1147}
1148
1149/**
1150 * beiscsi_fw_ver_disp()- Display Firmware Version
1151 * @dev: ptr to device not used.
1152 * @attr: device attribute, not used.
1153 * @buf: contains formatted text Firmware version
1154 *
1155 * return
1156 * size of the formatted string
1157 **/
1158ssize_t
1159beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1160		     char *buf)
1161{
1162	struct Scsi_Host *shost = class_to_shost(dev);
1163	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1164
1165	return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1166}
1167
1168/**
1169 * beiscsi_active_session_disp()- Display Sessions Active
1170 * @dev: ptr to device not used.
1171 * @attr: device attribute, not used.
1172 * @buf: contains formatted text Session Count
1173 *
1174 * return
1175 * size of the formatted string
1176 **/
1177ssize_t
1178beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1179			 char *buf)
1180{
1181	struct Scsi_Host *shost = class_to_shost(dev);
1182	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1183	uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1184
1185	for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1186		if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1187			avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1188			total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1189			len += scnprintf(buf+len, PAGE_SIZE - len,
1190					 "ULP%d : %d\n", ulp_num,
1191					 (total_cids - avlbl_cids));
1192		} else
1193			len += scnprintf(buf+len, PAGE_SIZE - len,
1194					 "ULP%d : %d\n", ulp_num, 0);
1195	}
1196
1197	return len;
1198}
1199
1200/**
1201 * beiscsi_free_session_disp()- Display Avaliable Session
1202 * @dev: ptr to device not used.
1203 * @attr: device attribute, not used.
1204 * @buf: contains formatted text Session Count
1205 *
1206 * return
1207 * size of the formatted string
1208 **/
1209ssize_t
1210beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1211		       char *buf)
1212{
1213	struct Scsi_Host *shost = class_to_shost(dev);
1214	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1215	uint16_t ulp_num, len = 0;
1216
1217	for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1218		if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1219			len += scnprintf(buf+len, PAGE_SIZE - len,
1220					 "ULP%d : %d\n", ulp_num,
1221					 BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1222		else
1223			len += scnprintf(buf+len, PAGE_SIZE - len,
1224					 "ULP%d : %d\n", ulp_num, 0);
1225	}
1226
1227	return len;
1228}
1229
1230/**
1231 * beiscsi_adap_family_disp()- Display adapter family.
1232 * @dev: ptr to device to get priv structure
1233 * @attr: device attribute, not used.
1234 * @buf: contains formatted text driver name and version
1235 *
1236 * return
1237 * size of the formatted string
1238 **/
1239ssize_t
1240beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1241			  char *buf)
1242{
1243	uint16_t dev_id = 0;
1244	struct Scsi_Host *shost = class_to_shost(dev);
1245	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1246
1247	dev_id = phba->pcidev->device;
1248	switch (dev_id) {
1249	case BE_DEVICE_ID1:
1250	case OC_DEVICE_ID1:
1251	case OC_DEVICE_ID2:
1252		return snprintf(buf, PAGE_SIZE,
1253				"Obsolete/Unsupported BE2 Adapter Family\n");
1254	case BE_DEVICE_ID2:
1255	case OC_DEVICE_ID3:
1256		return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1257	case OC_SKH_ID1:
1258		return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1259	default:
1260		return snprintf(buf, PAGE_SIZE,
1261				"Unknown Adapter Family: 0x%x\n", dev_id);
1262	}
1263}
1264
1265/**
1266 * beiscsi_phys_port_disp()- Display Physical Port Identifier
1267 * @dev: ptr to device not used.
1268 * @attr: device attribute, not used.
1269 * @buf: contains formatted text port identifier
1270 *
1271 * return
1272 * size of the formatted string
1273 **/
1274ssize_t
1275beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1276			 char *buf)
1277{
1278	struct Scsi_Host *shost = class_to_shost(dev);
1279	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1280
1281	return snprintf(buf, PAGE_SIZE, "Port Identifier : %u\n",
1282			phba->fw_config.phys_port);
1283}
1284
1285void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1286			     struct wrb_handle *pwrb_handle,
1287			     struct be_mem_descriptor *mem_descr,
1288			     struct hwi_wrb_context *pwrb_context)
1289{
1290	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1291
1292	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1293		      max_send_data_segment_length, pwrb,
1294		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1295		      max_send_data_segment_length) / 32]);
1296	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1297		      BE_TGT_CTX_UPDT_CMD);
1298	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1299		      first_burst_length,
1300		      pwrb,
1301		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1302		      first_burst_length) / 32]);
1303	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1304		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1305		      erl) / 32] & OFFLD_PARAMS_ERL));
1306	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1307		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1308		       dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1309	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1310		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1311		      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1312	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1313		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1314		      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1315	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1316		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1317		      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1318	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1319		      pwrb,
1320		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1321		      exp_statsn) / 32] + 1));
1322	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1323		      pwrb, pwrb_handle->wrb_index);
1324
1325	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1326		      max_burst_length, pwrb, params->dw[offsetof
1327		      (struct amap_beiscsi_offload_params,
1328		      max_burst_length) / 32]);
1329
1330	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1331		      pwrb, pwrb_handle->wrb_index);
1332	if (pwrb_context->plast_wrb)
1333		AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1334			      ptr2nextwrb,
1335			      pwrb_context->plast_wrb,
1336			      pwrb_handle->wrb_index);
1337	pwrb_context->plast_wrb = pwrb;
1338
1339	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1340		      session_state, pwrb, 0);
1341	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1342		      pwrb, 1);
1343	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1344		      pwrb, 0);
1345	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1346		      0);
1347
1348	mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1349	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1350		      pad_buffer_addr_hi, pwrb,
1351		      mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1352	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1353		      pad_buffer_addr_lo, pwrb,
1354		      mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1355}
1356
1357void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1358			     struct wrb_handle *pwrb_handle,
1359			     struct hwi_wrb_context *pwrb_context)
1360{
1361	struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1362
1363	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1364		      max_burst_length, pwrb, params->dw[offsetof
1365		      (struct amap_beiscsi_offload_params,
1366		      max_burst_length) / 32]);
1367	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1368		      type, pwrb,
1369		      BE_TGT_CTX_UPDT_CMD);
1370	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1371		      ptr2nextwrb,
1372		      pwrb, pwrb_handle->wrb_index);
1373	if (pwrb_context->plast_wrb)
1374		AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1375			      ptr2nextwrb,
1376			      pwrb_context->plast_wrb,
1377			      pwrb_handle->wrb_index);
1378	pwrb_context->plast_wrb = pwrb;
1379
1380	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1381		      pwrb, pwrb_handle->wrb_index);
1382	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1383		      max_send_data_segment_length, pwrb,
1384		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1385		      max_send_data_segment_length) / 32]);
1386	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1387		      first_burst_length, pwrb,
1388		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1389		      first_burst_length) / 32]);
1390	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1391		      max_recv_dataseg_len, pwrb,
1392		      params->dw[offsetof(struct amap_beiscsi_offload_params,
1393		      max_recv_data_segment_length) / 32]);
1394	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1395		      max_cxns, pwrb, BEISCSI_MAX_CXNS);
1396	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1397		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1398		      erl) / 32] & OFFLD_PARAMS_ERL));
1399	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1400		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1401		      dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1402	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1403		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1404		      hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1405	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1406		      ir2t, pwrb,
1407		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1408		      ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1409	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1410		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1411		      imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1412	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1413		      data_seq_inorder,
1414		      pwrb,
1415		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1416		      data_seq_inorder) / 32] &
1417		      OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1418	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1419		      pdu_seq_inorder,
1420		      pwrb,
1421		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1422		      pdu_seq_inorder) / 32] &
1423		      OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1424	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1425		      pwrb,
1426		      (params->dw[offsetof(struct amap_beiscsi_offload_params,
1427		      max_r2t) / 32] &
1428		      OFFLD_PARAMS_MAX_R2T) >> 8);
1429	AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1430		      pwrb,
1431		     (params->dw[offsetof(struct amap_beiscsi_offload_params,
1432		      exp_statsn) / 32] + 1));
1433}
1434
1435unsigned int beiscsi_invalidate_cxn(struct beiscsi_hba *phba,
1436				    struct beiscsi_endpoint *beiscsi_ep)
1437{
1438	struct be_invalidate_connection_params_in *req;
1439	struct be_ctrl_info *ctrl = &phba->ctrl;
1440	struct be_mcc_wrb *wrb;
1441	unsigned int tag = 0;
1442
1443	mutex_lock(&ctrl->mbox_lock);
1444	wrb = alloc_mcc_wrb(phba, &tag);
1445	if (!wrb) {
1446		mutex_unlock(&ctrl->mbox_lock);
1447		return 0;
1448	}
1449
1450	req = embedded_payload(wrb);
1451	be_wrb_hdr_prepare(wrb, sizeof(union be_invalidate_connection_params),
1452			   true, 0);
1453	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1454			   OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
1455			   sizeof(*req));
1456	req->session_handle = beiscsi_ep->fw_handle;
1457	req->cid = beiscsi_ep->ep_cid;
1458	if (beiscsi_ep->conn)
1459		req->cleanup_type = BE_CLEANUP_TYPE_INVALIDATE;
1460	else
1461		req->cleanup_type = BE_CLEANUP_TYPE_ISSUE_TCP_RST;
1462	/**
1463	 * 0 - non-persistent targets
1464	 * 1 - save session info on flash
1465	 */
1466	req->save_cfg = 0;
1467	be_mcc_notify(phba, tag);
1468	mutex_unlock(&ctrl->mbox_lock);
1469	return tag;
1470}
1471
1472unsigned int beiscsi_upload_cxn(struct beiscsi_hba *phba,
1473				struct beiscsi_endpoint *beiscsi_ep)
1474{
1475	struct be_ctrl_info *ctrl = &phba->ctrl;
1476	struct be_mcc_wrb *wrb;
1477	struct be_tcp_upload_params_in *req;
1478	unsigned int tag;
1479
1480	mutex_lock(&ctrl->mbox_lock);
1481	wrb = alloc_mcc_wrb(phba, &tag);
1482	if (!wrb) {
1483		mutex_unlock(&ctrl->mbox_lock);
1484		return 0;
1485	}
1486
1487	req = embedded_payload(wrb);
1488	be_wrb_hdr_prepare(wrb, sizeof(union be_tcp_upload_params), true, 0);
1489	be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
1490			   OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
1491	req->id = beiscsi_ep->ep_cid;
1492	if (beiscsi_ep->conn)
1493		req->upload_type = BE_UPLOAD_TYPE_GRACEFUL;
1494	else
1495		req->upload_type = BE_UPLOAD_TYPE_ABORT;
1496	be_mcc_notify(phba, tag);
1497	mutex_unlock(&ctrl->mbox_lock);
1498	return tag;
1499}
1500
1501int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba,
1502				 struct invldt_cmd_tbl *inv_tbl,
1503				 unsigned int nents)
1504{
1505	struct be_ctrl_info *ctrl = &phba->ctrl;
1506	struct invldt_cmds_params_in *req;
1507	struct be_dma_mem nonemb_cmd;
1508	struct be_mcc_wrb *wrb;
1509	unsigned int i, tag;
1510	struct be_sge *sge;
1511	int rc;
1512
1513	if (!nents || nents > BE_INVLDT_CMD_TBL_SZ)
1514		return -EINVAL;
1515
1516	nonemb_cmd.size = sizeof(union be_invldt_cmds_params);
1517	nonemb_cmd.va = dma_alloc_coherent(&phba->ctrl.pdev->dev,
1518					   nonemb_cmd.size, &nonemb_cmd.dma,
1519					   GFP_KERNEL);
1520	if (!nonemb_cmd.va) {
1521		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
1522			    "BM_%d : invldt_cmds_params alloc failed\n");
1523		return -ENOMEM;
1524	}
1525
1526	mutex_lock(&ctrl->mbox_lock);
1527	wrb = alloc_mcc_wrb(phba, &tag);
1528	if (!wrb) {
1529		mutex_unlock(&ctrl->mbox_lock);
1530		dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
1531				    nonemb_cmd.va, nonemb_cmd.dma);
1532		return -ENOMEM;
1533	}
1534
1535	req = nonemb_cmd.va;
1536	be_wrb_hdr_prepare(wrb, nonemb_cmd.size, false, 1);
1537	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1538			OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
1539			sizeof(*req));
1540	req->ref_handle = 0;
1541	req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
1542	for (i = 0; i < nents; i++) {
1543		req->table[i].icd = inv_tbl[i].icd;
1544		req->table[i].cid = inv_tbl[i].cid;
1545		req->icd_count++;
1546	}
1547	sge = nonembedded_sgl(wrb);
1548	sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
1549	sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd.dma));
1550	sge->len = cpu_to_le32(nonemb_cmd.size);
1551
1552	be_mcc_notify(phba, tag);
1553	mutex_unlock(&ctrl->mbox_lock);
1554
1555	rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
1556	if (rc != -EBUSY)
1557		dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
1558				    nonemb_cmd.va, nonemb_cmd.dma);
1559	return rc;
1560}
~/ Read-only file preview.