File Index
Files and directories
Sign in
FILE

be_iscsi.c

File preview with syntax highlighting.

linux-6.19.14/drivers/scsi/be2iscsi/be_iscsi.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * This file is part of the Emulex Linux Device Driver for Enterprise iSCSI
   4 * Host Bus Adapters. Refer to the README file included with this package
   5 * for driver version and adapter compatibility.
   6 *
   7 * Copyright (c) 2018 Broadcom. All Rights Reserved.
   8 * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
   9 *
  10 * Contact Information:
  11 * linux-drivers@broadcom.com
  12 */
  13
  14#include <scsi/libiscsi.h>
  15#include <scsi/scsi_transport_iscsi.h>
  16#include <scsi/scsi_transport.h>
  17#include <scsi/scsi_cmnd.h>
  18#include <scsi/scsi_device.h>
  19#include <scsi/scsi_host.h>
  20#include <scsi/scsi_netlink.h>
  21#include <net/netlink.h>
  22#include <scsi/scsi.h>
  23
  24#include "be_iscsi.h"
  25
  26extern struct iscsi_transport beiscsi_iscsi_transport;
  27
  28/**
  29 * beiscsi_session_create - creates a new iscsi session
  30 * @ep: pointer to iscsi ep
  31 * @cmds_max: max commands supported
  32 * @qdepth: max queue depth supported
  33 * @initial_cmdsn: initial iscsi CMDSN
  34 */
  35struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
  36						 u16 cmds_max,
  37						 u16 qdepth,
  38						 u32 initial_cmdsn)
  39{
  40	struct Scsi_Host *shost;
  41	struct beiscsi_endpoint *beiscsi_ep;
  42	struct iscsi_cls_session *cls_session;
  43	struct beiscsi_hba *phba;
  44	struct iscsi_session *sess;
  45	struct beiscsi_session *beiscsi_sess;
  46	struct beiscsi_io_task *io_task;
  47
  48
  49	if (!ep) {
  50		pr_err("beiscsi_session_create: invalid ep\n");
  51		return NULL;
  52	}
  53	beiscsi_ep = ep->dd_data;
  54	phba = beiscsi_ep->phba;
  55
  56	if (!beiscsi_hba_is_online(phba)) {
  57		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
  58			    "BS_%d : HBA in error 0x%lx\n", phba->state);
  59		return NULL;
  60	}
  61
  62	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
  63		    "BS_%d : In beiscsi_session_create\n");
  64	if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) {
  65		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
  66			    "BS_%d : Cannot handle %d cmds."
  67			    "Max cmds per session supported is %d. Using %d."
  68			    "\n", cmds_max,
  69			    beiscsi_ep->phba->params.wrbs_per_cxn,
  70			    beiscsi_ep->phba->params.wrbs_per_cxn);
  71
  72		cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
  73	}
  74
  75	shost = phba->shost;
  76	cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
  77					  shost, cmds_max,
  78					  sizeof(*beiscsi_sess),
  79					  sizeof(*io_task),
  80					  initial_cmdsn, ISCSI_MAX_TARGET);
  81	if (!cls_session)
  82		return NULL;
  83	sess = cls_session->dd_data;
  84	beiscsi_sess = sess->dd_data;
  85	beiscsi_sess->bhs_pool =  dma_pool_create("beiscsi_bhs_pool",
  86						   &phba->pcidev->dev,
  87						   sizeof(struct be_cmd_bhs),
  88						   64, 0);
  89	if (!beiscsi_sess->bhs_pool)
  90		goto destroy_sess;
  91
  92	return cls_session;
  93destroy_sess:
  94	iscsi_session_teardown(cls_session);
  95	return NULL;
  96}
  97
  98/**
  99 * beiscsi_session_destroy - destroys iscsi session
 100 * @cls_session:	pointer to iscsi cls session
 101 *
 102 * Destroys iSCSI session instance and releases
 103 * resources allocated for it.
 104 */
 105void beiscsi_session_destroy(struct iscsi_cls_session *cls_session)
 106{
 107	struct iscsi_session *sess = cls_session->dd_data;
 108	struct beiscsi_session *beiscsi_sess = sess->dd_data;
 109
 110	printk(KERN_INFO "In beiscsi_session_destroy\n");
 111	dma_pool_destroy(beiscsi_sess->bhs_pool);
 112	iscsi_session_teardown(cls_session);
 113}
 114
 115/**
 116 * beiscsi_session_fail(): Closing session with appropriate error
 117 * @cls_session: ptr to session
 118 **/
 119void beiscsi_session_fail(struct iscsi_cls_session *cls_session)
 120{
 121	iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 122}
 123
 124
 125/**
 126 * beiscsi_conn_create - create an instance of iscsi connection
 127 * @cls_session: ptr to iscsi_cls_session
 128 * @cid: iscsi cid
 129 */
 130struct iscsi_cls_conn *
 131beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid)
 132{
 133	struct beiscsi_hba *phba;
 134	struct Scsi_Host *shost;
 135	struct iscsi_cls_conn *cls_conn;
 136	struct beiscsi_conn *beiscsi_conn;
 137	struct iscsi_conn *conn;
 138	struct iscsi_session *sess;
 139	struct beiscsi_session *beiscsi_sess;
 140
 141	shost = iscsi_session_to_shost(cls_session);
 142	phba = iscsi_host_priv(shost);
 143
 144	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 145		    "BS_%d : In beiscsi_conn_create ,cid"
 146		    "from iscsi layer=%d\n", cid);
 147
 148	cls_conn = iscsi_conn_setup(cls_session, sizeof(*beiscsi_conn), cid);
 149	if (!cls_conn)
 150		return NULL;
 151
 152	conn = cls_conn->dd_data;
 153	beiscsi_conn = conn->dd_data;
 154	beiscsi_conn->ep = NULL;
 155	beiscsi_conn->phba = phba;
 156	beiscsi_conn->conn = conn;
 157	sess = cls_session->dd_data;
 158	beiscsi_sess = sess->dd_data;
 159	beiscsi_conn->beiscsi_sess = beiscsi_sess;
 160	return cls_conn;
 161}
 162
 163/**
 164 * beiscsi_conn_bind - Binds iscsi session/connection with TCP connection
 165 * @cls_session: pointer to iscsi cls session
 166 * @cls_conn: pointer to iscsi cls conn
 167 * @transport_fd: EP handle(64 bit)
 168 * @is_leading: indicate if this is the session leading connection (MCS)
 169 *
 170 * This function binds the TCP Conn with iSCSI Connection and Session.
 171 */
 172int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
 173		      struct iscsi_cls_conn *cls_conn,
 174		      u64 transport_fd, int is_leading)
 175{
 176	struct iscsi_conn *conn = cls_conn->dd_data;
 177	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 178	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
 179	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 180	struct hwi_controller *phwi_ctrlr = phba->phwi_ctrlr;
 181	struct hwi_wrb_context *pwrb_context;
 182	struct beiscsi_endpoint *beiscsi_ep;
 183	struct iscsi_endpoint *ep;
 184	uint16_t cri_index;
 185	int rc = 0;
 186
 187	ep = iscsi_lookup_endpoint(transport_fd);
 188	if (!ep)
 189		return -EINVAL;
 190
 191	beiscsi_ep = ep->dd_data;
 192
 193	if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) {
 194		rc = -EINVAL;
 195		goto put_ep;
 196	}
 197
 198	if (beiscsi_ep->phba != phba) {
 199		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 200			    "BS_%d : beiscsi_ep->hba=%p not equal to phba=%p\n",
 201			    beiscsi_ep->phba, phba);
 202		rc = -EEXIST;
 203		goto put_ep;
 204	}
 205	cri_index = BE_GET_CRI_FROM_CID(beiscsi_ep->ep_cid);
 206	if (phba->conn_table[cri_index]) {
 207		if (beiscsi_conn != phba->conn_table[cri_index] ||
 208		    beiscsi_ep != phba->conn_table[cri_index]->ep) {
 209			__beiscsi_log(phba, KERN_ERR,
 210				      "BS_%d : conn_table not empty at %u: cid %u conn %p:%p\n",
 211				      cri_index,
 212				      beiscsi_ep->ep_cid,
 213				      beiscsi_conn,
 214				      phba->conn_table[cri_index]);
 215			rc = -EINVAL;
 216			goto put_ep;
 217		}
 218	}
 219
 220	beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid;
 221	beiscsi_conn->ep = beiscsi_ep;
 222	beiscsi_ep->conn = beiscsi_conn;
 223	/**
 224	 * Each connection is associated with a WRBQ kept in wrb_context.
 225	 * Store doorbell offset for transmit path.
 226	 */
 227	pwrb_context = &phwi_ctrlr->wrb_context[cri_index];
 228	beiscsi_conn->doorbell_offset = pwrb_context->doorbell_offset;
 229	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 230		    "BS_%d : cid %d phba->conn_table[%u]=%p\n",
 231		    beiscsi_ep->ep_cid, cri_index, beiscsi_conn);
 232	phba->conn_table[cri_index] = beiscsi_conn;
 233
 234put_ep:
 235	iscsi_put_endpoint(ep);
 236	return rc;
 237}
 238
 239static int beiscsi_iface_create_ipv4(struct beiscsi_hba *phba)
 240{
 241	if (phba->ipv4_iface)
 242		return 0;
 243
 244	phba->ipv4_iface = iscsi_create_iface(phba->shost,
 245					      &beiscsi_iscsi_transport,
 246					      ISCSI_IFACE_TYPE_IPV4,
 247					      0, 0);
 248	if (!phba->ipv4_iface) {
 249		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 250			    "BS_%d : Could not "
 251			    "create default IPv4 address.\n");
 252		return -ENODEV;
 253	}
 254
 255	return 0;
 256}
 257
 258static int beiscsi_iface_create_ipv6(struct beiscsi_hba *phba)
 259{
 260	if (phba->ipv6_iface)
 261		return 0;
 262
 263	phba->ipv6_iface = iscsi_create_iface(phba->shost,
 264					      &beiscsi_iscsi_transport,
 265					      ISCSI_IFACE_TYPE_IPV6,
 266					      0, 0);
 267	if (!phba->ipv6_iface) {
 268		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 269			    "BS_%d : Could not "
 270			    "create default IPv6 address.\n");
 271		return -ENODEV;
 272	}
 273
 274	return 0;
 275}
 276
 277void beiscsi_iface_create_default(struct beiscsi_hba *phba)
 278{
 279	struct be_cmd_get_if_info_resp *if_info;
 280
 281	if (!beiscsi_if_get_info(phba, BEISCSI_IP_TYPE_V4, &if_info)) {
 282		beiscsi_iface_create_ipv4(phba);
 283		kfree(if_info);
 284	}
 285
 286	if (!beiscsi_if_get_info(phba, BEISCSI_IP_TYPE_V6, &if_info)) {
 287		beiscsi_iface_create_ipv6(phba);
 288		kfree(if_info);
 289	}
 290}
 291
 292void beiscsi_iface_destroy_default(struct beiscsi_hba *phba)
 293{
 294	if (phba->ipv6_iface) {
 295		iscsi_destroy_iface(phba->ipv6_iface);
 296		phba->ipv6_iface = NULL;
 297	}
 298	if (phba->ipv4_iface) {
 299		iscsi_destroy_iface(phba->ipv4_iface);
 300		phba->ipv4_iface = NULL;
 301	}
 302}
 303
 304/**
 305 * beiscsi_iface_config_vlan()- Set the VLAN TAG
 306 * @shost: Scsi Host for the driver instance
 307 * @iface_param: Interface paramters
 308 *
 309 * Set the VLAN TAG for the adapter or disable
 310 * the VLAN config
 311 *
 312 * returns
 313 *	Success: 0
 314 *	Failure: Non-Zero Value
 315 **/
 316static int
 317beiscsi_iface_config_vlan(struct Scsi_Host *shost,
 318			  struct iscsi_iface_param_info *iface_param)
 319{
 320	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 321	int ret = -EPERM;
 322
 323	switch (iface_param->param) {
 324	case ISCSI_NET_PARAM_VLAN_ENABLED:
 325		ret = 0;
 326		if (iface_param->value[0] != ISCSI_VLAN_ENABLE)
 327			ret = beiscsi_if_set_vlan(phba, BEISCSI_VLAN_DISABLE);
 328		break;
 329	case ISCSI_NET_PARAM_VLAN_TAG:
 330		ret = beiscsi_if_set_vlan(phba,
 331					  *((uint16_t *)iface_param->value));
 332		break;
 333	}
 334	return ret;
 335}
 336
 337
 338static int
 339beiscsi_iface_config_ipv4(struct Scsi_Host *shost,
 340			  struct iscsi_iface_param_info *info,
 341			  void *data, uint32_t dt_len)
 342{
 343	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 344	u8 *ip = NULL, *subnet = NULL, *gw;
 345	struct nlattr *nla;
 346	int ret = -EPERM;
 347
 348	/* Check the param */
 349	switch (info->param) {
 350	case ISCSI_NET_PARAM_IFACE_ENABLE:
 351		if (info->value[0] == ISCSI_IFACE_ENABLE)
 352			ret = beiscsi_iface_create_ipv4(phba);
 353		else {
 354			iscsi_destroy_iface(phba->ipv4_iface);
 355			phba->ipv4_iface = NULL;
 356		}
 357		break;
 358	case ISCSI_NET_PARAM_IPV4_GW:
 359		gw = info->value;
 360		ret = beiscsi_if_set_gw(phba, BEISCSI_IP_TYPE_V4, gw);
 361		break;
 362	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
 363		if (info->value[0] == ISCSI_BOOTPROTO_DHCP)
 364			ret = beiscsi_if_en_dhcp(phba, BEISCSI_IP_TYPE_V4);
 365		else if (info->value[0] == ISCSI_BOOTPROTO_STATIC)
 366			/* release DHCP IP address */
 367			ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4,
 368						   NULL, NULL);
 369		else
 370			beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 371				    "BS_%d : Invalid BOOTPROTO: %d\n",
 372				    info->value[0]);
 373		break;
 374	case ISCSI_NET_PARAM_IPV4_ADDR:
 375		ip = info->value;
 376		nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET);
 377		if (nla) {
 378			info = nla_data(nla);
 379			subnet = info->value;
 380		}
 381		ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4,
 382					   ip, subnet);
 383		break;
 384	case ISCSI_NET_PARAM_IPV4_SUBNET:
 385		/*
 386		 * OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR ioctl needs IP
 387		 * and subnet both. Find IP to be applied for this subnet.
 388		 */
 389		subnet = info->value;
 390		nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR);
 391		if (nla) {
 392			info = nla_data(nla);
 393			ip = info->value;
 394		}
 395		ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4,
 396					   ip, subnet);
 397		break;
 398	}
 399
 400	return ret;
 401}
 402
 403static int
 404beiscsi_iface_config_ipv6(struct Scsi_Host *shost,
 405			  struct iscsi_iface_param_info *iface_param,
 406			  void *data, uint32_t dt_len)
 407{
 408	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 409	int ret = -EPERM;
 410
 411	switch (iface_param->param) {
 412	case ISCSI_NET_PARAM_IFACE_ENABLE:
 413		if (iface_param->value[0] == ISCSI_IFACE_ENABLE)
 414			ret = beiscsi_iface_create_ipv6(phba);
 415		else {
 416			iscsi_destroy_iface(phba->ipv6_iface);
 417			phba->ipv6_iface = NULL;
 418		}
 419		break;
 420	case ISCSI_NET_PARAM_IPV6_ADDR:
 421		ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V6,
 422					   iface_param->value, NULL);
 423		break;
 424	}
 425
 426	return ret;
 427}
 428
 429int beiscsi_iface_set_param(struct Scsi_Host *shost,
 430			    void *data, uint32_t dt_len)
 431{
 432	struct iscsi_iface_param_info *iface_param = NULL;
 433	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 434	struct nlattr *attrib;
 435	uint32_t rm_len = dt_len;
 436	int ret;
 437
 438	if (!beiscsi_hba_is_online(phba)) {
 439		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 440			    "BS_%d : HBA in error 0x%lx\n", phba->state);
 441		return -EBUSY;
 442	}
 443
 444	/* update interface_handle */
 445	ret = beiscsi_if_get_handle(phba);
 446	if (ret) {
 447		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 448			    "BS_%d : Getting Interface Handle Failed\n");
 449		return ret;
 450	}
 451
 452	nla_for_each_attr(attrib, data, dt_len, rm_len) {
 453		/* ignore nla_type as it is never used */
 454		if (nla_len(attrib) < sizeof(*iface_param))
 455			return -EINVAL;
 456
 457		iface_param = nla_data(attrib);
 458
 459		if (iface_param->param_type != ISCSI_NET_PARAM)
 460			continue;
 461
 462		/*
 463		 * BE2ISCSI only supports 1 interface
 464		 */
 465		if (iface_param->iface_num) {
 466			beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 467				    "BS_%d : Invalid iface_num %d."
 468				    "Only iface_num 0 is supported.\n",
 469				    iface_param->iface_num);
 470
 471			return -EINVAL;
 472		}
 473
 474		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 475			    "BS_%d : %s.0 set param %d",
 476			    (iface_param->iface_type == ISCSI_IFACE_TYPE_IPV4) ?
 477			    "ipv4" : "ipv6", iface_param->param);
 478
 479		ret = -EPERM;
 480		switch (iface_param->param) {
 481		case ISCSI_NET_PARAM_VLAN_ENABLED:
 482		case ISCSI_NET_PARAM_VLAN_TAG:
 483			ret = beiscsi_iface_config_vlan(shost, iface_param);
 484			break;
 485		default:
 486			switch (iface_param->iface_type) {
 487			case ISCSI_IFACE_TYPE_IPV4:
 488				ret = beiscsi_iface_config_ipv4(shost,
 489								iface_param,
 490								data, dt_len);
 491				break;
 492			case ISCSI_IFACE_TYPE_IPV6:
 493				ret = beiscsi_iface_config_ipv6(shost,
 494								iface_param,
 495								data, dt_len);
 496				break;
 497			}
 498		}
 499
 500		if (ret == -EPERM) {
 501			__beiscsi_log(phba, KERN_ERR,
 502				      "BS_%d : %s.0 set param %d not permitted",
 503				      (iface_param->iface_type ==
 504				       ISCSI_IFACE_TYPE_IPV4) ? "ipv4" : "ipv6",
 505				      iface_param->param);
 506			ret = 0;
 507		}
 508		if (ret)
 509			break;
 510	}
 511
 512	return ret;
 513}
 514
 515static int __beiscsi_iface_get_param(struct beiscsi_hba *phba,
 516				     struct iscsi_iface *iface,
 517				     int param, char *buf)
 518{
 519	struct be_cmd_get_if_info_resp *if_info;
 520	int len, ip_type = BEISCSI_IP_TYPE_V4;
 521
 522	if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
 523		ip_type = BEISCSI_IP_TYPE_V6;
 524
 525	len = beiscsi_if_get_info(phba, ip_type, &if_info);
 526	if (len)
 527		return len;
 528
 529	switch (param) {
 530	case ISCSI_NET_PARAM_IPV4_ADDR:
 531		len = sprintf(buf, "%pI4\n", if_info->ip_addr.addr);
 532		break;
 533	case ISCSI_NET_PARAM_IPV6_ADDR:
 534		len = sprintf(buf, "%pI6\n", if_info->ip_addr.addr);
 535		break;
 536	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
 537		if (!if_info->dhcp_state)
 538			len = sprintf(buf, "static\n");
 539		else
 540			len = sprintf(buf, "dhcp\n");
 541		break;
 542	case ISCSI_NET_PARAM_IPV4_SUBNET:
 543		len = sprintf(buf, "%pI4\n", if_info->ip_addr.subnet_mask);
 544		break;
 545	case ISCSI_NET_PARAM_VLAN_ENABLED:
 546		len = sprintf(buf, "%s\n",
 547			      (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) ?
 548			      "disable" : "enable");
 549		break;
 550	case ISCSI_NET_PARAM_VLAN_ID:
 551		if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE)
 552			len = -EINVAL;
 553		else
 554			len = sprintf(buf, "%d\n",
 555				      (if_info->vlan_priority &
 556				       ISCSI_MAX_VLAN_ID));
 557		break;
 558	case ISCSI_NET_PARAM_VLAN_PRIORITY:
 559		if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE)
 560			len = -EINVAL;
 561		else
 562			len = sprintf(buf, "%d\n",
 563				      ((if_info->vlan_priority >> 13) &
 564				       ISCSI_MAX_VLAN_PRIORITY));
 565		break;
 566	default:
 567		WARN_ON(1);
 568	}
 569
 570	kfree(if_info);
 571	return len;
 572}
 573
 574int beiscsi_iface_get_param(struct iscsi_iface *iface,
 575			    enum iscsi_param_type param_type,
 576			    int param, char *buf)
 577{
 578	struct Scsi_Host *shost = iscsi_iface_to_shost(iface);
 579	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 580	struct be_cmd_get_def_gateway_resp gateway;
 581	int len = -EPERM;
 582
 583	if (param_type != ISCSI_NET_PARAM)
 584		return 0;
 585	if (!beiscsi_hba_is_online(phba)) {
 586		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 587			    "BS_%d : HBA in error 0x%lx\n", phba->state);
 588		return -EBUSY;
 589	}
 590
 591	switch (param) {
 592	case ISCSI_NET_PARAM_IPV4_ADDR:
 593	case ISCSI_NET_PARAM_IPV4_SUBNET:
 594	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
 595	case ISCSI_NET_PARAM_IPV6_ADDR:
 596	case ISCSI_NET_PARAM_VLAN_ENABLED:
 597	case ISCSI_NET_PARAM_VLAN_ID:
 598	case ISCSI_NET_PARAM_VLAN_PRIORITY:
 599		len = __beiscsi_iface_get_param(phba, iface, param, buf);
 600		break;
 601	case ISCSI_NET_PARAM_IFACE_ENABLE:
 602		if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)
 603			len = sprintf(buf, "%s\n",
 604				      phba->ipv4_iface ? "enable" : "disable");
 605		else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
 606			len = sprintf(buf, "%s\n",
 607				      phba->ipv6_iface ? "enable" : "disable");
 608		break;
 609	case ISCSI_NET_PARAM_IPV4_GW:
 610		memset(&gateway, 0, sizeof(gateway));
 611		len = beiscsi_if_get_gw(phba, BEISCSI_IP_TYPE_V4, &gateway);
 612		if (!len)
 613			len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr);
 614		break;
 615	}
 616
 617	return len;
 618}
 619
 620/**
 621 * beiscsi_ep_get_param - get the iscsi parameter
 622 * @ep: pointer to iscsi ep
 623 * @param: parameter type identifier
 624 * @buf: buffer pointer
 625 *
 626 * returns iscsi parameter
 627 */
 628int beiscsi_ep_get_param(struct iscsi_endpoint *ep,
 629			   enum iscsi_param param, char *buf)
 630{
 631	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
 632	int len;
 633
 634	beiscsi_log(beiscsi_ep->phba, KERN_INFO,
 635		    BEISCSI_LOG_CONFIG,
 636		    "BS_%d : In beiscsi_ep_get_param,"
 637		    " param= %d\n", param);
 638
 639	switch (param) {
 640	case ISCSI_PARAM_CONN_PORT:
 641		len = sprintf(buf, "%hu\n", beiscsi_ep->dst_tcpport);
 642		break;
 643	case ISCSI_PARAM_CONN_ADDRESS:
 644		if (beiscsi_ep->ip_type == BEISCSI_IP_TYPE_V4)
 645			len = sprintf(buf, "%pI4\n", &beiscsi_ep->dst_addr);
 646		else
 647			len = sprintf(buf, "%pI6\n", &beiscsi_ep->dst6_addr);
 648		break;
 649	default:
 650		len = -EPERM;
 651	}
 652	return len;
 653}
 654
 655int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
 656		      enum iscsi_param param, char *buf, int buflen)
 657{
 658	struct iscsi_conn *conn = cls_conn->dd_data;
 659	struct iscsi_session *session = conn->session;
 660	struct beiscsi_hba *phba = NULL;
 661	int ret;
 662
 663	phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
 664	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 665		    "BS_%d : In beiscsi_conn_set_param,"
 666		    " param= %d\n", param);
 667
 668	ret = iscsi_set_param(cls_conn, param, buf, buflen);
 669	if (ret)
 670		return ret;
 671	/*
 672	 * If userspace tried to set the value to higher than we can
 673	 * support override here.
 674	 */
 675	switch (param) {
 676	case ISCSI_PARAM_FIRST_BURST:
 677		if (session->first_burst > 8192)
 678			session->first_burst = 8192;
 679		break;
 680	case ISCSI_PARAM_MAX_RECV_DLENGTH:
 681		if (conn->max_recv_dlength > 65536)
 682			conn->max_recv_dlength = 65536;
 683		break;
 684	case ISCSI_PARAM_MAX_BURST:
 685		if (session->max_burst > 262144)
 686			session->max_burst = 262144;
 687		break;
 688	case ISCSI_PARAM_MAX_XMIT_DLENGTH:
 689		if (conn->max_xmit_dlength > 65536)
 690			conn->max_xmit_dlength = 65536;
 691		fallthrough;
 692	default:
 693		return 0;
 694	}
 695
 696	return 0;
 697}
 698
 699/**
 700 * beiscsi_get_port_state - Get the Port State
 701 * @shost : pointer to scsi_host structure
 702 *
 703 */
 704static void beiscsi_get_port_state(struct Scsi_Host *shost)
 705{
 706	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 707	struct iscsi_cls_host *ihost = shost->shost_data;
 708
 709	ihost->port_state = test_bit(BEISCSI_HBA_LINK_UP, &phba->state) ?
 710		ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN;
 711}
 712
 713/**
 714 * beiscsi_get_port_speed  - Get the Port Speed from Adapter
 715 * @shost : pointer to scsi_host structure
 716 *
 717 */
 718static void beiscsi_get_port_speed(struct Scsi_Host *shost)
 719{
 720	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 721	struct iscsi_cls_host *ihost = shost->shost_data;
 722
 723	switch (phba->port_speed) {
 724	case BE2ISCSI_LINK_SPEED_10MBPS:
 725		ihost->port_speed = ISCSI_PORT_SPEED_10MBPS;
 726		break;
 727	case BE2ISCSI_LINK_SPEED_100MBPS:
 728		ihost->port_speed = ISCSI_PORT_SPEED_100MBPS;
 729		break;
 730	case BE2ISCSI_LINK_SPEED_1GBPS:
 731		ihost->port_speed = ISCSI_PORT_SPEED_1GBPS;
 732		break;
 733	case BE2ISCSI_LINK_SPEED_10GBPS:
 734		ihost->port_speed = ISCSI_PORT_SPEED_10GBPS;
 735		break;
 736	case BE2ISCSI_LINK_SPEED_25GBPS:
 737		ihost->port_speed = ISCSI_PORT_SPEED_25GBPS;
 738		break;
 739	case BE2ISCSI_LINK_SPEED_40GBPS:
 740		ihost->port_speed = ISCSI_PORT_SPEED_40GBPS;
 741		break;
 742	default:
 743		ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN;
 744	}
 745}
 746
 747/**
 748 * beiscsi_get_host_param - get the iscsi parameter
 749 * @shost: pointer to scsi_host structure
 750 * @param: parameter type identifier
 751 * @buf: buffer pointer
 752 *
 753 */
 754int beiscsi_get_host_param(struct Scsi_Host *shost,
 755			   enum iscsi_host_param param, char *buf)
 756{
 757	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 758	int status = 0;
 759
 760	if (!beiscsi_hba_is_online(phba)) {
 761		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 762			    "BS_%d : HBA in error 0x%lx\n", phba->state);
 763		return 0;
 764	}
 765	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 766		    "BS_%d : In beiscsi_get_host_param, param = %d\n", param);
 767
 768	switch (param) {
 769	case ISCSI_HOST_PARAM_HWADDRESS:
 770		status = beiscsi_get_macaddr(buf, phba);
 771		if (status < 0) {
 772			beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 773				    "BS_%d : beiscsi_get_macaddr Failed\n");
 774			return 0;
 775		}
 776		break;
 777	case ISCSI_HOST_PARAM_INITIATOR_NAME:
 778		/* try fetching user configured name first */
 779		status = beiscsi_get_initiator_name(phba, buf, true);
 780		if (status < 0) {
 781			status = beiscsi_get_initiator_name(phba, buf, false);
 782			if (status < 0) {
 783				beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
 784					    "BS_%d : Retrieving Initiator Name Failed\n");
 785				status = 0;
 786			}
 787		}
 788		break;
 789	case ISCSI_HOST_PARAM_PORT_STATE:
 790		beiscsi_get_port_state(shost);
 791		status = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost));
 792		break;
 793	case ISCSI_HOST_PARAM_PORT_SPEED:
 794		beiscsi_get_port_speed(shost);
 795		status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost));
 796		break;
 797	default:
 798		return iscsi_host_get_param(shost, param, buf);
 799	}
 800	return status;
 801}
 802
 803int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba)
 804{
 805	struct be_cmd_get_nic_conf_resp resp;
 806	int rc;
 807
 808	if (phba->mac_addr_set)
 809		return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
 810
 811	memset(&resp, 0, sizeof(resp));
 812	rc = mgmt_get_nic_conf(phba, &resp);
 813	if (rc)
 814		return rc;
 815
 816	phba->mac_addr_set = true;
 817	memcpy(phba->mac_address, resp.mac_address, ETH_ALEN);
 818	return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
 819}
 820
 821/**
 822 * beiscsi_conn_get_stats - get the iscsi stats
 823 * @cls_conn: pointer to iscsi cls conn
 824 * @stats: pointer to iscsi_stats structure
 825 *
 826 * returns iscsi stats
 827 */
 828void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn,
 829			    struct iscsi_stats *stats)
 830{
 831	struct iscsi_conn *conn = cls_conn->dd_data;
 832	struct beiscsi_hba *phba = NULL;
 833
 834	phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
 835	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 836		    "BS_%d : In beiscsi_conn_get_stats\n");
 837
 838	stats->txdata_octets = conn->txdata_octets;
 839	stats->rxdata_octets = conn->rxdata_octets;
 840	stats->dataout_pdus = conn->dataout_pdus_cnt;
 841	stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
 842	stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
 843	stats->datain_pdus = conn->datain_pdus_cnt;
 844	stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
 845	stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
 846	stats->r2t_pdus = conn->r2t_pdus_cnt;
 847	stats->digest_err = 0;
 848	stats->timeout_err = 0;
 849	stats->custom_length = 1;
 850	strcpy(stats->custom[0].desc, "eh_abort_cnt");
 851	stats->custom[0].value = conn->eh_abort_cnt;
 852}
 853
 854/**
 855 * beiscsi_set_params_for_offld - get the parameters for offload
 856 * @beiscsi_conn: pointer to beiscsi_conn
 857 * @params: pointer to offload_params structure
 858 */
 859static void  beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn,
 860					  struct beiscsi_offload_params *params)
 861{
 862	struct iscsi_conn *conn = beiscsi_conn->conn;
 863	struct iscsi_session *session = conn->session;
 864
 865	AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_burst_length,
 866		      params, session->max_burst);
 867	AMAP_SET_BITS(struct amap_beiscsi_offload_params,
 868		      max_send_data_segment_length, params,
 869		      conn->max_xmit_dlength);
 870	AMAP_SET_BITS(struct amap_beiscsi_offload_params, first_burst_length,
 871		      params, session->first_burst);
 872	AMAP_SET_BITS(struct amap_beiscsi_offload_params, erl, params,
 873		      session->erl);
 874	AMAP_SET_BITS(struct amap_beiscsi_offload_params, dde, params,
 875		      conn->datadgst_en);
 876	AMAP_SET_BITS(struct amap_beiscsi_offload_params, hde, params,
 877		      conn->hdrdgst_en);
 878	AMAP_SET_BITS(struct amap_beiscsi_offload_params, ir2t, params,
 879		      session->initial_r2t_en);
 880	AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params,
 881		      session->imm_data_en);
 882	AMAP_SET_BITS(struct amap_beiscsi_offload_params,
 883		      data_seq_inorder, params,
 884		      session->dataseq_inorder_en);
 885	AMAP_SET_BITS(struct amap_beiscsi_offload_params,
 886		      pdu_seq_inorder, params,
 887		      session->pdu_inorder_en);
 888	AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_r2t, params,
 889		      session->max_r2t);
 890	AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params,
 891		      (conn->exp_statsn - 1));
 892	AMAP_SET_BITS(struct amap_beiscsi_offload_params,
 893		      max_recv_data_segment_length, params,
 894		      conn->max_recv_dlength);
 895
 896}
 897
 898/**
 899 * beiscsi_conn_start - offload of session to chip
 900 * @cls_conn: pointer to beiscsi_conn
 901 */
 902int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
 903{
 904	struct iscsi_conn *conn = cls_conn->dd_data;
 905	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 906	struct beiscsi_endpoint *beiscsi_ep;
 907	struct beiscsi_offload_params params;
 908	struct beiscsi_hba *phba;
 909
 910	phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
 911
 912	if (!beiscsi_hba_is_online(phba)) {
 913		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 914			    "BS_%d : HBA in error 0x%lx\n", phba->state);
 915		return -EBUSY;
 916	}
 917	beiscsi_log(beiscsi_conn->phba, KERN_INFO, BEISCSI_LOG_CONFIG,
 918		    "BS_%d : In beiscsi_conn_start\n");
 919
 920	memset(&params, 0, sizeof(struct beiscsi_offload_params));
 921	beiscsi_ep = beiscsi_conn->ep;
 922	if (!beiscsi_ep)
 923		beiscsi_log(beiscsi_conn->phba, KERN_ERR,
 924			    BEISCSI_LOG_CONFIG,
 925			    "BS_%d : In beiscsi_conn_start , no beiscsi_ep\n");
 926
 927	beiscsi_conn->login_in_progress = 0;
 928	beiscsi_set_params_for_offld(beiscsi_conn, &params);
 929	beiscsi_offload_connection(beiscsi_conn, &params);
 930	iscsi_conn_start(cls_conn);
 931	return 0;
 932}
 933
 934/**
 935 * beiscsi_get_cid - Allocate a cid
 936 * @phba: The phba instance
 937 */
 938static int beiscsi_get_cid(struct beiscsi_hba *phba)
 939{
 940	uint16_t cid_avlbl_ulp0, cid_avlbl_ulp1;
 941	unsigned short cid, cid_from_ulp;
 942	struct ulp_cid_info *cid_info;
 943
 944	/* Find the ULP which has more CID available */
 945	cid_avlbl_ulp0 = (phba->cid_array_info[BEISCSI_ULP0]) ?
 946			  BEISCSI_ULP0_AVLBL_CID(phba) : 0;
 947	cid_avlbl_ulp1 = (phba->cid_array_info[BEISCSI_ULP1]) ?
 948			  BEISCSI_ULP1_AVLBL_CID(phba) : 0;
 949	cid_from_ulp = (cid_avlbl_ulp0 > cid_avlbl_ulp1) ?
 950			BEISCSI_ULP0 : BEISCSI_ULP1;
 951	/**
 952	 * If iSCSI protocol is loaded only on ULP 0, and when cid_avlbl_ulp
 953	 * is ZERO for both, ULP 1 is returned.
 954	 * Check if ULP is loaded before getting new CID.
 955	 */
 956	if (!test_bit(cid_from_ulp, (void *)&phba->fw_config.ulp_supported))
 957		return BE_INVALID_CID;
 958
 959	cid_info = phba->cid_array_info[cid_from_ulp];
 960	cid = cid_info->cid_array[cid_info->cid_alloc];
 961	if (!cid_info->avlbl_cids || cid == BE_INVALID_CID) {
 962		__beiscsi_log(phba, KERN_ERR,
 963				"BS_%d : failed to get cid: available %u:%u\n",
 964				cid_info->avlbl_cids, cid_info->cid_free);
 965		return BE_INVALID_CID;
 966	}
 967	/* empty the slot */
 968	cid_info->cid_array[cid_info->cid_alloc++] = BE_INVALID_CID;
 969	if (cid_info->cid_alloc == BEISCSI_GET_CID_COUNT(phba, cid_from_ulp))
 970		cid_info->cid_alloc = 0;
 971	cid_info->avlbl_cids--;
 972	return cid;
 973}
 974
 975/**
 976 * beiscsi_put_cid - Free the cid
 977 * @phba: The phba for which the cid is being freed
 978 * @cid: The cid to free
 979 */
 980static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
 981{
 982	uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
 983	struct hwi_wrb_context *pwrb_context;
 984	struct hwi_controller *phwi_ctrlr;
 985	struct ulp_cid_info *cid_info;
 986	uint16_t cid_post_ulp;
 987
 988	phwi_ctrlr = phba->phwi_ctrlr;
 989	pwrb_context = &phwi_ctrlr->wrb_context[cri_index];
 990	cid_post_ulp = pwrb_context->ulp_num;
 991
 992	cid_info = phba->cid_array_info[cid_post_ulp];
 993	/* fill only in empty slot */
 994	if (cid_info->cid_array[cid_info->cid_free] != BE_INVALID_CID) {
 995		__beiscsi_log(phba, KERN_ERR,
 996			      "BS_%d : failed to put cid %u: available %u:%u\n",
 997			      cid, cid_info->avlbl_cids, cid_info->cid_free);
 998		return;
 999	}
1000	cid_info->cid_array[cid_info->cid_free++] = cid;
1001	if (cid_info->cid_free == BEISCSI_GET_CID_COUNT(phba, cid_post_ulp))
1002		cid_info->cid_free = 0;
1003	cid_info->avlbl_cids++;
1004}
1005
1006/**
1007 * beiscsi_free_ep - free endpoint
1008 * @beiscsi_ep: pointer to device endpoint struct
1009 */
1010static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
1011{
1012	struct beiscsi_hba *phba = beiscsi_ep->phba;
1013	struct beiscsi_conn *beiscsi_conn;
1014
1015	beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
1016	beiscsi_ep->phba = NULL;
1017	/* clear this to track freeing in beiscsi_ep_disconnect */
1018	phba->ep_array[BE_GET_CRI_FROM_CID(beiscsi_ep->ep_cid)] = NULL;
1019
1020	/**
1021	 * Check if any connection resource allocated by driver
1022	 * is to be freed.This case occurs when target redirection
1023	 * or connection retry is done.
1024	 **/
1025	if (!beiscsi_ep->conn)
1026		return;
1027
1028	beiscsi_conn = beiscsi_ep->conn;
1029	/**
1030	 * Break ep->conn link here so that completions after
1031	 * this are ignored.
1032	 */
1033	beiscsi_ep->conn = NULL;
1034	if (beiscsi_conn->login_in_progress) {
1035		beiscsi_free_mgmt_task_handles(beiscsi_conn,
1036					       beiscsi_conn->task);
1037		beiscsi_conn->login_in_progress = 0;
1038	}
1039}
1040
1041/**
1042 * beiscsi_open_conn - Ask FW to open a TCP connection
1043 * @ep: pointer to device endpoint struct
1044 * @src_addr: The source IP address
1045 * @dst_addr: The Destination  IP address
1046 * @non_blocking: blocking or non-blocking call
1047 *
1048 * Asks the FW to open a TCP connection
1049 */
1050static int beiscsi_open_conn(struct iscsi_endpoint *ep,
1051			     struct sockaddr *src_addr,
1052			     struct sockaddr *dst_addr, int non_blocking)
1053{
1054	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
1055	struct beiscsi_hba *phba = beiscsi_ep->phba;
1056	struct tcp_connect_and_offload_out *ptcpcnct_out;
1057	struct be_dma_mem nonemb_cmd;
1058	unsigned int tag, req_memsize;
1059	int ret = -ENOMEM;
1060
1061	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1062		    "BS_%d : In beiscsi_open_conn\n");
1063
1064	beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
1065	if (beiscsi_ep->ep_cid == BE_INVALID_CID) {
1066		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1067			    "BS_%d : No free cid available\n");
1068		return ret;
1069	}
1070
1071	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1072		    "BS_%d : In beiscsi_open_conn, ep_cid=%d\n",
1073		    beiscsi_ep->ep_cid);
1074
1075	phba->ep_array[BE_GET_CRI_FROM_CID
1076		       (beiscsi_ep->ep_cid)] = ep;
1077
1078	beiscsi_ep->cid_vld = 0;
1079
1080	if (is_chip_be2_be3r(phba))
1081		req_memsize = sizeof(struct tcp_connect_and_offload_in);
1082	else
1083		req_memsize = sizeof(struct tcp_connect_and_offload_in_v1);
1084
1085	nonemb_cmd.va = dma_alloc_coherent(&phba->ctrl.pdev->dev,
1086				req_memsize,
1087				&nonemb_cmd.dma, GFP_KERNEL);
1088	if (nonemb_cmd.va == NULL) {
1089
1090		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1091			    "BS_%d : Failed to allocate memory for"
1092			    " mgmt_open_connection\n");
1093
1094		beiscsi_free_ep(beiscsi_ep);
1095		return -ENOMEM;
1096	}
1097	nonemb_cmd.size = req_memsize;
1098	memset(nonemb_cmd.va, 0, nonemb_cmd.size);
1099	tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
1100	if (!tag) {
1101		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1102			    "BS_%d : mgmt_open_connection Failed for cid=%d\n",
1103			    beiscsi_ep->ep_cid);
1104
1105		dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
1106				    nonemb_cmd.va, nonemb_cmd.dma);
1107		beiscsi_free_ep(beiscsi_ep);
1108		return -EAGAIN;
1109	}
1110
1111	ret = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
1112	if (ret) {
1113		beiscsi_log(phba, KERN_ERR,
1114			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1115			    "BS_%d : mgmt_open_connection Failed");
1116
1117		if (ret != -EBUSY)
1118			dma_free_coherent(&phba->ctrl.pdev->dev,
1119					nonemb_cmd.size, nonemb_cmd.va,
1120					nonemb_cmd.dma);
1121
1122		beiscsi_free_ep(beiscsi_ep);
1123		return ret;
1124	}
1125
1126	ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va;
1127	beiscsi_ep = ep->dd_data;
1128	beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
1129	beiscsi_ep->cid_vld = 1;
1130	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1131		    "BS_%d : mgmt_open_connection Success\n");
1132
1133	dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size,
1134			    nonemb_cmd.va, nonemb_cmd.dma);
1135	return 0;
1136}
1137
1138/**
1139 * beiscsi_ep_connect - Ask chip to create TCP Conn
1140 * @shost: Pointer to scsi_host structure
1141 * @dst_addr: The IP address of Target
1142 * @non_blocking: blocking or non-blocking call
1143 *
1144 * This routines first asks chip to create a connection and then allocates an EP
1145 */
1146struct iscsi_endpoint *
1147beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
1148		   int non_blocking)
1149{
1150	struct beiscsi_hba *phba;
1151	struct beiscsi_endpoint *beiscsi_ep;
1152	struct iscsi_endpoint *ep;
1153	int ret;
1154
1155	if (!shost) {
1156		ret = -ENXIO;
1157		pr_err("beiscsi_ep_connect shost is NULL\n");
1158		return ERR_PTR(ret);
1159	}
1160
1161	phba = iscsi_host_priv(shost);
1162	if (!beiscsi_hba_is_online(phba)) {
1163		ret = -EIO;
1164		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1165			    "BS_%d : HBA in error 0x%lx\n", phba->state);
1166		return ERR_PTR(ret);
1167	}
1168	if (!test_bit(BEISCSI_HBA_LINK_UP, &phba->state)) {
1169		ret = -EBUSY;
1170		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1171			    "BS_%d : The Adapter Port state is Down!!!\n");
1172		return ERR_PTR(ret);
1173	}
1174
1175	ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint));
1176	if (!ep) {
1177		ret = -ENOMEM;
1178		return ERR_PTR(ret);
1179	}
1180
1181	beiscsi_ep = ep->dd_data;
1182	beiscsi_ep->phba = phba;
1183	beiscsi_ep->openiscsi_ep = ep;
1184	ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking);
1185	if (ret) {
1186		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1187			    "BS_%d : Failed in beiscsi_open_conn\n");
1188		goto free_ep;
1189	}
1190
1191	return ep;
1192
1193free_ep:
1194	iscsi_destroy_endpoint(ep);
1195	return ERR_PTR(ret);
1196}
1197
1198/**
1199 * beiscsi_ep_poll - Poll to see if connection is established
1200 * @ep:	endpoint to be used
1201 * @timeout_ms: timeout specified in millisecs
1202 *
1203 * Poll to see if TCP connection established
1204 */
1205int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
1206{
1207	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
1208
1209	beiscsi_log(beiscsi_ep->phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1210		    "BS_%d : In  beiscsi_ep_poll\n");
1211
1212	if (beiscsi_ep->cid_vld == 1)
1213		return 1;
1214	else
1215		return 0;
1216}
1217
1218/**
1219 * beiscsi_flush_cq()- Flush the CQ created.
1220 * @phba: ptr device priv structure.
1221 *
1222 * Before the connection resource are freed flush
1223 * all the CQ enteries
1224 **/
1225static void beiscsi_flush_cq(struct beiscsi_hba *phba)
1226{
1227	uint16_t i;
1228	struct be_eq_obj *pbe_eq;
1229	struct hwi_controller *phwi_ctrlr;
1230	struct hwi_context_memory *phwi_context;
1231
1232	phwi_ctrlr = phba->phwi_ctrlr;
1233	phwi_context = phwi_ctrlr->phwi_ctxt;
1234
1235	for (i = 0; i < phba->num_cpus; i++) {
1236		pbe_eq = &phwi_context->be_eq[i];
1237		irq_poll_disable(&pbe_eq->iopoll);
1238		beiscsi_process_cq(pbe_eq, BE2_MAX_NUM_CQ_PROC);
1239		irq_poll_enable(&pbe_eq->iopoll);
1240	}
1241}
1242
1243/**
1244 * beiscsi_conn_close - Invalidate and upload connection
1245 * @beiscsi_ep: pointer to device endpoint struct
1246 *
1247 * Returns 0 on success,  -1 on failure.
1248 */
1249static int beiscsi_conn_close(struct beiscsi_endpoint *beiscsi_ep)
1250{
1251	struct beiscsi_hba *phba = beiscsi_ep->phba;
1252	unsigned int tag, attempts;
1253	int ret;
1254
1255	/**
1256	 * Without successfully invalidating and uploading connection
1257	 * driver can't reuse the CID so attempt more than once.
1258	 */
1259	attempts = 0;
1260	while (attempts++ < 3) {
1261		tag = beiscsi_invalidate_cxn(phba, beiscsi_ep);
1262		if (tag) {
1263			ret = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
1264			if (!ret)
1265				break;
1266			beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1267				    "BS_%d : invalidate conn failed cid %d\n",
1268				    beiscsi_ep->ep_cid);
1269		}
1270	}
1271
1272	/* wait for all completions to arrive, then process them */
1273	msleep(250);
1274	/* flush CQ entries */
1275	beiscsi_flush_cq(phba);
1276
1277	if (attempts > 3)
1278		return -1;
1279
1280	attempts = 0;
1281	while (attempts++ < 3) {
1282		tag = beiscsi_upload_cxn(phba, beiscsi_ep);
1283		if (tag) {
1284			ret = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
1285			if (!ret)
1286				break;
1287			beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1288				    "BS_%d : upload conn failed cid %d\n",
1289				    beiscsi_ep->ep_cid);
1290		}
1291	}
1292	if (attempts > 3)
1293		return -1;
1294
1295	return 0;
1296}
1297
1298/**
1299 * beiscsi_ep_disconnect - Tears down the TCP connection
1300 * @ep:	endpoint to be used
1301 *
1302 * Tears down the TCP connection
1303 */
1304void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
1305{
1306	struct beiscsi_endpoint *beiscsi_ep;
1307	struct beiscsi_hba *phba;
1308	uint16_t cri_index;
1309
1310	beiscsi_ep = ep->dd_data;
1311	phba = beiscsi_ep->phba;
1312	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1313		    "BS_%d : In beiscsi_ep_disconnect for ep_cid = %u\n",
1314		    beiscsi_ep->ep_cid);
1315
1316	cri_index = BE_GET_CRI_FROM_CID(beiscsi_ep->ep_cid);
1317	if (!phba->ep_array[cri_index]) {
1318		__beiscsi_log(phba, KERN_ERR,
1319			      "BS_%d : ep_array at %u cid %u empty\n",
1320			      cri_index,
1321			      beiscsi_ep->ep_cid);
1322		return;
1323	}
1324
1325	if (!beiscsi_hba_is_online(phba)) {
1326		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1327			    "BS_%d : HBA in error 0x%lx\n", phba->state);
1328	} else {
1329		/**
1330		 * Make CID available even if close fails.
1331		 * If not freed, FW might fail open using the CID.
1332		 */
1333		if (beiscsi_conn_close(beiscsi_ep) < 0)
1334			__beiscsi_log(phba, KERN_ERR,
1335				      "BS_%d : close conn failed cid %d\n",
1336				      beiscsi_ep->ep_cid);
1337	}
1338
1339	beiscsi_free_ep(beiscsi_ep);
1340	if (!phba->conn_table[cri_index])
1341		__beiscsi_log(phba, KERN_ERR,
1342			      "BS_%d : conn_table empty at %u: cid %u\n",
1343			      cri_index, beiscsi_ep->ep_cid);
1344	phba->conn_table[cri_index] = NULL;
1345	iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
1346}
1347
1348umode_t beiscsi_attr_is_visible(int param_type, int param)
1349{
1350	switch (param_type) {
1351	case ISCSI_NET_PARAM:
1352		switch (param) {
1353		case ISCSI_NET_PARAM_IFACE_ENABLE:
1354		case ISCSI_NET_PARAM_IPV4_ADDR:
1355		case ISCSI_NET_PARAM_IPV4_SUBNET:
1356		case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
1357		case ISCSI_NET_PARAM_IPV4_GW:
1358		case ISCSI_NET_PARAM_IPV6_ADDR:
1359		case ISCSI_NET_PARAM_VLAN_ID:
1360		case ISCSI_NET_PARAM_VLAN_PRIORITY:
1361		case ISCSI_NET_PARAM_VLAN_ENABLED:
1362			return S_IRUGO;
1363		default:
1364			return 0;
1365		}
1366	case ISCSI_HOST_PARAM:
1367		switch (param) {
1368		case ISCSI_HOST_PARAM_HWADDRESS:
1369		case ISCSI_HOST_PARAM_INITIATOR_NAME:
1370		case ISCSI_HOST_PARAM_PORT_STATE:
1371		case ISCSI_HOST_PARAM_PORT_SPEED:
1372			return S_IRUGO;
1373		default:
1374			return 0;
1375		}
1376	case ISCSI_PARAM:
1377		switch (param) {
1378		case ISCSI_PARAM_MAX_RECV_DLENGTH:
1379		case ISCSI_PARAM_MAX_XMIT_DLENGTH:
1380		case ISCSI_PARAM_HDRDGST_EN:
1381		case ISCSI_PARAM_DATADGST_EN:
1382		case ISCSI_PARAM_CONN_ADDRESS:
1383		case ISCSI_PARAM_CONN_PORT:
1384		case ISCSI_PARAM_EXP_STATSN:
1385		case ISCSI_PARAM_PERSISTENT_ADDRESS:
1386		case ISCSI_PARAM_PERSISTENT_PORT:
1387		case ISCSI_PARAM_PING_TMO:
1388		case ISCSI_PARAM_RECV_TMO:
1389		case ISCSI_PARAM_INITIAL_R2T_EN:
1390		case ISCSI_PARAM_MAX_R2T:
1391		case ISCSI_PARAM_IMM_DATA_EN:
1392		case ISCSI_PARAM_FIRST_BURST:
1393		case ISCSI_PARAM_MAX_BURST:
1394		case ISCSI_PARAM_PDU_INORDER_EN:
1395		case ISCSI_PARAM_DATASEQ_INORDER_EN:
1396		case ISCSI_PARAM_ERL:
1397		case ISCSI_PARAM_TARGET_NAME:
1398		case ISCSI_PARAM_TPGT:
1399		case ISCSI_PARAM_USERNAME:
1400		case ISCSI_PARAM_PASSWORD:
1401		case ISCSI_PARAM_USERNAME_IN:
1402		case ISCSI_PARAM_PASSWORD_IN:
1403		case ISCSI_PARAM_FAST_ABORT:
1404		case ISCSI_PARAM_ABORT_TMO:
1405		case ISCSI_PARAM_LU_RESET_TMO:
1406		case ISCSI_PARAM_IFACE_NAME:
1407		case ISCSI_PARAM_INITIATOR_NAME:
1408			return S_IRUGO;
1409		default:
1410			return 0;
1411		}
1412	}
1413
1414	return 0;
1415}
~/ Read-only file preview.