Merge remote-tracking branch 'asoc/topic/omap' into asoc-next
[cascardo/linux.git] / drivers / scsi / be2iscsi / be_iscsi.c
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 }