xref: /linux/drivers/scsi/be2iscsi/be_iscsi.c (revision 0a513dd8736cdf96821d137b066b6fd44d3eb2cf)
16733b39aSJayamohan Kallickal /**
2255fa9a3SJayamohan Kallickal  * Copyright (C) 2005 - 2011 Emulex
36733b39aSJayamohan Kallickal  * All rights reserved.
46733b39aSJayamohan Kallickal  *
56733b39aSJayamohan Kallickal  * This program is free software; you can redistribute it and/or
66733b39aSJayamohan Kallickal  * modify it under the terms of the GNU General Public License version 2
76733b39aSJayamohan Kallickal  * as published by the Free Software Foundation.  The full GNU General
86733b39aSJayamohan Kallickal  * Public License is included in this distribution in the file called COPYING.
96733b39aSJayamohan Kallickal  *
10255fa9a3SJayamohan Kallickal  * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
116733b39aSJayamohan Kallickal  *
126733b39aSJayamohan Kallickal  * Contact Information:
13255fa9a3SJayamohan Kallickal  * linux-drivers@emulex.com
146733b39aSJayamohan Kallickal  *
15255fa9a3SJayamohan Kallickal  * Emulex
16255fa9a3SJayamohan Kallickal  * 3333 Susan Street
17255fa9a3SJayamohan Kallickal  * Costa Mesa, CA 92626
186733b39aSJayamohan Kallickal  */
196733b39aSJayamohan Kallickal 
206733b39aSJayamohan Kallickal #include <scsi/libiscsi.h>
216733b39aSJayamohan Kallickal #include <scsi/scsi_transport_iscsi.h>
226733b39aSJayamohan Kallickal #include <scsi/scsi_transport.h>
236733b39aSJayamohan Kallickal #include <scsi/scsi_cmnd.h>
246733b39aSJayamohan Kallickal #include <scsi/scsi_device.h>
256733b39aSJayamohan Kallickal #include <scsi/scsi_host.h>
260e43895eSMike Christie #include <scsi/scsi_netlink.h>
270e43895eSMike Christie #include <net/netlink.h>
286733b39aSJayamohan Kallickal #include <scsi/scsi.h>
296733b39aSJayamohan Kallickal 
306733b39aSJayamohan Kallickal #include "be_iscsi.h"
316733b39aSJayamohan Kallickal 
326733b39aSJayamohan Kallickal extern struct iscsi_transport beiscsi_iscsi_transport;
336733b39aSJayamohan Kallickal 
346733b39aSJayamohan Kallickal /**
356733b39aSJayamohan Kallickal  * beiscsi_session_create - creates a new iscsi session
366733b39aSJayamohan Kallickal  * @cmds_max: max commands supported
376733b39aSJayamohan Kallickal  * @qdepth: max queue depth supported
386733b39aSJayamohan Kallickal  * @initial_cmdsn: initial iscsi CMDSN
396733b39aSJayamohan Kallickal  */
406733b39aSJayamohan Kallickal struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
416733b39aSJayamohan Kallickal 						 u16 cmds_max,
426733b39aSJayamohan Kallickal 						 u16 qdepth,
436733b39aSJayamohan Kallickal 						 u32 initial_cmdsn)
446733b39aSJayamohan Kallickal {
456733b39aSJayamohan Kallickal 	struct Scsi_Host *shost;
466733b39aSJayamohan Kallickal 	struct beiscsi_endpoint *beiscsi_ep;
476733b39aSJayamohan Kallickal 	struct iscsi_cls_session *cls_session;
486733b39aSJayamohan Kallickal 	struct beiscsi_hba *phba;
49b8b9e1b8SJayamohan Kallickal 	struct iscsi_session *sess;
50b8b9e1b8SJayamohan Kallickal 	struct beiscsi_session *beiscsi_sess;
516733b39aSJayamohan Kallickal 	struct beiscsi_io_task *io_task;
526733b39aSJayamohan Kallickal 
536733b39aSJayamohan Kallickal 
546733b39aSJayamohan Kallickal 	if (!ep) {
5599bc5d55SJohn Soni Jose 		printk(KERN_ERR
5699bc5d55SJohn Soni Jose 		       "beiscsi_session_create: invalid ep\n");
576733b39aSJayamohan Kallickal 		return NULL;
586733b39aSJayamohan Kallickal 	}
596733b39aSJayamohan Kallickal 	beiscsi_ep = ep->dd_data;
606733b39aSJayamohan Kallickal 	phba = beiscsi_ep->phba;
616733b39aSJayamohan Kallickal 	shost = phba->shost;
6299bc5d55SJohn Soni Jose 
6399bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
6499bc5d55SJohn Soni Jose 		    "BS_%d : In beiscsi_session_create\n");
6599bc5d55SJohn Soni Jose 
666733b39aSJayamohan Kallickal 	if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) {
6799bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
6899bc5d55SJohn Soni Jose 			    "BS_%d : Cannot handle %d cmds."
696733b39aSJayamohan Kallickal 			    "Max cmds per session supported is %d. Using %d."
706733b39aSJayamohan Kallickal 			    "\n", cmds_max,
716733b39aSJayamohan Kallickal 			    beiscsi_ep->phba->params.wrbs_per_cxn,
726733b39aSJayamohan Kallickal 			    beiscsi_ep->phba->params.wrbs_per_cxn);
7399bc5d55SJohn Soni Jose 
746733b39aSJayamohan Kallickal 		cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
756733b39aSJayamohan Kallickal 	}
766733b39aSJayamohan Kallickal 
776733b39aSJayamohan Kallickal 	cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
786733b39aSJayamohan Kallickal 					  shost, cmds_max,
79b8b9e1b8SJayamohan Kallickal 					  sizeof(*beiscsi_sess),
80b8b9e1b8SJayamohan Kallickal 					  sizeof(*io_task),
816733b39aSJayamohan Kallickal 					  initial_cmdsn, ISCSI_MAX_TARGET);
826733b39aSJayamohan Kallickal 	if (!cls_session)
836733b39aSJayamohan Kallickal 		return NULL;
846733b39aSJayamohan Kallickal 	sess = cls_session->dd_data;
852afc95bfSJayamohan Kallickal 	beiscsi_sess = sess->dd_data;
862afc95bfSJayamohan Kallickal 	beiscsi_sess->bhs_pool =  pci_pool_create("beiscsi_bhs_pool",
872afc95bfSJayamohan Kallickal 						   phba->pcidev,
882afc95bfSJayamohan Kallickal 						   sizeof(struct be_cmd_bhs),
892afc95bfSJayamohan Kallickal 						   64, 0);
902afc95bfSJayamohan Kallickal 	if (!beiscsi_sess->bhs_pool)
912afc95bfSJayamohan Kallickal 		goto destroy_sess;
926733b39aSJayamohan Kallickal 
936733b39aSJayamohan Kallickal 	return cls_session;
942afc95bfSJayamohan Kallickal destroy_sess:
952afc95bfSJayamohan Kallickal 	iscsi_session_teardown(cls_session);
962afc95bfSJayamohan Kallickal 	return NULL;
976733b39aSJayamohan Kallickal }
986733b39aSJayamohan Kallickal 
996733b39aSJayamohan Kallickal /**
1006733b39aSJayamohan Kallickal  * beiscsi_session_destroy - destroys iscsi session
1016733b39aSJayamohan Kallickal  * @cls_session:	pointer to iscsi cls session
1026733b39aSJayamohan Kallickal  *
1036733b39aSJayamohan Kallickal  * Destroys iSCSI session instance and releases
1046733b39aSJayamohan Kallickal  * resources allocated for it.
1056733b39aSJayamohan Kallickal  */
1066733b39aSJayamohan Kallickal void beiscsi_session_destroy(struct iscsi_cls_session *cls_session)
1076733b39aSJayamohan Kallickal {
1086733b39aSJayamohan Kallickal 	struct iscsi_session *sess = cls_session->dd_data;
1092afc95bfSJayamohan Kallickal 	struct beiscsi_session *beiscsi_sess = sess->dd_data;
1106733b39aSJayamohan Kallickal 
11199bc5d55SJohn Soni Jose 	printk(KERN_INFO "In beiscsi_session_destroy\n");
1122afc95bfSJayamohan Kallickal 	pci_pool_destroy(beiscsi_sess->bhs_pool);
1136733b39aSJayamohan Kallickal 	iscsi_session_teardown(cls_session);
1146733b39aSJayamohan Kallickal }
1156733b39aSJayamohan Kallickal 
1166733b39aSJayamohan Kallickal /**
1176733b39aSJayamohan Kallickal  * beiscsi_conn_create - create an instance of iscsi connection
1186733b39aSJayamohan Kallickal  * @cls_session: ptr to iscsi_cls_session
1196733b39aSJayamohan Kallickal  * @cid: iscsi cid
1206733b39aSJayamohan Kallickal  */
1216733b39aSJayamohan Kallickal struct iscsi_cls_conn *
1226733b39aSJayamohan Kallickal beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid)
1236733b39aSJayamohan Kallickal {
1246733b39aSJayamohan Kallickal 	struct beiscsi_hba *phba;
1256733b39aSJayamohan Kallickal 	struct Scsi_Host *shost;
1266733b39aSJayamohan Kallickal 	struct iscsi_cls_conn *cls_conn;
1276733b39aSJayamohan Kallickal 	struct beiscsi_conn *beiscsi_conn;
1286733b39aSJayamohan Kallickal 	struct iscsi_conn *conn;
1292afc95bfSJayamohan Kallickal 	struct iscsi_session *sess;
1302afc95bfSJayamohan Kallickal 	struct beiscsi_session *beiscsi_sess;
1316733b39aSJayamohan Kallickal 
1326733b39aSJayamohan Kallickal 	shost = iscsi_session_to_shost(cls_session);
1336733b39aSJayamohan Kallickal 	phba = iscsi_host_priv(shost);
1346733b39aSJayamohan Kallickal 
13599bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
13699bc5d55SJohn Soni Jose 		    "BS_%d : In beiscsi_conn_create ,cid"
13799bc5d55SJohn Soni Jose 		    "from iscsi layer=%d\n", cid);
13899bc5d55SJohn Soni Jose 
1396733b39aSJayamohan Kallickal 	cls_conn = iscsi_conn_setup(cls_session, sizeof(*beiscsi_conn), cid);
1406733b39aSJayamohan Kallickal 	if (!cls_conn)
1416733b39aSJayamohan Kallickal 		return NULL;
1426733b39aSJayamohan Kallickal 
1436733b39aSJayamohan Kallickal 	conn = cls_conn->dd_data;
1446733b39aSJayamohan Kallickal 	beiscsi_conn = conn->dd_data;
1456733b39aSJayamohan Kallickal 	beiscsi_conn->ep = NULL;
1466733b39aSJayamohan Kallickal 	beiscsi_conn->phba = phba;
1476733b39aSJayamohan Kallickal 	beiscsi_conn->conn = conn;
1482afc95bfSJayamohan Kallickal 	sess = cls_session->dd_data;
1492afc95bfSJayamohan Kallickal 	beiscsi_sess = sess->dd_data;
1502afc95bfSJayamohan Kallickal 	beiscsi_conn->beiscsi_sess = beiscsi_sess;
1516733b39aSJayamohan Kallickal 	return cls_conn;
1526733b39aSJayamohan Kallickal }
1536733b39aSJayamohan Kallickal 
1546733b39aSJayamohan Kallickal /**
1556733b39aSJayamohan Kallickal  * beiscsi_bindconn_cid - Bind the beiscsi_conn with phba connection table
1566733b39aSJayamohan Kallickal  * @beiscsi_conn: The pointer to  beiscsi_conn structure
1576733b39aSJayamohan Kallickal  * @phba: The phba instance
1586733b39aSJayamohan Kallickal  * @cid: The cid to free
1596733b39aSJayamohan Kallickal  */
1606733b39aSJayamohan Kallickal static int beiscsi_bindconn_cid(struct beiscsi_hba *phba,
1616733b39aSJayamohan Kallickal 				struct beiscsi_conn *beiscsi_conn,
1626733b39aSJayamohan Kallickal 				unsigned int cid)
1636733b39aSJayamohan Kallickal {
1646733b39aSJayamohan Kallickal 	if (phba->conn_table[cid]) {
16599bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
16699bc5d55SJohn Soni Jose 			    "BS_%d : Connection table already occupied. Detected clash\n");
16799bc5d55SJohn Soni Jose 
1686733b39aSJayamohan Kallickal 		return -EINVAL;
1696733b39aSJayamohan Kallickal 	} else {
17099bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
17199bc5d55SJohn Soni Jose 			    "BS_%d : phba->conn_table[%d]=%p(beiscsi_conn)\n",
1726733b39aSJayamohan Kallickal 			    cid, beiscsi_conn);
17399bc5d55SJohn Soni Jose 
1746733b39aSJayamohan Kallickal 		phba->conn_table[cid] = beiscsi_conn;
1756733b39aSJayamohan Kallickal 	}
1766733b39aSJayamohan Kallickal 	return 0;
1776733b39aSJayamohan Kallickal }
1786733b39aSJayamohan Kallickal 
1796733b39aSJayamohan Kallickal /**
1806733b39aSJayamohan Kallickal  * beiscsi_conn_bind - Binds iscsi session/connection with TCP connection
1816733b39aSJayamohan Kallickal  * @cls_session: pointer to iscsi cls session
1826733b39aSJayamohan Kallickal  * @cls_conn: pointer to iscsi cls conn
1836733b39aSJayamohan Kallickal  * @transport_fd: EP handle(64 bit)
1846733b39aSJayamohan Kallickal  *
1856733b39aSJayamohan Kallickal  * This function binds the TCP Conn with iSCSI Connection and Session.
1866733b39aSJayamohan Kallickal  */
1876733b39aSJayamohan Kallickal int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
1886733b39aSJayamohan Kallickal 		      struct iscsi_cls_conn *cls_conn,
1896733b39aSJayamohan Kallickal 		      u64 transport_fd, int is_leading)
1906733b39aSJayamohan Kallickal {
1916733b39aSJayamohan Kallickal 	struct iscsi_conn *conn = cls_conn->dd_data;
1926733b39aSJayamohan Kallickal 	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
1933093b048SMike Christie 	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
1943093b048SMike Christie 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
1956733b39aSJayamohan Kallickal 	struct beiscsi_endpoint *beiscsi_ep;
1966733b39aSJayamohan Kallickal 	struct iscsi_endpoint *ep;
1976733b39aSJayamohan Kallickal 
1986733b39aSJayamohan Kallickal 	ep = iscsi_lookup_endpoint(transport_fd);
1996733b39aSJayamohan Kallickal 	if (!ep)
2006733b39aSJayamohan Kallickal 		return -EINVAL;
2016733b39aSJayamohan Kallickal 
2026733b39aSJayamohan Kallickal 	beiscsi_ep = ep->dd_data;
2036733b39aSJayamohan Kallickal 
2046733b39aSJayamohan Kallickal 	if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
2056733b39aSJayamohan Kallickal 		return -EINVAL;
2066733b39aSJayamohan Kallickal 
2076733b39aSJayamohan Kallickal 	if (beiscsi_ep->phba != phba) {
20899bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
20999bc5d55SJohn Soni Jose 			    "BS_%d : beiscsi_ep->hba=%p not equal to phba=%p\n",
2106733b39aSJayamohan Kallickal 			    beiscsi_ep->phba, phba);
21199bc5d55SJohn Soni Jose 
2126733b39aSJayamohan Kallickal 		return -EEXIST;
2136733b39aSJayamohan Kallickal 	}
2146733b39aSJayamohan Kallickal 
2156733b39aSJayamohan Kallickal 	beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid;
2166733b39aSJayamohan Kallickal 	beiscsi_conn->ep = beiscsi_ep;
2176733b39aSJayamohan Kallickal 	beiscsi_ep->conn = beiscsi_conn;
21899bc5d55SJohn Soni Jose 
21999bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
22099bc5d55SJohn Soni Jose 		    "BS_%d : beiscsi_conn=%p conn=%p ep_cid=%d\n",
2216733b39aSJayamohan Kallickal 		    beiscsi_conn, conn, beiscsi_ep->ep_cid);
22299bc5d55SJohn Soni Jose 
2236733b39aSJayamohan Kallickal 	return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid);
2246733b39aSJayamohan Kallickal }
2256733b39aSJayamohan Kallickal 
2260e43895eSMike Christie static int beiscsi_create_ipv4_iface(struct beiscsi_hba *phba)
2270e43895eSMike Christie {
2280e43895eSMike Christie 	if (phba->ipv4_iface)
2290e43895eSMike Christie 		return 0;
2300e43895eSMike Christie 
2310e43895eSMike Christie 	phba->ipv4_iface = iscsi_create_iface(phba->shost,
2320e43895eSMike Christie 					      &beiscsi_iscsi_transport,
2330e43895eSMike Christie 					      ISCSI_IFACE_TYPE_IPV4,
2340e43895eSMike Christie 					      0, 0);
2350e43895eSMike Christie 	if (!phba->ipv4_iface) {
23699bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
23799bc5d55SJohn Soni Jose 			    "BS_%d : Could not "
2380e43895eSMike Christie 			    "create default IPv4 address.\n");
2390e43895eSMike Christie 		return -ENODEV;
2400e43895eSMike Christie 	}
2410e43895eSMike Christie 
2420e43895eSMike Christie 	return 0;
2430e43895eSMike Christie }
2440e43895eSMike Christie 
2450e43895eSMike Christie static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba)
2460e43895eSMike Christie {
2470e43895eSMike Christie 	if (phba->ipv6_iface)
2480e43895eSMike Christie 		return 0;
2490e43895eSMike Christie 
2500e43895eSMike Christie 	phba->ipv6_iface = iscsi_create_iface(phba->shost,
2510e43895eSMike Christie 					      &beiscsi_iscsi_transport,
2520e43895eSMike Christie 					      ISCSI_IFACE_TYPE_IPV6,
2530e43895eSMike Christie 					      0, 0);
2540e43895eSMike Christie 	if (!phba->ipv6_iface) {
25599bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
25699bc5d55SJohn Soni Jose 			    "BS_%d : Could not "
2570e43895eSMike Christie 			    "create default IPv6 address.\n");
2580e43895eSMike Christie 		return -ENODEV;
2590e43895eSMike Christie 	}
2600e43895eSMike Christie 
2610e43895eSMike Christie 	return 0;
2620e43895eSMike Christie }
2630e43895eSMike Christie 
2640e43895eSMike Christie void beiscsi_create_def_ifaces(struct beiscsi_hba *phba)
2650e43895eSMike Christie {
2660e43895eSMike Christie 	struct be_cmd_get_if_info_resp if_info;
2670e43895eSMike Christie 
2680e43895eSMike Christie 	if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info))
2690e43895eSMike Christie 		beiscsi_create_ipv4_iface(phba);
2700e43895eSMike Christie 
2710e43895eSMike Christie 	if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info))
2720e43895eSMike Christie 		beiscsi_create_ipv6_iface(phba);
2730e43895eSMike Christie }
2740e43895eSMike Christie 
2750e43895eSMike Christie void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba)
2760e43895eSMike Christie {
2770e43895eSMike Christie 	if (phba->ipv6_iface)
2780e43895eSMike Christie 		iscsi_destroy_iface(phba->ipv6_iface);
2790e43895eSMike Christie 	if (phba->ipv4_iface)
2800e43895eSMike Christie 		iscsi_destroy_iface(phba->ipv4_iface);
2810e43895eSMike Christie }
2820e43895eSMike Christie 
2830e43895eSMike Christie static int
2840e43895eSMike Christie beiscsi_set_static_ip(struct Scsi_Host *shost,
2850e43895eSMike Christie 		struct iscsi_iface_param_info *iface_param,
2860e43895eSMike Christie 		void *data, uint32_t dt_len)
2870e43895eSMike Christie {
2880e43895eSMike Christie 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
2890e43895eSMike Christie 	struct iscsi_iface_param_info *iface_ip = NULL;
2900e43895eSMike Christie 	struct iscsi_iface_param_info *iface_subnet = NULL;
2910e43895eSMike Christie 	struct nlattr *nla;
2920e43895eSMike Christie 	int ret;
2930e43895eSMike Christie 
2940e43895eSMike Christie 
2950e43895eSMike Christie 	switch (iface_param->param) {
2960e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
2970e43895eSMike Christie 		nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR);
2980e43895eSMike Christie 		if (nla)
2990e43895eSMike Christie 			iface_ip = nla_data(nla);
3000e43895eSMike Christie 
3010e43895eSMike Christie 		nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET);
3020e43895eSMike Christie 		if (nla)
3030e43895eSMike Christie 			iface_subnet = nla_data(nla);
3040e43895eSMike Christie 		break;
3050e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_ADDR:
3060e43895eSMike Christie 		iface_ip = iface_param;
3070e43895eSMike Christie 		nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET);
3080e43895eSMike Christie 		if (nla)
3090e43895eSMike Christie 			iface_subnet = nla_data(nla);
3100e43895eSMike Christie 		break;
3110e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_SUBNET:
3120e43895eSMike Christie 		iface_subnet = iface_param;
3130e43895eSMike Christie 		nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR);
3140e43895eSMike Christie 		if (nla)
3150e43895eSMike Christie 			iface_ip = nla_data(nla);
3160e43895eSMike Christie 		break;
3170e43895eSMike Christie 	default:
31899bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
31999bc5d55SJohn Soni Jose 			    "BS_%d : Unsupported param %d\n",
3200e43895eSMike Christie 			    iface_param->param);
3210e43895eSMike Christie 	}
3220e43895eSMike Christie 
3230e43895eSMike Christie 	if (!iface_ip || !iface_subnet) {
32499bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
32599bc5d55SJohn Soni Jose 			    "BS_%d : IP and Subnet Mask required\n");
3260e43895eSMike Christie 		return -EINVAL;
3270e43895eSMike Christie 	}
3280e43895eSMike Christie 
3290e43895eSMike Christie 	ret = mgmt_set_ip(phba, iface_ip, iface_subnet,
3300e43895eSMike Christie 			ISCSI_BOOTPROTO_STATIC);
3310e43895eSMike Christie 
3320e43895eSMike Christie 	return ret;
3330e43895eSMike Christie }
3340e43895eSMike Christie 
3356f72238eSJohn Soni Jose /**
3366f72238eSJohn Soni Jose  * beiscsi_set_vlan_tag()- Set the VLAN TAG
3376f72238eSJohn Soni Jose  * @shost: Scsi Host for the driver instance
3386f72238eSJohn Soni Jose  * @iface_param: Interface paramters
3396f72238eSJohn Soni Jose  *
3406f72238eSJohn Soni Jose  * Set the VLAN TAG for the adapter or disable
3416f72238eSJohn Soni Jose  * the VLAN config
3426f72238eSJohn Soni Jose  *
3436f72238eSJohn Soni Jose  * returns
3446f72238eSJohn Soni Jose  *	Success: 0
3456f72238eSJohn Soni Jose  *	Failure: Non-Zero Value
3466f72238eSJohn Soni Jose  **/
3476f72238eSJohn Soni Jose static int
3486f72238eSJohn Soni Jose beiscsi_set_vlan_tag(struct Scsi_Host *shost,
3496f72238eSJohn Soni Jose 		      struct iscsi_iface_param_info *iface_param)
3506f72238eSJohn Soni Jose {
3516f72238eSJohn Soni Jose 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
3526f72238eSJohn Soni Jose 	int ret = 0;
3536f72238eSJohn Soni Jose 
3546f72238eSJohn Soni Jose 	/* Get the Interface Handle */
3556f72238eSJohn Soni Jose 	if (mgmt_get_all_if_id(phba)) {
3566f72238eSJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
3576f72238eSJohn Soni Jose 			    "BS_%d : Getting Interface Handle Failed\n");
3586f72238eSJohn Soni Jose 		return -EIO;
3596f72238eSJohn Soni Jose 	}
3606f72238eSJohn Soni Jose 
3616f72238eSJohn Soni Jose 	switch (iface_param->param) {
3626f72238eSJohn Soni Jose 	case ISCSI_NET_PARAM_VLAN_ENABLED:
3636f72238eSJohn Soni Jose 		if (iface_param->value[0] != ISCSI_VLAN_ENABLE)
3646f72238eSJohn Soni Jose 			ret = mgmt_set_vlan(phba, BEISCSI_VLAN_DISABLE);
3656f72238eSJohn Soni Jose 		break;
3666f72238eSJohn Soni Jose 	case ISCSI_NET_PARAM_VLAN_TAG:
3676f72238eSJohn Soni Jose 		ret = mgmt_set_vlan(phba,
3686f72238eSJohn Soni Jose 				    *((uint16_t *)iface_param->value));
3696f72238eSJohn Soni Jose 		break;
3706f72238eSJohn Soni Jose 	default:
3716f72238eSJohn Soni Jose 		beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
3726f72238eSJohn Soni Jose 			    "BS_%d : Unkown Param Type : %d\n",
3736f72238eSJohn Soni Jose 			    iface_param->param);
3746f72238eSJohn Soni Jose 		return -ENOSYS;
3756f72238eSJohn Soni Jose 	}
3766f72238eSJohn Soni Jose 	return ret;
3776f72238eSJohn Soni Jose }
3786f72238eSJohn Soni Jose 
3796f72238eSJohn Soni Jose 
3800e43895eSMike Christie static int
3810e43895eSMike Christie beiscsi_set_ipv4(struct Scsi_Host *shost,
3820e43895eSMike Christie 		struct iscsi_iface_param_info *iface_param,
3830e43895eSMike Christie 		void *data, uint32_t dt_len)
3840e43895eSMike Christie {
3850e43895eSMike Christie 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
3860e43895eSMike Christie 	int ret = 0;
3870e43895eSMike Christie 
3880e43895eSMike Christie 	/* Check the param */
3890e43895eSMike Christie 	switch (iface_param->param) {
3900e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_GW:
3910e43895eSMike Christie 		ret = mgmt_set_gateway(phba, iface_param);
3920e43895eSMike Christie 		break;
3930e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
3940e43895eSMike Christie 		if (iface_param->value[0] == ISCSI_BOOTPROTO_DHCP)
3950e43895eSMike Christie 			ret = mgmt_set_ip(phba, iface_param,
3960e43895eSMike Christie 					NULL, ISCSI_BOOTPROTO_DHCP);
3970e43895eSMike Christie 		else if (iface_param->value[0] == ISCSI_BOOTPROTO_STATIC)
3980e43895eSMike Christie 			ret = beiscsi_set_static_ip(shost, iface_param,
3990e43895eSMike Christie 						    data, dt_len);
4000e43895eSMike Christie 		else
40199bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
40299bc5d55SJohn Soni Jose 				    "BS_%d : Invalid BOOTPROTO: %d\n",
4030e43895eSMike Christie 				    iface_param->value[0]);
4040e43895eSMike Christie 		break;
4050e43895eSMike Christie 	case ISCSI_NET_PARAM_IFACE_ENABLE:
4060e43895eSMike Christie 		if (iface_param->value[0] == ISCSI_IFACE_ENABLE)
4070e43895eSMike Christie 			ret = beiscsi_create_ipv4_iface(phba);
4080e43895eSMike Christie 		else
4090e43895eSMike Christie 			iscsi_destroy_iface(phba->ipv4_iface);
4100e43895eSMike Christie 		break;
4110e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_SUBNET:
4120e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_ADDR:
4130e43895eSMike Christie 		ret = beiscsi_set_static_ip(shost, iface_param,
4140e43895eSMike Christie 					    data, dt_len);
4150e43895eSMike Christie 		break;
4166f72238eSJohn Soni Jose 	case ISCSI_NET_PARAM_VLAN_ENABLED:
4176f72238eSJohn Soni Jose 	case ISCSI_NET_PARAM_VLAN_TAG:
4186f72238eSJohn Soni Jose 		ret = beiscsi_set_vlan_tag(shost, iface_param);
4196f72238eSJohn Soni Jose 		break;
4200e43895eSMike Christie 	default:
42199bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
42299bc5d55SJohn Soni Jose 			    "BS_%d : Param %d not supported\n",
4230e43895eSMike Christie 			    iface_param->param);
4240e43895eSMike Christie 	}
4250e43895eSMike Christie 
4260e43895eSMike Christie 	return ret;
4270e43895eSMike Christie }
4280e43895eSMike Christie 
4290e43895eSMike Christie static int
4300e43895eSMike Christie beiscsi_set_ipv6(struct Scsi_Host *shost,
4310e43895eSMike Christie 		struct iscsi_iface_param_info *iface_param,
4320e43895eSMike Christie 		void *data, uint32_t dt_len)
4330e43895eSMike Christie {
4340e43895eSMike Christie 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
4350e43895eSMike Christie 	int ret = 0;
4360e43895eSMike Christie 
4370e43895eSMike Christie 	switch (iface_param->param) {
4380e43895eSMike Christie 	case ISCSI_NET_PARAM_IFACE_ENABLE:
4390e43895eSMike Christie 		if (iface_param->value[0] == ISCSI_IFACE_ENABLE)
4400e43895eSMike Christie 			ret = beiscsi_create_ipv6_iface(phba);
4410e43895eSMike Christie 		else {
4420e43895eSMike Christie 			iscsi_destroy_iface(phba->ipv6_iface);
4430e43895eSMike Christie 			ret = 0;
4440e43895eSMike Christie 		}
4450e43895eSMike Christie 		break;
4460e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV6_ADDR:
4470e43895eSMike Christie 		ret = mgmt_set_ip(phba, iface_param, NULL,
4480e43895eSMike Christie 				  ISCSI_BOOTPROTO_STATIC);
4490e43895eSMike Christie 		break;
4500e43895eSMike Christie 	default:
45199bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
45299bc5d55SJohn Soni Jose 			    "BS_%d : Param %d not supported\n",
4530e43895eSMike Christie 			    iface_param->param);
4540e43895eSMike Christie 	}
4550e43895eSMike Christie 
4560e43895eSMike Christie 	return ret;
4570e43895eSMike Christie }
4580e43895eSMike Christie 
4590e43895eSMike Christie int be2iscsi_iface_set_param(struct Scsi_Host *shost,
4600e43895eSMike Christie 		void *data, uint32_t dt_len)
4610e43895eSMike Christie {
4620e43895eSMike Christie 	struct iscsi_iface_param_info *iface_param = NULL;
46399bc5d55SJohn Soni Jose 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
4640e43895eSMike Christie 	struct nlattr *attrib;
4650e43895eSMike Christie 	uint32_t rm_len = dt_len;
4660e43895eSMike Christie 	int ret = 0 ;
4670e43895eSMike Christie 
4680e43895eSMike Christie 	nla_for_each_attr(attrib, data, dt_len, rm_len) {
4690e43895eSMike Christie 		iface_param = nla_data(attrib);
4700e43895eSMike Christie 
4710e43895eSMike Christie 		if (iface_param->param_type != ISCSI_NET_PARAM)
4720e43895eSMike Christie 			continue;
4730e43895eSMike Christie 
4740e43895eSMike Christie 		/*
4750e43895eSMike Christie 		 * BE2ISCSI only supports 1 interface
4760e43895eSMike Christie 		 */
4770e43895eSMike Christie 		if (iface_param->iface_num) {
47899bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
47999bc5d55SJohn Soni Jose 				    "BS_%d : Invalid iface_num %d."
4800e43895eSMike Christie 				    "Only iface_num 0 is supported.\n",
4810e43895eSMike Christie 				    iface_param->iface_num);
48299bc5d55SJohn Soni Jose 
4830e43895eSMike Christie 			return -EINVAL;
4840e43895eSMike Christie 		}
4850e43895eSMike Christie 
4860e43895eSMike Christie 		switch (iface_param->iface_type) {
4870e43895eSMike Christie 		case ISCSI_IFACE_TYPE_IPV4:
4880e43895eSMike Christie 			ret = beiscsi_set_ipv4(shost, iface_param,
4890e43895eSMike Christie 					       data, dt_len);
4900e43895eSMike Christie 			break;
4910e43895eSMike Christie 		case ISCSI_IFACE_TYPE_IPV6:
4920e43895eSMike Christie 			ret = beiscsi_set_ipv6(shost, iface_param,
4930e43895eSMike Christie 					       data, dt_len);
4940e43895eSMike Christie 			break;
4950e43895eSMike Christie 		default:
49699bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
49799bc5d55SJohn Soni Jose 				    "BS_%d : Invalid iface type :%d passed\n",
4980e43895eSMike Christie 				    iface_param->iface_type);
4990e43895eSMike Christie 			break;
5000e43895eSMike Christie 		}
5010e43895eSMike Christie 
5020e43895eSMike Christie 		if (ret)
5030e43895eSMike Christie 			return ret;
5040e43895eSMike Christie 	}
5050e43895eSMike Christie 
5060e43895eSMike Christie 	return ret;
5070e43895eSMike Christie }
5080e43895eSMike Christie 
5090e43895eSMike Christie static int be2iscsi_get_if_param(struct beiscsi_hba *phba,
5100e43895eSMike Christie 		struct iscsi_iface *iface, int param,
5110e43895eSMike Christie 		char *buf)
5120e43895eSMike Christie {
5130e43895eSMike Christie 	struct be_cmd_get_if_info_resp if_info;
5140e43895eSMike Christie 	int len, ip_type = BE2_IPV4;
5150e43895eSMike Christie 
5160e43895eSMike Christie 	memset(&if_info, 0, sizeof(if_info));
5170e43895eSMike Christie 
5180e43895eSMike Christie 	if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
5190e43895eSMike Christie 		ip_type = BE2_IPV6;
5200e43895eSMike Christie 
5210e43895eSMike Christie 	len = mgmt_get_if_info(phba, ip_type, &if_info);
5220e43895eSMike Christie 	if (len)
5230e43895eSMike Christie 		return len;
5240e43895eSMike Christie 
5250e43895eSMike Christie 	switch (param) {
5260e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_ADDR:
5270e43895eSMike Christie 		len = sprintf(buf, "%pI4\n", &if_info.ip_addr.addr);
5280e43895eSMike Christie 		break;
5290e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV6_ADDR:
5300e43895eSMike Christie 		len = sprintf(buf, "%pI6\n", &if_info.ip_addr.addr);
5310e43895eSMike Christie 		break;
5320e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
5330e43895eSMike Christie 		if (!if_info.dhcp_state)
5340e43895eSMike Christie 			len = sprintf(buf, "static");
5350e43895eSMike Christie 		else
5360e43895eSMike Christie 			len = sprintf(buf, "dhcp");
5370e43895eSMike Christie 		break;
5380e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_SUBNET:
5390e43895eSMike Christie 		len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask);
5400e43895eSMike Christie 		break;
5416f72238eSJohn Soni Jose 	case ISCSI_NET_PARAM_VLAN_ENABLED:
5426f72238eSJohn Soni Jose 		len = sprintf(buf, "%s\n",
5436f72238eSJohn Soni Jose 			     (if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
5446f72238eSJohn Soni Jose 			     ? "Disabled" : "Enabled");
5456f72238eSJohn Soni Jose 		break;
5466f72238eSJohn Soni Jose 	case ISCSI_NET_PARAM_VLAN_ID:
5476f72238eSJohn Soni Jose 		if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
5486f72238eSJohn Soni Jose 			return -EINVAL;
5496f72238eSJohn Soni Jose 		else
5506f72238eSJohn Soni Jose 			len = sprintf(buf, "%d\n",
5516f72238eSJohn Soni Jose 				     (if_info.vlan_priority &
5526f72238eSJohn Soni Jose 				     ISCSI_MAX_VLAN_ID));
5536f72238eSJohn Soni Jose 		break;
5546f72238eSJohn Soni Jose 	case ISCSI_NET_PARAM_VLAN_PRIORITY:
5556f72238eSJohn Soni Jose 		if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE)
5566f72238eSJohn Soni Jose 			return -EINVAL;
5576f72238eSJohn Soni Jose 		else
5586f72238eSJohn Soni Jose 			len = sprintf(buf, "%d\n",
5596f72238eSJohn Soni Jose 				     ((if_info.vlan_priority >> 13) &
5606f72238eSJohn Soni Jose 				     ISCSI_MAX_VLAN_PRIORITY));
5616f72238eSJohn Soni Jose 		break;
5620e43895eSMike Christie 	default:
5630e43895eSMike Christie 		WARN_ON(1);
5640e43895eSMike Christie 	}
5650e43895eSMike Christie 
5660e43895eSMike Christie 	return len;
5670e43895eSMike Christie }
5680e43895eSMike Christie 
5690e43895eSMike Christie int be2iscsi_iface_get_param(struct iscsi_iface *iface,
5700e43895eSMike Christie 		enum iscsi_param_type param_type,
5710e43895eSMike Christie 		int param, char *buf)
5720e43895eSMike Christie {
5730e43895eSMike Christie 	struct Scsi_Host *shost = iscsi_iface_to_shost(iface);
5740e43895eSMike Christie 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
5750e43895eSMike Christie 	struct be_cmd_get_def_gateway_resp gateway;
5760e43895eSMike Christie 	int len = -ENOSYS;
5770e43895eSMike Christie 
5780e43895eSMike Christie 	switch (param) {
5790e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_ADDR:
5800e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_SUBNET:
5810e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
5820e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV6_ADDR:
5836f72238eSJohn Soni Jose 	case ISCSI_NET_PARAM_VLAN_ENABLED:
5846f72238eSJohn Soni Jose 	case ISCSI_NET_PARAM_VLAN_ID:
5856f72238eSJohn Soni Jose 	case ISCSI_NET_PARAM_VLAN_PRIORITY:
5860e43895eSMike Christie 		len = be2iscsi_get_if_param(phba, iface, param, buf);
5870e43895eSMike Christie 		break;
5880e43895eSMike Christie 	case ISCSI_NET_PARAM_IFACE_ENABLE:
5890e43895eSMike Christie 		len = sprintf(buf, "enabled");
5900e43895eSMike Christie 		break;
5910e43895eSMike Christie 	case ISCSI_NET_PARAM_IPV4_GW:
5920e43895eSMike Christie 		memset(&gateway, 0, sizeof(gateway));
5930e43895eSMike Christie 		len = mgmt_get_gateway(phba, BE2_IPV4, &gateway);
5940e43895eSMike Christie 		if (!len)
5950e43895eSMike Christie 			len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr);
5960e43895eSMike Christie 		break;
5970e43895eSMike Christie 	default:
5980e43895eSMike Christie 		len = -ENOSYS;
5990e43895eSMike Christie 	}
6000e43895eSMike Christie 
6010e43895eSMike Christie 	return len;
6020e43895eSMike Christie }
6030e43895eSMike Christie 
6046733b39aSJayamohan Kallickal /**
605c7f7fd5bSMike Christie  * beiscsi_ep_get_param - get the iscsi parameter
606c7f7fd5bSMike Christie  * @ep: pointer to iscsi ep
6076733b39aSJayamohan Kallickal  * @param: parameter type identifier
6086733b39aSJayamohan Kallickal  * @buf: buffer pointer
6096733b39aSJayamohan Kallickal  *
6106733b39aSJayamohan Kallickal  * returns iscsi parameter
6116733b39aSJayamohan Kallickal  */
612c7f7fd5bSMike Christie int beiscsi_ep_get_param(struct iscsi_endpoint *ep,
6136733b39aSJayamohan Kallickal 			   enum iscsi_param param, char *buf)
6146733b39aSJayamohan Kallickal {
615c7f7fd5bSMike Christie 	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
6166733b39aSJayamohan Kallickal 	int len = 0;
6176733b39aSJayamohan Kallickal 
61899bc5d55SJohn Soni Jose 	beiscsi_log(beiscsi_ep->phba, KERN_INFO,
61999bc5d55SJohn Soni Jose 		    BEISCSI_LOG_CONFIG,
62099bc5d55SJohn Soni Jose 		    "BS_%d : In beiscsi_ep_get_param,"
62199bc5d55SJohn Soni Jose 		    " param= %d\n", param);
6226733b39aSJayamohan Kallickal 
6236733b39aSJayamohan Kallickal 	switch (param) {
6246733b39aSJayamohan Kallickal 	case ISCSI_PARAM_CONN_PORT:
6256733b39aSJayamohan Kallickal 		len = sprintf(buf, "%hu\n", beiscsi_ep->dst_tcpport);
6266733b39aSJayamohan Kallickal 		break;
6276733b39aSJayamohan Kallickal 	case ISCSI_PARAM_CONN_ADDRESS:
6286733b39aSJayamohan Kallickal 		if (beiscsi_ep->ip_type == BE2_IPV4)
6296733b39aSJayamohan Kallickal 			len = sprintf(buf, "%pI4\n", &beiscsi_ep->dst_addr);
6306733b39aSJayamohan Kallickal 		else
6316733b39aSJayamohan Kallickal 			len = sprintf(buf, "%pI6\n", &beiscsi_ep->dst6_addr);
6326733b39aSJayamohan Kallickal 		break;
6336733b39aSJayamohan Kallickal 	default:
634c7f7fd5bSMike Christie 		return -ENOSYS;
6356733b39aSJayamohan Kallickal 	}
6366733b39aSJayamohan Kallickal 	return len;
6376733b39aSJayamohan Kallickal }
6386733b39aSJayamohan Kallickal 
6396733b39aSJayamohan Kallickal int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
6406733b39aSJayamohan Kallickal 		      enum iscsi_param param, char *buf, int buflen)
6416733b39aSJayamohan Kallickal {
6426733b39aSJayamohan Kallickal 	struct iscsi_conn *conn = cls_conn->dd_data;
6436733b39aSJayamohan Kallickal 	struct iscsi_session *session = conn->session;
64499bc5d55SJohn Soni Jose 	struct beiscsi_hba *phba = NULL;
6456733b39aSJayamohan Kallickal 	int ret;
6466733b39aSJayamohan Kallickal 
64799bc5d55SJohn Soni Jose 	phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
64899bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
64999bc5d55SJohn Soni Jose 		    "BS_%d : In beiscsi_conn_set_param,"
65099bc5d55SJohn Soni Jose 		    " param= %d\n", param);
65199bc5d55SJohn Soni Jose 
6526733b39aSJayamohan Kallickal 	ret = iscsi_set_param(cls_conn, param, buf, buflen);
6536733b39aSJayamohan Kallickal 	if (ret)
6546733b39aSJayamohan Kallickal 		return ret;
6556733b39aSJayamohan Kallickal 	/*
6566733b39aSJayamohan Kallickal 	 * If userspace tried to set the value to higher than we can
6576733b39aSJayamohan Kallickal 	 * support override here.
6586733b39aSJayamohan Kallickal 	 */
6596733b39aSJayamohan Kallickal 	switch (param) {
6606733b39aSJayamohan Kallickal 	case ISCSI_PARAM_FIRST_BURST:
6616733b39aSJayamohan Kallickal 		if (session->first_burst > 8192)
6626733b39aSJayamohan Kallickal 			session->first_burst = 8192;
6636733b39aSJayamohan Kallickal 		break;
6646733b39aSJayamohan Kallickal 	case ISCSI_PARAM_MAX_RECV_DLENGTH:
6656733b39aSJayamohan Kallickal 		if (conn->max_recv_dlength > 65536)
6666733b39aSJayamohan Kallickal 			conn->max_recv_dlength = 65536;
6676733b39aSJayamohan Kallickal 		break;
6686733b39aSJayamohan Kallickal 	case ISCSI_PARAM_MAX_BURST:
669230dceb4SJayamohan Kallickal 		if (session->max_burst > 262144)
670230dceb4SJayamohan Kallickal 			session->max_burst = 262144;
6716733b39aSJayamohan Kallickal 		break;
67242f43c41SJayamohan Kallickal 	case ISCSI_PARAM_MAX_XMIT_DLENGTH:
67342f43c41SJayamohan Kallickal 		if ((conn->max_xmit_dlength > 65536) ||
67442f43c41SJayamohan Kallickal 		    (conn->max_xmit_dlength == 0))
67542f43c41SJayamohan Kallickal 			conn->max_xmit_dlength = 65536;
6766733b39aSJayamohan Kallickal 	default:
6776733b39aSJayamohan Kallickal 		return 0;
6786733b39aSJayamohan Kallickal 	}
6796733b39aSJayamohan Kallickal 
6806733b39aSJayamohan Kallickal 	return 0;
6816733b39aSJayamohan Kallickal }
6826733b39aSJayamohan Kallickal 
6836733b39aSJayamohan Kallickal /**
6842177199dSJohn Soni Jose  * beiscsi_get_initname - Read Initiator Name from flash
6852177199dSJohn Soni Jose  * @buf: buffer bointer
6862177199dSJohn Soni Jose  * @phba: The device priv structure instance
6872177199dSJohn Soni Jose  *
6882177199dSJohn Soni Jose  * returns number of bytes
6892177199dSJohn Soni Jose  */
6902177199dSJohn Soni Jose static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba)
6912177199dSJohn Soni Jose {
6922177199dSJohn Soni Jose 	int rc;
6932177199dSJohn Soni Jose 	unsigned int tag, wrb_num;
6942177199dSJohn Soni Jose 	unsigned short status, extd_status;
6952177199dSJohn Soni Jose 	struct be_mcc_wrb *wrb;
6962177199dSJohn Soni Jose 	struct be_cmd_hba_name *resp;
6972177199dSJohn Soni Jose 	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
6982177199dSJohn Soni Jose 
6992177199dSJohn Soni Jose 	tag = be_cmd_get_initname(phba);
7002177199dSJohn Soni Jose 	if (!tag) {
70199bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
70299bc5d55SJohn Soni Jose 			    "BS_%d : Getting Initiator Name Failed\n");
70399bc5d55SJohn Soni Jose 
7042177199dSJohn Soni Jose 		return -EBUSY;
7052177199dSJohn Soni Jose 	} else
7062177199dSJohn Soni Jose 		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
7072177199dSJohn Soni Jose 				phba->ctrl.mcc_numtag[tag]);
7082177199dSJohn Soni Jose 
7092177199dSJohn Soni Jose 	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
7102177199dSJohn Soni Jose 	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
7112177199dSJohn Soni Jose 	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
7122177199dSJohn Soni Jose 
7132177199dSJohn Soni Jose 	if (status || extd_status) {
71499bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR,
71599bc5d55SJohn Soni Jose 			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
71699bc5d55SJohn Soni Jose 			    "BS_%d : MailBox Command Failed with "
7172177199dSJohn Soni Jose 			    "status = %d extd_status = %d\n",
7182177199dSJohn Soni Jose 			    status, extd_status);
71999bc5d55SJohn Soni Jose 
7202177199dSJohn Soni Jose 		free_mcc_tag(&phba->ctrl, tag);
7212177199dSJohn Soni Jose 		return -EAGAIN;
7222177199dSJohn Soni Jose 	}
7232177199dSJohn Soni Jose 	wrb = queue_get_wrb(mccq, wrb_num);
7242177199dSJohn Soni Jose 	free_mcc_tag(&phba->ctrl, tag);
7252177199dSJohn Soni Jose 	resp = embedded_payload(wrb);
7262177199dSJohn Soni Jose 	rc = sprintf(buf, "%s\n", resp->initiator_name);
7272177199dSJohn Soni Jose 	return rc;
7282177199dSJohn Soni Jose }
7292177199dSJohn Soni Jose 
7302177199dSJohn Soni Jose /**
731c62eef0dSJohn Soni Jose  * beiscsi_get_port_state - Get the Port State
732c62eef0dSJohn Soni Jose  * @shost : pointer to scsi_host structure
733c62eef0dSJohn Soni Jose  *
734c62eef0dSJohn Soni Jose  * returns number of bytes
735c62eef0dSJohn Soni Jose  */
736c62eef0dSJohn Soni Jose static void beiscsi_get_port_state(struct Scsi_Host *shost)
737c62eef0dSJohn Soni Jose {
738c62eef0dSJohn Soni Jose 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
739c62eef0dSJohn Soni Jose 	struct iscsi_cls_host *ihost = shost->shost_data;
740c62eef0dSJohn Soni Jose 
741c62eef0dSJohn Soni Jose 	ihost->port_state = (phba->state == BE_ADAPTER_UP) ?
742c62eef0dSJohn Soni Jose 		ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN;
743c62eef0dSJohn Soni Jose }
744c62eef0dSJohn Soni Jose 
745c62eef0dSJohn Soni Jose /**
746c62eef0dSJohn Soni Jose  * beiscsi_get_port_speed  - Get the Port Speed from Adapter
747c62eef0dSJohn Soni Jose  * @shost : pointer to scsi_host structure
748c62eef0dSJohn Soni Jose  *
749c62eef0dSJohn Soni Jose  * returns Success/Failure
750c62eef0dSJohn Soni Jose  */
751c62eef0dSJohn Soni Jose static int beiscsi_get_port_speed(struct Scsi_Host *shost)
752c62eef0dSJohn Soni Jose {
753c62eef0dSJohn Soni Jose 	unsigned int tag, wrb_num;
754c62eef0dSJohn Soni Jose 	unsigned short status, extd_status;
755c62eef0dSJohn Soni Jose 	struct be_mcc_wrb *wrb;
756c62eef0dSJohn Soni Jose 	struct be_cmd_ntwk_link_status_resp *resp;
757c62eef0dSJohn Soni Jose 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
758c62eef0dSJohn Soni Jose 	struct iscsi_cls_host *ihost = shost->shost_data;
759c62eef0dSJohn Soni Jose 	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
760c62eef0dSJohn Soni Jose 
761c62eef0dSJohn Soni Jose 	tag = be_cmd_get_port_speed(phba);
762c62eef0dSJohn Soni Jose 	if (!tag) {
76399bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
76499bc5d55SJohn Soni Jose 			    "BS_%d : Getting Port Speed Failed\n");
76599bc5d55SJohn Soni Jose 
766c62eef0dSJohn Soni Jose 		 return -EBUSY;
767c62eef0dSJohn Soni Jose 	 } else
768c62eef0dSJohn Soni Jose 		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
769c62eef0dSJohn Soni Jose 				phba->ctrl.mcc_numtag[tag]);
770c62eef0dSJohn Soni Jose 
771c62eef0dSJohn Soni Jose 	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
772c62eef0dSJohn Soni Jose 	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
773c62eef0dSJohn Soni Jose 	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
774c62eef0dSJohn Soni Jose 
775c62eef0dSJohn Soni Jose 	if (status || extd_status) {
77699bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR,
77799bc5d55SJohn Soni Jose 			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
77899bc5d55SJohn Soni Jose 			    "BS_%d : MailBox Command Failed with "
779c62eef0dSJohn Soni Jose 			    "status = %d extd_status = %d\n",
780c62eef0dSJohn Soni Jose 			    status, extd_status);
78199bc5d55SJohn Soni Jose 
782c62eef0dSJohn Soni Jose 		free_mcc_tag(&phba->ctrl, tag);
783c62eef0dSJohn Soni Jose 		return -EAGAIN;
784c62eef0dSJohn Soni Jose 	}
785c62eef0dSJohn Soni Jose 	wrb = queue_get_wrb(mccq, wrb_num);
786c62eef0dSJohn Soni Jose 	free_mcc_tag(&phba->ctrl, tag);
787c62eef0dSJohn Soni Jose 	resp = embedded_payload(wrb);
788c62eef0dSJohn Soni Jose 
789c62eef0dSJohn Soni Jose 	switch (resp->mac_speed) {
790c62eef0dSJohn Soni Jose 	case BE2ISCSI_LINK_SPEED_10MBPS:
791c62eef0dSJohn Soni Jose 		ihost->port_speed = ISCSI_PORT_SPEED_10MBPS;
792c62eef0dSJohn Soni Jose 		break;
793c62eef0dSJohn Soni Jose 	case BE2ISCSI_LINK_SPEED_100MBPS:
794c62eef0dSJohn Soni Jose 		ihost->port_speed = BE2ISCSI_LINK_SPEED_100MBPS;
795c62eef0dSJohn Soni Jose 		break;
796c62eef0dSJohn Soni Jose 	case BE2ISCSI_LINK_SPEED_1GBPS:
797c62eef0dSJohn Soni Jose 		ihost->port_speed = ISCSI_PORT_SPEED_1GBPS;
798c62eef0dSJohn Soni Jose 		break;
799c62eef0dSJohn Soni Jose 	case BE2ISCSI_LINK_SPEED_10GBPS:
800c62eef0dSJohn Soni Jose 		ihost->port_speed = ISCSI_PORT_SPEED_10GBPS;
801c62eef0dSJohn Soni Jose 		break;
802c62eef0dSJohn Soni Jose 	default:
803c62eef0dSJohn Soni Jose 		ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN;
804c62eef0dSJohn Soni Jose 	}
805c62eef0dSJohn Soni Jose 	return 0;
806c62eef0dSJohn Soni Jose }
807c62eef0dSJohn Soni Jose 
808c62eef0dSJohn Soni Jose /**
8096733b39aSJayamohan Kallickal  * beiscsi_get_host_param - get the iscsi parameter
8106733b39aSJayamohan Kallickal  * @shost: pointer to scsi_host structure
8116733b39aSJayamohan Kallickal  * @param: parameter type identifier
8126733b39aSJayamohan Kallickal  * @buf: buffer pointer
8136733b39aSJayamohan Kallickal  *
8146733b39aSJayamohan Kallickal  * returns host parameter
8156733b39aSJayamohan Kallickal  */
8166733b39aSJayamohan Kallickal int beiscsi_get_host_param(struct Scsi_Host *shost,
8176733b39aSJayamohan Kallickal 			   enum iscsi_host_param param, char *buf)
8186733b39aSJayamohan Kallickal {
8193093b048SMike Christie 	struct beiscsi_hba *phba = iscsi_host_priv(shost);
820b15d05b0SJayamohan Kallickal 	int status = 0;
8216733b39aSJayamohan Kallickal 
82299bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
82399bc5d55SJohn Soni Jose 		    "BS_%d : In beiscsi_get_host_param,"
82499bc5d55SJohn Soni Jose 		    " param= %d\n", param);
82599bc5d55SJohn Soni Jose 
8266733b39aSJayamohan Kallickal 	switch (param) {
8276733b39aSJayamohan Kallickal 	case ISCSI_HOST_PARAM_HWADDRESS:
828c7acc5b8SJayamohan Kallickal 		status = beiscsi_get_macaddr(buf, phba);
829c7acc5b8SJayamohan Kallickal 		if (status < 0) {
83099bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
83199bc5d55SJohn Soni Jose 				    "BS_%d : beiscsi_get_macaddr Failed\n");
832c7acc5b8SJayamohan Kallickal 			return status;
833c7acc5b8SJayamohan Kallickal 		}
834c7acc5b8SJayamohan Kallickal 		break;
8352177199dSJohn Soni Jose 	case ISCSI_HOST_PARAM_INITIATOR_NAME:
8362177199dSJohn Soni Jose 		status = beiscsi_get_initname(buf, phba);
8372177199dSJohn Soni Jose 		if (status < 0) {
83899bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
83999bc5d55SJohn Soni Jose 				    "BS_%d : Retreiving Initiator Name Failed\n");
8402177199dSJohn Soni Jose 			return status;
8412177199dSJohn Soni Jose 		}
8422177199dSJohn Soni Jose 		break;
843c62eef0dSJohn Soni Jose 	case ISCSI_HOST_PARAM_PORT_STATE:
844c62eef0dSJohn Soni Jose 		beiscsi_get_port_state(shost);
845c62eef0dSJohn Soni Jose 		status = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost));
846c62eef0dSJohn Soni Jose 		break;
847c62eef0dSJohn Soni Jose 	case ISCSI_HOST_PARAM_PORT_SPEED:
848c62eef0dSJohn Soni Jose 		status = beiscsi_get_port_speed(shost);
849c62eef0dSJohn Soni Jose 		if (status) {
85099bc5d55SJohn Soni Jose 			beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
85199bc5d55SJohn Soni Jose 				    "BS_%d : Retreiving Port Speed Failed\n");
852c62eef0dSJohn Soni Jose 			return status;
853c62eef0dSJohn Soni Jose 		}
854c62eef0dSJohn Soni Jose 		status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost));
855c62eef0dSJohn Soni Jose 		break;
856c7acc5b8SJayamohan Kallickal 	default:
857c7acc5b8SJayamohan Kallickal 		return iscsi_host_get_param(shost, param, buf);
858c7acc5b8SJayamohan Kallickal 	}
859b15d05b0SJayamohan Kallickal 	return status;
860c7acc5b8SJayamohan Kallickal }
861c7acc5b8SJayamohan Kallickal 
862c7acc5b8SJayamohan Kallickal int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba)
863c7acc5b8SJayamohan Kallickal {
8640e43895eSMike Christie 	struct be_cmd_get_nic_conf_resp resp;
865c7acc5b8SJayamohan Kallickal 	int rc;
866c7acc5b8SJayamohan Kallickal 
8670e43895eSMike Christie 	if (strlen(phba->mac_address))
868df5d0e6eSJohn Soni Jose 		return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
869c7acc5b8SJayamohan Kallickal 
8700e43895eSMike Christie 	memset(&resp, 0, sizeof(resp));
8710e43895eSMike Christie 	rc = mgmt_get_nic_conf(phba, &resp);
8720e43895eSMike Christie 	if (rc)
873c7acc5b8SJayamohan Kallickal 		return rc;
874c7acc5b8SJayamohan Kallickal 
8750e43895eSMike Christie 	memcpy(phba->mac_address, resp.mac_address, ETH_ALEN);
8760e43895eSMike Christie 	return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
8770e43895eSMike Christie }
8786733b39aSJayamohan Kallickal 
8796733b39aSJayamohan Kallickal /**
8806733b39aSJayamohan Kallickal  * beiscsi_conn_get_stats - get the iscsi stats
8816733b39aSJayamohan Kallickal  * @cls_conn: pointer to iscsi cls conn
8826733b39aSJayamohan Kallickal  * @stats: pointer to iscsi_stats structure
8836733b39aSJayamohan Kallickal  *
8846733b39aSJayamohan Kallickal  * returns iscsi stats
8856733b39aSJayamohan Kallickal  */
8866733b39aSJayamohan Kallickal void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn,
8876733b39aSJayamohan Kallickal 			    struct iscsi_stats *stats)
8886733b39aSJayamohan Kallickal {
8896733b39aSJayamohan Kallickal 	struct iscsi_conn *conn = cls_conn->dd_data;
89099bc5d55SJohn Soni Jose 	struct beiscsi_hba *phba = NULL;
8916733b39aSJayamohan Kallickal 
89299bc5d55SJohn Soni Jose 	phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
89399bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
89499bc5d55SJohn Soni Jose 		    "BS_%d : In beiscsi_conn_get_stats\n");
89599bc5d55SJohn Soni Jose 
8966733b39aSJayamohan Kallickal 	stats->txdata_octets = conn->txdata_octets;
8976733b39aSJayamohan Kallickal 	stats->rxdata_octets = conn->rxdata_octets;
8986733b39aSJayamohan Kallickal 	stats->dataout_pdus = conn->dataout_pdus_cnt;
8996733b39aSJayamohan Kallickal 	stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
9006733b39aSJayamohan Kallickal 	stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
9016733b39aSJayamohan Kallickal 	stats->datain_pdus = conn->datain_pdus_cnt;
9026733b39aSJayamohan Kallickal 	stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
9036733b39aSJayamohan Kallickal 	stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
9046733b39aSJayamohan Kallickal 	stats->r2t_pdus = conn->r2t_pdus_cnt;
9056733b39aSJayamohan Kallickal 	stats->digest_err = 0;
9066733b39aSJayamohan Kallickal 	stats->timeout_err = 0;
9076733b39aSJayamohan Kallickal 	stats->custom_length = 0;
9086733b39aSJayamohan Kallickal 	strcpy(stats->custom[0].desc, "eh_abort_cnt");
9096733b39aSJayamohan Kallickal 	stats->custom[0].value = conn->eh_abort_cnt;
9106733b39aSJayamohan Kallickal }
9116733b39aSJayamohan Kallickal 
9126733b39aSJayamohan Kallickal /**
9136733b39aSJayamohan Kallickal  * beiscsi_set_params_for_offld - get the parameters for offload
9146733b39aSJayamohan Kallickal  * @beiscsi_conn: pointer to beiscsi_conn
9156733b39aSJayamohan Kallickal  * @params: pointer to offload_params structure
9166733b39aSJayamohan Kallickal  */
9176733b39aSJayamohan Kallickal static void  beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn,
9186733b39aSJayamohan Kallickal 					  struct beiscsi_offload_params *params)
9196733b39aSJayamohan Kallickal {
9206733b39aSJayamohan Kallickal 	struct iscsi_conn *conn = beiscsi_conn->conn;
9216733b39aSJayamohan Kallickal 	struct iscsi_session *session = conn->session;
9226733b39aSJayamohan Kallickal 
9236733b39aSJayamohan Kallickal 	AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_burst_length,
9246733b39aSJayamohan Kallickal 		      params, session->max_burst);
9256733b39aSJayamohan Kallickal 	AMAP_SET_BITS(struct amap_beiscsi_offload_params,
9266733b39aSJayamohan Kallickal 		      max_send_data_segment_length, params,
9276733b39aSJayamohan Kallickal 		      conn->max_xmit_dlength);
9286733b39aSJayamohan Kallickal 	AMAP_SET_BITS(struct amap_beiscsi_offload_params, first_burst_length,
9296733b39aSJayamohan Kallickal 		      params, session->first_burst);
9306733b39aSJayamohan Kallickal 	AMAP_SET_BITS(struct amap_beiscsi_offload_params, erl, params,
9316733b39aSJayamohan Kallickal 		      session->erl);
9326733b39aSJayamohan Kallickal 	AMAP_SET_BITS(struct amap_beiscsi_offload_params, dde, params,
9336733b39aSJayamohan Kallickal 		      conn->datadgst_en);
9346733b39aSJayamohan Kallickal 	AMAP_SET_BITS(struct amap_beiscsi_offload_params, hde, params,
9356733b39aSJayamohan Kallickal 		      conn->hdrdgst_en);
9366733b39aSJayamohan Kallickal 	AMAP_SET_BITS(struct amap_beiscsi_offload_params, ir2t, params,
9376733b39aSJayamohan Kallickal 		      session->initial_r2t_en);
9386733b39aSJayamohan Kallickal 	AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params,
9396733b39aSJayamohan Kallickal 		      session->imm_data_en);
9406733b39aSJayamohan Kallickal 	AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params,
9416733b39aSJayamohan Kallickal 		      (conn->exp_statsn - 1));
9426733b39aSJayamohan Kallickal }
9436733b39aSJayamohan Kallickal 
9446733b39aSJayamohan Kallickal /**
9456733b39aSJayamohan Kallickal  * beiscsi_conn_start - offload of session to chip
9466733b39aSJayamohan Kallickal  * @cls_conn: pointer to beiscsi_conn
9476733b39aSJayamohan Kallickal  */
9486733b39aSJayamohan Kallickal int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
9496733b39aSJayamohan Kallickal {
9506733b39aSJayamohan Kallickal 	struct iscsi_conn *conn = cls_conn->dd_data;
9516733b39aSJayamohan Kallickal 	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
9526733b39aSJayamohan Kallickal 	struct beiscsi_endpoint *beiscsi_ep;
9536733b39aSJayamohan Kallickal 	struct beiscsi_offload_params params;
9546733b39aSJayamohan Kallickal 
95599bc5d55SJohn Soni Jose 	beiscsi_log(beiscsi_conn->phba, KERN_INFO,
95699bc5d55SJohn Soni Jose 		    BEISCSI_LOG_CONFIG,
95799bc5d55SJohn Soni Jose 		    "BS_%d : In beiscsi_conn_start\n");
95899bc5d55SJohn Soni Jose 
9596733b39aSJayamohan Kallickal 	memset(&params, 0, sizeof(struct beiscsi_offload_params));
9606733b39aSJayamohan Kallickal 	beiscsi_ep = beiscsi_conn->ep;
9616733b39aSJayamohan Kallickal 	if (!beiscsi_ep)
96299bc5d55SJohn Soni Jose 		beiscsi_log(beiscsi_conn->phba, KERN_ERR,
96399bc5d55SJohn Soni Jose 			    BEISCSI_LOG_CONFIG,
96499bc5d55SJohn Soni Jose 			    "BS_%d : In beiscsi_conn_start , no beiscsi_ep\n");
9656733b39aSJayamohan Kallickal 
9666733b39aSJayamohan Kallickal 	beiscsi_conn->login_in_progress = 0;
9676733b39aSJayamohan Kallickal 	beiscsi_set_params_for_offld(beiscsi_conn, &params);
9686733b39aSJayamohan Kallickal 	beiscsi_offload_connection(beiscsi_conn, &params);
9696733b39aSJayamohan Kallickal 	iscsi_conn_start(cls_conn);
9706733b39aSJayamohan Kallickal 	return 0;
9716733b39aSJayamohan Kallickal }
9726733b39aSJayamohan Kallickal 
9736733b39aSJayamohan Kallickal /**
9746733b39aSJayamohan Kallickal  * beiscsi_get_cid - Allocate a cid
9756733b39aSJayamohan Kallickal  * @phba: The phba instance
9766733b39aSJayamohan Kallickal  */
9776733b39aSJayamohan Kallickal static int beiscsi_get_cid(struct beiscsi_hba *phba)
9786733b39aSJayamohan Kallickal {
9796733b39aSJayamohan Kallickal 	unsigned short cid = 0xFFFF;
9806733b39aSJayamohan Kallickal 
9816733b39aSJayamohan Kallickal 	if (!phba->avlbl_cids)
9826733b39aSJayamohan Kallickal 		return cid;
9836733b39aSJayamohan Kallickal 
9846733b39aSJayamohan Kallickal 	cid = phba->cid_array[phba->cid_alloc++];
9856733b39aSJayamohan Kallickal 	if (phba->cid_alloc == phba->params.cxns_per_ctrl)
9866733b39aSJayamohan Kallickal 		phba->cid_alloc = 0;
9876733b39aSJayamohan Kallickal 	phba->avlbl_cids--;
9886733b39aSJayamohan Kallickal 	return cid;
9896733b39aSJayamohan Kallickal }
9906733b39aSJayamohan Kallickal 
9916733b39aSJayamohan Kallickal /**
992fa95d206SMike Christie  * beiscsi_put_cid - Free the cid
993fa95d206SMike Christie  * @phba: The phba for which the cid is being freed
994fa95d206SMike Christie  * @cid: The cid to free
995fa95d206SMike Christie  */
996fa95d206SMike Christie static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
997fa95d206SMike Christie {
998fa95d206SMike Christie 	phba->avlbl_cids++;
999fa95d206SMike Christie 	phba->cid_array[phba->cid_free++] = cid;
1000fa95d206SMike Christie 	if (phba->cid_free == phba->params.cxns_per_ctrl)
1001fa95d206SMike Christie 		phba->cid_free = 0;
1002fa95d206SMike Christie }
1003fa95d206SMike Christie 
1004fa95d206SMike Christie /**
1005fa95d206SMike Christie  * beiscsi_free_ep - free endpoint
1006fa95d206SMike Christie  * @ep:	pointer to iscsi endpoint structure
1007fa95d206SMike Christie  */
1008fa95d206SMike Christie static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
1009fa95d206SMike Christie {
1010fa95d206SMike Christie 	struct beiscsi_hba *phba = beiscsi_ep->phba;
1011fa95d206SMike Christie 
1012fa95d206SMike Christie 	beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
1013fa95d206SMike Christie 	beiscsi_ep->phba = NULL;
1014fa95d206SMike Christie }
1015fa95d206SMike Christie 
1016fa95d206SMike Christie /**
10176733b39aSJayamohan Kallickal  * beiscsi_open_conn - Ask FW to open a TCP connection
10186733b39aSJayamohan Kallickal  * @ep:	endpoint to be used
10196733b39aSJayamohan Kallickal  * @src_addr: The source IP address
10206733b39aSJayamohan Kallickal  * @dst_addr: The Destination  IP address
10216733b39aSJayamohan Kallickal  *
10226733b39aSJayamohan Kallickal  * Asks the FW to open a TCP connection
10236733b39aSJayamohan Kallickal  */
10246733b39aSJayamohan Kallickal static int beiscsi_open_conn(struct iscsi_endpoint *ep,
10256733b39aSJayamohan Kallickal 			     struct sockaddr *src_addr,
10266733b39aSJayamohan Kallickal 			     struct sockaddr *dst_addr, int non_blocking)
10276733b39aSJayamohan Kallickal {
10286733b39aSJayamohan Kallickal 	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
10296733b39aSJayamohan Kallickal 	struct beiscsi_hba *phba = beiscsi_ep->phba;
1030756d29c8SJayamohan Kallickal 	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
1031756d29c8SJayamohan Kallickal 	struct be_mcc_wrb *wrb;
1032756d29c8SJayamohan Kallickal 	struct tcp_connect_and_offload_out *ptcpcnct_out;
1033756d29c8SJayamohan Kallickal 	unsigned short status, extd_status;
10343cbb7a74SJayamohan Kallickal 	struct be_dma_mem nonemb_cmd;
1035756d29c8SJayamohan Kallickal 	unsigned int tag, wrb_num;
1036d3ad2bb3SJayamohan Kallickal 	int ret = -ENOMEM;
10376733b39aSJayamohan Kallickal 
103899bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
103999bc5d55SJohn Soni Jose 		    "BS_%d : In beiscsi_open_conn\n");
104099bc5d55SJohn Soni Jose 
10416733b39aSJayamohan Kallickal 	beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
10426733b39aSJayamohan Kallickal 	if (beiscsi_ep->ep_cid == 0xFFFF) {
104399bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
104499bc5d55SJohn Soni Jose 			    "BS_%d : No free cid available\n");
10456733b39aSJayamohan Kallickal 		return ret;
10466733b39aSJayamohan Kallickal 	}
104799bc5d55SJohn Soni Jose 
104899bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
104999bc5d55SJohn Soni Jose 		    "BS_%d : In beiscsi_open_conn, ep_cid=%d\n",
10506733b39aSJayamohan Kallickal 		    beiscsi_ep->ep_cid);
105199bc5d55SJohn Soni Jose 
10527da50879SJayamohan Kallickal 	phba->ep_array[beiscsi_ep->ep_cid -
10537da50879SJayamohan Kallickal 		       phba->fw_config.iscsi_cid_start] = ep;
10547da50879SJayamohan Kallickal 	if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start +
10557da50879SJayamohan Kallickal 				  phba->params.cxns_per_ctrl * 2)) {
105699bc5d55SJohn Soni Jose 
105799bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
105899bc5d55SJohn Soni Jose 			    "BS_%d : Failed in allocate iscsi cid\n");
1059fa95d206SMike Christie 		goto free_ep;
10606733b39aSJayamohan Kallickal 	}
10616733b39aSJayamohan Kallickal 
10626733b39aSJayamohan Kallickal 	beiscsi_ep->cid_vld = 0;
10633cbb7a74SJayamohan Kallickal 	nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
10643cbb7a74SJayamohan Kallickal 				sizeof(struct tcp_connect_and_offload_in),
10653cbb7a74SJayamohan Kallickal 				&nonemb_cmd.dma);
10663cbb7a74SJayamohan Kallickal 	if (nonemb_cmd.va == NULL) {
106799bc5d55SJohn Soni Jose 
106899bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
106999bc5d55SJohn Soni Jose 			    "BS_%d : Failed to allocate memory for"
107099bc5d55SJohn Soni Jose 			    " mgmt_open_connection\n");
107199bc5d55SJohn Soni Jose 
10723cbb7a74SJayamohan Kallickal 		beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
10733cbb7a74SJayamohan Kallickal 		return -ENOMEM;
10743cbb7a74SJayamohan Kallickal 	}
10753cbb7a74SJayamohan Kallickal 	nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in);
10763cbb7a74SJayamohan Kallickal 	memset(nonemb_cmd.va, 0, nonemb_cmd.size);
10773cbb7a74SJayamohan Kallickal 	tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
1078756d29c8SJayamohan Kallickal 	if (!tag) {
107999bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
108099bc5d55SJohn Soni Jose 			    "BS_%d : mgmt_open_connection Failed for cid=%d\n",
1081756d29c8SJayamohan Kallickal 			    beiscsi_ep->ep_cid);
108299bc5d55SJohn Soni Jose 
10831f92638fSJayamohan Kallickal 		beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
10843cbb7a74SJayamohan Kallickal 		pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
10853cbb7a74SJayamohan Kallickal 				    nonemb_cmd.va, nonemb_cmd.dma);
10861f92638fSJayamohan Kallickal 		return -EAGAIN;
1087756d29c8SJayamohan Kallickal 	} else {
1088756d29c8SJayamohan Kallickal 		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
1089756d29c8SJayamohan Kallickal 					 phba->ctrl.mcc_numtag[tag]);
1090756d29c8SJayamohan Kallickal 	}
1091756d29c8SJayamohan Kallickal 	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
1092756d29c8SJayamohan Kallickal 	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
1093756d29c8SJayamohan Kallickal 	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
1094756d29c8SJayamohan Kallickal 	if (status || extd_status) {
109599bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR,
109699bc5d55SJohn Soni Jose 			    BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
109799bc5d55SJohn Soni Jose 			    "BS_%d : mgmt_open_connection Failed"
1098756d29c8SJayamohan Kallickal 			    " status = %d extd_status = %d\n",
1099756d29c8SJayamohan Kallickal 			    status, extd_status);
110099bc5d55SJohn Soni Jose 
1101756d29c8SJayamohan Kallickal 		free_mcc_tag(&phba->ctrl, tag);
11023cbb7a74SJayamohan Kallickal 		pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
11033cbb7a74SJayamohan Kallickal 			    nonemb_cmd.va, nonemb_cmd.dma);
1104fa95d206SMike Christie 		goto free_ep;
1105756d29c8SJayamohan Kallickal 	} else {
1106756d29c8SJayamohan Kallickal 		wrb = queue_get_wrb(mccq, wrb_num);
1107756d29c8SJayamohan Kallickal 		free_mcc_tag(&phba->ctrl, tag);
1108756d29c8SJayamohan Kallickal 
1109756d29c8SJayamohan Kallickal 		ptcpcnct_out = embedded_payload(wrb);
1110756d29c8SJayamohan Kallickal 		beiscsi_ep = ep->dd_data;
1111756d29c8SJayamohan Kallickal 		beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
1112756d29c8SJayamohan Kallickal 		beiscsi_ep->cid_vld = 1;
111399bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
111499bc5d55SJohn Soni Jose 			    "BS_%d : mgmt_open_connection Success\n");
1115756d29c8SJayamohan Kallickal 	}
11163cbb7a74SJayamohan Kallickal 	pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
11173cbb7a74SJayamohan Kallickal 			    nonemb_cmd.va, nonemb_cmd.dma);
1118756d29c8SJayamohan Kallickal 	return 0;
11196733b39aSJayamohan Kallickal 
1120fa95d206SMike Christie free_ep:
1121fa95d206SMike Christie 	beiscsi_free_ep(beiscsi_ep);
1122d3ad2bb3SJayamohan Kallickal 	return -EBUSY;
11236733b39aSJayamohan Kallickal }
11246733b39aSJayamohan Kallickal 
11256733b39aSJayamohan Kallickal /**
11266733b39aSJayamohan Kallickal  * beiscsi_ep_connect - Ask chip to create TCP Conn
11276733b39aSJayamohan Kallickal  * @scsi_host: Pointer to scsi_host structure
11286733b39aSJayamohan Kallickal  * @dst_addr: The IP address of Target
11296733b39aSJayamohan Kallickal  * @non_blocking: blocking or non-blocking call
11306733b39aSJayamohan Kallickal  *
11316733b39aSJayamohan Kallickal  * This routines first asks chip to create a connection and then allocates an EP
11326733b39aSJayamohan Kallickal  */
11336733b39aSJayamohan Kallickal struct iscsi_endpoint *
11346733b39aSJayamohan Kallickal beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
11356733b39aSJayamohan Kallickal 		   int non_blocking)
11366733b39aSJayamohan Kallickal {
11376733b39aSJayamohan Kallickal 	struct beiscsi_hba *phba;
11386733b39aSJayamohan Kallickal 	struct beiscsi_endpoint *beiscsi_ep;
11396733b39aSJayamohan Kallickal 	struct iscsi_endpoint *ep;
11406733b39aSJayamohan Kallickal 	int ret;
11416733b39aSJayamohan Kallickal 
11426733b39aSJayamohan Kallickal 	if (shost)
11436733b39aSJayamohan Kallickal 		phba = iscsi_host_priv(shost);
11446733b39aSJayamohan Kallickal 	else {
11456733b39aSJayamohan Kallickal 		ret = -ENXIO;
114699bc5d55SJohn Soni Jose 		printk(KERN_ERR
114799bc5d55SJohn Soni Jose 		       "beiscsi_ep_connect shost is NULL\n");
11486733b39aSJayamohan Kallickal 		return ERR_PTR(ret);
11496733b39aSJayamohan Kallickal 	}
1150bfead3b2SJayamohan Kallickal 
11515dc1c416SJayamohan Kallickal 	if (phba->state != BE_ADAPTER_UP) {
1152bfead3b2SJayamohan Kallickal 		ret = -EBUSY;
115399bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
115499bc5d55SJohn Soni Jose 			    "BS_%d : The Adapter state is Not UP\n");
1155bfead3b2SJayamohan Kallickal 		return ERR_PTR(ret);
1156bfead3b2SJayamohan Kallickal 	}
1157bfead3b2SJayamohan Kallickal 
11586733b39aSJayamohan Kallickal 	ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint));
11596733b39aSJayamohan Kallickal 	if (!ep) {
11606733b39aSJayamohan Kallickal 		ret = -ENOMEM;
11616733b39aSJayamohan Kallickal 		return ERR_PTR(ret);
11626733b39aSJayamohan Kallickal 	}
11636733b39aSJayamohan Kallickal 
11646733b39aSJayamohan Kallickal 	beiscsi_ep = ep->dd_data;
11656733b39aSJayamohan Kallickal 	beiscsi_ep->phba = phba;
1166c2462288SJayamohan Kallickal 	beiscsi_ep->openiscsi_ep = ep;
1167f5ed7bd4SJayamohan Kallickal 	ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking);
1168f5ed7bd4SJayamohan Kallickal 	if (ret) {
116999bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
117099bc5d55SJohn Soni Jose 			    "BS_%d : Failed in beiscsi_open_conn\n");
11716733b39aSJayamohan Kallickal 		goto free_ep;
11726733b39aSJayamohan Kallickal 	}
11736733b39aSJayamohan Kallickal 
11746733b39aSJayamohan Kallickal 	return ep;
11756733b39aSJayamohan Kallickal 
11766733b39aSJayamohan Kallickal free_ep:
1177fa95d206SMike Christie 	iscsi_destroy_endpoint(ep);
11786733b39aSJayamohan Kallickal 	return ERR_PTR(ret);
11796733b39aSJayamohan Kallickal }
11806733b39aSJayamohan Kallickal 
11816733b39aSJayamohan Kallickal /**
11826733b39aSJayamohan Kallickal  * beiscsi_ep_poll - Poll to see if connection is established
11836733b39aSJayamohan Kallickal  * @ep:	endpoint to be used
11846733b39aSJayamohan Kallickal  * @timeout_ms: timeout specified in millisecs
11856733b39aSJayamohan Kallickal  *
11866733b39aSJayamohan Kallickal  * Poll to see if TCP connection established
11876733b39aSJayamohan Kallickal  */
11886733b39aSJayamohan Kallickal int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
11896733b39aSJayamohan Kallickal {
11906733b39aSJayamohan Kallickal 	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
11916733b39aSJayamohan Kallickal 
119299bc5d55SJohn Soni Jose 	beiscsi_log(beiscsi_ep->phba, KERN_INFO, BEISCSI_LOG_CONFIG,
119399bc5d55SJohn Soni Jose 		    "BS_%d : In  beiscsi_ep_poll\n");
119499bc5d55SJohn Soni Jose 
11956733b39aSJayamohan Kallickal 	if (beiscsi_ep->cid_vld == 1)
11966733b39aSJayamohan Kallickal 		return 1;
11976733b39aSJayamohan Kallickal 	else
11986733b39aSJayamohan Kallickal 		return 0;
11996733b39aSJayamohan Kallickal }
12006733b39aSJayamohan Kallickal 
12016733b39aSJayamohan Kallickal /**
12026733b39aSJayamohan Kallickal  * beiscsi_close_conn - Upload the  connection
12036733b39aSJayamohan Kallickal  * @ep: The iscsi endpoint
12046733b39aSJayamohan Kallickal  * @flag: The type of connection closure
12056733b39aSJayamohan Kallickal  */
1206c2462288SJayamohan Kallickal static int beiscsi_close_conn(struct  beiscsi_endpoint *beiscsi_ep, int flag)
12076733b39aSJayamohan Kallickal {
12086733b39aSJayamohan Kallickal 	int ret = 0;
1209756d29c8SJayamohan Kallickal 	unsigned int tag;
12106733b39aSJayamohan Kallickal 	struct beiscsi_hba *phba = beiscsi_ep->phba;
12116733b39aSJayamohan Kallickal 
1212756d29c8SJayamohan Kallickal 	tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag);
1213756d29c8SJayamohan Kallickal 	if (!tag) {
121499bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
121599bc5d55SJohn Soni Jose 			    "BS_%d : upload failed for cid 0x%x\n",
12166733b39aSJayamohan Kallickal 			    beiscsi_ep->ep_cid);
121799bc5d55SJohn Soni Jose 
1218d3ad2bb3SJayamohan Kallickal 		ret = -EAGAIN;
1219756d29c8SJayamohan Kallickal 	} else {
1220756d29c8SJayamohan Kallickal 		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
1221756d29c8SJayamohan Kallickal 					 phba->ctrl.mcc_numtag[tag]);
1222756d29c8SJayamohan Kallickal 		free_mcc_tag(&phba->ctrl, tag);
12236733b39aSJayamohan Kallickal 	}
12246733b39aSJayamohan Kallickal 	return ret;
12256733b39aSJayamohan Kallickal }
12266733b39aSJayamohan Kallickal 
12276733b39aSJayamohan Kallickal /**
12286733b39aSJayamohan Kallickal  * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table
12296733b39aSJayamohan Kallickal  * @phba: The phba instance
12306733b39aSJayamohan Kallickal  * @cid: The cid to free
12316733b39aSJayamohan Kallickal  */
12326733b39aSJayamohan Kallickal static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba,
12336733b39aSJayamohan Kallickal 				      unsigned int cid)
12346733b39aSJayamohan Kallickal {
12356733b39aSJayamohan Kallickal 	if (phba->conn_table[cid])
12366733b39aSJayamohan Kallickal 		phba->conn_table[cid] = NULL;
12376733b39aSJayamohan Kallickal 	else {
123899bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
123999bc5d55SJohn Soni Jose 			    "BS_%d : Connection table Not occupied.\n");
12406733b39aSJayamohan Kallickal 		return -EINVAL;
12416733b39aSJayamohan Kallickal 	}
12426733b39aSJayamohan Kallickal 	return 0;
12436733b39aSJayamohan Kallickal }
12446733b39aSJayamohan Kallickal 
12456733b39aSJayamohan Kallickal /**
1246fa95d206SMike Christie  * beiscsi_ep_disconnect - Tears down the TCP connection
1247fa95d206SMike Christie  * @ep:	endpoint to be used
1248fa95d206SMike Christie  *
1249fa95d206SMike Christie  * Tears down the TCP connection
12506733b39aSJayamohan Kallickal  */
1251fa95d206SMike Christie void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
12526733b39aSJayamohan Kallickal {
1253fa95d206SMike Christie 	struct beiscsi_conn *beiscsi_conn;
12546733b39aSJayamohan Kallickal 	struct beiscsi_endpoint *beiscsi_ep;
1255fa95d206SMike Christie 	struct beiscsi_hba *phba;
1256756d29c8SJayamohan Kallickal 	unsigned int tag;
1257*0a513dd8SJohn Soni Jose 	uint8_t mgmt_invalidate_flag, tcp_upload_flag;
12586733b39aSJayamohan Kallickal 	unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;
12596733b39aSJayamohan Kallickal 
1260fa95d206SMike Christie 	beiscsi_ep = ep->dd_data;
1261fa95d206SMike Christie 	phba = beiscsi_ep->phba;
126299bc5d55SJohn Soni Jose 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
126399bc5d55SJohn Soni Jose 		    "BS_%d : In beiscsi_ep_disconnect for ep_cid = %d\n",
1264fa95d206SMike Christie 		    beiscsi_ep->ep_cid);
1265fa95d206SMike Christie 
1266*0a513dd8SJohn Soni Jose 	if (beiscsi_ep->conn) {
1267fa95d206SMike Christie 		beiscsi_conn = beiscsi_ep->conn;
1268fa95d206SMike Christie 		iscsi_suspend_queue(beiscsi_conn->conn);
1269*0a513dd8SJohn Soni Jose 		mgmt_invalidate_flag = ~BEISCSI_NO_RST_ISSUE;
1270*0a513dd8SJohn Soni Jose 		tcp_upload_flag = CONNECTION_UPLOAD_GRACEFUL;
1271*0a513dd8SJohn Soni Jose 	} else {
1272*0a513dd8SJohn Soni Jose 		mgmt_invalidate_flag = BEISCSI_NO_RST_ISSUE;
1273*0a513dd8SJohn Soni Jose 		tcp_upload_flag = CONNECTION_UPLOAD_ABORT;
1274*0a513dd8SJohn Soni Jose 	}
1275fa95d206SMike Christie 
1276756d29c8SJayamohan Kallickal 	tag = mgmt_invalidate_connection(phba, beiscsi_ep,
1277*0a513dd8SJohn Soni Jose 					  beiscsi_ep->ep_cid,
1278*0a513dd8SJohn Soni Jose 					  mgmt_invalidate_flag,
12796733b39aSJayamohan Kallickal 					  savecfg_flag);
1280756d29c8SJayamohan Kallickal 	if (!tag) {
128199bc5d55SJohn Soni Jose 		beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1282*0a513dd8SJohn Soni Jose 			    "BS_%d : mgmt_invalidate_connection Failed for cid=%d\n",
12836733b39aSJayamohan Kallickal 			    beiscsi_ep->ep_cid);
1284756d29c8SJayamohan Kallickal 	} else {
1285756d29c8SJayamohan Kallickal 		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
1286756d29c8SJayamohan Kallickal 					 phba->ctrl.mcc_numtag[tag]);
1287756d29c8SJayamohan Kallickal 		free_mcc_tag(&phba->ctrl, tag);
12886733b39aSJayamohan Kallickal 	}
1289fa95d206SMike Christie 
1290*0a513dd8SJohn Soni Jose 	beiscsi_close_conn(beiscsi_ep, tcp_upload_flag);
1291c2462288SJayamohan Kallickal 	beiscsi_free_ep(beiscsi_ep);
12926733b39aSJayamohan Kallickal 	beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
1293fa95d206SMike Christie 	iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
12946733b39aSJayamohan Kallickal }
12953128c6c7SMike Christie 
1296587a1f16SAl Viro umode_t be2iscsi_attr_is_visible(int param_type, int param)
12973128c6c7SMike Christie {
12983128c6c7SMike Christie 	switch (param_type) {
12990e43895eSMike Christie 	case ISCSI_NET_PARAM:
13000e43895eSMike Christie 		switch (param) {
13010e43895eSMike Christie 		case ISCSI_NET_PARAM_IFACE_ENABLE:
13020e43895eSMike Christie 		case ISCSI_NET_PARAM_IPV4_ADDR:
13030e43895eSMike Christie 		case ISCSI_NET_PARAM_IPV4_SUBNET:
13040e43895eSMike Christie 		case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
13050e43895eSMike Christie 		case ISCSI_NET_PARAM_IPV4_GW:
13060e43895eSMike Christie 		case ISCSI_NET_PARAM_IPV6_ADDR:
13076f72238eSJohn Soni Jose 		case ISCSI_NET_PARAM_VLAN_ID:
13086f72238eSJohn Soni Jose 		case ISCSI_NET_PARAM_VLAN_PRIORITY:
13096f72238eSJohn Soni Jose 		case ISCSI_NET_PARAM_VLAN_ENABLED:
13100e43895eSMike Christie 			return S_IRUGO;
13110e43895eSMike Christie 		default:
13120e43895eSMike Christie 			return 0;
13130e43895eSMike Christie 		}
1314f27fb2efSMike Christie 	case ISCSI_HOST_PARAM:
1315f27fb2efSMike Christie 		switch (param) {
1316f27fb2efSMike Christie 		case ISCSI_HOST_PARAM_HWADDRESS:
1317c62eef0dSJohn Soni Jose 		case ISCSI_HOST_PARAM_INITIATOR_NAME:
1318c62eef0dSJohn Soni Jose 		case ISCSI_HOST_PARAM_PORT_STATE:
1319c62eef0dSJohn Soni Jose 		case ISCSI_HOST_PARAM_PORT_SPEED:
1320f27fb2efSMike Christie 			return S_IRUGO;
1321f27fb2efSMike Christie 		default:
1322f27fb2efSMike Christie 			return 0;
1323f27fb2efSMike Christie 		}
13243128c6c7SMike Christie 	case ISCSI_PARAM:
13253128c6c7SMike Christie 		switch (param) {
13263128c6c7SMike Christie 		case ISCSI_PARAM_MAX_RECV_DLENGTH:
13273128c6c7SMike Christie 		case ISCSI_PARAM_MAX_XMIT_DLENGTH:
13283128c6c7SMike Christie 		case ISCSI_PARAM_HDRDGST_EN:
13293128c6c7SMike Christie 		case ISCSI_PARAM_DATADGST_EN:
13303128c6c7SMike Christie 		case ISCSI_PARAM_CONN_ADDRESS:
13313128c6c7SMike Christie 		case ISCSI_PARAM_CONN_PORT:
13323128c6c7SMike Christie 		case ISCSI_PARAM_EXP_STATSN:
13333128c6c7SMike Christie 		case ISCSI_PARAM_PERSISTENT_ADDRESS:
13343128c6c7SMike Christie 		case ISCSI_PARAM_PERSISTENT_PORT:
13353128c6c7SMike Christie 		case ISCSI_PARAM_PING_TMO:
13363128c6c7SMike Christie 		case ISCSI_PARAM_RECV_TMO:
13371d063c17SMike Christie 		case ISCSI_PARAM_INITIAL_R2T_EN:
13381d063c17SMike Christie 		case ISCSI_PARAM_MAX_R2T:
13391d063c17SMike Christie 		case ISCSI_PARAM_IMM_DATA_EN:
13401d063c17SMike Christie 		case ISCSI_PARAM_FIRST_BURST:
13411d063c17SMike Christie 		case ISCSI_PARAM_MAX_BURST:
13421d063c17SMike Christie 		case ISCSI_PARAM_PDU_INORDER_EN:
13431d063c17SMike Christie 		case ISCSI_PARAM_DATASEQ_INORDER_EN:
13441d063c17SMike Christie 		case ISCSI_PARAM_ERL:
13451d063c17SMike Christie 		case ISCSI_PARAM_TARGET_NAME:
13461d063c17SMike Christie 		case ISCSI_PARAM_TPGT:
13471d063c17SMike Christie 		case ISCSI_PARAM_USERNAME:
13481d063c17SMike Christie 		case ISCSI_PARAM_PASSWORD:
13491d063c17SMike Christie 		case ISCSI_PARAM_USERNAME_IN:
13501d063c17SMike Christie 		case ISCSI_PARAM_PASSWORD_IN:
13511d063c17SMike Christie 		case ISCSI_PARAM_FAST_ABORT:
13521d063c17SMike Christie 		case ISCSI_PARAM_ABORT_TMO:
13531d063c17SMike Christie 		case ISCSI_PARAM_LU_RESET_TMO:
13541d063c17SMike Christie 		case ISCSI_PARAM_IFACE_NAME:
13551d063c17SMike Christie 		case ISCSI_PARAM_INITIATOR_NAME:
13563128c6c7SMike Christie 			return S_IRUGO;
13573128c6c7SMike Christie 		default:
13583128c6c7SMike Christie 			return 0;
13593128c6c7SMike Christie 		}
13603128c6c7SMike Christie 	}
13613128c6c7SMike Christie 
13623128c6c7SMike Christie 	return 0;
13633128c6c7SMike Christie }
1364