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