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