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