blob: a4844578e3577e833952af48e02dcb5570446d97 [file] [log] [blame]
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301/**
Jitendra Bhivare60f36e02016-08-19 15:20:24 +05302 * Copyright (C) 2005 - 2016 Broadcom
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05303 * 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 *
Jitendra Bhivare60f36e02016-08-19 15:20:24 +053010 * Written by: Jayamohan Kallickal (jayamohan.kallickal@broadcom.com)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053011 *
12 * Contact Information:
Jitendra Bhivare60f36e02016-08-19 15:20:24 +053013 * linux-drivers@broadcom.com
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053014 *
Ketan Mukadamc4f39bd2015-07-04 04:12:33 +053015 * Emulex
Jayamohan Kallickal255fa9a2011-03-25 14:23:57 -070016 * 3333 Susan Street
17 * Costa Mesa, CA 92626
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053018 */
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>
Mike Christie0e438952012-04-03 23:41:51 -050026#include <scsi/scsi_netlink.h>
27#include <net/netlink.h>
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053028#include <scsi/scsi.h>
29
30#include "be_iscsi.h"
31
32extern 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 */
40struct 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;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053048 struct beiscsi_hba *phba;
Jayamohan Kallickalb8b9e1b82009-09-22 08:21:22 +053049 struct iscsi_session *sess;
50 struct beiscsi_session *beiscsi_sess;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053051 struct beiscsi_io_task *io_task;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053052
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053053
54 if (!ep) {
Jitendra Bhivare9122e992016-08-19 15:20:11 +053055 pr_err("beiscsi_session_create: invalid ep\n");
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053056 return NULL;
57 }
58 beiscsi_ep = ep->dd_data;
59 phba = beiscsi_ep->phba;
John Soni Jose99bc5d52012-08-20 23:00:18 +053060
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +053061 if (!beiscsi_hba_is_online(phba)) {
Jayamohan Kallickal3567f362013-09-28 15:35:58 -070062 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
Jitendra Bhivare9122e992016-08-19 15:20:11 +053063 "BS_%d : HBA in error 0x%lx\n", phba->state);
64 return NULL;
Jayamohan Kallickal3567f362013-09-28 15:35:58 -070065 }
John Soni Jose99bc5d52012-08-20 23:00:18 +053066
Jitendra Bhivare9122e992016-08-19 15:20:11 +053067 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
68 "BS_%d : In beiscsi_session_create\n");
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053069 if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) {
John Soni Jose99bc5d52012-08-20 23:00:18 +053070 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
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053077 cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
78 }
79
Jayamohan Kallickal3567f362013-09-28 15:35:58 -070080 shost = phba->shost;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +053081 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);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053086 if (!cls_session)
87 return NULL;
88 sess = cls_session->dd_data;
Jayamohan Kallickal2afc95b2009-09-22 08:22:26 +053089 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;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053096
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053097 return cls_session;
Jayamohan Kallickal2afc95b2009-09-22 08:22:26 +053098destroy_sess:
99 iscsi_session_teardown(cls_session);
100 return NULL;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530101}
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 */
110void beiscsi_session_destroy(struct iscsi_cls_session *cls_session)
111{
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530112 struct iscsi_session *sess = cls_session->dd_data;
Jayamohan Kallickal2afc95b2009-09-22 08:22:26 +0530113 struct beiscsi_session *beiscsi_sess = sess->dd_data;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530114
John Soni Jose99bc5d52012-08-20 23:00:18 +0530115 printk(KERN_INFO "In beiscsi_session_destroy\n");
Jayamohan Kallickal2afc95b2009-09-22 08:22:26 +0530116 pci_pool_destroy(beiscsi_sess->bhs_pool);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530117 iscsi_session_teardown(cls_session);
118}
119
120/**
Jitendra Bhivare480195c2016-08-19 15:20:15 +0530121 * beiscsi_session_fail(): Closing session with appropriate error
122 * @cls_session: ptr to session
123 **/
124void 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/**
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530131 * beiscsi_conn_create - create an instance of iscsi connection
132 * @cls_session: ptr to iscsi_cls_session
133 * @cid: iscsi cid
134 */
135struct iscsi_cls_conn *
136beiscsi_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;
Jayamohan Kallickal2afc95b2009-09-22 08:22:26 +0530143 struct iscsi_session *sess;
144 struct beiscsi_session *beiscsi_sess;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530145
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530146 shost = iscsi_session_to_shost(cls_session);
147 phba = iscsi_host_priv(shost);
148
John Soni Jose99bc5d52012-08-20 23:00:18 +0530149 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
150 "BS_%d : In beiscsi_conn_create ,cid"
151 "from iscsi layer=%d\n", cid);
152
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530153 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;
Jayamohan Kallickal2afc95b2009-09-22 08:22:26 +0530162 sess = cls_session->dd_data;
163 beiscsi_sess = sess->dd_data;
164 beiscsi_conn->beiscsi_sess = beiscsi_sess;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530165 return cls_conn;
166}
167
168/**
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530169 * 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 */
176int 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;
Mike Christie3093b042011-07-25 13:48:46 -0500182 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
183 struct beiscsi_hba *phba = iscsi_host_priv(shost);
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700184 struct hwi_controller *phwi_ctrlr = phba->phwi_ctrlr;
185 struct hwi_wrb_context *pwrb_context;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530186 struct beiscsi_endpoint *beiscsi_ep;
187 struct iscsi_endpoint *ep;
Jitendra Bhivare413f3652016-12-13 15:56:03 +0530188 uint16_t cri_index;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530189
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530190 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) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530200 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
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530204 return -EEXIST;
205 }
Jitendra Bhivare413f3652016-12-13 15:56:03 +0530206 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 }
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700219
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530220 beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid;
221 beiscsi_conn->ep = beiscsi_ep;
222 beiscsi_ep->conn = beiscsi_conn;
Jitendra Bhivare413f3652016-12-13 15:56:03 +0530223 /**
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];
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700228 beiscsi_conn->doorbell_offset = pwrb_context->doorbell_offset;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530229 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
Jitendra Bhivare413f3652016-12-13 15:56:03 +0530230 "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;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530234}
235
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530236static int beiscsi_iface_create_ipv4(struct beiscsi_hba *phba)
Mike Christie0e438952012-04-03 23:41:51 -0500237{
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) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530246 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
247 "BS_%d : Could not "
248 "create default IPv4 address.\n");
Mike Christie0e438952012-04-03 23:41:51 -0500249 return -ENODEV;
250 }
251
252 return 0;
253}
254
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530255static int beiscsi_iface_create_ipv6(struct beiscsi_hba *phba)
Mike Christie0e438952012-04-03 23:41:51 -0500256{
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) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530265 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
266 "BS_%d : Could not "
267 "create default IPv6 address.\n");
Mike Christie0e438952012-04-03 23:41:51 -0500268 return -ENODEV;
269 }
270
271 return 0;
272}
273
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530274void beiscsi_iface_create_default(struct beiscsi_hba *phba)
Mike Christie0e438952012-04-03 23:41:51 -0500275{
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700276 struct be_cmd_get_if_info_resp *if_info;
Mike Christie0e438952012-04-03 23:41:51 -0500277
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530278 if (!beiscsi_if_get_info(phba, BEISCSI_IP_TYPE_V4, &if_info)) {
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530279 beiscsi_iface_create_ipv4(phba);
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700280 kfree(if_info);
281 }
Mike Christie0e438952012-04-03 23:41:51 -0500282
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530283 if (!beiscsi_if_get_info(phba, BEISCSI_IP_TYPE_V6, &if_info)) {
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530284 beiscsi_iface_create_ipv6(phba);
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700285 kfree(if_info);
286 }
Mike Christie0e438952012-04-03 23:41:51 -0500287}
288
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530289void beiscsi_iface_destroy_default(struct beiscsi_hba *phba)
Mike Christie0e438952012-04-03 23:41:51 -0500290{
Jitendra Bhivaref7dd0172016-08-19 15:20:01 +0530291 if (phba->ipv6_iface) {
Mike Christie0e438952012-04-03 23:41:51 -0500292 iscsi_destroy_iface(phba->ipv6_iface);
Jitendra Bhivaref7dd0172016-08-19 15:20:01 +0530293 phba->ipv6_iface = NULL;
294 }
295 if (phba->ipv4_iface) {
Mike Christie0e438952012-04-03 23:41:51 -0500296 iscsi_destroy_iface(phba->ipv4_iface);
Jitendra Bhivaref7dd0172016-08-19 15:20:01 +0530297 phba->ipv4_iface = NULL;
298 }
Mike Christie0e438952012-04-03 23:41:51 -0500299}
300
John Soni Jose6f72238e2012-08-20 23:00:43 +0530301/**
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 **/
313static int
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530314beiscsi_iface_config_vlan(struct Scsi_Host *shost,
315 struct iscsi_iface_param_info *iface_param)
John Soni Jose6f72238e2012-08-20 23:00:43 +0530316{
317 struct beiscsi_hba *phba = iscsi_host_priv(shost);
Jitendra Bhivarec5bf8882016-08-19 15:20:05 +0530318 int ret = -EPERM;
John Soni Jose6f72238e2012-08-20 23:00:43 +0530319
John Soni Jose6f72238e2012-08-20 23:00:43 +0530320 switch (iface_param->param) {
321 case ISCSI_NET_PARAM_VLAN_ENABLED:
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530322 ret = 0;
John Soni Jose6f72238e2012-08-20 23:00:43 +0530323 if (iface_param->value[0] != ISCSI_VLAN_ENABLE)
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530324 ret = beiscsi_if_set_vlan(phba, BEISCSI_VLAN_DISABLE);
John Soni Jose6f72238e2012-08-20 23:00:43 +0530325 break;
326 case ISCSI_NET_PARAM_VLAN_TAG:
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530327 ret = beiscsi_if_set_vlan(phba,
328 *((uint16_t *)iface_param->value));
John Soni Jose6f72238e2012-08-20 23:00:43 +0530329 break;
John Soni Jose6f72238e2012-08-20 23:00:43 +0530330 }
331 return ret;
332}
333
334
Mike Christie0e438952012-04-03 23:41:51 -0500335static int
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530336beiscsi_iface_config_ipv4(struct Scsi_Host *shost,
337 struct iscsi_iface_param_info *info,
338 void *data, uint32_t dt_len)
Mike Christie0e438952012-04-03 23:41:51 -0500339{
340 struct beiscsi_hba *phba = iscsi_host_priv(shost);
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530341 u8 *ip = NULL, *subnet = NULL, *gw;
342 struct nlattr *nla;
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530343 int ret = -EPERM;
Mike Christie0e438952012-04-03 23:41:51 -0500344
345 /* Check the param */
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530346 switch (info->param) {
Jitendra Bhivaref7dd0172016-08-19 15:20:01 +0530347 case ISCSI_NET_PARAM_IFACE_ENABLE:
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530348 if (info->value[0] == ISCSI_IFACE_ENABLE)
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530349 ret = beiscsi_iface_create_ipv4(phba);
Jitendra Bhivaref7dd0172016-08-19 15:20:01 +0530350 else {
351 iscsi_destroy_iface(phba->ipv4_iface);
352 phba->ipv4_iface = NULL;
353 }
354 break;
Mike Christie0e438952012-04-03 23:41:51 -0500355 case ISCSI_NET_PARAM_IPV4_GW:
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530356 gw = info->value;
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530357 ret = beiscsi_if_set_gw(phba, BEISCSI_IP_TYPE_V4, gw);
Mike Christie0e438952012-04-03 23:41:51 -0500358 break;
359 case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530360 if (info->value[0] == ISCSI_BOOTPROTO_DHCP)
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530361 ret = beiscsi_if_en_dhcp(phba, BEISCSI_IP_TYPE_V4);
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530362 else if (info->value[0] == ISCSI_BOOTPROTO_STATIC)
363 /* release DHCP IP address */
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530364 ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4,
365 NULL, NULL);
Mike Christie0e438952012-04-03 23:41:51 -0500366 else
John Soni Jose99bc5d52012-08-20 23:00:18 +0530367 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
368 "BS_%d : Invalid BOOTPROTO: %d\n",
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530369 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 }
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530378 ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4,
379 ip, subnet);
Mike Christie0e438952012-04-03 23:41:51 -0500380 break;
Mike Christie0e438952012-04-03 23:41:51 -0500381 case ISCSI_NET_PARAM_IPV4_SUBNET:
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530382 /*
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 }
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530392 ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4,
393 ip, subnet);
Mike Christie0e438952012-04-03 23:41:51 -0500394 break;
Mike Christie0e438952012-04-03 23:41:51 -0500395 }
396
397 return ret;
398}
399
400static int
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530401beiscsi_iface_config_ipv6(struct Scsi_Host *shost,
402 struct iscsi_iface_param_info *iface_param,
403 void *data, uint32_t dt_len)
Mike Christie0e438952012-04-03 23:41:51 -0500404{
405 struct beiscsi_hba *phba = iscsi_host_priv(shost);
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530406 int ret = -EPERM;
Mike Christie0e438952012-04-03 23:41:51 -0500407
408 switch (iface_param->param) {
409 case ISCSI_NET_PARAM_IFACE_ENABLE:
410 if (iface_param->value[0] == ISCSI_IFACE_ENABLE)
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530411 ret = beiscsi_iface_create_ipv6(phba);
Mike Christie0e438952012-04-03 23:41:51 -0500412 else {
413 iscsi_destroy_iface(phba->ipv6_iface);
Jitendra Bhivaref7dd0172016-08-19 15:20:01 +0530414 phba->ipv6_iface = NULL;
Mike Christie0e438952012-04-03 23:41:51 -0500415 }
416 break;
417 case ISCSI_NET_PARAM_IPV6_ADDR:
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530418 ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V6,
Jitendra Bhivare0152a7e2016-08-19 15:20:03 +0530419 iface_param->value, NULL);
Mike Christie0e438952012-04-03 23:41:51 -0500420 break;
Mike Christie0e438952012-04-03 23:41:51 -0500421 }
422
423 return ret;
424}
425
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530426int beiscsi_iface_set_param(struct Scsi_Host *shost,
427 void *data, uint32_t dt_len)
Mike Christie0e438952012-04-03 23:41:51 -0500428{
429 struct iscsi_iface_param_info *iface_param = NULL;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530430 struct beiscsi_hba *phba = iscsi_host_priv(shost);
Mike Christie0e438952012-04-03 23:41:51 -0500431 struct nlattr *attrib;
432 uint32_t rm_len = dt_len;
Jitendra Bhivarec5bf8882016-08-19 15:20:05 +0530433 int ret;
Mike Christie0e438952012-04-03 23:41:51 -0500434
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +0530435 if (!beiscsi_hba_is_online(phba)) {
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530436 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
437 "BS_%d : HBA in error 0x%lx\n", phba->state);
Jayamohan Kallickal3567f362013-09-28 15:35:58 -0700438 return -EBUSY;
439 }
440
Jitendra Bhivarec5bf8882016-08-19 15:20:05 +0530441 /* 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
Mike Christie0e438952012-04-03 23:41:51 -0500449 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) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530459 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
Mike Christie0e438952012-04-03 23:41:51 -0500464 return -EINVAL;
465 }
466
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530467 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);
Mike Christie0e438952012-04-03 23:41:51 -0500477 break;
478 default:
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530479 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 }
Mike Christie0e438952012-04-03 23:41:51 -0500491 }
492
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530493 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 }
Mike Christie0e438952012-04-03 23:41:51 -0500501 if (ret)
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530502 break;
Mike Christie0e438952012-04-03 23:41:51 -0500503 }
504
505 return ret;
506}
507
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530508static int __beiscsi_iface_get_param(struct beiscsi_hba *phba,
509 struct iscsi_iface *iface,
510 int param, char *buf)
Mike Christie0e438952012-04-03 23:41:51 -0500511{
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700512 struct be_cmd_get_if_info_resp *if_info;
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530513 int len, ip_type = BEISCSI_IP_TYPE_V4;
Mike Christie0e438952012-04-03 23:41:51 -0500514
Mike Christie0e438952012-04-03 23:41:51 -0500515 if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530516 ip_type = BEISCSI_IP_TYPE_V6;
Mike Christie0e438952012-04-03 23:41:51 -0500517
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530518 len = beiscsi_if_get_info(phba, ip_type, &if_info);
Geyslan G. Bem0e7c60c2013-11-18 16:42:57 -0300519 if (len)
Mike Christie0e438952012-04-03 23:41:51 -0500520 return len;
521
522 switch (param) {
523 case ISCSI_NET_PARAM_IPV4_ADDR:
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700524 len = sprintf(buf, "%pI4\n", if_info->ip_addr.addr);
Mike Christie0e438952012-04-03 23:41:51 -0500525 break;
526 case ISCSI_NET_PARAM_IPV6_ADDR:
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700527 len = sprintf(buf, "%pI6\n", if_info->ip_addr.addr);
Mike Christie0e438952012-04-03 23:41:51 -0500528 break;
529 case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700530 if (!if_info->dhcp_state)
John Soni Jose8359c792012-10-20 04:43:03 +0530531 len = sprintf(buf, "static\n");
Mike Christie0e438952012-04-03 23:41:51 -0500532 else
John Soni Jose8359c792012-10-20 04:43:03 +0530533 len = sprintf(buf, "dhcp\n");
Mike Christie0e438952012-04-03 23:41:51 -0500534 break;
535 case ISCSI_NET_PARAM_IPV4_SUBNET:
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700536 len = sprintf(buf, "%pI4\n", if_info->ip_addr.subnet_mask);
Mike Christie0e438952012-04-03 23:41:51 -0500537 break;
John Soni Jose6f72238e2012-08-20 23:00:43 +0530538 case ISCSI_NET_PARAM_VLAN_ENABLED:
539 len = sprintf(buf, "%s\n",
Jitendra Bhivareea896042016-08-19 15:19:58 +0530540 (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) ?
541 "disable" : "enable");
John Soni Jose6f72238e2012-08-20 23:00:43 +0530542 break;
543 case ISCSI_NET_PARAM_VLAN_ID:
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700544 if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE)
Geyslan G. Bem0e7c60c2013-11-18 16:42:57 -0300545 len = -EINVAL;
John Soni Jose6f72238e2012-08-20 23:00:43 +0530546 else
547 len = sprintf(buf, "%d\n",
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530548 (if_info->vlan_priority &
549 ISCSI_MAX_VLAN_ID));
John Soni Jose6f72238e2012-08-20 23:00:43 +0530550 break;
551 case ISCSI_NET_PARAM_VLAN_PRIORITY:
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700552 if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE)
Geyslan G. Bem0e7c60c2013-11-18 16:42:57 -0300553 len = -EINVAL;
John Soni Jose6f72238e2012-08-20 23:00:43 +0530554 else
555 len = sprintf(buf, "%d\n",
Jitendra Bhivaredb02aea2016-08-19 15:20:04 +0530556 ((if_info->vlan_priority >> 13) &
557 ISCSI_MAX_VLAN_PRIORITY));
John Soni Jose6f72238e2012-08-20 23:00:43 +0530558 break;
Mike Christie0e438952012-04-03 23:41:51 -0500559 default:
560 WARN_ON(1);
561 }
562
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700563 kfree(if_info);
Mike Christie0e438952012-04-03 23:41:51 -0500564 return len;
565}
566
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530567int beiscsi_iface_get_param(struct iscsi_iface *iface,
568 enum iscsi_param_type param_type,
569 int param, char *buf)
Mike Christie0e438952012-04-03 23:41:51 -0500570{
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;
Jitendra Bhivarec5bf8882016-08-19 15:20:05 +0530574 int len = -EPERM;
Mike Christie0e438952012-04-03 23:41:51 -0500575
Jitendra Bhivared8383b32016-08-19 15:20:07 +0530576 if (param_type != ISCSI_NET_PARAM)
577 return 0;
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +0530578 if (!beiscsi_hba_is_online(phba)) {
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530579 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
580 "BS_%d : HBA in error 0x%lx\n", phba->state);
Jayamohan Kallickal3567f362013-09-28 15:35:58 -0700581 return -EBUSY;
582 }
583
Mike Christie0e438952012-04-03 23:41:51 -0500584 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:
John Soni Jose6f72238e2012-08-20 23:00:43 +0530589 case ISCSI_NET_PARAM_VLAN_ENABLED:
590 case ISCSI_NET_PARAM_VLAN_ID:
591 case ISCSI_NET_PARAM_VLAN_PRIORITY:
Jitendra Bhivare96b48b92016-08-19 15:20:06 +0530592 len = __beiscsi_iface_get_param(phba, iface, param, buf);
Mike Christie0e438952012-04-03 23:41:51 -0500593 break;
594 case ISCSI_NET_PARAM_IFACE_ENABLE:
Jitendra Bhivaref7dd0172016-08-19 15:20:01 +0530595 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");
Mike Christie0e438952012-04-03 23:41:51 -0500601 break;
602 case ISCSI_NET_PARAM_IPV4_GW:
603 memset(&gateway, 0, sizeof(gateway));
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530604 len = beiscsi_if_get_gw(phba, BEISCSI_IP_TYPE_V4, &gateway);
Mike Christie0e438952012-04-03 23:41:51 -0500605 if (!len)
606 len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr);
607 break;
Mike Christie0e438952012-04-03 23:41:51 -0500608 }
609
610 return len;
611}
612
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530613/**
Mike Christiec7f7fd52011-02-16 15:04:41 -0600614 * beiscsi_ep_get_param - get the iscsi parameter
615 * @ep: pointer to iscsi ep
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530616 * @param: parameter type identifier
617 * @buf: buffer pointer
618 *
619 * returns iscsi parameter
620 */
Mike Christiec7f7fd52011-02-16 15:04:41 -0600621int beiscsi_ep_get_param(struct iscsi_endpoint *ep,
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530622 enum iscsi_param param, char *buf)
623{
Mike Christiec7f7fd52011-02-16 15:04:41 -0600624 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
Jitendra Bhivarec5bf8882016-08-19 15:20:05 +0530625 int len;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530626
John Soni Jose99bc5d52012-08-20 23:00:18 +0530627 beiscsi_log(beiscsi_ep->phba, KERN_INFO,
628 BEISCSI_LOG_CONFIG,
629 "BS_%d : In beiscsi_ep_get_param,"
630 " param= %d\n", param);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530631
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:
Jitendra Bhivare290aa372016-08-19 15:20:08 +0530637 if (beiscsi_ep->ip_type == BEISCSI_IP_TYPE_V4)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530638 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:
Jitendra Bhivarec5bf8882016-08-19 15:20:05 +0530643 len = -EPERM;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530644 }
645 return len;
646}
647
648int 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;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530653 struct beiscsi_hba *phba = NULL;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530654 int ret;
655
John Soni Jose99bc5d52012-08-20 23:00:18 +0530656 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
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530661 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:
Jayamohan Kallickal230dceb2010-01-23 05:36:10 +0530678 if (session->max_burst > 262144)
679 session->max_burst = 262144;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530680 break;
Jayamohan Kallickal42f43c42010-07-22 04:26:45 +0530681 case ISCSI_PARAM_MAX_XMIT_DLENGTH:
Jayamohan Kallickal73316132013-09-28 15:35:41 -0700682 if (conn->max_xmit_dlength > 65536)
Jayamohan Kallickal42f43c42010-07-22 04:26:45 +0530683 conn->max_xmit_dlength = 65536;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530684 default:
685 return 0;
686 }
687
688 return 0;
689}
690
691/**
John Soni Jose21771992012-04-03 23:41:49 -0500692 * 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 */
698static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba)
699{
700 int rc;
John Soni Josee175def2012-10-20 04:45:40 +0530701 unsigned int tag;
John Soni Jose21771992012-04-03 23:41:49 -0500702 struct be_mcc_wrb *wrb;
703 struct be_cmd_hba_name *resp;
John Soni Jose21771992012-04-03 23:41:49 -0500704
705 tag = be_cmd_get_initname(phba);
706 if (!tag) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530707 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
708 "BS_%d : Getting Initiator Name Failed\n");
709
John Soni Jose21771992012-04-03 23:41:49 -0500710 return -EBUSY;
John Soni Josee175def2012-10-20 04:45:40 +0530711 }
John Soni Jose21771992012-04-03 23:41:49 -0500712
Jitendra Bhivare88840332016-02-04 15:49:12 +0530713 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
John Soni Josee175def2012-10-20 04:45:40 +0530714 if (rc) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530715 beiscsi_log(phba, KERN_ERR,
716 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
John Soni Josee175def2012-10-20 04:45:40 +0530717 "BS_%d : Initiator Name MBX Failed\n");
718 return rc;
John Soni Jose21771992012-04-03 23:41:49 -0500719 }
John Soni Josee175def2012-10-20 04:45:40 +0530720
John Soni Jose21771992012-04-03 23:41:49 -0500721 resp = embedded_payload(wrb);
722 rc = sprintf(buf, "%s\n", resp->initiator_name);
723 return rc;
724}
725
726/**
John Soni Josec62eef02012-04-03 23:41:52 -0500727 * beiscsi_get_port_state - Get the Port State
728 * @shost : pointer to scsi_host structure
729 *
John Soni Josec62eef02012-04-03 23:41:52 -0500730 */
731static 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
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530736 ihost->port_state = test_bit(BEISCSI_HBA_LINK_UP, &phba->state) ?
John Soni Josec62eef02012-04-03 23:41:52 -0500737 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 *
John Soni Josec62eef02012-04-03 23:41:52 -0500744 */
Jitendra Bhivare048084c2016-01-20 14:10:58 +0530745static void beiscsi_get_port_speed(struct Scsi_Host *shost)
John Soni Josec62eef02012-04-03 23:41:52 -0500746{
John Soni Josec62eef02012-04-03 23:41:52 -0500747 struct beiscsi_hba *phba = iscsi_host_priv(shost);
748 struct iscsi_cls_host *ihost = shost->shost_data;
John Soni Josec62eef02012-04-03 23:41:52 -0500749
Jitendra Bhivare048084c2016-01-20 14:10:58 +0530750 switch (phba->port_speed) {
John Soni Josec62eef02012-04-03 23:41:52 -0500751 case BE2ISCSI_LINK_SPEED_10MBPS:
752 ihost->port_speed = ISCSI_PORT_SPEED_10MBPS;
753 break;
754 case BE2ISCSI_LINK_SPEED_100MBPS:
Jayamohan Kallickal3e393172014-01-29 02:16:40 -0500755 ihost->port_speed = ISCSI_PORT_SPEED_100MBPS;
John Soni Josec62eef02012-04-03 23:41:52 -0500756 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;
Jitendra Bhivare048084c2016-01-20 14:10:58 +0530763 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;
John Soni Josec62eef02012-04-03 23:41:52 -0500769 default:
770 ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN;
771 }
John Soni Josec62eef02012-04-03 23:41:52 -0500772}
773
774/**
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530775 * 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 */
782int beiscsi_get_host_param(struct Scsi_Host *shost,
783 enum iscsi_host_param param, char *buf)
784{
Mike Christie3093b042011-07-25 13:48:46 -0500785 struct beiscsi_hba *phba = iscsi_host_priv(shost);
Jayamohan Kallickalb15d05b2010-08-12 23:36:06 +0530786 int status = 0;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530787
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +0530788 if (!beiscsi_hba_is_online(phba)) {
Jayamohan Kallickal3567f362013-09-28 15:35:58 -0700789 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530790 "BS_%d : HBA in error 0x%lx\n", phba->state);
791 return -EBUSY;
Jayamohan Kallickal3567f362013-09-28 15:35:58 -0700792 }
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530793 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
794 "BS_%d : In beiscsi_get_host_param, param = %d\n", param);
John Soni Jose99bc5d52012-08-20 23:00:18 +0530795
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530796 switch (param) {
797 case ISCSI_HOST_PARAM_HWADDRESS:
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530798 status = beiscsi_get_macaddr(buf, phba);
799 if (status < 0) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530800 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
801 "BS_%d : beiscsi_get_macaddr Failed\n");
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530802 return status;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530803 }
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530804 break;
John Soni Jose21771992012-04-03 23:41:49 -0500805 case ISCSI_HOST_PARAM_INITIATOR_NAME:
806 status = beiscsi_get_initname(buf, phba);
807 if (status < 0) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530808 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
809 "BS_%d : Retreiving Initiator Name Failed\n");
John Soni Jose21771992012-04-03 23:41:49 -0500810 return status;
811 }
812 break;
John Soni Josec62eef02012-04-03 23:41:52 -0500813 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:
Jitendra Bhivare048084c2016-01-20 14:10:58 +0530818 beiscsi_get_port_speed(shost);
John Soni Josec62eef02012-04-03 23:41:52 -0500819 status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost));
820 break;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530821 default:
822 return iscsi_host_get_param(shost, param, buf);
823 }
Jayamohan Kallickalb15d05b2010-08-12 23:36:06 +0530824 return status;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530825}
826
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530827int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba)
828{
Mike Christie0e438952012-04-03 23:41:51 -0500829 struct be_cmd_get_nic_conf_resp resp;
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530830 int rc;
831
Jayamohan Kallickal6c831852013-09-28 15:35:40 -0700832 if (phba->mac_addr_set)
John Soni Josedf5d0e62012-08-20 23:00:31 +0530833 return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530834
Mike Christie0e438952012-04-03 23:41:51 -0500835 memset(&resp, 0, sizeof(resp));
836 rc = mgmt_get_nic_conf(phba, &resp);
837 if (rc)
838 return rc;
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530839
Jayamohan Kallickal6c831852013-09-28 15:35:40 -0700840 phba->mac_addr_set = true;
Mike Christie0e438952012-04-03 23:41:51 -0500841 memcpy(phba->mac_address, resp.mac_address, ETH_ALEN);
842 return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530843}
844
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530845/**
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 */
852void 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;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530856 struct beiscsi_hba *phba = NULL;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530857
John Soni Jose99bc5d52012-08-20 23:00:18 +0530858 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
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530862 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;
Mike Christie915aafd2014-07-01 11:24:38 -0500873 stats->custom_length = 1;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530874 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 */
883static 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);
John Soni Joseacb96932012-10-20 04:44:35 +0530906 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);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530914 AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params,
915 (conn->exp_statsn - 1));
Jayamohan Kallickal73316132013-09-28 15:35:41 -0700916 AMAP_SET_BITS(struct amap_beiscsi_offload_params,
917 max_recv_data_segment_length, params,
918 conn->max_recv_dlength);
919
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530920}
921
922/**
923 * beiscsi_conn_start - offload of session to chip
924 * @cls_conn: pointer to beiscsi_conn
925 */
926int 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;
Jayamohan Kallickal3567f362013-09-28 15:35:58 -0700932 struct beiscsi_hba *phba;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530933
Jayamohan Kallickal3567f362013-09-28 15:35:58 -0700934 phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
935
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +0530936 if (!beiscsi_hba_is_online(phba)) {
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530937 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
938 "BS_%d : HBA in error 0x%lx\n", phba->state);
Jayamohan Kallickal3567f362013-09-28 15:35:58 -0700939 return -EBUSY;
Jayamohan Kallickal3567f362013-09-28 15:35:58 -0700940 }
Jitendra Bhivare9122e992016-08-19 15:20:11 +0530941 beiscsi_log(beiscsi_conn->phba, KERN_INFO, BEISCSI_LOG_CONFIG,
942 "BS_%d : In beiscsi_conn_start\n");
John Soni Jose99bc5d52012-08-20 23:00:18 +0530943
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530944 memset(&params, 0, sizeof(struct beiscsi_offload_params));
945 beiscsi_ep = beiscsi_conn->ep;
946 if (!beiscsi_ep)
John Soni Jose99bc5d52012-08-20 23:00:18 +0530947 beiscsi_log(beiscsi_conn->phba, KERN_ERR,
948 BEISCSI_LOG_CONFIG,
949 "BS_%d : In beiscsi_conn_start , no beiscsi_ep\n");
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530950
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530951 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 */
962static int beiscsi_get_cid(struct beiscsi_hba *phba)
963{
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -0700964 uint16_t cid_avlbl_ulp0, cid_avlbl_ulp1;
Jitendra Bhivare413f3652016-12-13 15:56:03 +0530965 unsigned short cid, cid_from_ulp;
966 struct ulp_cid_info *cid_info;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530967
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -0700968 /* 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;
Jitendra Bhivare413f3652016-12-13 15:56:03 +0530975 /**
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;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530982
Jitendra Bhivare413f3652016-12-13 15:56:03 +0530983 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;
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -0700990 }
Jitendra Bhivare413f3652016-12-13 15:56:03 +0530991 /* 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--;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530996 return cid;
997}
998
999/**
Mike Christiefa95d202010-06-09 03:30:08 -05001000 * beiscsi_put_cid - Free the cid
1001 * @phba: The phba for which the cid is being freed
1002 * @cid: The cid to free
1003 */
1004static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
1005{
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -07001006 uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
Jitendra Bhivare413f3652016-12-13 15:56:03 +05301007 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;
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -07001011
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];
Jitendra Bhivare413f3652016-12-13 15:56:03 +05301017 /* 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 }
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -07001024 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;
Jitendra Bhivare413f3652016-12-13 15:56:03 +05301027 cid_info->avlbl_cids++;
Mike Christiefa95d202010-06-09 03:30:08 -05001028}
1029
1030/**
1031 * beiscsi_free_ep - free endpoint
1032 * @ep: pointer to iscsi endpoint structure
1033 */
1034static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
1035{
1036 struct beiscsi_hba *phba = beiscsi_ep->phba;
Jayamohan Kallickal43f388b2013-04-05 20:38:25 -07001037 struct beiscsi_conn *beiscsi_conn;
Mike Christiefa95d202010-06-09 03:30:08 -05001038
1039 beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
1040 beiscsi_ep->phba = NULL;
Jitendra Bhivare413f3652016-12-13 15:56:03 +05301041 /* clear this to track freeing in beiscsi_ep_disconnect */
1042 phba->ep_array[BE_GET_CRI_FROM_CID(beiscsi_ep->ep_cid)] = NULL;
Jayamohan Kallickal43f388b2013-04-05 20:38:25 -07001043
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;
Jitendra Bhivare413f3652016-12-13 15:56:03 +05301053 /**
1054 * Break ep->conn link here so that completions after
1055 * this are ignored.
1056 */
1057 beiscsi_ep->conn = NULL;
Jayamohan Kallickal43f388b2013-04-05 20:38:25 -07001058 if (beiscsi_conn->login_in_progress) {
Jayamohan Kallickal4a4a11b2013-04-05 20:38:31 -07001059 beiscsi_free_mgmt_task_handles(beiscsi_conn,
1060 beiscsi_conn->task);
Jayamohan Kallickal43f388b2013-04-05 20:38:25 -07001061 beiscsi_conn->login_in_progress = 0;
1062 }
Mike Christiefa95d202010-06-09 03:30:08 -05001063}
1064
1065/**
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301066 * 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 */
1073static 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;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +05301079 struct tcp_connect_and_offload_out *ptcpcnct_out;
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +05301080 struct be_dma_mem nonemb_cmd;
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -04001081 unsigned int tag, req_memsize;
Jayamohan Kallickald3ad2bb2010-07-22 04:16:38 +05301082 int ret = -ENOMEM;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301083
John Soni Jose99bc5d52012-08-20 23:00:18 +05301084 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1085 "BS_%d : In beiscsi_open_conn\n");
1086
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301087 beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
Jitendra Bhivare413f3652016-12-13 15:56:03 +05301088 if (beiscsi_ep->ep_cid == BE_INVALID_CID) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301089 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1090 "BS_%d : No free cid available\n");
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301091 return ret;
1092 }
John Soni Jose99bc5d52012-08-20 23:00:18 +05301093
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
Jayamohan Kallickala7909b32013-04-05 20:38:32 -07001098 phba->ep_array[BE_GET_CRI_FROM_CID
1099 (beiscsi_ep->ep_cid)] = ep;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301100
1101 beiscsi_ep->cid_vld = 0;
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -04001102
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
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +05301108 nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -04001109 req_memsize,
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +05301110 &nonemb_cmd.dma);
1111 if (nonemb_cmd.va == NULL) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301112
1113 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1114 "BS_%d : Failed to allocate memory for"
1115 " mgmt_open_connection\n");
1116
Jayamohan Kallickala7909b32013-04-05 20:38:32 -07001117 beiscsi_free_ep(beiscsi_ep);
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +05301118 return -ENOMEM;
1119 }
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -04001120 nonemb_cmd.size = req_memsize;
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +05301121 memset(nonemb_cmd.va, 0, nonemb_cmd.size);
1122 tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
Jitendra Bhivarefa1261c2016-12-13 15:56:01 +05301123 if (!tag) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301124 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
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +05301128 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1129 nonemb_cmd.va, nonemb_cmd.dma);
Jayamohan Kallickala7909b32013-04-05 20:38:32 -07001130 beiscsi_free_ep(beiscsi_ep);
Jayamohan Kallickal1f926382010-07-22 04:22:27 +05301131 return -EAGAIN;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +05301132 }
John Soni Josee175def2012-10-20 04:45:40 +05301133
Jitendra Bhivare88840332016-02-04 15:49:12 +05301134 ret = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
John Soni Josee175def2012-10-20 04:45:40 +05301135 if (ret) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301136 beiscsi_log(phba, KERN_ERR,
1137 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
John Soni Josee175def2012-10-20 04:45:40 +05301138 "BS_%d : mgmt_open_connection Failed");
John Soni Jose99bc5d52012-08-20 23:00:18 +05301139
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -05001140 if (ret != -EBUSY)
1141 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1142 nonemb_cmd.va, nonemb_cmd.dma);
1143
Jayamohan Kallickala7909b32013-04-05 20:38:32 -07001144 beiscsi_free_ep(beiscsi_ep);
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -05001145 return ret;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +05301146 }
John Soni Josee175def2012-10-20 04:45:40 +05301147
Jayamohan Kallickal1e234bb2013-04-05 20:38:23 -07001148 ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va;
John Soni Josee175def2012-10-20 04:45:40 +05301149 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
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +05301155 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1156 nonemb_cmd.va, nonemb_cmd.dma);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +05301157 return 0;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301158}
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 */
1168struct iscsi_endpoint *
1169beiscsi_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
Jitendra Bhivare9122e992016-08-19 15:20:11 +05301177 if (!shost) {
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301178 ret = -ENXIO;
Jitendra Bhivare9122e992016-08-19 15:20:11 +05301179 pr_err("beiscsi_ep_connect shost is NULL\n");
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301180 return ERR_PTR(ret);
1181 }
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +05301182
Jitendra Bhivare9122e992016-08-19 15:20:11 +05301183 phba = iscsi_host_priv(shost);
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +05301184 if (!beiscsi_hba_is_online(phba)) {
Jayamohan Kallickalcf6e3c62013-04-05 20:38:33 -07001185 ret = -EIO;
Jitendra Bhivare9122e992016-08-19 15:20:11 +05301186 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1187 "BS_%d : HBA in error 0x%lx\n", phba->state);
Jayamohan Kallickalcf6e3c62013-04-05 20:38:33 -07001188 return ERR_PTR(ret);
1189 }
Jitendra Bhivare9122e992016-08-19 15:20:11 +05301190 if (!test_bit(BEISCSI_HBA_LINK_UP, &phba->state)) {
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +05301191 ret = -EBUSY;
John Soni Jose8359c792012-10-20 04:43:03 +05301192 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1193 "BS_%d : The Adapter Port state is Down!!!\n");
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +05301194 return ERR_PTR(ret);
1195 }
1196
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301197 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;
Jayamohan Kallickalc24622882010-01-05 05:05:34 +05301205 beiscsi_ep->openiscsi_ep = ep;
Jayamohan Kallickalf5ed7bd2010-07-22 04:18:01 +05301206 ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking);
1207 if (ret) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301208 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1209 "BS_%d : Failed in beiscsi_open_conn\n");
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301210 goto free_ep;
1211 }
1212
1213 return ep;
1214
1215free_ep:
Mike Christiefa95d202010-06-09 03:30:08 -05001216 iscsi_destroy_endpoint(ep);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301217 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 */
1227int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
1228{
1229 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
1230
John Soni Jose99bc5d52012-08-20 23:00:18 +05301231 beiscsi_log(beiscsi_ep->phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1232 "BS_%d : In beiscsi_ep_poll\n");
1233
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301234 if (beiscsi_ep->cid_vld == 1)
1235 return 1;
1236 else
1237 return 0;
1238}
1239
1240/**
Jayamohan Kallickalb7ab35b2014-08-08 01:00:01 -04001241 * 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 **/
1247static 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];
Christoph Hellwig511cbce2015-11-10 14:56:14 +01001259 irq_poll_disable(&pbe_eq->iopoll);
Jitendra Bhivare1094cf62016-01-20 14:10:56 +05301260 beiscsi_process_cq(pbe_eq, BE2_MAX_NUM_CQ_PROC);
Christoph Hellwig511cbce2015-11-10 14:56:14 +01001261 irq_poll_enable(&pbe_eq->iopoll);
Jayamohan Kallickalb7ab35b2014-08-08 01:00:01 -04001262 }
1263}
1264
1265/**
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301266 * beiscsi_close_conn - Upload the connection
1267 * @ep: The iscsi endpoint
1268 * @flag: The type of connection closure
1269 */
Jayamohan Kallickalc24622882010-01-05 05:05:34 +05301270static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301271{
1272 int ret = 0;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +05301273 unsigned int tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301274 struct beiscsi_hba *phba = beiscsi_ep->phba;
1275
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +05301276 tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag);
1277 if (!tag) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301278 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1279 "BS_%d : upload failed for cid 0x%x\n",
1280 beiscsi_ep->ep_cid);
1281
Jayamohan Kallickald3ad2bb2010-07-22 04:16:38 +05301282 ret = -EAGAIN;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301283 }
John Soni Josee175def2012-10-20 04:45:40 +05301284
Jitendra Bhivare88840332016-02-04 15:49:12 +05301285 ret = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
Jayamohan Kallickalb7ab35b2014-08-08 01:00:01 -04001286
1287 /* Flush the CQ entries */
1288 beiscsi_flush_cq(phba);
1289
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301290 return ret;
1291}
1292
1293/**
Mike Christiefa95d202010-06-09 03:30:08 -05001294 * beiscsi_ep_disconnect - Tears down the TCP connection
1295 * @ep: endpoint to be used
1296 *
1297 * Tears down the TCP connection
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301298 */
Mike Christiefa95d202010-06-09 03:30:08 -05001299void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301300{
Mike Christiefa95d202010-06-09 03:30:08 -05001301 struct beiscsi_conn *beiscsi_conn;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301302 struct beiscsi_endpoint *beiscsi_ep;
Mike Christiefa95d202010-06-09 03:30:08 -05001303 struct beiscsi_hba *phba;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +05301304 unsigned int tag;
John Soni Jose0a513dd2012-08-20 23:00:55 +05301305 uint8_t mgmt_invalidate_flag, tcp_upload_flag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301306 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;
Jitendra Bhivare413f3652016-12-13 15:56:03 +05301307 uint16_t cri_index;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301308
Mike Christiefa95d202010-06-09 03:30:08 -05001309 beiscsi_ep = ep->dd_data;
1310 phba = beiscsi_ep->phba;
John Soni Jose99bc5d52012-08-20 23:00:18 +05301311 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
Jitendra Bhivare413f3652016-12-13 15:56:03 +05301312 "BS_%d : In beiscsi_ep_disconnect for ep_cid = %u\n",
John Soni Jose99bc5d52012-08-20 23:00:18 +05301313 beiscsi_ep->ep_cid);
Mike Christiefa95d202010-06-09 03:30:08 -05001314
Jitendra Bhivare413f3652016-12-13 15:56:03 +05301315 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
John Soni Jose0a513dd2012-08-20 23:00:55 +05301324 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;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301332 }
Mike Christiefa95d202010-06-09 03:30:08 -05001333
Jitendra Bhivared1d5ca82016-08-19 15:20:18 +05301334 if (!beiscsi_hba_is_online(phba)) {
Jitendra Bhivare9122e992016-08-19 15:20:11 +05301335 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1336 "BS_%d : HBA in error 0x%lx\n", phba->state);
Jayamohan Kallickal3567f362013-09-28 15:35:58 -07001337 goto free_ep;
1338 }
1339
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +05301340 tag = mgmt_invalidate_connection(phba, beiscsi_ep,
John Soni Jose0a513dd2012-08-20 23:00:55 +05301341 beiscsi_ep->ep_cid,
1342 mgmt_invalidate_flag,
1343 savecfg_flag);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +05301344 if (!tag) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301345 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
John Soni Jose0a513dd2012-08-20 23:00:55 +05301346 "BS_%d : mgmt_invalidate_connection Failed for cid=%d\n",
John Soni Jose99bc5d52012-08-20 23:00:18 +05301347 beiscsi_ep->ep_cid);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301348 }
Mike Christiefa95d202010-06-09 03:30:08 -05001349
Jitendra Bhivare88840332016-02-04 15:49:12 +05301350 beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
John Soni Jose0a513dd2012-08-20 23:00:55 +05301351 beiscsi_close_conn(beiscsi_ep, tcp_upload_flag);
Jayamohan Kallickal3567f362013-09-28 15:35:58 -07001352free_ep:
Jayamohan Kallickal9343be72014-01-29 02:16:43 -05001353 msleep(BEISCSI_LOGOUT_SYNC_DELAY);
Jayamohan Kallickalc24622882010-01-05 05:05:34 +05301354 beiscsi_free_ep(beiscsi_ep);
Jitendra Bhivare413f3652016-12-13 15:56:03 +05301355 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;
Mike Christiefa95d202010-06-09 03:30:08 -05001361 iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301362}
Mike Christie3128c6c2011-07-25 13:48:42 -05001363
Jitendra Bhivare96b48b92016-08-19 15:20:06 +05301364umode_t beiscsi_attr_is_visible(int param_type, int param)
Mike Christie3128c6c2011-07-25 13:48:42 -05001365{
1366 switch (param_type) {
Mike Christie0e438952012-04-03 23:41:51 -05001367 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:
John Soni Jose6f72238e2012-08-20 23:00:43 +05301375 case ISCSI_NET_PARAM_VLAN_ID:
1376 case ISCSI_NET_PARAM_VLAN_PRIORITY:
1377 case ISCSI_NET_PARAM_VLAN_ENABLED:
Mike Christie0e438952012-04-03 23:41:51 -05001378 return S_IRUGO;
1379 default:
1380 return 0;
1381 }
Mike Christief27fb2e2011-07-25 13:48:45 -05001382 case ISCSI_HOST_PARAM:
1383 switch (param) {
1384 case ISCSI_HOST_PARAM_HWADDRESS:
John Soni Josec62eef02012-04-03 23:41:52 -05001385 case ISCSI_HOST_PARAM_INITIATOR_NAME:
1386 case ISCSI_HOST_PARAM_PORT_STATE:
1387 case ISCSI_HOST_PARAM_PORT_SPEED:
Mike Christief27fb2e2011-07-25 13:48:45 -05001388 return S_IRUGO;
1389 default:
1390 return 0;
1391 }
Mike Christie3128c6c2011-07-25 13:48:42 -05001392 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:
Mike Christie1d063c12011-07-25 13:48:43 -05001405 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:
Mike Christie3128c6c2011-07-25 13:48:42 -05001424 return S_IRUGO;
1425 default:
1426 return 0;
1427 }
1428 }
1429
1430 return 0;
1431}