blob: bdd9a29f4201c32e320cd643c9cda5038c58af57 [file] [log] [blame]
dea31012005-04-17 16:05:31 -05001/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04003 * Fibre Channel Host Bus Adapters. *
James Smart145e5a82020-01-27 16:23:12 -08004 * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term *
James Smart3e21d1c2018-05-04 20:37:59 -07005 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
James Smart50611572016-03-31 14:12:34 -07006 * Copyright (C) 2004-2016 Emulex. All rights reserved. *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04007 * EMULEX and SLI are trademarks of Emulex. *
James Smartd080abe2017-02-12 13:52:39 -08008 * www.broadcom.com *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04009 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
dea31012005-04-17 16:05:31 -050010 * *
11 * This program is free software; you can redistribute it and/or *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -040012 * modify it under the terms of version 2 of the GNU General *
13 * Public License as published by the Free Software Foundation. *
14 * This program is distributed in the hope that it will be useful. *
15 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
16 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
17 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
18 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
19 * TO BE LEGALLY INVALID. See the GNU General Public License for *
20 * more details, a copy of which can be found in the file COPYING *
21 * included with this package. *
dea31012005-04-17 16:05:31 -050022 *******************************************************************/
23
dea31012005-04-17 16:05:31 -050024#include <linux/ctype.h>
James Smart46fa3112007-04-25 09:51:45 -040025#include <linux/delay.h>
dea31012005-04-17 16:05:31 -050026#include <linux/pci.h>
27#include <linux/interrupt.h>
Paul Gortmakeracf3368f2011-05-27 09:47:43 -040028#include <linux/module.h>
James Smart0d878412009-10-02 15:16:56 -040029#include <linux/aer.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090030#include <linux/gfp.h>
Andy Shevchenkoecc30992010-08-10 18:01:27 -070031#include <linux/kernel.h>
dea31012005-04-17 16:05:31 -050032
James.Smart@Emulex.Com91886522005-08-10 15:03:09 -040033#include <scsi/scsi.h>
dea31012005-04-17 16:05:31 -050034#include <scsi/scsi_device.h>
35#include <scsi/scsi_host.h>
36#include <scsi/scsi_tcq.h>
37#include <scsi/scsi_transport_fc.h>
James Smart6a9c52c2009-10-02 15:16:51 -040038#include <scsi/fc/fc_fs.h>
dea31012005-04-17 16:05:31 -050039
James Smartda0436e2009-05-22 14:51:39 -040040#include "lpfc_hw4.h"
dea31012005-04-17 16:05:31 -050041#include "lpfc_hw.h"
42#include "lpfc_sli.h"
James Smartda0436e2009-05-22 14:51:39 -040043#include "lpfc_sli4.h"
James Smartea2151b2008-09-07 11:52:10 -040044#include "lpfc_nl.h"
dea31012005-04-17 16:05:31 -050045#include "lpfc_disc.h"
dea31012005-04-17 16:05:31 -050046#include "lpfc.h"
James Smart895427b2017-02-12 13:52:30 -080047#include "lpfc_scsi.h"
48#include "lpfc_nvme.h"
dea31012005-04-17 16:05:31 -050049#include "lpfc_logmsg.h"
50#include "lpfc_version.h"
51#include "lpfc_compat.h"
52#include "lpfc_crtn.h"
James Smart92d7f7b2007-06-17 19:56:38 -050053#include "lpfc_vport.h"
James Smart93dd1912016-07-06 12:36:10 -070054#include "lpfc_attr.h"
dea31012005-04-17 16:05:31 -050055
James Smart2ea259e2017-02-12 13:52:27 -080056#define LPFC_DEF_DEVLOSS_TMO 30
57#define LPFC_MIN_DEVLOSS_TMO 1
58#define LPFC_MAX_DEVLOSS_TMO 255
dea31012005-04-17 16:05:31 -050059
James Smartf7a919b2011-08-21 21:49:16 -040060/*
61 * Write key size should be multiple of 4. If write key is changed
62 * make sure that library write key is also changed.
63 */
64#define LPFC_REG_WRITE_KEY_SIZE 4
65#define LPFC_REG_WRITE_KEY "EMLX"
66
Bart Van Asschea73cb812019-03-28 11:06:19 -070067const char *const trunk_errmsg[] = { /* map errcode */
68 "", /* There is no such error code at index 0*/
69 "link negotiated speed does not match existing"
70 " trunk - link was \"low\" speed",
71 "link negotiated speed does not match"
72 " existing trunk - link was \"middle\" speed",
73 "link negotiated speed does not match existing"
74 " trunk - link was \"high\" speed",
75 "Attached to non-trunking port - F_Port",
76 "Attached to non-trunking port - N_Port",
77 "FLOGI response timeout",
78 "non-FLOGI frame received",
79 "Invalid FLOGI response",
80 "Trunking initialization protocol",
81 "Trunk peer device mismatch",
82};
83
James Smarte59058c2008-08-24 21:49:00 -040084/**
James Smart3621a712009-04-06 18:47:14 -040085 * lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules
James Smarte59058c2008-08-24 21:49:00 -040086 * @incr: integer to convert.
87 * @hdw: ascii string holding converted integer plus a string terminator.
88 *
89 * Description:
90 * JEDEC Joint Electron Device Engineering Council.
91 * Convert a 32 bit integer composed of 8 nibbles into an 8 byte ascii
92 * character string. The string is then terminated with a NULL in byte 9.
93 * Hex 0-9 becomes ascii '0' to '9'.
94 * Hex a-f becomes ascii '=' to 'B' capital B.
95 *
96 * Notes:
97 * Coded for 32 bit integers only.
98 **/
dea31012005-04-17 16:05:31 -050099static void
100lpfc_jedec_to_ascii(int incr, char hdw[])
101{
102 int i, j;
103 for (i = 0; i < 8; i++) {
104 j = (incr & 0xf);
105 if (j <= 9)
106 hdw[7 - i] = 0x30 + j;
107 else
108 hdw[7 - i] = 0x61 + j - 10;
109 incr = (incr >> 4);
110 }
111 hdw[8] = 0;
112 return;
113}
114
James Smarte59058c2008-08-24 21:49:00 -0400115/**
James Smart3621a712009-04-06 18:47:14 -0400116 * lpfc_drvr_version_show - Return the Emulex driver string with version number
James Smarte59058c2008-08-24 21:49:00 -0400117 * @dev: class unused variable.
118 * @attr: device attribute, not used.
119 * @buf: on return contains the module description text.
120 *
121 * Returns: size of formatted string.
122 **/
dea31012005-04-17 16:05:31 -0500123static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100124lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr,
125 char *buf)
dea31012005-04-17 16:05:31 -0500126{
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700127 return scnprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n");
dea31012005-04-17 16:05:31 -0500128}
129
James Smart45ed1192009-10-02 15:17:02 -0400130/**
131 * lpfc_enable_fip_show - Return the fip mode of the HBA
132 * @dev: class unused variable.
133 * @attr: device attribute, not used.
134 * @buf: on return contains the module description text.
135 *
136 * Returns: size of formatted string.
137 **/
138static ssize_t
139lpfc_enable_fip_show(struct device *dev, struct device_attribute *attr,
140 char *buf)
141{
142 struct Scsi_Host *shost = class_to_shost(dev);
143 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
144 struct lpfc_hba *phba = vport->phba;
145
146 if (phba->hba_flag & HBA_FIP_SUPPORT)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700147 return scnprintf(buf, PAGE_SIZE, "1\n");
James Smart45ed1192009-10-02 15:17:02 -0400148 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700149 return scnprintf(buf, PAGE_SIZE, "0\n");
James Smart45ed1192009-10-02 15:17:02 -0400150}
151
James Smart81301a92008-12-04 22:39:46 -0500152static ssize_t
James Smart895427b2017-02-12 13:52:30 -0800153lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
154 char *buf)
155{
156 struct Scsi_Host *shost = class_to_shost(dev);
157 struct lpfc_vport *vport = shost_priv(shost);
158 struct lpfc_hba *phba = vport->phba;
James Smartf358dd02017-02-12 13:52:34 -0800159 struct lpfc_nvmet_tgtport *tgtp;
James Smart895427b2017-02-12 13:52:30 -0800160 struct nvme_fc_local_port *localport;
James Smart4b056682017-12-08 17:18:10 -0800161 struct lpfc_nvme_lport *lport;
James Smart01466022018-04-09 14:24:27 -0700162 struct lpfc_nvme_rport *rport;
James Smart80cc0042017-06-01 21:06:56 -0700163 struct lpfc_nodelist *ndlp;
James Smart895427b2017-02-12 13:52:30 -0800164 struct nvme_fc_remote_port *nrport;
James Smart4c47efc2019-01-28 11:14:25 -0800165 struct lpfc_fc4_ctrl_stat *cstat;
James Smart66a210f2018-04-09 14:24:23 -0700166 uint64_t data1, data2, data3;
167 uint64_t totin, totout, tot;
James Smart895427b2017-02-12 13:52:30 -0800168 char *statep;
James Smart66a210f2018-04-09 14:24:23 -0700169 int i;
James Smart895427b2017-02-12 13:52:30 -0800170 int len = 0;
James Smartafff0d22018-06-26 08:24:22 -0700171 char tmp[LPFC_MAX_NVME_INFO_TMP_LEN] = {0};
James Smart895427b2017-02-12 13:52:30 -0800172
James Smartf6e84792019-01-28 11:14:38 -0800173 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) {
James Smartafff0d22018-06-26 08:24:22 -0700174 len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n");
James Smart895427b2017-02-12 13:52:30 -0800175 return len;
176 }
James Smartf358dd02017-02-12 13:52:34 -0800177 if (phba->nvmet_support) {
178 if (!phba->targetport) {
James Smartafff0d22018-06-26 08:24:22 -0700179 len = scnprintf(buf, PAGE_SIZE,
James Smartf358dd02017-02-12 13:52:34 -0800180 "NVME Target: x%llx is not allocated\n",
181 wwn_to_u64(vport->fc_portname.u.wwn));
182 return len;
183 }
184 /* Port state is only one of two values for now. */
185 if (phba->targetport->port_id)
186 statep = "REGISTERED";
187 else
188 statep = "INIT";
James Smartafff0d22018-06-26 08:24:22 -0700189 scnprintf(tmp, sizeof(tmp),
190 "NVME Target Enabled State %s\n",
191 statep);
192 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
193 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800194
James Smartafff0d22018-06-26 08:24:22 -0700195 scnprintf(tmp, sizeof(tmp),
196 "%s%d WWPN x%llx WWNN x%llx DID x%06x\n",
197 "NVME Target: lpfc",
198 phba->brd_no,
199 wwn_to_u64(vport->fc_portname.u.wwn),
200 wwn_to_u64(vport->fc_nodename.u.wwn),
201 phba->targetport->port_id);
202 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
203 goto buffer_done;
204
205 if (strlcat(buf, "\nNVME Target: Statistics\n", PAGE_SIZE)
206 >= PAGE_SIZE)
207 goto buffer_done;
208
James Smartf358dd02017-02-12 13:52:34 -0800209 tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
James Smartafff0d22018-06-26 08:24:22 -0700210 scnprintf(tmp, sizeof(tmp),
211 "LS: Rcv %08x Drop %08x Abort %08x\n",
212 atomic_read(&tgtp->rcv_ls_req_in),
213 atomic_read(&tgtp->rcv_ls_req_drop),
214 atomic_read(&tgtp->xmt_ls_abort));
215 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
216 goto buffer_done;
217
James Smartf358dd02017-02-12 13:52:34 -0800218 if (atomic_read(&tgtp->rcv_ls_req_in) !=
219 atomic_read(&tgtp->rcv_ls_req_out)) {
James Smartafff0d22018-06-26 08:24:22 -0700220 scnprintf(tmp, sizeof(tmp),
221 "Rcv LS: in %08x != out %08x\n",
222 atomic_read(&tgtp->rcv_ls_req_in),
223 atomic_read(&tgtp->rcv_ls_req_out));
224 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
225 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800226 }
227
James Smartafff0d22018-06-26 08:24:22 -0700228 scnprintf(tmp, sizeof(tmp),
229 "LS: Xmt %08x Drop %08x Cmpl %08x\n",
230 atomic_read(&tgtp->xmt_ls_rsp),
231 atomic_read(&tgtp->xmt_ls_drop),
232 atomic_read(&tgtp->xmt_ls_rsp_cmpl));
233 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
234 goto buffer_done;
James Smart4b056682017-12-08 17:18:10 -0800235
James Smartafff0d22018-06-26 08:24:22 -0700236 scnprintf(tmp, sizeof(tmp),
237 "LS: RSP Abort %08x xb %08x Err %08x\n",
238 atomic_read(&tgtp->xmt_ls_rsp_aborted),
239 atomic_read(&tgtp->xmt_ls_rsp_xb_set),
240 atomic_read(&tgtp->xmt_ls_rsp_error));
241 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
242 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800243
James Smartafff0d22018-06-26 08:24:22 -0700244 scnprintf(tmp, sizeof(tmp),
245 "FCP: Rcv %08x Defer %08x Release %08x "
246 "Drop %08x\n",
247 atomic_read(&tgtp->rcv_fcp_cmd_in),
248 atomic_read(&tgtp->rcv_fcp_cmd_defer),
249 atomic_read(&tgtp->xmt_fcp_release),
250 atomic_read(&tgtp->rcv_fcp_cmd_drop));
251 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
252 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800253
254 if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
255 atomic_read(&tgtp->rcv_fcp_cmd_out)) {
James Smartafff0d22018-06-26 08:24:22 -0700256 scnprintf(tmp, sizeof(tmp),
257 "Rcv FCP: in %08x != out %08x\n",
258 atomic_read(&tgtp->rcv_fcp_cmd_in),
259 atomic_read(&tgtp->rcv_fcp_cmd_out));
260 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
261 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800262 }
263
James Smartafff0d22018-06-26 08:24:22 -0700264 scnprintf(tmp, sizeof(tmp),
265 "FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x "
266 "drop %08x\n",
267 atomic_read(&tgtp->xmt_fcp_read),
268 atomic_read(&tgtp->xmt_fcp_read_rsp),
269 atomic_read(&tgtp->xmt_fcp_write),
270 atomic_read(&tgtp->xmt_fcp_rsp),
271 atomic_read(&tgtp->xmt_fcp_drop));
272 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
273 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800274
James Smartafff0d22018-06-26 08:24:22 -0700275 scnprintf(tmp, sizeof(tmp),
276 "FCP Rsp Cmpl: %08x err %08x drop %08x\n",
277 atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
278 atomic_read(&tgtp->xmt_fcp_rsp_error),
279 atomic_read(&tgtp->xmt_fcp_rsp_drop));
280 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
281 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800282
James Smartafff0d22018-06-26 08:24:22 -0700283 scnprintf(tmp, sizeof(tmp),
284 "FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
285 atomic_read(&tgtp->xmt_fcp_rsp_aborted),
286 atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
287 atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
288 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
289 goto buffer_done;
James Smart4b056682017-12-08 17:18:10 -0800290
James Smartafff0d22018-06-26 08:24:22 -0700291 scnprintf(tmp, sizeof(tmp),
292 "ABORT: Xmt %08x Cmpl %08x\n",
293 atomic_read(&tgtp->xmt_fcp_abort),
294 atomic_read(&tgtp->xmt_fcp_abort_cmpl));
295 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
296 goto buffer_done;
James Smart547077a2017-05-15 15:20:40 -0700297
James Smartafff0d22018-06-26 08:24:22 -0700298 scnprintf(tmp, sizeof(tmp),
299 "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x\n",
300 atomic_read(&tgtp->xmt_abort_sol),
301 atomic_read(&tgtp->xmt_abort_unsol),
302 atomic_read(&tgtp->xmt_abort_rsp),
303 atomic_read(&tgtp->xmt_abort_rsp_error));
304 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
305 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800306
James Smartafff0d22018-06-26 08:24:22 -0700307 scnprintf(tmp, sizeof(tmp),
308 "DELAY: ctx %08x fod %08x wqfull %08x\n",
309 atomic_read(&tgtp->defer_ctx),
310 atomic_read(&tgtp->defer_fod),
311 atomic_read(&tgtp->defer_wqfull));
312 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
313 goto buffer_done;
James Smart411de512018-01-30 15:58:52 -0800314
Dick Kennedy66d7ce92017-08-23 16:55:42 -0700315 /* Calculate outstanding IOs */
316 tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
317 tot += atomic_read(&tgtp->xmt_fcp_release);
318 tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
James Smart2cee7802017-06-01 21:07:02 -0700319
James Smartafff0d22018-06-26 08:24:22 -0700320 scnprintf(tmp, sizeof(tmp),
321 "IO_CTX: %08x WAIT: cur %08x tot %08x\n"
322 "CTX Outstanding %08llx\n\n",
323 phba->sli4_hba.nvmet_xri_cnt,
324 phba->sli4_hba.nvmet_io_wait_cnt,
325 phba->sli4_hba.nvmet_io_wait_total,
326 tot);
327 strlcat(buf, tmp, PAGE_SIZE);
328 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800329 }
James Smart895427b2017-02-12 13:52:30 -0800330
331 localport = vport->localport;
332 if (!localport) {
James Smartafff0d22018-06-26 08:24:22 -0700333 len = scnprintf(buf, PAGE_SIZE,
James Smart895427b2017-02-12 13:52:30 -0800334 "NVME Initiator x%llx is not allocated\n",
335 wwn_to_u64(vport->fc_portname.u.wwn));
336 return len;
337 }
Colin Ian King5c665ae2017-12-22 00:28:52 +0000338 lport = (struct lpfc_nvme_lport *)localport->private;
James Smartafff0d22018-06-26 08:24:22 -0700339 if (strlcat(buf, "\nNVME Initiator Enabled\n", PAGE_SIZE) >= PAGE_SIZE)
340 goto buffer_done;
James Smart895427b2017-02-12 13:52:30 -0800341
James Smartafff0d22018-06-26 08:24:22 -0700342 scnprintf(tmp, sizeof(tmp),
James Smart0794d602019-01-28 11:14:19 -0800343 "XRI Dist lpfc%d Total %d IO %d ELS %d\n",
James Smartafff0d22018-06-26 08:24:22 -0700344 phba->brd_no,
345 phba->sli4_hba.max_cfg_param.max_xri,
James Smart5e5b5112019-01-28 11:14:22 -0800346 phba->sli4_hba.io_xri_max,
James Smartafff0d22018-06-26 08:24:22 -0700347 lpfc_sli4_get_els_iocb_cnt(phba));
348 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800349 goto buffer_done;
James Smart895427b2017-02-12 13:52:30 -0800350
351 /* Port state is only one of two values for now. */
352 if (localport->port_id)
353 statep = "ONLINE";
354 else
355 statep = "UNKNOWN ";
356
James Smartafff0d22018-06-26 08:24:22 -0700357 scnprintf(tmp, sizeof(tmp),
358 "%s%d WWPN x%llx WWNN x%llx DID x%06x %s\n",
359 "NVME LPORT lpfc",
360 phba->brd_no,
361 wwn_to_u64(vport->fc_portname.u.wwn),
362 wwn_to_u64(vport->fc_nodename.u.wwn),
363 localport->port_id, statep);
364 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800365 goto buffer_done;
366
367 spin_lock_irq(shost->host_lock);
James Smart895427b2017-02-12 13:52:30 -0800368
James Smart80cc0042017-06-01 21:06:56 -0700369 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart9e210172018-09-13 15:41:10 -0700370 nrport = NULL;
James Smartc6adba12020-11-15 11:26:34 -0800371 spin_lock(&ndlp->lock);
James Smart01466022018-04-09 14:24:27 -0700372 rport = lpfc_ndlp_get_nrport(ndlp);
James Smart9e210172018-09-13 15:41:10 -0700373 if (rport)
374 nrport = rport->remoteport;
James Smartc6adba12020-11-15 11:26:34 -0800375 spin_unlock(&ndlp->lock);
James Smart01466022018-04-09 14:24:27 -0700376 if (!nrport)
377 continue;
James Smart895427b2017-02-12 13:52:30 -0800378
379 /* Port state is only one of two values for now. */
380 switch (nrport->port_state) {
381 case FC_OBJSTATE_ONLINE:
382 statep = "ONLINE";
383 break;
384 case FC_OBJSTATE_UNKNOWN:
385 statep = "UNKNOWN ";
386 break;
387 default:
388 statep = "UNSUPPORTED";
389 break;
390 }
391
392 /* Tab in to show lport ownership. */
James Smartafff0d22018-06-26 08:24:22 -0700393 if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800394 goto unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700395 if (phba->brd_no >= 10) {
396 if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800397 goto unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700398 }
James Smart895427b2017-02-12 13:52:30 -0800399
James Smartafff0d22018-06-26 08:24:22 -0700400 scnprintf(tmp, sizeof(tmp), "WWPN x%llx ",
401 nrport->port_name);
402 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800403 goto unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700404
405 scnprintf(tmp, sizeof(tmp), "WWNN x%llx ",
406 nrport->node_name);
407 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800408 goto unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700409
410 scnprintf(tmp, sizeof(tmp), "DID x%06x ",
411 nrport->port_id);
412 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800413 goto unlock_buf_done;
James Smart895427b2017-02-12 13:52:30 -0800414
James Smart7d790f02017-06-01 21:06:57 -0700415 /* An NVME rport can have multiple roles. */
James Smartafff0d22018-06-26 08:24:22 -0700416 if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) {
417 if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800418 goto unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700419 }
420 if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) {
421 if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800422 goto unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700423 }
424 if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) {
425 if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800426 goto unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700427 }
James Smart7d790f02017-06-01 21:06:57 -0700428 if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
429 FC_PORT_ROLE_NVME_TARGET |
James Smartafff0d22018-06-26 08:24:22 -0700430 FC_PORT_ROLE_NVME_DISCOVERY)) {
431 scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x",
432 nrport->port_role);
433 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800434 goto unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700435 }
James Smart7d790f02017-06-01 21:06:57 -0700436
James Smartafff0d22018-06-26 08:24:22 -0700437 scnprintf(tmp, sizeof(tmp), "%s\n", statep);
438 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart6c1e8032019-11-04 16:57:00 -0800439 goto unlock_buf_done;
James Smart895427b2017-02-12 13:52:30 -0800440 }
James Smart6c1e8032019-11-04 16:57:00 -0800441 spin_unlock_irq(shost->host_lock);
James Smart895427b2017-02-12 13:52:30 -0800442
James Smart66a210f2018-04-09 14:24:23 -0700443 if (!lport)
James Smartafff0d22018-06-26 08:24:22 -0700444 goto buffer_done;
James Smart66a210f2018-04-09 14:24:23 -0700445
James Smartafff0d22018-06-26 08:24:22 -0700446 if (strlcat(buf, "\nNVME Statistics\n", PAGE_SIZE) >= PAGE_SIZE)
447 goto buffer_done;
James Smart4b056682017-12-08 17:18:10 -0800448
James Smartafff0d22018-06-26 08:24:22 -0700449 scnprintf(tmp, sizeof(tmp),
450 "LS: Xmt %010x Cmpl %010x Abort %08x\n",
451 atomic_read(&lport->fc4NvmeLsRequests),
452 atomic_read(&lport->fc4NvmeLsCmpls),
453 atomic_read(&lport->xmt_ls_abort));
454 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
455 goto buffer_done;
456
457 scnprintf(tmp, sizeof(tmp),
458 "LS XMIT: Err %08x CMPL: xb %08x Err %08x\n",
459 atomic_read(&lport->xmt_ls_err),
460 atomic_read(&lport->cmpl_ls_xb),
461 atomic_read(&lport->cmpl_ls_err));
462 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
463 goto buffer_done;
James Smart895427b2017-02-12 13:52:30 -0800464
James Smart66a210f2018-04-09 14:24:23 -0700465 totin = 0;
466 totout = 0;
James Smartcdb42be2019-01-28 11:14:21 -0800467 for (i = 0; i < phba->cfg_hdw_queue; i++) {
James Smart4c47efc2019-01-28 11:14:25 -0800468 cstat = &phba->sli4_hba.hdwq[i].nvme_cstat;
469 tot = cstat->io_cmpls;
James Smart66a210f2018-04-09 14:24:23 -0700470 totin += tot;
James Smart4c47efc2019-01-28 11:14:25 -0800471 data1 = cstat->input_requests;
472 data2 = cstat->output_requests;
473 data3 = cstat->control_requests;
James Smart66a210f2018-04-09 14:24:23 -0700474 totout += (data1 + data2 + data3);
475 }
James Smartafff0d22018-06-26 08:24:22 -0700476 scnprintf(tmp, sizeof(tmp),
477 "Total FCP Cmpl %016llx Issue %016llx "
478 "OutIO %016llx\n",
479 totin, totout, totout - totin);
480 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
481 goto buffer_done;
James Smart895427b2017-02-12 13:52:30 -0800482
James Smartafff0d22018-06-26 08:24:22 -0700483 scnprintf(tmp, sizeof(tmp),
484 "\tabort %08x noxri %08x nondlp %08x qdepth %08x "
485 "wqerr %08x err %08x\n",
486 atomic_read(&lport->xmt_fcp_abort),
487 atomic_read(&lport->xmt_fcp_noxri),
488 atomic_read(&lport->xmt_fcp_bad_ndlp),
489 atomic_read(&lport->xmt_fcp_qdepth),
490 atomic_read(&lport->xmt_fcp_err),
491 atomic_read(&lport->xmt_fcp_wqerr));
492 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
493 goto buffer_done;
James Smart4b056682017-12-08 17:18:10 -0800494
James Smartafff0d22018-06-26 08:24:22 -0700495 scnprintf(tmp, sizeof(tmp),
496 "FCP CMPL: xb %08x Err %08x\n",
497 atomic_read(&lport->cmpl_fcp_xb),
498 atomic_read(&lport->cmpl_fcp_err));
499 strlcat(buf, tmp, PAGE_SIZE);
500
James Smart6c1e8032019-11-04 16:57:00 -0800501 /* host_lock is already unlocked. */
James Smart79080d32019-05-06 17:26:48 -0700502 goto buffer_done;
503
James Smart6c1e8032019-11-04 16:57:00 -0800504 unlock_buf_done:
505 spin_unlock_irq(shost->host_lock);
James Smart79080d32019-05-06 17:26:48 -0700506
507 buffer_done:
James Smartafff0d22018-06-26 08:24:22 -0700508 len = strnlen(buf, PAGE_SIZE);
509
510 if (unlikely(len >= (PAGE_SIZE - 1))) {
511 lpfc_printf_log(phba, KERN_INFO, LOG_NVME,
512 "6314 Catching potential buffer "
513 "overflow > PAGE_SIZE = %lu bytes\n",
514 PAGE_SIZE);
515 strlcpy(buf + PAGE_SIZE - 1 -
516 strnlen(LPFC_NVME_INFO_MORE_STR, PAGE_SIZE - 1),
517 LPFC_NVME_INFO_MORE_STR,
518 strnlen(LPFC_NVME_INFO_MORE_STR, PAGE_SIZE - 1)
519 + 1);
520 }
521
James Smart895427b2017-02-12 13:52:30 -0800522 return len;
523}
524
525static ssize_t
James Smart4c47efc2019-01-28 11:14:25 -0800526lpfc_scsi_stat_show(struct device *dev, struct device_attribute *attr,
527 char *buf)
528{
529 struct Scsi_Host *shost = class_to_shost(dev);
530 struct lpfc_vport *vport = shost_priv(shost);
531 struct lpfc_hba *phba = vport->phba;
532 int len;
533 struct lpfc_fc4_ctrl_stat *cstat;
534 u64 data1, data2, data3;
535 u64 tot, totin, totout;
536 int i;
537 char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
538
James Smartf6e84792019-01-28 11:14:38 -0800539 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
James Smart4c47efc2019-01-28 11:14:25 -0800540 (phba->sli_rev != LPFC_SLI_REV4))
541 return 0;
542
543 scnprintf(buf, PAGE_SIZE, "SCSI HDWQ Statistics\n");
544
545 totin = 0;
546 totout = 0;
547 for (i = 0; i < phba->cfg_hdw_queue; i++) {
548 cstat = &phba->sli4_hba.hdwq[i].scsi_cstat;
549 tot = cstat->io_cmpls;
550 totin += tot;
551 data1 = cstat->input_requests;
552 data2 = cstat->output_requests;
553 data3 = cstat->control_requests;
554 totout += (data1 + data2 + data3);
555
556 scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
557 "IO %016llx ", i, data1, data2, data3);
558 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
559 goto buffer_done;
560
561 scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
562 tot, ((data1 + data2 + data3) - tot));
563 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
564 goto buffer_done;
565 }
566 scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
567 "OutIO %016llx\n", totin, totout, totout - totin);
568 strlcat(buf, tmp, PAGE_SIZE);
569
570buffer_done:
571 len = strnlen(buf, PAGE_SIZE);
572
573 return len;
574}
575
576static ssize_t
James Smart81301a92008-12-04 22:39:46 -0500577lpfc_bg_info_show(struct device *dev, struct device_attribute *attr,
578 char *buf)
579{
580 struct Scsi_Host *shost = class_to_shost(dev);
581 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
582 struct lpfc_hba *phba = vport->phba;
583
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700584 if (phba->cfg_enable_bg) {
James Smart81301a92008-12-04 22:39:46 -0500585 if (phba->sli3_options & LPFC_SLI3_BG_ENABLED)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700586 return scnprintf(buf, PAGE_SIZE,
587 "BlockGuard Enabled\n");
James Smart81301a92008-12-04 22:39:46 -0500588 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700589 return scnprintf(buf, PAGE_SIZE,
James Smart81301a92008-12-04 22:39:46 -0500590 "BlockGuard Not Supported\n");
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700591 } else
592 return scnprintf(buf, PAGE_SIZE,
James Smart81301a92008-12-04 22:39:46 -0500593 "BlockGuard Disabled\n");
594}
595
596static ssize_t
597lpfc_bg_guard_err_show(struct device *dev, struct device_attribute *attr,
598 char *buf)
599{
600 struct Scsi_Host *shost = class_to_shost(dev);
601 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
602 struct lpfc_hba *phba = vport->phba;
603
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700604 return scnprintf(buf, PAGE_SIZE, "%llu\n",
James Smart87b5c322008-12-16 10:34:09 -0500605 (unsigned long long)phba->bg_guard_err_cnt);
James Smart81301a92008-12-04 22:39:46 -0500606}
607
608static ssize_t
609lpfc_bg_apptag_err_show(struct device *dev, struct device_attribute *attr,
610 char *buf)
611{
612 struct Scsi_Host *shost = class_to_shost(dev);
613 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
614 struct lpfc_hba *phba = vport->phba;
615
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700616 return scnprintf(buf, PAGE_SIZE, "%llu\n",
James Smart87b5c322008-12-16 10:34:09 -0500617 (unsigned long long)phba->bg_apptag_err_cnt);
James Smart81301a92008-12-04 22:39:46 -0500618}
619
620static ssize_t
621lpfc_bg_reftag_err_show(struct device *dev, struct device_attribute *attr,
622 char *buf)
623{
624 struct Scsi_Host *shost = class_to_shost(dev);
625 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
626 struct lpfc_hba *phba = vport->phba;
627
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700628 return scnprintf(buf, PAGE_SIZE, "%llu\n",
James Smart87b5c322008-12-16 10:34:09 -0500629 (unsigned long long)phba->bg_reftag_err_cnt);
James Smart81301a92008-12-04 22:39:46 -0500630}
631
James Smarte59058c2008-08-24 21:49:00 -0400632/**
James Smart3621a712009-04-06 18:47:14 -0400633 * lpfc_info_show - Return some pci info about the host in ascii
James Smarte59058c2008-08-24 21:49:00 -0400634 * @dev: class converted to a Scsi_host structure.
635 * @attr: device attribute, not used.
636 * @buf: on return contains the formatted text from lpfc_info().
637 *
638 * Returns: size of formatted string.
639 **/
dea31012005-04-17 16:05:31 -0500640static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100641lpfc_info_show(struct device *dev, struct device_attribute *attr,
642 char *buf)
dea31012005-04-17 16:05:31 -0500643{
Tony Jonesee959b02008-02-22 00:13:36 +0100644 struct Scsi_Host *host = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500645
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700646 return scnprintf(buf, PAGE_SIZE, "%s\n", lpfc_info(host));
dea31012005-04-17 16:05:31 -0500647}
648
James Smarte59058c2008-08-24 21:49:00 -0400649/**
James Smart3621a712009-04-06 18:47:14 -0400650 * lpfc_serialnum_show - Return the hba serial number in ascii
James Smarte59058c2008-08-24 21:49:00 -0400651 * @dev: class converted to a Scsi_host structure.
652 * @attr: device attribute, not used.
653 * @buf: on return contains the formatted text serial number.
654 *
655 * Returns: size of formatted string.
656 **/
dea31012005-04-17 16:05:31 -0500657static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100658lpfc_serialnum_show(struct device *dev, struct device_attribute *attr,
659 char *buf)
dea31012005-04-17 16:05:31 -0500660{
Tony Jonesee959b02008-02-22 00:13:36 +0100661 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500662 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
663 struct lpfc_hba *phba = vport->phba;
664
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700665 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->SerialNumber);
dea31012005-04-17 16:05:31 -0500666}
667
James Smarte59058c2008-08-24 21:49:00 -0400668/**
James Smart3621a712009-04-06 18:47:14 -0400669 * lpfc_temp_sensor_show - Return the temperature sensor level
James Smarte59058c2008-08-24 21:49:00 -0400670 * @dev: class converted to a Scsi_host structure.
671 * @attr: device attribute, not used.
672 * @buf: on return contains the formatted support level.
673 *
674 * Description:
675 * Returns a number indicating the temperature sensor level currently
676 * supported, zero or one in ascii.
677 *
678 * Returns: size of formatted string.
679 **/
dea31012005-04-17 16:05:31 -0500680static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100681lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr,
682 char *buf)
James Smart57127f12007-10-27 13:37:05 -0400683{
Tony Jonesee959b02008-02-22 00:13:36 +0100684 struct Scsi_Host *shost = class_to_shost(dev);
James Smart57127f12007-10-27 13:37:05 -0400685 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
686 struct lpfc_hba *phba = vport->phba;
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700687 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->temp_sensor_support);
James Smart57127f12007-10-27 13:37:05 -0400688}
689
James Smarte59058c2008-08-24 21:49:00 -0400690/**
James Smart3621a712009-04-06 18:47:14 -0400691 * lpfc_modeldesc_show - Return the model description of the hba
James Smarte59058c2008-08-24 21:49:00 -0400692 * @dev: class converted to a Scsi_host structure.
693 * @attr: device attribute, not used.
694 * @buf: on return contains the scsi vpd model description.
695 *
696 * Returns: size of formatted string.
697 **/
James Smart57127f12007-10-27 13:37:05 -0400698static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100699lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr,
700 char *buf)
dea31012005-04-17 16:05:31 -0500701{
Tony Jonesee959b02008-02-22 00:13:36 +0100702 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500703 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
704 struct lpfc_hba *phba = vport->phba;
705
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700706 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ModelDesc);
dea31012005-04-17 16:05:31 -0500707}
708
James Smarte59058c2008-08-24 21:49:00 -0400709/**
James Smart3621a712009-04-06 18:47:14 -0400710 * lpfc_modelname_show - Return the model name of the hba
James Smarte59058c2008-08-24 21:49:00 -0400711 * @dev: class converted to a Scsi_host structure.
712 * @attr: device attribute, not used.
713 * @buf: on return contains the scsi vpd model name.
714 *
715 * Returns: size of formatted string.
716 **/
dea31012005-04-17 16:05:31 -0500717static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100718lpfc_modelname_show(struct device *dev, struct device_attribute *attr,
719 char *buf)
dea31012005-04-17 16:05:31 -0500720{
Tony Jonesee959b02008-02-22 00:13:36 +0100721 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500722 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
723 struct lpfc_hba *phba = vport->phba;
724
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700725 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ModelName);
dea31012005-04-17 16:05:31 -0500726}
727
James Smarte59058c2008-08-24 21:49:00 -0400728/**
James Smart3621a712009-04-06 18:47:14 -0400729 * lpfc_programtype_show - Return the program type of the hba
James Smarte59058c2008-08-24 21:49:00 -0400730 * @dev: class converted to a Scsi_host structure.
731 * @attr: device attribute, not used.
732 * @buf: on return contains the scsi vpd program type.
733 *
734 * Returns: size of formatted string.
735 **/
dea31012005-04-17 16:05:31 -0500736static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100737lpfc_programtype_show(struct device *dev, struct device_attribute *attr,
738 char *buf)
dea31012005-04-17 16:05:31 -0500739{
Tony Jonesee959b02008-02-22 00:13:36 +0100740 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500741 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
742 struct lpfc_hba *phba = vport->phba;
743
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700744 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ProgramType);
dea31012005-04-17 16:05:31 -0500745}
746
James Smarte59058c2008-08-24 21:49:00 -0400747/**
James Smart3621a712009-04-06 18:47:14 -0400748 * lpfc_mlomgmt_show - Return the Menlo Maintenance sli flag
James Smart84774a42008-08-24 21:50:06 -0400749 * @dev: class converted to a Scsi_host structure.
750 * @attr: device attribute, not used.
751 * @buf: on return contains the Menlo Maintenance sli flag.
752 *
753 * Returns: size of formatted string.
754 **/
755static ssize_t
756lpfc_mlomgmt_show(struct device *dev, struct device_attribute *attr, char *buf)
757{
758 struct Scsi_Host *shost = class_to_shost(dev);
759 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
760 struct lpfc_hba *phba = vport->phba;
761
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700762 return scnprintf(buf, PAGE_SIZE, "%d\n",
James Smart84774a42008-08-24 21:50:06 -0400763 (phba->sli.sli_flag & LPFC_MENLO_MAINT));
764}
765
766/**
James Smart3621a712009-04-06 18:47:14 -0400767 * lpfc_vportnum_show - Return the port number in ascii of the hba
James Smarte59058c2008-08-24 21:49:00 -0400768 * @dev: class converted to a Scsi_host structure.
769 * @attr: device attribute, not used.
770 * @buf: on return contains scsi vpd program type.
771 *
772 * Returns: size of formatted string.
773 **/
dea31012005-04-17 16:05:31 -0500774static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100775lpfc_vportnum_show(struct device *dev, struct device_attribute *attr,
776 char *buf)
dea31012005-04-17 16:05:31 -0500777{
Tony Jonesee959b02008-02-22 00:13:36 +0100778 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500779 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
780 struct lpfc_hba *phba = vport->phba;
781
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700782 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->Port);
dea31012005-04-17 16:05:31 -0500783}
784
James Smarte59058c2008-08-24 21:49:00 -0400785/**
James Smart3621a712009-04-06 18:47:14 -0400786 * lpfc_fwrev_show - Return the firmware rev running in the hba
James Smarte59058c2008-08-24 21:49:00 -0400787 * @dev: class converted to a Scsi_host structure.
788 * @attr: device attribute, not used.
789 * @buf: on return contains the scsi vpd program type.
790 *
791 * Returns: size of formatted string.
792 **/
dea31012005-04-17 16:05:31 -0500793static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100794lpfc_fwrev_show(struct device *dev, struct device_attribute *attr,
795 char *buf)
dea31012005-04-17 16:05:31 -0500796{
Tony Jonesee959b02008-02-22 00:13:36 +0100797 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500798 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
799 struct lpfc_hba *phba = vport->phba;
James Smart026abb82011-12-13 13:20:45 -0500800 uint32_t if_type;
801 uint8_t sli_family;
James Smart6b5151f2012-01-18 16:24:06 -0500802 char fwrev[FW_REV_STR_SIZE];
James Smart026abb82011-12-13 13:20:45 -0500803 int len;
James Smart2e0fef82007-06-17 19:56:36 -0500804
dea31012005-04-17 16:05:31 -0500805 lpfc_decode_firmware_rev(phba, fwrev, 1);
James Smart026abb82011-12-13 13:20:45 -0500806 if_type = phba->sli4_hba.pc_sli4_params.if_type;
807 sli_family = phba->sli4_hba.pc_sli4_params.sli_family;
808
809 if (phba->sli_rev < LPFC_SLI_REV4)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700810 len = scnprintf(buf, PAGE_SIZE, "%s, sli-%d\n",
James Smart026abb82011-12-13 13:20:45 -0500811 fwrev, phba->sli_rev);
812 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700813 len = scnprintf(buf, PAGE_SIZE, "%s, sli-%d:%d:%x\n",
James Smart026abb82011-12-13 13:20:45 -0500814 fwrev, phba->sli_rev, if_type, sli_family);
815
816 return len;
dea31012005-04-17 16:05:31 -0500817}
818
James Smarte59058c2008-08-24 21:49:00 -0400819/**
James Smart3621a712009-04-06 18:47:14 -0400820 * lpfc_hdw_show - Return the jedec information about the hba
James Smarte59058c2008-08-24 21:49:00 -0400821 * @dev: class converted to a Scsi_host structure.
822 * @attr: device attribute, not used.
823 * @buf: on return contains the scsi vpd program type.
824 *
825 * Returns: size of formatted string.
826 **/
dea31012005-04-17 16:05:31 -0500827static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100828lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf)
dea31012005-04-17 16:05:31 -0500829{
830 char hdw[9];
Tony Jonesee959b02008-02-22 00:13:36 +0100831 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500832 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
833 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -0500834 lpfc_vpd_t *vp = &phba->vpd;
James Smart2e0fef82007-06-17 19:56:36 -0500835
dea31012005-04-17 16:05:31 -0500836 lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
James Smartec762422019-08-14 16:57:07 -0700837 return scnprintf(buf, PAGE_SIZE, "%s %08x %08x\n", hdw,
838 vp->rev.smRev, vp->rev.smFwRev);
dea31012005-04-17 16:05:31 -0500839}
James Smarte59058c2008-08-24 21:49:00 -0400840
841/**
James Smart3621a712009-04-06 18:47:14 -0400842 * lpfc_option_rom_version_show - Return the adapter ROM FCode version
James Smarte59058c2008-08-24 21:49:00 -0400843 * @dev: class converted to a Scsi_host structure.
844 * @attr: device attribute, not used.
845 * @buf: on return contains the ROM and FCode ascii strings.
846 *
847 * Returns: size of formatted string.
848 **/
dea31012005-04-17 16:05:31 -0500849static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100850lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr,
851 char *buf)
dea31012005-04-17 16:05:31 -0500852{
Tony Jonesee959b02008-02-22 00:13:36 +0100853 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500854 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
855 struct lpfc_hba *phba = vport->phba;
James Smarta0683bf2015-04-07 15:07:16 -0400856 char fwrev[FW_REV_STR_SIZE];
James Smart2e0fef82007-06-17 19:56:36 -0500857
James Smarta0683bf2015-04-07 15:07:16 -0400858 if (phba->sli_rev < LPFC_SLI_REV4)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700859 return scnprintf(buf, PAGE_SIZE, "%s\n",
860 phba->OptionROMVersion);
James Smarta0683bf2015-04-07 15:07:16 -0400861
862 lpfc_decode_firmware_rev(phba, fwrev, 1);
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700863 return scnprintf(buf, PAGE_SIZE, "%s\n", fwrev);
dea31012005-04-17 16:05:31 -0500864}
James Smarte59058c2008-08-24 21:49:00 -0400865
866/**
James Smart3621a712009-04-06 18:47:14 -0400867 * lpfc_state_show - Return the link state of the port
James Smarte59058c2008-08-24 21:49:00 -0400868 * @dev: class converted to a Scsi_host structure.
869 * @attr: device attribute, not used.
870 * @buf: on return contains text describing the state of the link.
871 *
872 * Notes:
873 * The switch statement has no default so zero will be returned.
874 *
875 * Returns: size of formatted string.
876 **/
dea31012005-04-17 16:05:31 -0500877static ssize_t
Hannes Reineckebbd1ae42008-03-18 14:32:28 +0100878lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
879 char *buf)
dea31012005-04-17 16:05:31 -0500880{
Tony Jonesee959b02008-02-22 00:13:36 +0100881 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500882 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
883 struct lpfc_hba *phba = vport->phba;
884 int len = 0;
885
886 switch (phba->link_state) {
887 case LPFC_LINK_UNKNOWN:
Jamie Wellnitz41415862006-02-28 19:25:27 -0500888 case LPFC_WARM_START:
dea31012005-04-17 16:05:31 -0500889 case LPFC_INIT_START:
890 case LPFC_INIT_MBX_CMDS:
891 case LPFC_LINK_DOWN:
James Smart2e0fef82007-06-17 19:56:36 -0500892 case LPFC_HBA_ERROR:
James Smarta0c87cb2009-07-19 10:01:10 -0400893 if (phba->hba_flag & LINK_DISABLED)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700894 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smarta0c87cb2009-07-19 10:01:10 -0400895 "Link Down - User disabled\n");
896 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700897 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smarta0c87cb2009-07-19 10:01:10 -0400898 "Link Down\n");
dea31012005-04-17 16:05:31 -0500899 break;
900 case LPFC_LINK_UP:
dea31012005-04-17 16:05:31 -0500901 case LPFC_CLEAR_LA:
dea31012005-04-17 16:05:31 -0500902 case LPFC_HBA_READY:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700903 len += scnprintf(buf + len, PAGE_SIZE-len, "Link Up - ");
James Smart2e0fef82007-06-17 19:56:36 -0500904
905 switch (vport->port_state) {
James Smart2e0fef82007-06-17 19:56:36 -0500906 case LPFC_LOCAL_CFG_LINK:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700907 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart92d7f7b2007-06-17 19:56:38 -0500908 "Configuring Link\n");
James Smart2e0fef82007-06-17 19:56:36 -0500909 break;
James Smart92d7f7b2007-06-17 19:56:38 -0500910 case LPFC_FDISC:
James Smart2e0fef82007-06-17 19:56:36 -0500911 case LPFC_FLOGI:
912 case LPFC_FABRIC_CFG_LINK:
913 case LPFC_NS_REG:
914 case LPFC_NS_QRY:
915 case LPFC_BUILD_DISC_LIST:
916 case LPFC_DISC_AUTH:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700917 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart2e0fef82007-06-17 19:56:36 -0500918 "Discovery\n");
919 break;
920 case LPFC_VPORT_READY:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700921 len += scnprintf(buf + len, PAGE_SIZE - len,
922 "Ready\n");
James Smart2e0fef82007-06-17 19:56:36 -0500923 break;
924
James Smart92d7f7b2007-06-17 19:56:38 -0500925 case LPFC_VPORT_FAILED:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700926 len += scnprintf(buf + len, PAGE_SIZE - len,
927 "Failed\n");
James Smart92d7f7b2007-06-17 19:56:38 -0500928 break;
929
930 case LPFC_VPORT_UNKNOWN:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700931 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart2e0fef82007-06-17 19:56:36 -0500932 "Unknown\n");
933 break;
934 }
James Smart84774a42008-08-24 21:50:06 -0400935 if (phba->sli.sli_flag & LPFC_MENLO_MAINT)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700936 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart84774a42008-08-24 21:50:06 -0400937 " Menlo Maint Mode\n");
James Smart76a95d72010-11-20 23:11:48 -0500938 else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smart2e0fef82007-06-17 19:56:36 -0500939 if (vport->fc_flag & FC_PUBLIC_LOOP)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700940 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500941 " Public Loop\n");
942 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700943 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500944 " Private Loop\n");
945 } else {
James Smart2e0fef82007-06-17 19:56:36 -0500946 if (vport->fc_flag & FC_FABRIC)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700947 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500948 " Fabric\n");
949 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700950 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500951 " Point-2-Point\n");
952 }
953 }
James Smart2e0fef82007-06-17 19:56:36 -0500954
James Smart1dc5ec22018-10-23 13:41:11 -0700955 if ((phba->sli_rev == LPFC_SLI_REV4) &&
956 ((bf_get(lpfc_sli_intf_if_type,
957 &phba->sli4_hba.sli_intf) ==
958 LPFC_SLI_INTF_IF_TYPE_6))) {
959 struct lpfc_trunk_link link = phba->trunk_link;
960
961 if (bf_get(lpfc_conf_trunk_port0, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700962 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700963 "Trunk port 0: Link %s %s\n",
964 (link.link0.state == LPFC_LINK_UP) ?
965 "Up" : "Down. ",
966 trunk_errmsg[link.link0.fault]);
967
968 if (bf_get(lpfc_conf_trunk_port1, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700969 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700970 "Trunk port 1: Link %s %s\n",
971 (link.link1.state == LPFC_LINK_UP) ?
972 "Up" : "Down. ",
973 trunk_errmsg[link.link1.fault]);
974
975 if (bf_get(lpfc_conf_trunk_port2, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700976 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700977 "Trunk port 2: Link %s %s\n",
978 (link.link2.state == LPFC_LINK_UP) ?
979 "Up" : "Down. ",
980 trunk_errmsg[link.link2.fault]);
981
982 if (bf_get(lpfc_conf_trunk_port3, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700983 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700984 "Trunk port 3: Link %s %s\n",
985 (link.link3.state == LPFC_LINK_UP) ?
986 "Up" : "Down. ",
987 trunk_errmsg[link.link3.fault]);
988
989 }
990
dea31012005-04-17 16:05:31 -0500991 return len;
992}
993
James Smarte59058c2008-08-24 21:49:00 -0400994/**
James Smart026abb82011-12-13 13:20:45 -0500995 * lpfc_sli4_protocol_show - Return the fip mode of the HBA
996 * @dev: class unused variable.
997 * @attr: device attribute, not used.
998 * @buf: on return contains the module description text.
999 *
1000 * Returns: size of formatted string.
1001 **/
1002static ssize_t
1003lpfc_sli4_protocol_show(struct device *dev, struct device_attribute *attr,
1004 char *buf)
1005{
1006 struct Scsi_Host *shost = class_to_shost(dev);
1007 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1008 struct lpfc_hba *phba = vport->phba;
1009
1010 if (phba->sli_rev < LPFC_SLI_REV4)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001011 return scnprintf(buf, PAGE_SIZE, "fc\n");
James Smart026abb82011-12-13 13:20:45 -05001012
1013 if (phba->sli4_hba.lnk_info.lnk_dv == LPFC_LNK_DAT_VAL) {
1014 if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_GE)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001015 return scnprintf(buf, PAGE_SIZE, "fcoe\n");
James Smart026abb82011-12-13 13:20:45 -05001016 if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001017 return scnprintf(buf, PAGE_SIZE, "fc\n");
James Smart026abb82011-12-13 13:20:45 -05001018 }
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001019 return scnprintf(buf, PAGE_SIZE, "unknown\n");
James Smart026abb82011-12-13 13:20:45 -05001020}
1021
1022/**
James Smart1ba981f2014-02-20 09:56:45 -05001023 * lpfc_oas_supported_show - Return whether or not Optimized Access Storage
1024 * (OAS) is supported.
1025 * @dev: class unused variable.
1026 * @attr: device attribute, not used.
1027 * @buf: on return contains the module description text.
1028 *
1029 * Returns: size of formatted string.
1030 **/
1031static ssize_t
1032lpfc_oas_supported_show(struct device *dev, struct device_attribute *attr,
1033 char *buf)
1034{
1035 struct Scsi_Host *shost = class_to_shost(dev);
1036 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
1037 struct lpfc_hba *phba = vport->phba;
1038
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001039 return scnprintf(buf, PAGE_SIZE, "%d\n",
James Smart1ba981f2014-02-20 09:56:45 -05001040 phba->sli4_hba.pc_sli4_params.oas_supported);
1041}
1042
1043/**
James Smart84d1b002010-02-12 14:42:33 -05001044 * lpfc_link_state_store - Transition the link_state on an HBA port
1045 * @dev: class device that is converted into a Scsi_host.
1046 * @attr: device attribute, not used.
1047 * @buf: one or more lpfc_polling_flags values.
1048 * @count: not used.
1049 *
1050 * Returns:
1051 * -EINVAL if the buffer is not "up" or "down"
1052 * return from link state change function if non-zero
1053 * length of the buf on success
1054 **/
1055static ssize_t
1056lpfc_link_state_store(struct device *dev, struct device_attribute *attr,
1057 const char *buf, size_t count)
1058{
1059 struct Scsi_Host *shost = class_to_shost(dev);
1060 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1061 struct lpfc_hba *phba = vport->phba;
1062
1063 int status = -EINVAL;
1064
1065 if ((strncmp(buf, "up", sizeof("up") - 1) == 0) &&
1066 (phba->link_state == LPFC_LINK_DOWN))
James Smart6e7288d2010-06-07 15:23:35 -04001067 status = phba->lpfc_hba_init_link(phba, MBX_NOWAIT);
James Smart84d1b002010-02-12 14:42:33 -05001068 else if ((strncmp(buf, "down", sizeof("down") - 1) == 0) &&
1069 (phba->link_state >= LPFC_LINK_UP))
James Smart6e7288d2010-06-07 15:23:35 -04001070 status = phba->lpfc_hba_down_link(phba, MBX_NOWAIT);
James Smart84d1b002010-02-12 14:42:33 -05001071
1072 if (status == 0)
1073 return strlen(buf);
1074 else
1075 return status;
1076}
1077
1078/**
James Smart3621a712009-04-06 18:47:14 -04001079 * lpfc_num_discovered_ports_show - Return sum of mapped and unmapped vports
James Smarte59058c2008-08-24 21:49:00 -04001080 * @dev: class device that is converted into a Scsi_host.
1081 * @attr: device attribute, not used.
1082 * @buf: on return contains the sum of fc mapped and unmapped.
1083 *
1084 * Description:
1085 * Returns the ascii text number of the sum of the fc mapped and unmapped
1086 * vport counts.
1087 *
1088 * Returns: size of formatted string.
1089 **/
dea31012005-04-17 16:05:31 -05001090static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001091lpfc_num_discovered_ports_show(struct device *dev,
1092 struct device_attribute *attr, char *buf)
dea31012005-04-17 16:05:31 -05001093{
Tony Jonesee959b02008-02-22 00:13:36 +01001094 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001095 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1096
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001097 return scnprintf(buf, PAGE_SIZE, "%d\n",
James Smart2e0fef82007-06-17 19:56:36 -05001098 vport->fc_map_cnt + vport->fc_unmap_cnt);
dea31012005-04-17 16:05:31 -05001099}
1100
James Smarte59058c2008-08-24 21:49:00 -04001101/**
James Smart3621a712009-04-06 18:47:14 -04001102 * lpfc_issue_lip - Misnomer, name carried over from long ago
James Smarte59058c2008-08-24 21:49:00 -04001103 * @shost: Scsi_Host pointer.
1104 *
1105 * Description:
1106 * Bring the link down gracefully then re-init the link. The firmware will
1107 * re-init the fiber channel interface as required. Does not issue a LIP.
1108 *
1109 * Returns:
1110 * -EPERM port offline or management commands are being blocked
1111 * -ENOMEM cannot allocate memory for the mailbox command
1112 * -EIO error sending the mailbox command
1113 * zero for success
1114 **/
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07001115static int
James Smart2e0fef82007-06-17 19:56:36 -05001116lpfc_issue_lip(struct Scsi_Host *shost)
dea31012005-04-17 16:05:31 -05001117{
James Smart2e0fef82007-06-17 19:56:36 -05001118 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1119 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05001120 LPFC_MBOXQ_t *pmboxq;
1121 int mbxstatus = MBXERR_ERROR;
1122
James Smart2289e952018-01-30 15:58:55 -08001123 /*
1124 * If the link is offline, disabled or BLOCK_MGMT_IO
1125 * it doesn't make any sense to allow issue_lip
1126 */
James Smart2e0fef82007-06-17 19:56:36 -05001127 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smart2289e952018-01-30 15:58:55 -08001128 (phba->hba_flag & LINK_DISABLED) ||
James Smart83108bd2008-01-11 01:53:09 -05001129 (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO))
dea31012005-04-17 16:05:31 -05001130 return -EPERM;
1131
1132 pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);
1133
1134 if (!pmboxq)
1135 return -ENOMEM;
1136
1137 memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
James Smart04c68492009-05-22 14:52:52 -04001138 pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK;
1139 pmboxq->u.mb.mbxOwner = OWN_HOST;
James Smart4db621e2006-07-06 15:49:49 -04001140
James Smart33ccf8d2006-08-17 11:57:58 -04001141 mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2);
dea31012005-04-17 16:05:31 -05001142
James Smart04c68492009-05-22 14:52:52 -04001143 if ((mbxstatus == MBX_SUCCESS) &&
1144 (pmboxq->u.mb.mbxStatus == 0 ||
1145 pmboxq->u.mb.mbxStatus == MBXERR_LINK_DOWN)) {
James Smart4db621e2006-07-06 15:49:49 -04001146 memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
1147 lpfc_init_link(phba, pmboxq, phba->cfg_topology,
1148 phba->cfg_link_speed);
1149 mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq,
1150 phba->fc_ratov * 2);
James Smartdcf2a4e2010-09-29 11:18:53 -04001151 if ((mbxstatus == MBX_SUCCESS) &&
1152 (pmboxq->u.mb.mbxStatus == MBXERR_SEC_NO_PERMISSION))
1153 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
1154 "2859 SLI authentication is required "
1155 "for INIT_LINK but has not done yet\n");
James Smart4db621e2006-07-06 15:49:49 -04001156 }
1157
James Smart5b8bd0c2007-04-25 09:52:49 -04001158 lpfc_set_loopback_flag(phba);
James Smart858c9f62007-06-17 19:56:39 -05001159 if (mbxstatus != MBX_TIMEOUT)
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04001160 mempool_free(pmboxq, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05001161
1162 if (mbxstatus == MBXERR_ERROR)
1163 return -EIO;
1164
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07001165 return 0;
dea31012005-04-17 16:05:31 -05001166}
1167
James Smart895427b2017-02-12 13:52:30 -08001168int
1169lpfc_emptyq_wait(struct lpfc_hba *phba, struct list_head *q, spinlock_t *lock)
1170{
1171 int cnt = 0;
1172
1173 spin_lock_irq(lock);
1174 while (!list_empty(q)) {
1175 spin_unlock_irq(lock);
1176 msleep(20);
1177 if (cnt++ > 250) { /* 5 secs */
1178 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
1179 "0466 %s %s\n",
1180 "Outstanding IO when ",
1181 "bringing Adapter offline\n");
1182 return 0;
1183 }
1184 spin_lock_irq(lock);
1185 }
1186 spin_unlock_irq(lock);
1187 return 1;
1188}
1189
James Smarte59058c2008-08-24 21:49:00 -04001190/**
James Smart3621a712009-04-06 18:47:14 -04001191 * lpfc_do_offline - Issues a mailbox command to bring the link down
James Smarte59058c2008-08-24 21:49:00 -04001192 * @phba: lpfc_hba pointer.
1193 * @type: LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL.
1194 *
1195 * Notes:
1196 * Assumes any error from lpfc_do_offline() will be negative.
1197 * Can wait up to 5 seconds for the port ring buffers count
1198 * to reach zero, prints a warning if it is not zero and continues.
James Smart3621a712009-04-06 18:47:14 -04001199 * lpfc_workq_post_event() returns a non-zero return code if call fails.
James Smarte59058c2008-08-24 21:49:00 -04001200 *
1201 * Returns:
1202 * -EIO error posting the event
1203 * zero for success
1204 **/
James Smart40496f02006-07-06 15:50:22 -04001205static int
James Smart46fa3112007-04-25 09:51:45 -04001206lpfc_do_offline(struct lpfc_hba *phba, uint32_t type)
1207{
1208 struct completion online_compl;
James Smart895427b2017-02-12 13:52:30 -08001209 struct lpfc_queue *qp = NULL;
James Smart46fa3112007-04-25 09:51:45 -04001210 struct lpfc_sli_ring *pring;
1211 struct lpfc_sli *psli;
1212 int status = 0;
James Smart46fa3112007-04-25 09:51:45 -04001213 int i;
James Smartfedd3b72011-02-16 12:39:24 -05001214 int rc;
James Smart46fa3112007-04-25 09:51:45 -04001215
1216 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001217 rc = lpfc_workq_post_event(phba, &status, &online_compl,
James Smart46fa3112007-04-25 09:51:45 -04001218 LPFC_EVT_OFFLINE_PREP);
James Smartfedd3b72011-02-16 12:39:24 -05001219 if (rc == 0)
1220 return -ENOMEM;
1221
James Smart46fa3112007-04-25 09:51:45 -04001222 wait_for_completion(&online_compl);
1223
1224 if (status != 0)
1225 return -EIO;
1226
1227 psli = &phba->sli;
1228
James Smart4645f7b2019-03-12 16:30:14 -07001229 /*
1230 * If freeing the queues have already started, don't access them.
1231 * Otherwise set FREE_WAIT to indicate that queues are being used
1232 * to hold the freeing process until we finish.
1233 */
1234 spin_lock_irq(&phba->hbalock);
1235 if (!(psli->sli_flag & LPFC_QUEUE_FREE_INIT)) {
1236 psli->sli_flag |= LPFC_QUEUE_FREE_WAIT;
1237 } else {
1238 spin_unlock_irq(&phba->hbalock);
1239 goto skip_wait;
1240 }
1241 spin_unlock_irq(&phba->hbalock);
1242
James Smart09372822008-01-11 01:52:54 -05001243 /* Wait a little for things to settle down, but not
1244 * long enough for dev loss timeout to expire.
1245 */
James Smart895427b2017-02-12 13:52:30 -08001246 if (phba->sli_rev != LPFC_SLI_REV4) {
1247 for (i = 0; i < psli->num_rings; i++) {
1248 pring = &psli->sli3_ring[i];
1249 if (!lpfc_emptyq_wait(phba, &pring->txcmplq,
1250 &phba->hbalock))
1251 goto out;
1252 }
1253 } else {
1254 list_for_each_entry(qp, &phba->sli4_hba.lpfc_wq_list, wq_list) {
1255 pring = qp->pring;
1256 if (!pring)
1257 continue;
1258 if (!lpfc_emptyq_wait(phba, &pring->txcmplq,
1259 &pring->ring_lock))
1260 goto out;
James Smart46fa3112007-04-25 09:51:45 -04001261 }
1262 }
James Smart895427b2017-02-12 13:52:30 -08001263out:
James Smart4645f7b2019-03-12 16:30:14 -07001264 spin_lock_irq(&phba->hbalock);
1265 psli->sli_flag &= ~LPFC_QUEUE_FREE_WAIT;
1266 spin_unlock_irq(&phba->hbalock);
1267
1268skip_wait:
James Smart46fa3112007-04-25 09:51:45 -04001269 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001270 rc = lpfc_workq_post_event(phba, &status, &online_compl, type);
1271 if (rc == 0)
1272 return -ENOMEM;
1273
James Smart46fa3112007-04-25 09:51:45 -04001274 wait_for_completion(&online_compl);
1275
1276 if (status != 0)
1277 return -EIO;
1278
1279 return 0;
1280}
1281
James Smarte59058c2008-08-24 21:49:00 -04001282/**
James Smart50212672018-12-13 15:17:57 -08001283 * lpfc_reset_pci_bus - resets PCI bridge controller's secondary bus of an HBA
1284 * @phba: lpfc_hba pointer.
1285 *
1286 * Description:
1287 * Issues a PCI secondary bus reset for the phba->pcidev.
1288 *
1289 * Notes:
1290 * First walks the bus_list to ensure only PCI devices with Emulex
1291 * vendor id, device ids that support hot reset, only one occurrence
1292 * of function 0, and all ports on the bus are in offline mode to ensure the
1293 * hot reset only affects one valid HBA.
1294 *
1295 * Returns:
1296 * -ENOTSUPP, cfg_enable_hba_reset must be of value 2
1297 * -ENODEV, NULL ptr to pcidev
1298 * -EBADSLT, detected invalid device
1299 * -EBUSY, port is not in offline state
1300 * 0, successful
1301 */
Bart Van Assche3999df72019-03-28 11:06:16 -07001302static int
James Smart50212672018-12-13 15:17:57 -08001303lpfc_reset_pci_bus(struct lpfc_hba *phba)
1304{
1305 struct pci_dev *pdev = phba->pcidev;
1306 struct Scsi_Host *shost = NULL;
1307 struct lpfc_hba *phba_other = NULL;
1308 struct pci_dev *ptr = NULL;
1309 int res;
1310
1311 if (phba->cfg_enable_hba_reset != 2)
1312 return -ENOTSUPP;
1313
1314 if (!pdev) {
1315 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "8345 pdev NULL!\n");
1316 return -ENODEV;
1317 }
1318
1319 res = lpfc_check_pci_resettable(phba);
1320 if (res)
1321 return res;
1322
1323 /* Walk the list of devices on the pci_dev's bus */
1324 list_for_each_entry(ptr, &pdev->bus->devices, bus_list) {
1325 /* Check port is offline */
1326 shost = pci_get_drvdata(ptr);
1327 if (shost) {
1328 phba_other =
1329 ((struct lpfc_vport *)shost->hostdata)->phba;
1330 if (!(phba_other->pport->fc_flag & FC_OFFLINE_MODE)) {
1331 lpfc_printf_log(phba_other, KERN_INFO, LOG_INIT,
1332 "8349 WWPN = 0x%02x%02x%02x%02x"
1333 "%02x%02x%02x%02x is not "
1334 "offline!\n",
1335 phba_other->wwpn[0],
1336 phba_other->wwpn[1],
1337 phba_other->wwpn[2],
1338 phba_other->wwpn[3],
1339 phba_other->wwpn[4],
1340 phba_other->wwpn[5],
1341 phba_other->wwpn[6],
1342 phba_other->wwpn[7]);
1343 return -EBUSY;
1344 }
1345 }
1346 }
1347
1348 /* Issue PCI bus reset */
1349 res = pci_reset_bus(pdev);
1350 if (res) {
1351 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1352 "8350 PCI reset bus failed: %d\n", res);
1353 }
1354
1355 return res;
1356}
1357
1358/**
James Smart3621a712009-04-06 18:47:14 -04001359 * lpfc_selective_reset - Offline then onlines the port
James Smarte59058c2008-08-24 21:49:00 -04001360 * @phba: lpfc_hba pointer.
1361 *
1362 * Description:
1363 * If the port is configured to allow a reset then the hba is brought
1364 * offline then online.
1365 *
1366 * Notes:
1367 * Assumes any error from lpfc_do_offline() will be negative.
James Smartab56dc22011-02-16 12:39:57 -05001368 * Do not make this function static.
James Smarte59058c2008-08-24 21:49:00 -04001369 *
1370 * Returns:
1371 * lpfc_do_offline() return code if not zero
1372 * -EIO reset not configured or error posting the event
1373 * zero for success
1374 **/
James Smart7f860592011-03-11 16:05:52 -05001375int
James Smart40496f02006-07-06 15:50:22 -04001376lpfc_selective_reset(struct lpfc_hba *phba)
1377{
1378 struct completion online_compl;
1379 int status = 0;
James Smartfedd3b72011-02-16 12:39:24 -05001380 int rc;
James Smart40496f02006-07-06 15:50:22 -04001381
James Smart71157c92013-07-15 18:34:36 -04001382 if (!phba->cfg_enable_hba_reset)
James Smartf7a919b2011-08-21 21:49:16 -04001383 return -EACCES;
James Smart13815c82008-01-11 01:52:48 -05001384
James Smart71157c92013-07-15 18:34:36 -04001385 if (!(phba->pport->fc_flag & FC_OFFLINE_MODE)) {
1386 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
James Smart40496f02006-07-06 15:50:22 -04001387
James Smart71157c92013-07-15 18:34:36 -04001388 if (status != 0)
1389 return status;
1390 }
James Smart40496f02006-07-06 15:50:22 -04001391
1392 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001393 rc = lpfc_workq_post_event(phba, &status, &online_compl,
James Smart40496f02006-07-06 15:50:22 -04001394 LPFC_EVT_ONLINE);
James Smartfedd3b72011-02-16 12:39:24 -05001395 if (rc == 0)
1396 return -ENOMEM;
1397
James Smart40496f02006-07-06 15:50:22 -04001398 wait_for_completion(&online_compl);
1399
1400 if (status != 0)
1401 return -EIO;
1402
1403 return 0;
1404}
1405
James Smarte59058c2008-08-24 21:49:00 -04001406/**
James Smart3621a712009-04-06 18:47:14 -04001407 * lpfc_issue_reset - Selectively resets an adapter
James Smarte59058c2008-08-24 21:49:00 -04001408 * @dev: class device that is converted into a Scsi_host.
1409 * @attr: device attribute, not used.
1410 * @buf: containing the string "selective".
1411 * @count: unused variable.
1412 *
1413 * Description:
1414 * If the buf contains the string "selective" then lpfc_selective_reset()
1415 * is called to perform the reset.
1416 *
1417 * Notes:
1418 * Assumes any error from lpfc_selective_reset() will be negative.
1419 * If lpfc_selective_reset() returns zero then the length of the buffer
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02001420 * is returned which indicates success
James Smarte59058c2008-08-24 21:49:00 -04001421 *
1422 * Returns:
1423 * -EINVAL if the buffer does not contain the string "selective"
1424 * length of buf if lpfc-selective_reset() if the call succeeds
1425 * return value of lpfc_selective_reset() if the call fails
1426**/
James Smart40496f02006-07-06 15:50:22 -04001427static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001428lpfc_issue_reset(struct device *dev, struct device_attribute *attr,
1429 const char *buf, size_t count)
James Smart40496f02006-07-06 15:50:22 -04001430{
Tony Jonesee959b02008-02-22 00:13:36 +01001431 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001432 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1433 struct lpfc_hba *phba = vport->phba;
James Smart40496f02006-07-06 15:50:22 -04001434 int status = -EINVAL;
1435
James Smart73d91e52011-10-10 21:32:10 -04001436 if (!phba->cfg_enable_hba_reset)
1437 return -EACCES;
1438
James Smart40496f02006-07-06 15:50:22 -04001439 if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
James Smart7f860592011-03-11 16:05:52 -05001440 status = phba->lpfc_selective_reset(phba);
James Smart40496f02006-07-06 15:50:22 -04001441
1442 if (status == 0)
1443 return strlen(buf);
1444 else
1445 return status;
1446}
1447
James Smarte59058c2008-08-24 21:49:00 -04001448/**
James Smart88a2cfb2011-07-22 18:36:33 -04001449 * lpfc_sli4_pdev_status_reg_wait - Wait for pdev status register for readyness
1450 * @phba: lpfc_hba pointer.
1451 *
1452 * Description:
1453 * SLI4 interface type-2 device to wait on the sliport status register for
1454 * the readyness after performing a firmware reset.
1455 *
1456 * Returns:
Masanari Iida0b1587b2013-07-17 04:37:44 +09001457 * zero for success, -EPERM when port does not have privilege to perform the
James Smart026abb82011-12-13 13:20:45 -05001458 * reset, -EIO when port timeout from recovering from the reset.
1459 *
1460 * Note:
1461 * As the caller will interpret the return code by value, be careful in making
1462 * change or addition to return codes.
James Smart88a2cfb2011-07-22 18:36:33 -04001463 **/
James Smart73d91e52011-10-10 21:32:10 -04001464int
James Smart88a2cfb2011-07-22 18:36:33 -04001465lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba)
1466{
James Smartf7a919b2011-08-21 21:49:16 -04001467 struct lpfc_register portstat_reg = {0};
James Smart88a2cfb2011-07-22 18:36:33 -04001468 int i;
1469
James Smartf7a919b2011-08-21 21:49:16 -04001470 msleep(100);
James Smartb7b95fb2019-09-21 20:58:49 -07001471 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
1472 &portstat_reg.word0))
1473 return -EIO;
James Smart88a2cfb2011-07-22 18:36:33 -04001474
Masanari Iida0b1587b2013-07-17 04:37:44 +09001475 /* verify if privileged for the request operation */
James Smartf7a919b2011-08-21 21:49:16 -04001476 if (!bf_get(lpfc_sliport_status_rn, &portstat_reg) &&
1477 !bf_get(lpfc_sliport_status_err, &portstat_reg))
1478 return -EPERM;
1479
James Smart88a2cfb2011-07-22 18:36:33 -04001480 /* wait for the SLI port firmware ready after firmware reset */
1481 for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) {
1482 msleep(10);
James Smartb7b95fb2019-09-21 20:58:49 -07001483 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
1484 &portstat_reg.word0))
1485 continue;
James Smart88a2cfb2011-07-22 18:36:33 -04001486 if (!bf_get(lpfc_sliport_status_err, &portstat_reg))
1487 continue;
1488 if (!bf_get(lpfc_sliport_status_rn, &portstat_reg))
1489 continue;
1490 if (!bf_get(lpfc_sliport_status_rdy, &portstat_reg))
1491 continue;
1492 break;
1493 }
1494
1495 if (i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT)
1496 return 0;
1497 else
1498 return -EIO;
1499}
1500
1501/**
James Smart52d52442011-05-24 11:42:45 -04001502 * lpfc_sli4_pdev_reg_request - Request physical dev to perform a register acc
James Smartc0c11512011-05-24 11:41:34 -04001503 * @phba: lpfc_hba pointer.
Lee Jones9176ad22020-11-02 14:23:44 +00001504 * @opcode: The sli4 config command opcode.
James Smartc0c11512011-05-24 11:41:34 -04001505 *
1506 * Description:
James Smart52d52442011-05-24 11:42:45 -04001507 * Request SLI4 interface type-2 device to perform a physical register set
1508 * access.
James Smartc0c11512011-05-24 11:41:34 -04001509 *
1510 * Returns:
1511 * zero for success
1512 **/
1513static ssize_t
James Smart52d52442011-05-24 11:42:45 -04001514lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
James Smartc0c11512011-05-24 11:41:34 -04001515{
1516 struct completion online_compl;
James Smartb76f2dc2011-07-22 18:37:42 -04001517 struct pci_dev *pdev = phba->pcidev;
James Smart026abb82011-12-13 13:20:45 -05001518 uint32_t before_fc_flag;
1519 uint32_t sriov_nr_virtfn;
James Smartc0c11512011-05-24 11:41:34 -04001520 uint32_t reg_val;
James Smart026abb82011-12-13 13:20:45 -05001521 int status = 0, rc = 0;
1522 int job_posted = 1, sriov_err;
James Smartc0c11512011-05-24 11:41:34 -04001523
1524 if (!phba->cfg_enable_hba_reset)
James Smartf7a919b2011-08-21 21:49:16 -04001525 return -EACCES;
James Smartc0c11512011-05-24 11:41:34 -04001526
James Smart52d52442011-05-24 11:42:45 -04001527 if ((phba->sli_rev < LPFC_SLI_REV4) ||
James Smart719162b2018-12-10 19:37:01 -08001528 (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
James Smart52d52442011-05-24 11:42:45 -04001529 LPFC_SLI_INTF_IF_TYPE_2))
1530 return -EPERM;
1531
James Smart026abb82011-12-13 13:20:45 -05001532 /* Keep state if we need to restore back */
1533 before_fc_flag = phba->pport->fc_flag;
1534 sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn;
1535
James Smartb76f2dc2011-07-22 18:37:42 -04001536 /* Disable SR-IOV virtual functions if enabled */
1537 if (phba->cfg_sriov_nr_virtfn) {
1538 pci_disable_sriov(pdev);
1539 phba->cfg_sriov_nr_virtfn = 0;
1540 }
James Smart229adb02013-04-17 20:16:51 -04001541
James Smart02936352014-04-04 13:52:12 -04001542 if (opcode == LPFC_FW_DUMP)
1543 phba->hba_flag |= HBA_FW_DUMP_OP;
1544
James Smartc0c11512011-05-24 11:41:34 -04001545 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
1546
James Smart02936352014-04-04 13:52:12 -04001547 if (status != 0) {
1548 phba->hba_flag &= ~HBA_FW_DUMP_OP;
James Smartc0c11512011-05-24 11:41:34 -04001549 return status;
James Smart02936352014-04-04 13:52:12 -04001550 }
James Smartc0c11512011-05-24 11:41:34 -04001551
1552 /* wait for the device to be quiesced before firmware reset */
1553 msleep(100);
1554
1555 reg_val = readl(phba->sli4_hba.conf_regs_memmap_p +
1556 LPFC_CTL_PDEV_CTL_OFFSET);
James Smart52d52442011-05-24 11:42:45 -04001557
1558 if (opcode == LPFC_FW_DUMP)
1559 reg_val |= LPFC_FW_DUMP_REQUEST;
1560 else if (opcode == LPFC_FW_RESET)
1561 reg_val |= LPFC_CTL_PDEV_CTL_FRST;
1562 else if (opcode == LPFC_DV_RESET)
1563 reg_val |= LPFC_CTL_PDEV_CTL_DRST;
1564
James Smartc0c11512011-05-24 11:41:34 -04001565 writel(reg_val, phba->sli4_hba.conf_regs_memmap_p +
1566 LPFC_CTL_PDEV_CTL_OFFSET);
1567 /* flush */
1568 readl(phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET);
1569
1570 /* delay driver action following IF_TYPE_2 reset */
James Smart88a2cfb2011-07-22 18:36:33 -04001571 rc = lpfc_sli4_pdev_status_reg_wait(phba);
1572
James Smart026abb82011-12-13 13:20:45 -05001573 if (rc == -EPERM) {
Masanari Iida0b1587b2013-07-17 04:37:44 +09001574 /* no privilege for reset */
James Smart6b5151f2012-01-18 16:24:06 -05001575 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
Masanari Iida0b1587b2013-07-17 04:37:44 +09001576 "3150 No privilege to perform the requested "
James Smart6b5151f2012-01-18 16:24:06 -05001577 "access: x%x\n", reg_val);
James Smart026abb82011-12-13 13:20:45 -05001578 } else if (rc == -EIO) {
1579 /* reset failed, there is nothing more we can do */
James Smart6b5151f2012-01-18 16:24:06 -05001580 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
1581 "3153 Fail to perform the requested "
1582 "access: x%x\n", reg_val);
James Smartf7a919b2011-08-21 21:49:16 -04001583 return rc;
James Smart026abb82011-12-13 13:20:45 -05001584 }
1585
1586 /* keep the original port state */
1587 if (before_fc_flag & FC_OFFLINE_MODE)
1588 goto out;
James Smartc0c11512011-05-24 11:41:34 -04001589
1590 init_completion(&online_compl);
James Smart026abb82011-12-13 13:20:45 -05001591 job_posted = lpfc_workq_post_event(phba, &status, &online_compl,
1592 LPFC_EVT_ONLINE);
1593 if (!job_posted)
1594 goto out;
James Smartc0c11512011-05-24 11:41:34 -04001595
1596 wait_for_completion(&online_compl);
1597
James Smart026abb82011-12-13 13:20:45 -05001598out:
1599 /* in any case, restore the virtual functions enabled as before */
1600 if (sriov_nr_virtfn) {
1601 sriov_err =
1602 lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn);
1603 if (!sriov_err)
1604 phba->cfg_sriov_nr_virtfn = sriov_nr_virtfn;
1605 }
James Smartc0c11512011-05-24 11:41:34 -04001606
James Smart026abb82011-12-13 13:20:45 -05001607 /* return proper error code */
1608 if (!rc) {
1609 if (!job_posted)
1610 rc = -ENOMEM;
1611 else if (status)
1612 rc = -EIO;
1613 }
1614 return rc;
James Smartc0c11512011-05-24 11:41:34 -04001615}
1616
1617/**
James Smart3621a712009-04-06 18:47:14 -04001618 * lpfc_nport_evt_cnt_show - Return the number of nport events
James Smarte59058c2008-08-24 21:49:00 -04001619 * @dev: class device that is converted into a Scsi_host.
1620 * @attr: device attribute, not used.
1621 * @buf: on return contains the ascii number of nport events.
1622 *
1623 * Returns: size of formatted string.
1624 **/
dea31012005-04-17 16:05:31 -05001625static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001626lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr,
1627 char *buf)
dea31012005-04-17 16:05:31 -05001628{
Tony Jonesee959b02008-02-22 00:13:36 +01001629 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001630 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1631 struct lpfc_hba *phba = vport->phba;
1632
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001633 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
dea31012005-04-17 16:05:31 -05001634}
1635
Bart Van Assche3999df72019-03-28 11:06:16 -07001636static int
James Smart1dc5ec22018-10-23 13:41:11 -07001637lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out)
1638{
1639 LPFC_MBOXQ_t *mbox = NULL;
1640 unsigned long val = 0;
Saurav Girepunje2c7fb462019-10-24 08:27:29 +05301641 char *pval = NULL;
James Smart1dc5ec22018-10-23 13:41:11 -07001642 int rc = 0;
1643
1644 if (!strncmp("enable", buff_out,
1645 strlen("enable"))) {
1646 pval = buff_out + strlen("enable") + 1;
1647 rc = kstrtoul(pval, 0, &val);
1648 if (rc)
1649 return rc; /* Invalid number */
1650 } else if (!strncmp("disable", buff_out,
1651 strlen("disable"))) {
1652 val = 0;
1653 } else {
1654 return -EINVAL; /* Invalid command */
1655 }
1656
1657 switch (val) {
1658 case 0:
1659 val = 0x0; /* Disable */
1660 break;
1661 case 2:
1662 val = 0x1; /* Enable two port trunk */
1663 break;
1664 case 4:
1665 val = 0x2; /* Enable four port trunk */
1666 break;
1667 default:
1668 return -EINVAL;
1669 }
1670
1671 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1672 "0070 Set trunk mode with val %ld ", val);
1673
1674 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1675 if (!mbox)
1676 return -ENOMEM;
1677
1678 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
1679 LPFC_MBOX_OPCODE_FCOE_FC_SET_TRUNK_MODE,
1680 12, LPFC_SLI4_MBX_EMBED);
1681
1682 bf_set(lpfc_mbx_set_trunk_mode,
1683 &mbox->u.mqe.un.set_trunk_mode,
1684 val);
1685 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
1686 if (rc)
1687 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1688 "0071 Set trunk mode failed with status: %d",
1689 rc);
1690 if (rc != MBX_TIMEOUT)
1691 mempool_free(mbox, phba->mbox_mem_pool);
1692
1693 return 0;
1694}
1695
James Smarte59058c2008-08-24 21:49:00 -04001696/**
James Smart3621a712009-04-06 18:47:14 -04001697 * lpfc_board_mode_show - Return the state of the board
James Smarte59058c2008-08-24 21:49:00 -04001698 * @dev: class device that is converted into a Scsi_host.
1699 * @attr: device attribute, not used.
1700 * @buf: on return contains the state of the adapter.
1701 *
1702 * Returns: size of formatted string.
1703 **/
dea31012005-04-17 16:05:31 -05001704static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001705lpfc_board_mode_show(struct device *dev, struct device_attribute *attr,
1706 char *buf)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001707{
Tony Jonesee959b02008-02-22 00:13:36 +01001708 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001709 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1710 struct lpfc_hba *phba = vport->phba;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001711 char * state;
1712
James Smart2e0fef82007-06-17 19:56:36 -05001713 if (phba->link_state == LPFC_HBA_ERROR)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001714 state = "error";
James Smart2e0fef82007-06-17 19:56:36 -05001715 else if (phba->link_state == LPFC_WARM_START)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001716 state = "warm start";
James Smart2e0fef82007-06-17 19:56:36 -05001717 else if (phba->link_state == LPFC_INIT_START)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001718 state = "offline";
1719 else
1720 state = "online";
1721
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001722 return scnprintf(buf, PAGE_SIZE, "%s\n", state);
Jamie Wellnitz41415862006-02-28 19:25:27 -05001723}
1724
James Smarte59058c2008-08-24 21:49:00 -04001725/**
James Smart3621a712009-04-06 18:47:14 -04001726 * lpfc_board_mode_store - Puts the hba in online, offline, warm or error state
James Smarte59058c2008-08-24 21:49:00 -04001727 * @dev: class device that is converted into a Scsi_host.
1728 * @attr: device attribute, not used.
1729 * @buf: containing one of the strings "online", "offline", "warm" or "error".
1730 * @count: unused variable.
1731 *
1732 * Returns:
1733 * -EACCES if enable hba reset not enabled
1734 * -EINVAL if the buffer does not contain a valid string (see above)
1735 * -EIO if lpfc_workq_post_event() or lpfc_do_offline() fails
1736 * buf length greater than zero indicates success
1737 **/
Jamie Wellnitz41415862006-02-28 19:25:27 -05001738static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001739lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
1740 const char *buf, size_t count)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001741{
Tony Jonesee959b02008-02-22 00:13:36 +01001742 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001743 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1744 struct lpfc_hba *phba = vport->phba;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001745 struct completion online_compl;
James Smart026abb82011-12-13 13:20:45 -05001746 char *board_mode_str = NULL;
1747 int status = 0;
James Smartfedd3b72011-02-16 12:39:24 -05001748 int rc;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001749
James Smart026abb82011-12-13 13:20:45 -05001750 if (!phba->cfg_enable_hba_reset) {
1751 status = -EACCES;
1752 goto board_mode_out;
1753 }
James Smart88a2cfb2011-07-22 18:36:33 -04001754
1755 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart026abb82011-12-13 13:20:45 -05001756 "3050 lpfc_board_mode set to %s\n", buf);
James Smart88a2cfb2011-07-22 18:36:33 -04001757
Jamie Wellnitz41415862006-02-28 19:25:27 -05001758 init_completion(&online_compl);
1759
James Smart46fa3112007-04-25 09:51:45 -04001760 if(strncmp(buf, "online", sizeof("online") - 1) == 0) {
James Smartfedd3b72011-02-16 12:39:24 -05001761 rc = lpfc_workq_post_event(phba, &status, &online_compl,
Jamie Wellnitz41415862006-02-28 19:25:27 -05001762 LPFC_EVT_ONLINE);
James Smart026abb82011-12-13 13:20:45 -05001763 if (rc == 0) {
1764 status = -ENOMEM;
1765 goto board_mode_out;
1766 }
James Smart46fa3112007-04-25 09:51:45 -04001767 wait_for_completion(&online_compl);
James Smart522dcee2017-06-01 21:07:03 -07001768 if (status)
1769 status = -EIO;
James Smart46fa3112007-04-25 09:51:45 -04001770 } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
1771 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
Jamie Wellnitz41415862006-02-28 19:25:27 -05001772 else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0)
James Smart6a9c52c2009-10-02 15:16:51 -04001773 if (phba->sli_rev == LPFC_SLI_REV4)
James Smart026abb82011-12-13 13:20:45 -05001774 status = -EINVAL;
James Smart6a9c52c2009-10-02 15:16:51 -04001775 else
1776 status = lpfc_do_offline(phba, LPFC_EVT_WARM_START);
James Smart46fa3112007-04-25 09:51:45 -04001777 else if (strncmp(buf, "error", sizeof("error") - 1) == 0)
James Smart6a9c52c2009-10-02 15:16:51 -04001778 if (phba->sli_rev == LPFC_SLI_REV4)
James Smart026abb82011-12-13 13:20:45 -05001779 status = -EINVAL;
James Smart6a9c52c2009-10-02 15:16:51 -04001780 else
1781 status = lpfc_do_offline(phba, LPFC_EVT_KILL);
James Smartc0c11512011-05-24 11:41:34 -04001782 else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0)
James Smart52d52442011-05-24 11:42:45 -04001783 status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_DUMP);
1784 else if (strncmp(buf, "fw_reset", sizeof("fw_reset") - 1) == 0)
1785 status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_RESET);
1786 else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0)
1787 status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET);
James Smart50212672018-12-13 15:17:57 -08001788 else if (strncmp(buf, "pci_bus_reset", sizeof("pci_bus_reset") - 1)
1789 == 0)
1790 status = lpfc_reset_pci_bus(phba);
James Smarta22d73b2021-01-04 10:02:38 -08001791 else if (strncmp(buf, "heartbeat", sizeof("heartbeat") - 1) == 0)
1792 lpfc_issue_hb_tmo(phba);
James Smart1dc5ec22018-10-23 13:41:11 -07001793 else if (strncmp(buf, "trunk", sizeof("trunk") - 1) == 0)
1794 status = lpfc_set_trunking(phba, (char *)buf + sizeof("trunk"));
Jamie Wellnitz41415862006-02-28 19:25:27 -05001795 else
James Smart026abb82011-12-13 13:20:45 -05001796 status = -EINVAL;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001797
James Smart026abb82011-12-13 13:20:45 -05001798board_mode_out:
Jamie Wellnitz41415862006-02-28 19:25:27 -05001799 if (!status)
1800 return strlen(buf);
James Smart026abb82011-12-13 13:20:45 -05001801 else {
1802 board_mode_str = strchr(buf, '\n');
1803 if (board_mode_str)
1804 *board_mode_str = '\0';
1805 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1806 "3097 Failed \"%s\", status(%d), "
1807 "fc_flag(x%x)\n",
1808 buf, status, phba->pport->fc_flag);
James Smartf7a919b2011-08-21 21:49:16 -04001809 return status;
James Smart026abb82011-12-13 13:20:45 -05001810 }
Jamie Wellnitz41415862006-02-28 19:25:27 -05001811}
1812
James Smarte59058c2008-08-24 21:49:00 -04001813/**
James Smart3621a712009-04-06 18:47:14 -04001814 * lpfc_get_hba_info - Return various bits of informaton about the adapter
James Smarte59058c2008-08-24 21:49:00 -04001815 * @phba: pointer to the adapter structure.
James Smart3621a712009-04-06 18:47:14 -04001816 * @mxri: max xri count.
1817 * @axri: available xri count.
1818 * @mrpi: max rpi count.
1819 * @arpi: available rpi count.
1820 * @mvpi: max vpi count.
1821 * @avpi: available vpi count.
James Smarte59058c2008-08-24 21:49:00 -04001822 *
1823 * Description:
1824 * If an integer pointer for an count is not null then the value for the
1825 * count is returned.
1826 *
1827 * Returns:
1828 * zero on error
1829 * one for success
1830 **/
James Smart311464e2007-08-02 11:10:37 -04001831static int
James Smart858c9f62007-06-17 19:56:39 -05001832lpfc_get_hba_info(struct lpfc_hba *phba,
1833 uint32_t *mxri, uint32_t *axri,
1834 uint32_t *mrpi, uint32_t *arpi,
1835 uint32_t *mvpi, uint32_t *avpi)
James Smart92d7f7b2007-06-17 19:56:38 -05001836{
James Smart04c68492009-05-22 14:52:52 -04001837 struct lpfc_mbx_read_config *rd_config;
James Smart92d7f7b2007-06-17 19:56:38 -05001838 LPFC_MBOXQ_t *pmboxq;
1839 MAILBOX_t *pmb;
1840 int rc = 0;
James Smart15672312010-04-06 14:49:03 -04001841 uint32_t max_vpi;
James Smart92d7f7b2007-06-17 19:56:38 -05001842
1843 /*
1844 * prevent udev from issuing mailbox commands until the port is
1845 * configured.
1846 */
1847 if (phba->link_state < LPFC_LINK_DOWN ||
1848 !phba->mbox_mem_pool ||
James Smartf4b4c682009-05-22 14:53:12 -04001849 (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
James Smart92d7f7b2007-06-17 19:56:38 -05001850 return 0;
1851
1852 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
1853 return 0;
1854
1855 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1856 if (!pmboxq)
1857 return 0;
1858 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
1859
James Smart04c68492009-05-22 14:52:52 -04001860 pmb = &pmboxq->u.mb;
James Smart92d7f7b2007-06-17 19:56:38 -05001861 pmb->mbxCommand = MBX_READ_CONFIG;
1862 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08001863 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05001864
James Smart75baf692010-06-08 18:31:21 -04001865 if (phba->pport->fc_flag & FC_OFFLINE_MODE)
James Smart92d7f7b2007-06-17 19:56:38 -05001866 rc = MBX_NOT_FINISHED;
1867 else
1868 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1869
1870 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05001871 if (rc != MBX_TIMEOUT)
James Smart92d7f7b2007-06-17 19:56:38 -05001872 mempool_free(pmboxq, phba->mbox_mem_pool);
1873 return 0;
1874 }
1875
James Smartda0436e2009-05-22 14:51:39 -04001876 if (phba->sli_rev == LPFC_SLI_REV4) {
1877 rd_config = &pmboxq->u.mqe.un.rd_config;
1878 if (mrpi)
1879 *mrpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config);
1880 if (arpi)
1881 *arpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config) -
1882 phba->sli4_hba.max_cfg_param.rpi_used;
1883 if (mxri)
1884 *mxri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
1885 if (axri)
1886 *axri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config) -
1887 phba->sli4_hba.max_cfg_param.xri_used;
James Smart15672312010-04-06 14:49:03 -04001888
1889 /* Account for differences with SLI-3. Get vpi count from
1890 * mailbox data and subtract one for max vpi value.
1891 */
1892 max_vpi = (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) > 0) ?
1893 (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) - 1) : 0;
1894
James Smart8b47ae62018-11-29 16:09:33 -08001895 /* Limit the max we support */
1896 if (max_vpi > LPFC_MAX_VPI)
1897 max_vpi = LPFC_MAX_VPI;
James Smartda0436e2009-05-22 14:51:39 -04001898 if (mvpi)
James Smart15672312010-04-06 14:49:03 -04001899 *mvpi = max_vpi;
James Smartda0436e2009-05-22 14:51:39 -04001900 if (avpi)
James Smart15672312010-04-06 14:49:03 -04001901 *avpi = max_vpi - phba->sli4_hba.max_cfg_param.vpi_used;
James Smartda0436e2009-05-22 14:51:39 -04001902 } else {
1903 if (mrpi)
1904 *mrpi = pmb->un.varRdConfig.max_rpi;
1905 if (arpi)
1906 *arpi = pmb->un.varRdConfig.avail_rpi;
1907 if (mxri)
1908 *mxri = pmb->un.varRdConfig.max_xri;
1909 if (axri)
1910 *axri = pmb->un.varRdConfig.avail_xri;
1911 if (mvpi)
1912 *mvpi = pmb->un.varRdConfig.max_vpi;
James Smart8b47ae62018-11-29 16:09:33 -08001913 if (avpi) {
1914 /* avail_vpi is only valid if link is up and ready */
1915 if (phba->link_state == LPFC_HBA_READY)
1916 *avpi = pmb->un.varRdConfig.avail_vpi;
1917 else
1918 *avpi = pmb->un.varRdConfig.max_vpi;
1919 }
James Smartda0436e2009-05-22 14:51:39 -04001920 }
James Smart92d7f7b2007-06-17 19:56:38 -05001921
1922 mempool_free(pmboxq, phba->mbox_mem_pool);
1923 return 1;
1924}
1925
James Smarte59058c2008-08-24 21:49:00 -04001926/**
James Smart3621a712009-04-06 18:47:14 -04001927 * lpfc_max_rpi_show - Return maximum rpi
James Smarte59058c2008-08-24 21:49:00 -04001928 * @dev: class device that is converted into a Scsi_host.
1929 * @attr: device attribute, not used.
1930 * @buf: on return contains the maximum rpi count in decimal or "Unknown".
1931 *
1932 * Description:
1933 * Calls lpfc_get_hba_info() asking for just the mrpi count.
1934 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1935 * to "Unknown" and the buffer length is returned, therefore the caller
1936 * must check for "Unknown" in the buffer to detect a failure.
1937 *
1938 * Returns: size of formatted string.
1939 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001940static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001941lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr,
1942 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001943{
Tony Jonesee959b02008-02-22 00:13:36 +01001944 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05001945 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1946 struct lpfc_hba *phba = vport->phba;
1947 uint32_t cnt;
1948
James Smart858c9f62007-06-17 19:56:39 -05001949 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001950 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
1951 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001952}
1953
James Smarte59058c2008-08-24 21:49:00 -04001954/**
James Smart3621a712009-04-06 18:47:14 -04001955 * lpfc_used_rpi_show - Return maximum rpi minus available rpi
James Smarte59058c2008-08-24 21:49:00 -04001956 * @dev: class device that is converted into a Scsi_host.
1957 * @attr: device attribute, not used.
1958 * @buf: containing the used rpi count in decimal or "Unknown".
1959 *
1960 * Description:
1961 * Calls lpfc_get_hba_info() asking for just the mrpi and arpi counts.
1962 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1963 * to "Unknown" and the buffer length is returned, therefore the caller
1964 * must check for "Unknown" in the buffer to detect a failure.
1965 *
1966 * Returns: size of formatted string.
1967 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001968static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001969lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr,
1970 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001971{
Tony Jonesee959b02008-02-22 00:13:36 +01001972 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05001973 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1974 struct lpfc_hba *phba = vport->phba;
1975 uint32_t cnt, acnt;
1976
James Smart858c9f62007-06-17 19:56:39 -05001977 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001978 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
1979 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001980}
1981
James Smarte59058c2008-08-24 21:49:00 -04001982/**
James Smart3621a712009-04-06 18:47:14 -04001983 * lpfc_max_xri_show - Return maximum xri
James Smarte59058c2008-08-24 21:49:00 -04001984 * @dev: class device that is converted into a Scsi_host.
1985 * @attr: device attribute, not used.
1986 * @buf: on return contains the maximum xri count in decimal or "Unknown".
1987 *
1988 * Description:
1989 * Calls lpfc_get_hba_info() asking for just the mrpi count.
1990 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1991 * to "Unknown" and the buffer length is returned, therefore the caller
1992 * must check for "Unknown" in the buffer to detect a failure.
1993 *
1994 * Returns: size of formatted string.
1995 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001996static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001997lpfc_max_xri_show(struct device *dev, struct device_attribute *attr,
1998 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001999{
Tony Jonesee959b02008-02-22 00:13:36 +01002000 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05002001 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2002 struct lpfc_hba *phba = vport->phba;
2003 uint32_t cnt;
2004
James Smart858c9f62007-06-17 19:56:39 -05002005 if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002006 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
2007 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002008}
2009
James Smarte59058c2008-08-24 21:49:00 -04002010/**
James Smart3621a712009-04-06 18:47:14 -04002011 * lpfc_used_xri_show - Return maximum xpi minus the available xpi
James Smarte59058c2008-08-24 21:49:00 -04002012 * @dev: class device that is converted into a Scsi_host.
2013 * @attr: device attribute, not used.
2014 * @buf: on return contains the used xri count in decimal or "Unknown".
2015 *
2016 * Description:
2017 * Calls lpfc_get_hba_info() asking for just the mxri and axri counts.
2018 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2019 * to "Unknown" and the buffer length is returned, therefore the caller
2020 * must check for "Unknown" in the buffer to detect a failure.
2021 *
2022 * Returns: size of formatted string.
2023 **/
James Smart92d7f7b2007-06-17 19:56:38 -05002024static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002025lpfc_used_xri_show(struct device *dev, struct device_attribute *attr,
2026 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05002027{
Tony Jonesee959b02008-02-22 00:13:36 +01002028 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05002029 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2030 struct lpfc_hba *phba = vport->phba;
2031 uint32_t cnt, acnt;
2032
James Smart858c9f62007-06-17 19:56:39 -05002033 if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002034 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
2035 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart858c9f62007-06-17 19:56:39 -05002036}
2037
James Smarte59058c2008-08-24 21:49:00 -04002038/**
James Smart3621a712009-04-06 18:47:14 -04002039 * lpfc_max_vpi_show - Return maximum vpi
James Smarte59058c2008-08-24 21:49:00 -04002040 * @dev: class device that is converted into a Scsi_host.
2041 * @attr: device attribute, not used.
2042 * @buf: on return contains the maximum vpi count in decimal or "Unknown".
2043 *
2044 * Description:
2045 * Calls lpfc_get_hba_info() asking for just the mvpi count.
2046 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2047 * to "Unknown" and the buffer length is returned, therefore the caller
2048 * must check for "Unknown" in the buffer to detect a failure.
2049 *
2050 * Returns: size of formatted string.
2051 **/
James Smart858c9f62007-06-17 19:56:39 -05002052static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002053lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr,
2054 char *buf)
James Smart858c9f62007-06-17 19:56:39 -05002055{
Tony Jonesee959b02008-02-22 00:13:36 +01002056 struct Scsi_Host *shost = class_to_shost(dev);
James Smart858c9f62007-06-17 19:56:39 -05002057 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2058 struct lpfc_hba *phba = vport->phba;
2059 uint32_t cnt;
2060
2061 if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002062 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
2063 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart858c9f62007-06-17 19:56:39 -05002064}
2065
James Smarte59058c2008-08-24 21:49:00 -04002066/**
James Smart3621a712009-04-06 18:47:14 -04002067 * lpfc_used_vpi_show - Return maximum vpi minus the available vpi
James Smarte59058c2008-08-24 21:49:00 -04002068 * @dev: class device that is converted into a Scsi_host.
2069 * @attr: device attribute, not used.
2070 * @buf: on return contains the used vpi count in decimal or "Unknown".
2071 *
2072 * Description:
2073 * Calls lpfc_get_hba_info() asking for just the mvpi and avpi counts.
2074 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2075 * to "Unknown" and the buffer length is returned, therefore the caller
2076 * must check for "Unknown" in the buffer to detect a failure.
2077 *
2078 * Returns: size of formatted string.
2079 **/
James Smart858c9f62007-06-17 19:56:39 -05002080static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002081lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr,
2082 char *buf)
James Smart858c9f62007-06-17 19:56:39 -05002083{
Tony Jonesee959b02008-02-22 00:13:36 +01002084 struct Scsi_Host *shost = class_to_shost(dev);
James Smart858c9f62007-06-17 19:56:39 -05002085 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2086 struct lpfc_hba *phba = vport->phba;
2087 uint32_t cnt, acnt;
2088
2089 if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, &acnt))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002090 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
2091 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002092}
2093
James Smarte59058c2008-08-24 21:49:00 -04002094/**
James Smart3621a712009-04-06 18:47:14 -04002095 * lpfc_npiv_info_show - Return text about NPIV support for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002096 * @dev: class device that is converted into a Scsi_host.
2097 * @attr: device attribute, not used.
2098 * @buf: text that must be interpreted to determine if npiv is supported.
2099 *
2100 * Description:
2101 * Buffer will contain text indicating npiv is not suppoerted on the port,
2102 * the port is an NPIV physical port, or it is an npiv virtual port with
2103 * the id of the vport.
2104 *
2105 * Returns: size of formatted string.
2106 **/
James Smart92d7f7b2007-06-17 19:56:38 -05002107static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002108lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr,
2109 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05002110{
Tony Jonesee959b02008-02-22 00:13:36 +01002111 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05002112 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2113 struct lpfc_hba *phba = vport->phba;
2114
2115 if (!(phba->max_vpi))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002116 return scnprintf(buf, PAGE_SIZE, "NPIV Not Supported\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002117 if (vport->port_type == LPFC_PHYSICAL_PORT)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002118 return scnprintf(buf, PAGE_SIZE, "NPIV Physical\n");
2119 return scnprintf(buf, PAGE_SIZE, "NPIV Virtual (VPI %d)\n", vport->vpi);
James Smart92d7f7b2007-06-17 19:56:38 -05002120}
2121
James Smarte59058c2008-08-24 21:49:00 -04002122/**
James Smart3621a712009-04-06 18:47:14 -04002123 * lpfc_poll_show - Return text about poll support for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002124 * @dev: class device that is converted into a Scsi_host.
2125 * @attr: device attribute, not used.
2126 * @buf: on return contains the cfg_poll in hex.
2127 *
2128 * Notes:
2129 * cfg_poll should be a lpfc_polling_flags type.
2130 *
2131 * Returns: size of formatted string.
2132 **/
Jamie Wellnitz41415862006-02-28 19:25:27 -05002133static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002134lpfc_poll_show(struct device *dev, struct device_attribute *attr,
2135 char *buf)
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002136{
Tony Jonesee959b02008-02-22 00:13:36 +01002137 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05002138 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2139 struct lpfc_hba *phba = vport->phba;
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002140
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002141 return scnprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002142}
2143
James Smarte59058c2008-08-24 21:49:00 -04002144/**
James Smart3621a712009-04-06 18:47:14 -04002145 * lpfc_poll_store - Set the value of cfg_poll for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002146 * @dev: class device that is converted into a Scsi_host.
2147 * @attr: device attribute, not used.
2148 * @buf: one or more lpfc_polling_flags values.
2149 * @count: not used.
2150 *
2151 * Notes:
2152 * buf contents converted to integer and checked for a valid value.
2153 *
2154 * Returns:
2155 * -EINVAL if the buffer connot be converted or is out of range
2156 * length of the buf on success
2157 **/
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002158static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002159lpfc_poll_store(struct device *dev, struct device_attribute *attr,
2160 const char *buf, size_t count)
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002161{
Tony Jonesee959b02008-02-22 00:13:36 +01002162 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05002163 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2164 struct lpfc_hba *phba = vport->phba;
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002165 uint32_t creg_val;
2166 uint32_t old_val;
2167 int val=0;
2168
2169 if (!isdigit(buf[0]))
2170 return -EINVAL;
2171
2172 if (sscanf(buf, "%i", &val) != 1)
2173 return -EINVAL;
2174
2175 if ((val & 0x3) != val)
2176 return -EINVAL;
2177
James Smart45ed1192009-10-02 15:17:02 -04002178 if (phba->sli_rev == LPFC_SLI_REV4)
2179 val = 0;
2180
James Smart88a2cfb2011-07-22 18:36:33 -04002181 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
2182 "3051 lpfc_poll changed from %d to %d\n",
2183 phba->cfg_poll, val);
2184
James Smart2e0fef82007-06-17 19:56:36 -05002185 spin_lock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002186
2187 old_val = phba->cfg_poll;
2188
2189 if (val & ENABLE_FCP_RING_POLLING) {
2190 if ((val & DISABLE_FCP_RING_INT) &&
2191 !(old_val & DISABLE_FCP_RING_INT)) {
James Smart9940b972011-03-11 16:06:12 -05002192 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
2193 spin_unlock_irq(&phba->hbalock);
2194 return -EINVAL;
2195 }
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002196 creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
2197 writel(creg_val, phba->HCregaddr);
2198 readl(phba->HCregaddr); /* flush */
2199
2200 lpfc_poll_start_timer(phba);
2201 }
2202 } else if (val != 0x0) {
James Smart2e0fef82007-06-17 19:56:36 -05002203 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002204 return -EINVAL;
2205 }
2206
2207 if (!(val & DISABLE_FCP_RING_INT) &&
2208 (old_val & DISABLE_FCP_RING_INT))
2209 {
James Smart2e0fef82007-06-17 19:56:36 -05002210 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002211 del_timer(&phba->fcp_poll_timer);
James Smart2e0fef82007-06-17 19:56:36 -05002212 spin_lock_irq(&phba->hbalock);
James Smart9940b972011-03-11 16:06:12 -05002213 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
2214 spin_unlock_irq(&phba->hbalock);
2215 return -EINVAL;
2216 }
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002217 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
2218 writel(creg_val, phba->HCregaddr);
2219 readl(phba->HCregaddr); /* flush */
2220 }
2221
2222 phba->cfg_poll = val;
2223
James Smart2e0fef82007-06-17 19:56:36 -05002224 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002225
2226 return strlen(buf);
2227}
dea31012005-04-17 16:05:31 -05002228
James Smarte59058c2008-08-24 21:49:00 -04002229/**
James Smart912e3ac2011-05-24 11:42:11 -04002230 * lpfc_sriov_hw_max_virtfn_show - Return maximum number of virtual functions
2231 * @dev: class converted to a Scsi_host structure.
2232 * @attr: device attribute, not used.
2233 * @buf: on return contains the formatted support level.
2234 *
2235 * Description:
2236 * Returns the maximum number of virtual functions a physical function can
2237 * support, 0 will be returned if called on virtual function.
2238 *
2239 * Returns: size of formatted string.
2240 **/
2241static ssize_t
2242lpfc_sriov_hw_max_virtfn_show(struct device *dev,
2243 struct device_attribute *attr,
2244 char *buf)
2245{
2246 struct Scsi_Host *shost = class_to_shost(dev);
2247 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2248 struct lpfc_hba *phba = vport->phba;
James Smart0a96e972011-07-22 18:37:28 -04002249 uint16_t max_nr_virtfn;
James Smart912e3ac2011-05-24 11:42:11 -04002250
James Smart0a96e972011-07-22 18:37:28 -04002251 max_nr_virtfn = lpfc_sli_sriov_nr_virtfn_get(phba);
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002252 return scnprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn);
James Smart912e3ac2011-05-24 11:42:11 -04002253}
2254
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002255static inline bool lpfc_rangecheck(uint val, uint min, uint max)
2256{
2257 return val >= min && val <= max;
2258}
2259
James Smart912e3ac2011-05-24 11:42:11 -04002260/**
James Smart44fd7fe2017-08-23 16:55:47 -07002261 * lpfc_enable_bbcr_set: Sets an attribute value.
2262 * @phba: pointer the the adapter structure.
2263 * @val: integer attribute value.
2264 *
2265 * Description:
2266 * Validates the min and max values then sets the
2267 * adapter config field if in the valid range. prints error message
2268 * and does not set the parameter if invalid.
2269 *
2270 * Returns:
2271 * zero on success
2272 * -EINVAL if val is invalid
2273 */
2274static ssize_t
2275lpfc_enable_bbcr_set(struct lpfc_hba *phba, uint val)
2276{
2277 if (lpfc_rangecheck(val, 0, 1) && phba->sli_rev == LPFC_SLI_REV4) {
2278 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2279 "3068 %s_enable_bbcr changed from %d to %d\n",
2280 LPFC_DRIVER_NAME, phba->cfg_enable_bbcr, val);
2281 phba->cfg_enable_bbcr = val;
2282 return 0;
2283 }
2284 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2285 "0451 %s_enable_bbcr cannot set to %d, range is 0, 1\n",
2286 LPFC_DRIVER_NAME, val);
2287 return -EINVAL;
2288}
2289
Lee Jones9176ad22020-11-02 14:23:44 +00002290/*
James Smart3621a712009-04-06 18:47:14 -04002291 * lpfc_param_show - Return a cfg attribute value in decimal
James Smarte59058c2008-08-24 21:49:00 -04002292 *
2293 * Description:
2294 * Macro that given an attr e.g. hba_queue_depth expands
2295 * into a function with the name lpfc_hba_queue_depth_show.
2296 *
2297 * lpfc_##attr##_show: Return the decimal value of an adapters cfg_xxx field.
2298 * @dev: class device that is converted into a Scsi_host.
2299 * @attr: device attribute, not used.
2300 * @buf: on return contains the attribute value in decimal.
2301 *
2302 * Returns: size of formatted string.
2303 **/
dea31012005-04-17 16:05:31 -05002304#define lpfc_param_show(attr) \
2305static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002306lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2307 char *buf) \
dea31012005-04-17 16:05:31 -05002308{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002309 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002310 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2311 struct lpfc_hba *phba = vport->phba;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002312 return scnprintf(buf, PAGE_SIZE, "%d\n",\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002313 phba->cfg_##attr);\
dea31012005-04-17 16:05:31 -05002314}
2315
Lee Jones9176ad22020-11-02 14:23:44 +00002316/*
James Smart3621a712009-04-06 18:47:14 -04002317 * lpfc_param_hex_show - Return a cfg attribute value in hex
James Smarte59058c2008-08-24 21:49:00 -04002318 *
2319 * Description:
2320 * Macro that given an attr e.g. hba_queue_depth expands
2321 * into a function with the name lpfc_hba_queue_depth_show
2322 *
2323 * lpfc_##attr##_show: Return the hex value of an adapters cfg_xxx field.
2324 * @dev: class device that is converted into a Scsi_host.
2325 * @attr: device attribute, not used.
James Smart3621a712009-04-06 18:47:14 -04002326 * @buf: on return contains the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002327 *
2328 * Returns: size of formatted string.
2329 **/
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002330#define lpfc_param_hex_show(attr) \
2331static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002332lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2333 char *buf) \
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002334{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002335 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002336 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2337 struct lpfc_hba *phba = vport->phba;\
James Smart84d1b002010-02-12 14:42:33 -05002338 uint val = 0;\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002339 val = phba->cfg_##attr;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002340 return scnprintf(buf, PAGE_SIZE, "%#x\n",\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002341 phba->cfg_##attr);\
2342}
2343
Lee Jones9176ad22020-11-02 14:23:44 +00002344/*
Uwe Kleine-Königb5950762010-11-01 15:38:34 -04002345 * lpfc_param_init - Initializes a cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002346 *
2347 * Description:
2348 * Macro that given an attr e.g. hba_queue_depth expands
2349 * into a function with the name lpfc_hba_queue_depth_init. The macro also
2350 * takes a default argument, a minimum and maximum argument.
2351 *
2352 * lpfc_##attr##_init: Initializes an attribute.
2353 * @phba: pointer the the adapter structure.
2354 * @val: integer attribute value.
2355 *
2356 * Validates the min and max values then sets the adapter config field
2357 * accordingly, or uses the default if out of range and prints an error message.
2358 *
2359 * Returns:
2360 * zero on success
2361 * -EINVAL if default used
2362 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002363#define lpfc_param_init(attr, default, minval, maxval) \
2364static int \
James Smart84d1b002010-02-12 14:42:33 -05002365lpfc_##attr##_init(struct lpfc_hba *phba, uint val) \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002366{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002367 if (lpfc_rangecheck(val, minval, maxval)) {\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002368 phba->cfg_##attr = val;\
2369 return 0;\
2370 }\
2371 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
James Smarte8b62012007-08-02 11:10:09 -04002372 "0449 lpfc_"#attr" attribute cannot be set to %d, "\
2373 "allowed range is ["#minval", "#maxval"]\n", val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002374 phba->cfg_##attr = default;\
2375 return -EINVAL;\
2376}
2377
Lee Jones9176ad22020-11-02 14:23:44 +00002378/*
James Smart3621a712009-04-06 18:47:14 -04002379 * lpfc_param_set - Set a cfg attribute value
James Smarte59058c2008-08-24 21:49:00 -04002380 *
2381 * Description:
2382 * Macro that given an attr e.g. hba_queue_depth expands
2383 * into a function with the name lpfc_hba_queue_depth_set
2384 *
2385 * lpfc_##attr##_set: Sets an attribute value.
2386 * @phba: pointer the the adapter structure.
2387 * @val: integer attribute value.
2388 *
2389 * Description:
2390 * Validates the min and max values then sets the
2391 * adapter config field if in the valid range. prints error message
2392 * and does not set the parameter if invalid.
2393 *
2394 * Returns:
2395 * zero on success
2396 * -EINVAL if val is invalid
2397 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002398#define lpfc_param_set(attr, default, minval, maxval) \
2399static int \
James Smart84d1b002010-02-12 14:42:33 -05002400lpfc_##attr##_set(struct lpfc_hba *phba, uint val) \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002401{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002402 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart88a2cfb2011-07-22 18:36:33 -04002403 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
2404 "3052 lpfc_" #attr " changed from %d to %d\n", \
2405 phba->cfg_##attr, val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002406 phba->cfg_##attr = val;\
2407 return 0;\
2408 }\
2409 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
James Smarte8b62012007-08-02 11:10:09 -04002410 "0450 lpfc_"#attr" attribute cannot be set to %d, "\
2411 "allowed range is ["#minval", "#maxval"]\n", val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002412 return -EINVAL;\
2413}
2414
Lee Jones9176ad22020-11-02 14:23:44 +00002415/*
James Smart3621a712009-04-06 18:47:14 -04002416 * lpfc_param_store - Set a vport attribute value
James Smarte59058c2008-08-24 21:49:00 -04002417 *
2418 * Description:
2419 * Macro that given an attr e.g. hba_queue_depth expands
2420 * into a function with the name lpfc_hba_queue_depth_store.
2421 *
2422 * lpfc_##attr##_store: Set an sttribute value.
2423 * @dev: class device that is converted into a Scsi_host.
2424 * @attr: device attribute, not used.
2425 * @buf: contains the attribute value in ascii.
2426 * @count: not used.
2427 *
2428 * Description:
2429 * Convert the ascii text number to an integer, then
2430 * use the lpfc_##attr##_set function to set the value.
2431 *
2432 * Returns:
2433 * -EINVAL if val is invalid or lpfc_##attr##_set() fails
2434 * length of buffer upon success.
2435 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002436#define lpfc_param_store(attr) \
dea31012005-04-17 16:05:31 -05002437static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002438lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
2439 const char *buf, size_t count) \
dea31012005-04-17 16:05:31 -05002440{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002441 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002442 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2443 struct lpfc_hba *phba = vport->phba;\
James Smart84d1b002010-02-12 14:42:33 -05002444 uint val = 0;\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002445 if (!isdigit(buf[0]))\
2446 return -EINVAL;\
2447 if (sscanf(buf, "%i", &val) != 1)\
2448 return -EINVAL;\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002449 if (lpfc_##attr##_set(phba, val) == 0) \
James.Smart@Emulex.Com755c0d02005-10-28 20:29:06 -04002450 return strlen(buf);\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002451 else \
2452 return -EINVAL;\
dea31012005-04-17 16:05:31 -05002453}
2454
Lee Jones9176ad22020-11-02 14:23:44 +00002455/*
James Smart3621a712009-04-06 18:47:14 -04002456 * lpfc_vport_param_show - Return decimal formatted cfg attribute value
James Smarte59058c2008-08-24 21:49:00 -04002457 *
2458 * Description:
2459 * Macro that given an attr e.g. hba_queue_depth expands
2460 * into a function with the name lpfc_hba_queue_depth_show
2461 *
2462 * lpfc_##attr##_show: prints the attribute value in decimal.
2463 * @dev: class device that is converted into a Scsi_host.
2464 * @attr: device attribute, not used.
2465 * @buf: on return contains the attribute value in decimal.
2466 *
2467 * Returns: length of formatted string.
2468 **/
James Smart3de2a652007-08-02 11:09:59 -04002469#define lpfc_vport_param_show(attr) \
2470static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002471lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2472 char *buf) \
James Smart3de2a652007-08-02 11:09:59 -04002473{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002474 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002475 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002476 return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\
James Smart3de2a652007-08-02 11:09:59 -04002477}
2478
Lee Jones9176ad22020-11-02 14:23:44 +00002479/*
James Smart3621a712009-04-06 18:47:14 -04002480 * lpfc_vport_param_hex_show - Return hex formatted attribute value
James Smarte59058c2008-08-24 21:49:00 -04002481 *
2482 * Description:
2483 * Macro that given an attr e.g.
2484 * hba_queue_depth expands into a function with the name
2485 * lpfc_hba_queue_depth_show
2486 *
James Smart3621a712009-04-06 18:47:14 -04002487 * lpfc_##attr##_show: prints the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002488 * @dev: class device that is converted into a Scsi_host.
2489 * @attr: device attribute, not used.
James Smart3621a712009-04-06 18:47:14 -04002490 * @buf: on return contains the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002491 *
2492 * Returns: length of formatted string.
2493 **/
James Smart3de2a652007-08-02 11:09:59 -04002494#define lpfc_vport_param_hex_show(attr) \
2495static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002496lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2497 char *buf) \
James Smart3de2a652007-08-02 11:09:59 -04002498{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002499 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002500 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002501 return scnprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\
James Smart3de2a652007-08-02 11:09:59 -04002502}
2503
Lee Jones9176ad22020-11-02 14:23:44 +00002504/*
James Smart3621a712009-04-06 18:47:14 -04002505 * lpfc_vport_param_init - Initialize a vport cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002506 *
2507 * Description:
2508 * Macro that given an attr e.g. hba_queue_depth expands
2509 * into a function with the name lpfc_hba_queue_depth_init. The macro also
2510 * takes a default argument, a minimum and maximum argument.
2511 *
2512 * lpfc_##attr##_init: validates the min and max values then sets the
2513 * adapter config field accordingly, or uses the default if out of range
2514 * and prints an error message.
2515 * @phba: pointer the the adapter structure.
2516 * @val: integer attribute value.
2517 *
2518 * Returns:
2519 * zero on success
2520 * -EINVAL if default used
2521 **/
James Smart3de2a652007-08-02 11:09:59 -04002522#define lpfc_vport_param_init(attr, default, minval, maxval) \
2523static int \
James Smart84d1b002010-02-12 14:42:33 -05002524lpfc_##attr##_init(struct lpfc_vport *vport, uint val) \
James Smart3de2a652007-08-02 11:09:59 -04002525{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002526 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart3de2a652007-08-02 11:09:59 -04002527 vport->cfg_##attr = val;\
2528 return 0;\
2529 }\
James Smarte8b62012007-08-02 11:10:09 -04002530 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smartd7c255b2008-08-24 21:50:00 -04002531 "0423 lpfc_"#attr" attribute cannot be set to %d, "\
James Smarte8b62012007-08-02 11:10:09 -04002532 "allowed range is ["#minval", "#maxval"]\n", val); \
James Smart3de2a652007-08-02 11:09:59 -04002533 vport->cfg_##attr = default;\
2534 return -EINVAL;\
2535}
2536
Lee Jones9176ad22020-11-02 14:23:44 +00002537/*
James Smart3621a712009-04-06 18:47:14 -04002538 * lpfc_vport_param_set - Set a vport cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002539 *
2540 * Description:
2541 * Macro that given an attr e.g. hba_queue_depth expands
2542 * into a function with the name lpfc_hba_queue_depth_set
2543 *
2544 * lpfc_##attr##_set: validates the min and max values then sets the
2545 * adapter config field if in the valid range. prints error message
2546 * and does not set the parameter if invalid.
2547 * @phba: pointer the the adapter structure.
2548 * @val: integer attribute value.
2549 *
2550 * Returns:
2551 * zero on success
2552 * -EINVAL if val is invalid
2553 **/
James Smart3de2a652007-08-02 11:09:59 -04002554#define lpfc_vport_param_set(attr, default, minval, maxval) \
2555static int \
James Smart84d1b002010-02-12 14:42:33 -05002556lpfc_##attr##_set(struct lpfc_vport *vport, uint val) \
James Smart3de2a652007-08-02 11:09:59 -04002557{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002558 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart88a2cfb2011-07-22 18:36:33 -04002559 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smart14660f42013-09-06 12:20:20 -04002560 "3053 lpfc_" #attr \
2561 " changed from %d (x%x) to %d (x%x)\n", \
2562 vport->cfg_##attr, vport->cfg_##attr, \
2563 val, val); \
James Smart3de2a652007-08-02 11:09:59 -04002564 vport->cfg_##attr = val;\
2565 return 0;\
2566 }\
James Smarte8b62012007-08-02 11:10:09 -04002567 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smartd7c255b2008-08-24 21:50:00 -04002568 "0424 lpfc_"#attr" attribute cannot be set to %d, "\
James Smarte8b62012007-08-02 11:10:09 -04002569 "allowed range is ["#minval", "#maxval"]\n", val); \
James Smart3de2a652007-08-02 11:09:59 -04002570 return -EINVAL;\
2571}
2572
Lee Jones9176ad22020-11-02 14:23:44 +00002573/*
James Smart3621a712009-04-06 18:47:14 -04002574 * lpfc_vport_param_store - Set a vport attribute
James Smarte59058c2008-08-24 21:49:00 -04002575 *
2576 * Description:
2577 * Macro that given an attr e.g. hba_queue_depth
2578 * expands into a function with the name lpfc_hba_queue_depth_store
2579 *
2580 * lpfc_##attr##_store: convert the ascii text number to an integer, then
2581 * use the lpfc_##attr##_set function to set the value.
2582 * @cdev: class device that is converted into a Scsi_host.
2583 * @buf: contains the attribute value in decimal.
2584 * @count: not used.
2585 *
2586 * Returns:
2587 * -EINVAL if val is invalid or lpfc_##attr##_set() fails
2588 * length of buffer upon success.
2589 **/
James Smart3de2a652007-08-02 11:09:59 -04002590#define lpfc_vport_param_store(attr) \
2591static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002592lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
2593 const char *buf, size_t count) \
James Smart3de2a652007-08-02 11:09:59 -04002594{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002595 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002596 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
James Smart84d1b002010-02-12 14:42:33 -05002597 uint val = 0;\
James Smart3de2a652007-08-02 11:09:59 -04002598 if (!isdigit(buf[0]))\
2599 return -EINVAL;\
2600 if (sscanf(buf, "%i", &val) != 1)\
2601 return -EINVAL;\
2602 if (lpfc_##attr##_set(vport, val) == 0) \
2603 return strlen(buf);\
2604 else \
2605 return -EINVAL;\
2606}
2607
2608
James Smart895427b2017-02-12 13:52:30 -08002609static DEVICE_ATTR(nvme_info, 0444, lpfc_nvme_info_show, NULL);
James Smart4c47efc2019-01-28 11:14:25 -08002610static DEVICE_ATTR(scsi_stat, 0444, lpfc_scsi_stat_show, NULL);
James Smart81301a92008-12-04 22:39:46 -05002611static DEVICE_ATTR(bg_info, S_IRUGO, lpfc_bg_info_show, NULL);
2612static DEVICE_ATTR(bg_guard_err, S_IRUGO, lpfc_bg_guard_err_show, NULL);
2613static DEVICE_ATTR(bg_apptag_err, S_IRUGO, lpfc_bg_apptag_err_show, NULL);
2614static DEVICE_ATTR(bg_reftag_err, S_IRUGO, lpfc_bg_reftag_err_show, NULL);
Tony Jonesee959b02008-02-22 00:13:36 +01002615static DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
2616static DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
2617static DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
2618static DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL);
2619static DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);
2620static DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL);
2621static DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);
2622static DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);
James Smart84d1b002010-02-12 14:42:33 -05002623static DEVICE_ATTR(link_state, S_IRUGO | S_IWUSR, lpfc_link_state_show,
2624 lpfc_link_state_store);
Tony Jonesee959b02008-02-22 00:13:36 +01002625static DEVICE_ATTR(option_rom_version, S_IRUGO,
2626 lpfc_option_rom_version_show, NULL);
2627static DEVICE_ATTR(num_discovered_ports, S_IRUGO,
2628 lpfc_num_discovered_ports_show, NULL);
James Smart84774a42008-08-24 21:50:06 -04002629static DEVICE_ATTR(menlo_mgmt_mode, S_IRUGO, lpfc_mlomgmt_show, NULL);
Tony Jonesee959b02008-02-22 00:13:36 +01002630static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
Joe Perchesc828a892017-12-19 10:15:08 -08002631static DEVICE_ATTR_RO(lpfc_drvr_version);
2632static DEVICE_ATTR_RO(lpfc_enable_fip);
Tony Jonesee959b02008-02-22 00:13:36 +01002633static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
2634 lpfc_board_mode_show, lpfc_board_mode_store);
2635static DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
2636static DEVICE_ATTR(max_vpi, S_IRUGO, lpfc_max_vpi_show, NULL);
2637static DEVICE_ATTR(used_vpi, S_IRUGO, lpfc_used_vpi_show, NULL);
2638static DEVICE_ATTR(max_rpi, S_IRUGO, lpfc_max_rpi_show, NULL);
2639static DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL);
2640static DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL);
2641static DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL);
2642static DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL);
Joe Perchesc828a892017-12-19 10:15:08 -08002643static DEVICE_ATTR_RO(lpfc_temp_sensor);
Joe Perchesc828a892017-12-19 10:15:08 -08002644static DEVICE_ATTR_RO(lpfc_sriov_hw_max_virtfn);
James Smart026abb82011-12-13 13:20:45 -05002645static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL);
James Smart1ba981f2014-02-20 09:56:45 -05002646static DEVICE_ATTR(lpfc_xlane_supported, S_IRUGO, lpfc_oas_supported_show,
2647 NULL);
James Smartc3f28af2006-08-18 17:47:18 -04002648
James Smart352e5fd2016-12-30 06:57:47 -08002649static char *lpfc_soft_wwn_key = "C99G71SL8032A";
James Smart1ba981f2014-02-20 09:56:45 -05002650#define WWN_SZ 8
2651/**
2652 * lpfc_wwn_set - Convert string to the 8 byte WWN value.
2653 * @buf: WWN string.
2654 * @cnt: Length of string.
2655 * @wwn: Array to receive converted wwn value.
2656 *
2657 * Returns:
2658 * -EINVAL if the buffer does not contain a valid wwn
2659 * 0 success
2660 **/
2661static size_t
2662lpfc_wwn_set(const char *buf, size_t cnt, char wwn[])
2663{
2664 unsigned int i, j;
James Smartc3f28af2006-08-18 17:47:18 -04002665
James Smart1ba981f2014-02-20 09:56:45 -05002666 /* Count may include a LF at end of string */
2667 if (buf[cnt-1] == '\n')
2668 cnt--;
2669
2670 if ((cnt < 16) || (cnt > 18) || ((cnt == 17) && (*buf++ != 'x')) ||
2671 ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
2672 return -EINVAL;
2673
2674 memset(wwn, 0, WWN_SZ);
2675
2676 /* Validate and store the new name */
2677 for (i = 0, j = 0; i < 16; i++) {
2678 if ((*buf >= 'a') && (*buf <= 'f'))
2679 j = ((j << 4) | ((*buf++ - 'a') + 10));
2680 else if ((*buf >= 'A') && (*buf <= 'F'))
2681 j = ((j << 4) | ((*buf++ - 'A') + 10));
2682 else if ((*buf >= '0') && (*buf <= '9'))
2683 j = ((j << 4) | (*buf++ - '0'));
2684 else
2685 return -EINVAL;
2686 if (i % 2) {
2687 wwn[i/2] = j & 0xff;
2688 j = 0;
2689 }
2690 }
2691 return 0;
2692}
James Smart352e5fd2016-12-30 06:57:47 -08002693/**
2694 * lpfc_soft_wwn_enable_store - Allows setting of the wwn if the key is valid
2695 * @dev: class device that is converted into a Scsi_host.
2696 * @attr: device attribute, not used.
2697 * @buf: containing the string lpfc_soft_wwn_key.
2698 * @count: must be size of lpfc_soft_wwn_key.
2699 *
2700 * Returns:
2701 * -EINVAL if the buffer does not contain lpfc_soft_wwn_key
2702 * length of buf indicates success
2703 **/
2704static ssize_t
2705lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr,
2706 const char *buf, size_t count)
2707{
2708 struct Scsi_Host *shost = class_to_shost(dev);
2709 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2710 struct lpfc_hba *phba = vport->phba;
2711 unsigned int cnt = count;
James Smartaeb3c812017-04-21 16:05:02 -07002712 uint8_t vvvl = vport->fc_sparam.cmn.valid_vendor_ver_level;
2713 u32 *fawwpn_key = (uint32_t *)&vport->fc_sparam.un.vendorVersion[0];
James Smart352e5fd2016-12-30 06:57:47 -08002714
2715 /*
2716 * We're doing a simple sanity check for soft_wwpn setting.
2717 * We require that the user write a specific key to enable
2718 * the soft_wwpn attribute to be settable. Once the attribute
2719 * is written, the enable key resets. If further updates are
2720 * desired, the key must be written again to re-enable the
2721 * attribute.
2722 *
2723 * The "key" is not secret - it is a hardcoded string shown
2724 * here. The intent is to protect against the random user or
2725 * application that is just writing attributes.
2726 */
James Smartaeb3c812017-04-21 16:05:02 -07002727 if (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR) {
2728 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2729 "0051 "LPFC_DRIVER_NAME" soft wwpn can not"
2730 " be enabled: fawwpn is enabled\n");
2731 return -EINVAL;
2732 }
James Smart352e5fd2016-12-30 06:57:47 -08002733
2734 /* count may include a LF at end of string */
2735 if (buf[cnt-1] == '\n')
2736 cnt--;
2737
2738 if ((cnt != strlen(lpfc_soft_wwn_key)) ||
2739 (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0))
2740 return -EINVAL;
2741
2742 phba->soft_wwn_enable = 1;
2743
2744 dev_printk(KERN_WARNING, &phba->pcidev->dev,
2745 "lpfc%d: soft_wwpn assignment has been enabled.\n",
2746 phba->brd_no);
2747 dev_printk(KERN_WARNING, &phba->pcidev->dev,
2748 " The soft_wwpn feature is not supported by Broadcom.");
2749
2750 return count;
2751}
Joe Perches6cbaefb2017-12-19 10:15:09 -08002752static DEVICE_ATTR_WO(lpfc_soft_wwn_enable);
James Smart352e5fd2016-12-30 06:57:47 -08002753
2754/**
2755 * lpfc_soft_wwpn_show - Return the cfg soft ww port name of the adapter
2756 * @dev: class device that is converted into a Scsi_host.
2757 * @attr: device attribute, not used.
2758 * @buf: on return contains the wwpn in hexadecimal.
2759 *
2760 * Returns: size of formatted string.
2761 **/
2762static ssize_t
2763lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr,
2764 char *buf)
2765{
2766 struct Scsi_Host *shost = class_to_shost(dev);
2767 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2768 struct lpfc_hba *phba = vport->phba;
2769
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002770 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart352e5fd2016-12-30 06:57:47 -08002771 (unsigned long long)phba->cfg_soft_wwpn);
2772}
2773
2774/**
2775 * lpfc_soft_wwpn_store - Set the ww port name of the adapter
Lee Jonesa738bd92020-11-02 14:23:45 +00002776 * @dev: class device that is converted into a Scsi_host.
James Smart352e5fd2016-12-30 06:57:47 -08002777 * @attr: device attribute, not used.
2778 * @buf: contains the wwpn in hexadecimal.
2779 * @count: number of wwpn bytes in buf
2780 *
2781 * Returns:
2782 * -EACCES hba reset not enabled, adapter over temp
2783 * -EINVAL soft wwn not enabled, count is invalid, invalid wwpn byte invalid
2784 * -EIO error taking adapter offline or online
2785 * value of count on success
2786 **/
2787static ssize_t
2788lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr,
2789 const char *buf, size_t count)
2790{
2791 struct Scsi_Host *shost = class_to_shost(dev);
2792 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2793 struct lpfc_hba *phba = vport->phba;
2794 struct completion online_compl;
2795 int stat1 = 0, stat2 = 0;
2796 unsigned int cnt = count;
2797 u8 wwpn[WWN_SZ];
2798 int rc;
2799
2800 if (!phba->cfg_enable_hba_reset)
2801 return -EACCES;
2802 spin_lock_irq(&phba->hbalock);
2803 if (phba->over_temp_state == HBA_OVER_TEMP) {
2804 spin_unlock_irq(&phba->hbalock);
2805 return -EACCES;
2806 }
2807 spin_unlock_irq(&phba->hbalock);
2808 /* count may include a LF at end of string */
2809 if (buf[cnt-1] == '\n')
2810 cnt--;
2811
2812 if (!phba->soft_wwn_enable)
2813 return -EINVAL;
2814
2815 /* lock setting wwpn, wwnn down */
2816 phba->soft_wwn_enable = 0;
2817
2818 rc = lpfc_wwn_set(buf, cnt, wwpn);
James Smarte2934ed2017-01-17 12:31:56 -08002819 if (rc) {
James Smart352e5fd2016-12-30 06:57:47 -08002820 /* not able to set wwpn, unlock it */
2821 phba->soft_wwn_enable = 1;
2822 return rc;
2823 }
2824
2825 phba->cfg_soft_wwpn = wwn_to_u64(wwpn);
2826 fc_host_port_name(shost) = phba->cfg_soft_wwpn;
2827 if (phba->cfg_soft_wwnn)
2828 fc_host_node_name(shost) = phba->cfg_soft_wwnn;
2829
2830 dev_printk(KERN_NOTICE, &phba->pcidev->dev,
2831 "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no);
2832
2833 stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
2834 if (stat1)
2835 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2836 "0463 lpfc_soft_wwpn attribute set failed to "
2837 "reinit adapter - %d\n", stat1);
2838 init_completion(&online_compl);
2839 rc = lpfc_workq_post_event(phba, &stat2, &online_compl,
2840 LPFC_EVT_ONLINE);
2841 if (rc == 0)
2842 return -ENOMEM;
2843
2844 wait_for_completion(&online_compl);
2845 if (stat2)
2846 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2847 "0464 lpfc_soft_wwpn attribute set failed to "
2848 "reinit adapter - %d\n", stat2);
2849 return (stat1 || stat2) ? -EIO : count;
2850}
Joe Perchesb6b996b2017-12-19 10:15:07 -08002851static DEVICE_ATTR_RW(lpfc_soft_wwpn);
James Smart352e5fd2016-12-30 06:57:47 -08002852
2853/**
2854 * lpfc_soft_wwnn_show - Return the cfg soft ww node name for the adapter
2855 * @dev: class device that is converted into a Scsi_host.
2856 * @attr: device attribute, not used.
2857 * @buf: on return contains the wwnn in hexadecimal.
2858 *
2859 * Returns: size of formatted string.
2860 **/
2861static ssize_t
2862lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr,
2863 char *buf)
2864{
2865 struct Scsi_Host *shost = class_to_shost(dev);
2866 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002867 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart352e5fd2016-12-30 06:57:47 -08002868 (unsigned long long)phba->cfg_soft_wwnn);
2869}
2870
2871/**
2872 * lpfc_soft_wwnn_store - sets the ww node name of the adapter
Lee Jonesa738bd92020-11-02 14:23:45 +00002873 * @dev: class device that is converted into a Scsi_host.
2874 * @attr: device attribute, not used.
James Smart352e5fd2016-12-30 06:57:47 -08002875 * @buf: contains the ww node name in hexadecimal.
2876 * @count: number of wwnn bytes in buf.
2877 *
2878 * Returns:
2879 * -EINVAL soft wwn not enabled, count is invalid, invalid wwnn byte invalid
2880 * value of count on success
2881 **/
2882static ssize_t
2883lpfc_soft_wwnn_store(struct device *dev, struct device_attribute *attr,
2884 const char *buf, size_t count)
2885{
2886 struct Scsi_Host *shost = class_to_shost(dev);
2887 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2888 unsigned int cnt = count;
2889 u8 wwnn[WWN_SZ];
2890 int rc;
2891
2892 /* count may include a LF at end of string */
2893 if (buf[cnt-1] == '\n')
2894 cnt--;
2895
2896 if (!phba->soft_wwn_enable)
2897 return -EINVAL;
2898
2899 rc = lpfc_wwn_set(buf, cnt, wwnn);
James Smarte2934ed2017-01-17 12:31:56 -08002900 if (rc) {
James Smart352e5fd2016-12-30 06:57:47 -08002901 /* Allow wwnn to be set many times, as long as the enable
2902 * is set. However, once the wwpn is set, everything locks.
2903 */
2904 return rc;
2905 }
2906
2907 phba->cfg_soft_wwnn = wwn_to_u64(wwnn);
2908
2909 dev_printk(KERN_NOTICE, &phba->pcidev->dev,
2910 "lpfc%d: soft_wwnn set. Value will take effect upon "
2911 "setting of the soft_wwpn\n", phba->brd_no);
2912
2913 return count;
2914}
Joe Perchesb6b996b2017-12-19 10:15:07 -08002915static DEVICE_ATTR_RW(lpfc_soft_wwnn);
James Smarta12e07b2006-12-02 13:35:30 -05002916
James Smart1ba981f2014-02-20 09:56:45 -05002917/**
2918 * lpfc_oas_tgt_show - Return wwpn of target whose luns maybe enabled for
2919 * Optimized Access Storage (OAS) operations.
2920 * @dev: class device that is converted into a Scsi_host.
2921 * @attr: device attribute, not used.
2922 * @buf: buffer for passing information.
2923 *
2924 * Returns:
2925 * value of count
2926 **/
2927static ssize_t
2928lpfc_oas_tgt_show(struct device *dev, struct device_attribute *attr,
2929 char *buf)
2930{
2931 struct Scsi_Host *shost = class_to_shost(dev);
2932 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2933
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002934 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart1ba981f2014-02-20 09:56:45 -05002935 wwn_to_u64(phba->cfg_oas_tgt_wwpn));
2936}
2937
2938/**
2939 * lpfc_oas_tgt_store - Store wwpn of target whose luns maybe enabled for
2940 * Optimized Access Storage (OAS) operations.
2941 * @dev: class device that is converted into a Scsi_host.
2942 * @attr: device attribute, not used.
2943 * @buf: buffer for passing information.
2944 * @count: Size of the data buffer.
2945 *
2946 * Returns:
2947 * -EINVAL count is invalid, invalid wwpn byte invalid
2948 * -EPERM oas is not supported by hba
2949 * value of count on success
2950 **/
2951static ssize_t
2952lpfc_oas_tgt_store(struct device *dev, struct device_attribute *attr,
2953 const char *buf, size_t count)
2954{
2955 struct Scsi_Host *shost = class_to_shost(dev);
2956 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2957 unsigned int cnt = count;
2958 uint8_t wwpn[WWN_SZ];
2959 int rc;
2960
James Smartf38fa0b2014-04-04 13:52:21 -04002961 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05002962 return -EPERM;
2963
2964 /* count may include a LF at end of string */
2965 if (buf[cnt-1] == '\n')
2966 cnt--;
2967
2968 rc = lpfc_wwn_set(buf, cnt, wwpn);
2969 if (rc)
2970 return rc;
2971
2972 memcpy(phba->cfg_oas_tgt_wwpn, wwpn, (8 * sizeof(uint8_t)));
2973 memcpy(phba->sli4_hba.oas_next_tgt_wwpn, wwpn, (8 * sizeof(uint8_t)));
2974 if (wwn_to_u64(wwpn) == 0)
2975 phba->cfg_oas_flags |= OAS_FIND_ANY_TARGET;
2976 else
2977 phba->cfg_oas_flags &= ~OAS_FIND_ANY_TARGET;
2978 phba->cfg_oas_flags &= ~OAS_LUN_VALID;
2979 phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
2980 return count;
2981}
2982static DEVICE_ATTR(lpfc_xlane_tgt, S_IRUGO | S_IWUSR,
2983 lpfc_oas_tgt_show, lpfc_oas_tgt_store);
2984
2985/**
James Smartc92c8412016-07-06 12:36:05 -07002986 * lpfc_oas_priority_show - Return wwpn of target whose luns maybe enabled for
2987 * Optimized Access Storage (OAS) operations.
2988 * @dev: class device that is converted into a Scsi_host.
2989 * @attr: device attribute, not used.
2990 * @buf: buffer for passing information.
2991 *
2992 * Returns:
2993 * value of count
2994 **/
2995static ssize_t
2996lpfc_oas_priority_show(struct device *dev, struct device_attribute *attr,
2997 char *buf)
2998{
2999 struct Scsi_Host *shost = class_to_shost(dev);
3000 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3001
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003002 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_priority);
James Smartc92c8412016-07-06 12:36:05 -07003003}
3004
3005/**
3006 * lpfc_oas_priority_store - Store wwpn of target whose luns maybe enabled for
3007 * Optimized Access Storage (OAS) operations.
3008 * @dev: class device that is converted into a Scsi_host.
3009 * @attr: device attribute, not used.
3010 * @buf: buffer for passing information.
3011 * @count: Size of the data buffer.
3012 *
3013 * Returns:
3014 * -EINVAL count is invalid, invalid wwpn byte invalid
3015 * -EPERM oas is not supported by hba
3016 * value of count on success
3017 **/
3018static ssize_t
3019lpfc_oas_priority_store(struct device *dev, struct device_attribute *attr,
3020 const char *buf, size_t count)
3021{
3022 struct Scsi_Host *shost = class_to_shost(dev);
3023 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3024 unsigned int cnt = count;
3025 unsigned long val;
3026 int ret;
3027
3028 if (!phba->cfg_fof)
3029 return -EPERM;
3030
3031 /* count may include a LF at end of string */
3032 if (buf[cnt-1] == '\n')
3033 cnt--;
3034
3035 ret = kstrtoul(buf, 0, &val);
3036 if (ret || (val > 0x7f))
3037 return -EINVAL;
3038
3039 if (val)
3040 phba->cfg_oas_priority = (uint8_t)val;
3041 else
3042 phba->cfg_oas_priority = phba->cfg_XLanePriority;
3043 return count;
3044}
3045static DEVICE_ATTR(lpfc_xlane_priority, S_IRUGO | S_IWUSR,
3046 lpfc_oas_priority_show, lpfc_oas_priority_store);
3047
3048/**
James Smart1ba981f2014-02-20 09:56:45 -05003049 * lpfc_oas_vpt_show - Return wwpn of vport whose targets maybe enabled
3050 * for Optimized Access Storage (OAS) operations.
3051 * @dev: class device that is converted into a Scsi_host.
3052 * @attr: device attribute, not used.
3053 * @buf: buffer for passing information.
3054 *
3055 * Returns:
3056 * value of count on success
3057 **/
3058static ssize_t
3059lpfc_oas_vpt_show(struct device *dev, struct device_attribute *attr,
3060 char *buf)
3061{
3062 struct Scsi_Host *shost = class_to_shost(dev);
3063 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3064
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003065 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart1ba981f2014-02-20 09:56:45 -05003066 wwn_to_u64(phba->cfg_oas_vpt_wwpn));
3067}
3068
3069/**
3070 * lpfc_oas_vpt_store - Store wwpn of vport whose targets maybe enabled
3071 * for Optimized Access Storage (OAS) operations.
3072 * @dev: class device that is converted into a Scsi_host.
3073 * @attr: device attribute, not used.
3074 * @buf: buffer for passing information.
3075 * @count: Size of the data buffer.
3076 *
3077 * Returns:
3078 * -EINVAL count is invalid, invalid wwpn byte invalid
3079 * -EPERM oas is not supported by hba
3080 * value of count on success
3081 **/
3082static ssize_t
3083lpfc_oas_vpt_store(struct device *dev, struct device_attribute *attr,
3084 const char *buf, size_t count)
3085{
3086 struct Scsi_Host *shost = class_to_shost(dev);
3087 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3088 unsigned int cnt = count;
3089 uint8_t wwpn[WWN_SZ];
3090 int rc;
3091
James Smartf38fa0b2014-04-04 13:52:21 -04003092 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003093 return -EPERM;
3094
3095 /* count may include a LF at end of string */
3096 if (buf[cnt-1] == '\n')
3097 cnt--;
3098
3099 rc = lpfc_wwn_set(buf, cnt, wwpn);
3100 if (rc)
3101 return rc;
3102
3103 memcpy(phba->cfg_oas_vpt_wwpn, wwpn, (8 * sizeof(uint8_t)));
3104 memcpy(phba->sli4_hba.oas_next_vpt_wwpn, wwpn, (8 * sizeof(uint8_t)));
3105 if (wwn_to_u64(wwpn) == 0)
3106 phba->cfg_oas_flags |= OAS_FIND_ANY_VPORT;
3107 else
3108 phba->cfg_oas_flags &= ~OAS_FIND_ANY_VPORT;
3109 phba->cfg_oas_flags &= ~OAS_LUN_VALID;
James Smartb5749fe2016-12-19 15:07:26 -08003110 if (phba->cfg_oas_priority == 0)
3111 phba->cfg_oas_priority = phba->cfg_XLanePriority;
James Smart1ba981f2014-02-20 09:56:45 -05003112 phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
3113 return count;
3114}
3115static DEVICE_ATTR(lpfc_xlane_vpt, S_IRUGO | S_IWUSR,
3116 lpfc_oas_vpt_show, lpfc_oas_vpt_store);
3117
3118/**
3119 * lpfc_oas_lun_state_show - Return the current state (enabled or disabled)
3120 * of whether luns will be enabled or disabled
3121 * for Optimized Access Storage (OAS) operations.
3122 * @dev: class device that is converted into a Scsi_host.
3123 * @attr: device attribute, not used.
3124 * @buf: buffer for passing information.
3125 *
3126 * Returns:
3127 * size of formatted string.
3128 **/
3129static ssize_t
3130lpfc_oas_lun_state_show(struct device *dev, struct device_attribute *attr,
3131 char *buf)
3132{
3133 struct Scsi_Host *shost = class_to_shost(dev);
3134 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3135
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003136 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_state);
James Smart1ba981f2014-02-20 09:56:45 -05003137}
3138
3139/**
3140 * lpfc_oas_lun_state_store - Store the state (enabled or disabled)
3141 * of whether luns will be enabled or disabled
3142 * for Optimized Access Storage (OAS) operations.
3143 * @dev: class device that is converted into a Scsi_host.
3144 * @attr: device attribute, not used.
3145 * @buf: buffer for passing information.
3146 * @count: Size of the data buffer.
3147 *
3148 * Returns:
3149 * -EINVAL count is invalid, invalid wwpn byte invalid
3150 * -EPERM oas is not supported by hba
3151 * value of count on success
3152 **/
3153static ssize_t
3154lpfc_oas_lun_state_store(struct device *dev, struct device_attribute *attr,
3155 const char *buf, size_t count)
3156{
3157 struct Scsi_Host *shost = class_to_shost(dev);
3158 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3159 int val = 0;
3160
James Smartf38fa0b2014-04-04 13:52:21 -04003161 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003162 return -EPERM;
3163
3164 if (!isdigit(buf[0]))
3165 return -EINVAL;
3166
3167 if (sscanf(buf, "%i", &val) != 1)
3168 return -EINVAL;
3169
3170 if ((val != 0) && (val != 1))
3171 return -EINVAL;
3172
3173 phba->cfg_oas_lun_state = val;
James Smart1ba981f2014-02-20 09:56:45 -05003174 return strlen(buf);
3175}
3176static DEVICE_ATTR(lpfc_xlane_lun_state, S_IRUGO | S_IWUSR,
3177 lpfc_oas_lun_state_show, lpfc_oas_lun_state_store);
3178
3179/**
3180 * lpfc_oas_lun_status_show - Return the status of the Optimized Access
3181 * Storage (OAS) lun returned by the
3182 * lpfc_oas_lun_show function.
3183 * @dev: class device that is converted into a Scsi_host.
3184 * @attr: device attribute, not used.
3185 * @buf: buffer for passing information.
3186 *
3187 * Returns:
3188 * size of formatted string.
3189 **/
3190static ssize_t
3191lpfc_oas_lun_status_show(struct device *dev, struct device_attribute *attr,
3192 char *buf)
3193{
3194 struct Scsi_Host *shost = class_to_shost(dev);
3195 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3196
3197 if (!(phba->cfg_oas_flags & OAS_LUN_VALID))
3198 return -EFAULT;
3199
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003200 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_status);
James Smart1ba981f2014-02-20 09:56:45 -05003201}
3202static DEVICE_ATTR(lpfc_xlane_lun_status, S_IRUGO,
3203 lpfc_oas_lun_status_show, NULL);
3204
3205
3206/**
3207 * lpfc_oas_lun_state_set - enable or disable a lun for Optimized Access Storage
3208 * (OAS) operations.
3209 * @phba: lpfc_hba pointer.
Lee Jonesa738bd92020-11-02 14:23:45 +00003210 * @vpt_wwpn: wwpn of the vport associated with the returned lun
3211 * @tgt_wwpn: wwpn of the target associated with the returned lun
James Smart1ba981f2014-02-20 09:56:45 -05003212 * @lun: the fc lun for setting oas state.
3213 * @oas_state: the oas state to be set to the lun.
Lee Jonesa738bd92020-11-02 14:23:45 +00003214 * @pri: priority
James Smart1ba981f2014-02-20 09:56:45 -05003215 *
3216 * Returns:
3217 * SUCCESS : 0
3218 * -EPERM OAS is not enabled or not supported by this port.
3219 *
3220 */
3221static size_t
3222lpfc_oas_lun_state_set(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
James Smartc92c8412016-07-06 12:36:05 -07003223 uint8_t tgt_wwpn[], uint64_t lun,
3224 uint32_t oas_state, uint8_t pri)
James Smart1ba981f2014-02-20 09:56:45 -05003225{
3226
3227 int rc = 0;
3228
James Smartf38fa0b2014-04-04 13:52:21 -04003229 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003230 return -EPERM;
3231
3232 if (oas_state) {
3233 if (!lpfc_enable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
James Smartc92c8412016-07-06 12:36:05 -07003234 (struct lpfc_name *)tgt_wwpn,
3235 lun, pri))
James Smart1ba981f2014-02-20 09:56:45 -05003236 rc = -ENOMEM;
3237 } else {
3238 lpfc_disable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003239 (struct lpfc_name *)tgt_wwpn, lun, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003240 }
3241 return rc;
3242
3243}
3244
3245/**
3246 * lpfc_oas_lun_get_next - get the next lun that has been enabled for Optimized
3247 * Access Storage (OAS) operations.
3248 * @phba: lpfc_hba pointer.
3249 * @vpt_wwpn: wwpn of the vport associated with the returned lun
3250 * @tgt_wwpn: wwpn of the target associated with the returned lun
3251 * @lun_status: status of the lun returned lun
Lee Jonesa738bd92020-11-02 14:23:45 +00003252 * @lun_pri: priority of the lun returned lun
James Smart1ba981f2014-02-20 09:56:45 -05003253 *
3254 * Returns the first or next lun enabled for OAS operations for the vport/target
3255 * specified. If a lun is found, its vport wwpn, target wwpn and status is
3256 * returned. If the lun is not found, NOT_OAS_ENABLED_LUN is returned.
3257 *
3258 * Return:
3259 * lun that is OAS enabled for the vport/target
3260 * NOT_OAS_ENABLED_LUN when no oas enabled lun found.
3261 */
3262static uint64_t
3263lpfc_oas_lun_get_next(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
James Smartb5749fe2016-12-19 15:07:26 -08003264 uint8_t tgt_wwpn[], uint32_t *lun_status,
3265 uint32_t *lun_pri)
James Smart1ba981f2014-02-20 09:56:45 -05003266{
3267 uint64_t found_lun;
3268
3269 if (unlikely(!phba) || !vpt_wwpn || !tgt_wwpn)
3270 return NOT_OAS_ENABLED_LUN;
3271 if (lpfc_find_next_oas_lun(phba, (struct lpfc_name *)
3272 phba->sli4_hba.oas_next_vpt_wwpn,
3273 (struct lpfc_name *)
3274 phba->sli4_hba.oas_next_tgt_wwpn,
3275 &phba->sli4_hba.oas_next_lun,
3276 (struct lpfc_name *)vpt_wwpn,
3277 (struct lpfc_name *)tgt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003278 &found_lun, lun_status, lun_pri))
James Smart1ba981f2014-02-20 09:56:45 -05003279 return found_lun;
3280 else
3281 return NOT_OAS_ENABLED_LUN;
3282}
3283
3284/**
3285 * lpfc_oas_lun_state_change - enable/disable a lun for OAS operations
3286 * @phba: lpfc_hba pointer.
3287 * @vpt_wwpn: vport wwpn by reference.
3288 * @tgt_wwpn: target wwpn by reference.
3289 * @lun: the fc lun for setting oas state.
3290 * @oas_state: the oas state to be set to the oas_lun.
Lee Jonesa738bd92020-11-02 14:23:45 +00003291 * @pri: priority
James Smart1ba981f2014-02-20 09:56:45 -05003292 *
3293 * This routine enables (OAS_LUN_ENABLE) or disables (OAS_LUN_DISABLE)
3294 * a lun for OAS operations.
3295 *
3296 * Return:
3297 * SUCCESS: 0
3298 * -ENOMEM: failed to enable an lun for OAS operations
3299 * -EPERM: OAS is not enabled
3300 */
3301static ssize_t
3302lpfc_oas_lun_state_change(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
3303 uint8_t tgt_wwpn[], uint64_t lun,
James Smartc92c8412016-07-06 12:36:05 -07003304 uint32_t oas_state, uint8_t pri)
James Smart1ba981f2014-02-20 09:56:45 -05003305{
3306
3307 int rc;
3308
3309 rc = lpfc_oas_lun_state_set(phba, vpt_wwpn, tgt_wwpn, lun,
James Smartc92c8412016-07-06 12:36:05 -07003310 oas_state, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003311 return rc;
3312}
3313
3314/**
3315 * lpfc_oas_lun_show - Return oas enabled luns from a chosen target
3316 * @dev: class device that is converted into a Scsi_host.
3317 * @attr: device attribute, not used.
3318 * @buf: buffer for passing information.
3319 *
3320 * This routine returns a lun enabled for OAS each time the function
3321 * is called.
3322 *
3323 * Returns:
3324 * SUCCESS: size of formatted string.
3325 * -EFAULT: target or vport wwpn was not set properly.
3326 * -EPERM: oas is not enabled.
3327 **/
3328static ssize_t
3329lpfc_oas_lun_show(struct device *dev, struct device_attribute *attr,
3330 char *buf)
3331{
3332 struct Scsi_Host *shost = class_to_shost(dev);
3333 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3334
3335 uint64_t oas_lun;
3336 int len = 0;
3337
James Smartf38fa0b2014-04-04 13:52:21 -04003338 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003339 return -EPERM;
3340
3341 if (wwn_to_u64(phba->cfg_oas_vpt_wwpn) == 0)
3342 if (!(phba->cfg_oas_flags & OAS_FIND_ANY_VPORT))
3343 return -EFAULT;
3344
3345 if (wwn_to_u64(phba->cfg_oas_tgt_wwpn) == 0)
3346 if (!(phba->cfg_oas_flags & OAS_FIND_ANY_TARGET))
3347 return -EFAULT;
3348
3349 oas_lun = lpfc_oas_lun_get_next(phba, phba->cfg_oas_vpt_wwpn,
3350 phba->cfg_oas_tgt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003351 &phba->cfg_oas_lun_status,
3352 &phba->cfg_oas_priority);
James Smart1ba981f2014-02-20 09:56:45 -05003353 if (oas_lun != NOT_OAS_ENABLED_LUN)
3354 phba->cfg_oas_flags |= OAS_LUN_VALID;
3355
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003356 len += scnprintf(buf + len, PAGE_SIZE-len, "0x%llx", oas_lun);
James Smart1ba981f2014-02-20 09:56:45 -05003357
3358 return len;
3359}
3360
3361/**
3362 * lpfc_oas_lun_store - Sets the OAS state for lun
3363 * @dev: class device that is converted into a Scsi_host.
3364 * @attr: device attribute, not used.
3365 * @buf: buffer for passing information.
Lee Jonesa738bd92020-11-02 14:23:45 +00003366 * @count: size of the formatting string
James Smart1ba981f2014-02-20 09:56:45 -05003367 *
3368 * This function sets the OAS state for lun. Before this function is called,
3369 * the vport wwpn, target wwpn, and oas state need to be set.
3370 *
3371 * Returns:
3372 * SUCCESS: size of formatted string.
3373 * -EFAULT: target or vport wwpn was not set properly.
3374 * -EPERM: oas is not enabled.
3375 * size of formatted string.
3376 **/
3377static ssize_t
3378lpfc_oas_lun_store(struct device *dev, struct device_attribute *attr,
3379 const char *buf, size_t count)
3380{
3381 struct Scsi_Host *shost = class_to_shost(dev);
3382 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3383 uint64_t scsi_lun;
James Smartb5749fe2016-12-19 15:07:26 -08003384 uint32_t pri;
James Smart1ba981f2014-02-20 09:56:45 -05003385 ssize_t rc;
3386
James Smartf38fa0b2014-04-04 13:52:21 -04003387 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003388 return -EPERM;
3389
3390 if (wwn_to_u64(phba->cfg_oas_vpt_wwpn) == 0)
3391 return -EFAULT;
3392
3393 if (wwn_to_u64(phba->cfg_oas_tgt_wwpn) == 0)
3394 return -EFAULT;
3395
3396 if (!isdigit(buf[0]))
3397 return -EINVAL;
3398
3399 if (sscanf(buf, "0x%llx", &scsi_lun) != 1)
3400 return -EINVAL;
3401
James Smartb5749fe2016-12-19 15:07:26 -08003402 pri = phba->cfg_oas_priority;
3403 if (pri == 0)
3404 pri = phba->cfg_XLanePriority;
3405
James Smart1ba981f2014-02-20 09:56:45 -05003406 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
James Smartc92c8412016-07-06 12:36:05 -07003407 "3372 Try to set vport 0x%llx target 0x%llx lun:0x%llx "
3408 "priority 0x%x with oas state %d\n",
James Smart1ba981f2014-02-20 09:56:45 -05003409 wwn_to_u64(phba->cfg_oas_vpt_wwpn),
3410 wwn_to_u64(phba->cfg_oas_tgt_wwpn), scsi_lun,
James Smartb5749fe2016-12-19 15:07:26 -08003411 pri, phba->cfg_oas_lun_state);
James Smart1ba981f2014-02-20 09:56:45 -05003412
3413 rc = lpfc_oas_lun_state_change(phba, phba->cfg_oas_vpt_wwpn,
James Smartc92c8412016-07-06 12:36:05 -07003414 phba->cfg_oas_tgt_wwpn, scsi_lun,
James Smartb5749fe2016-12-19 15:07:26 -08003415 phba->cfg_oas_lun_state, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003416 if (rc)
3417 return rc;
3418
3419 return count;
3420}
3421static DEVICE_ATTR(lpfc_xlane_lun, S_IRUGO | S_IWUSR,
3422 lpfc_oas_lun_show, lpfc_oas_lun_store);
James Smartc3f28af2006-08-18 17:47:18 -04003423
James Smartf358dd02017-02-12 13:52:34 -08003424int lpfc_enable_nvmet_cnt;
3425unsigned long long lpfc_enable_nvmet[LPFC_NVMET_MAX_PORTS] = {
3426 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3427 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
3428module_param_array(lpfc_enable_nvmet, ullong, &lpfc_enable_nvmet_cnt, 0444);
3429MODULE_PARM_DESC(lpfc_enable_nvmet, "Enable HBA port(s) WWPN as a NVME Target");
3430
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05003431static int lpfc_poll = 0;
James Smartab56dc22011-02-16 12:39:57 -05003432module_param(lpfc_poll, int, S_IRUGO);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05003433MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
3434 " 0 - none,"
3435 " 1 - poll with interrupts enabled"
3436 " 3 - poll and disable FCP ring interrupts");
3437
Joe Perchesb6b996b2017-12-19 10:15:07 -08003438static DEVICE_ATTR_RW(lpfc_poll);
dea31012005-04-17 16:05:31 -05003439
James Smart96418b52017-03-04 09:30:31 -08003440int lpfc_no_hba_reset_cnt;
3441unsigned long lpfc_no_hba_reset[MAX_HBAS_NO_RESET] = {
3442 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
3443module_param_array(lpfc_no_hba_reset, ulong, &lpfc_no_hba_reset_cnt, 0444);
3444MODULE_PARM_DESC(lpfc_no_hba_reset, "WWPN of HBAs that should not be reset");
3445
James Smartd2f25472021-01-04 10:02:27 -08003446LPFC_ATTR(sli_mode, 3, 3, 3,
3447 "SLI mode selector: 3 - select SLI-3");
James Smart92d7f7b2007-06-17 19:56:38 -05003448
James Smart458c0832016-07-06 12:36:07 -07003449LPFC_ATTR_R(enable_npiv, 1, 0, 1,
3450 "Enable NPIV functionality");
James Smart92d7f7b2007-06-17 19:56:38 -05003451
James Smart7d791df2011-07-22 18:37:52 -04003452LPFC_ATTR_R(fcf_failover_policy, 1, 1, 2,
3453 "FCF Fast failover=1 Priority failover=2");
3454
James Smarte5771b42013-03-01 16:37:14 -05003455/*
3456# lpfc_enable_rrq: Track XRI/OXID reuse after IO failures
3457# 0x0 = disabled, XRI/OXID use not tracked.
3458# 0x1 = XRI/OXID reuse is timed with ratov, RRQ sent.
3459# 0x2 = XRI/OXID reuse is timed with ratov, No RRQ sent.
3460*/
James Smart31202b02016-10-13 15:06:08 -07003461LPFC_ATTR_R(enable_rrq, 2, 0, 2,
3462 "Enable RRQ functionality");
James Smart19ca7602010-11-20 23:11:55 -05003463
dea31012005-04-17 16:05:31 -05003464/*
James Smart84d1b002010-02-12 14:42:33 -05003465# lpfc_suppress_link_up: Bring link up at initialization
3466# 0x0 = bring link up (issue MBX_INIT_LINK)
3467# 0x1 = do NOT bring link up at initialization(MBX_INIT_LINK)
3468# 0x2 = never bring up link
3469# Default value is 0.
3470*/
James Smarte40a02c2010-02-26 14:13:54 -05003471LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK,
3472 LPFC_DELAY_INIT_LINK_INDEFINITELY,
3473 "Suppress Link Up at initialization");
James Smart83c6cb12019-10-18 14:18:30 -07003474
3475static ssize_t
3476lpfc_pls_show(struct device *dev, struct device_attribute *attr, char *buf)
3477{
3478 struct Scsi_Host *shost = class_to_shost(dev);
3479 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3480
3481 return scnprintf(buf, PAGE_SIZE, "%d\n",
3482 phba->sli4_hba.pc_sli4_params.pls);
3483}
3484static DEVICE_ATTR(pls, 0444,
3485 lpfc_pls_show, NULL);
3486
3487static ssize_t
3488lpfc_pt_show(struct device *dev, struct device_attribute *attr, char *buf)
3489{
3490 struct Scsi_Host *shost = class_to_shost(dev);
3491 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3492
3493 return scnprintf(buf, PAGE_SIZE, "%d\n",
3494 (phba->hba_flag & HBA_PERSISTENT_TOPO) ? 1 : 0);
3495}
3496static DEVICE_ATTR(pt, 0444,
3497 lpfc_pt_show, NULL);
3498
James Smart2a9bf3d2010-06-07 15:24:45 -04003499/*
3500# lpfc_cnt: Number of IOCBs allocated for ELS, CT, and ABTS
3501# 1 - (1024)
3502# 2 - (2048)
3503# 3 - (3072)
3504# 4 - (4096)
3505# 5 - (5120)
3506*/
3507static ssize_t
3508lpfc_iocb_hw_show(struct device *dev, struct device_attribute *attr, char *buf)
3509{
3510 struct Scsi_Host *shost = class_to_shost(dev);
3511 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
3512
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003513 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->iocb_max);
James Smart2a9bf3d2010-06-07 15:24:45 -04003514}
3515
3516static DEVICE_ATTR(iocb_hw, S_IRUGO,
3517 lpfc_iocb_hw_show, NULL);
3518static ssize_t
3519lpfc_txq_hw_show(struct device *dev, struct device_attribute *attr, char *buf)
3520{
3521 struct Scsi_Host *shost = class_to_shost(dev);
3522 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
James Smart895427b2017-02-12 13:52:30 -08003523 struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
James Smart2a9bf3d2010-06-07 15:24:45 -04003524
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003525 return scnprintf(buf, PAGE_SIZE, "%d\n",
Dick Kennedy1234a6d2017-09-29 17:34:29 -07003526 pring ? pring->txq_max : 0);
James Smart2a9bf3d2010-06-07 15:24:45 -04003527}
3528
3529static DEVICE_ATTR(txq_hw, S_IRUGO,
3530 lpfc_txq_hw_show, NULL);
3531static ssize_t
3532lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr,
3533 char *buf)
3534{
3535 struct Scsi_Host *shost = class_to_shost(dev);
3536 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
James Smart895427b2017-02-12 13:52:30 -08003537 struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
James Smart2a9bf3d2010-06-07 15:24:45 -04003538
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003539 return scnprintf(buf, PAGE_SIZE, "%d\n",
Dick Kennedy1234a6d2017-09-29 17:34:29 -07003540 pring ? pring->txcmplq_max : 0);
James Smart2a9bf3d2010-06-07 15:24:45 -04003541}
3542
3543static DEVICE_ATTR(txcmplq_hw, S_IRUGO,
3544 lpfc_txcmplq_hw_show, NULL);
3545
James Smart84d1b002010-02-12 14:42:33 -05003546/*
James Smartc01f3202006-08-18 17:47:08 -04003547# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
3548# until the timer expires. Value range is [0,255]. Default value is 30.
3549*/
3550static int lpfc_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
3551static int lpfc_devloss_tmo = LPFC_DEF_DEVLOSS_TMO;
3552module_param(lpfc_nodev_tmo, int, 0);
3553MODULE_PARM_DESC(lpfc_nodev_tmo,
3554 "Seconds driver will hold I/O waiting "
3555 "for a device to come back");
James Smarte59058c2008-08-24 21:49:00 -04003556
3557/**
James Smart3621a712009-04-06 18:47:14 -04003558 * lpfc_nodev_tmo_show - Return the hba dev loss timeout value
James Smarte59058c2008-08-24 21:49:00 -04003559 * @dev: class converted to a Scsi_host structure.
3560 * @attr: device attribute, not used.
3561 * @buf: on return contains the dev loss timeout in decimal.
3562 *
3563 * Returns: size of formatted string.
3564 **/
James Smartc01f3202006-08-18 17:47:08 -04003565static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01003566lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr,
3567 char *buf)
James Smartc01f3202006-08-18 17:47:08 -04003568{
Tony Jonesee959b02008-02-22 00:13:36 +01003569 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05003570 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
James Smarte40a02c2010-02-26 14:13:54 -05003571
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003572 return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003573}
3574
James Smarte59058c2008-08-24 21:49:00 -04003575/**
James Smart3621a712009-04-06 18:47:14 -04003576 * lpfc_nodev_tmo_init - Set the hba nodev timeout value
James Smarte59058c2008-08-24 21:49:00 -04003577 * @vport: lpfc vport structure pointer.
3578 * @val: contains the nodev timeout value.
3579 *
3580 * Description:
3581 * If the devloss tmo is already set then nodev tmo is set to devloss tmo,
3582 * a kernel error message is printed and zero is returned.
3583 * Else if val is in range then nodev tmo and devloss tmo are set to val.
3584 * Otherwise nodev tmo is set to the default value.
3585 *
3586 * Returns:
3587 * zero if already set or if val is in range
3588 * -EINVAL val out of range
3589 **/
James Smartc01f3202006-08-18 17:47:08 -04003590static int
James Smart3de2a652007-08-02 11:09:59 -04003591lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003592{
James Smart3de2a652007-08-02 11:09:59 -04003593 if (vport->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) {
3594 vport->cfg_nodev_tmo = vport->cfg_devloss_tmo;
3595 if (val != LPFC_DEF_DEVLOSS_TMO)
James Smarte8b62012007-08-02 11:10:09 -04003596 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003597 "0407 Ignoring lpfc_nodev_tmo module "
3598 "parameter because lpfc_devloss_tmo "
3599 "is set.\n");
James Smartc01f3202006-08-18 17:47:08 -04003600 return 0;
3601 }
3602
3603 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003604 vport->cfg_nodev_tmo = val;
3605 vport->cfg_devloss_tmo = val;
James Smartc01f3202006-08-18 17:47:08 -04003606 return 0;
3607 }
James Smarte8b62012007-08-02 11:10:09 -04003608 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3609 "0400 lpfc_nodev_tmo attribute cannot be set to"
3610 " %d, allowed range is [%d, %d]\n",
3611 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smart3de2a652007-08-02 11:09:59 -04003612 vport->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
James Smartc01f3202006-08-18 17:47:08 -04003613 return -EINVAL;
3614}
3615
James Smarte59058c2008-08-24 21:49:00 -04003616/**
James Smart3621a712009-04-06 18:47:14 -04003617 * lpfc_update_rport_devloss_tmo - Update dev loss tmo value
James Smarte59058c2008-08-24 21:49:00 -04003618 * @vport: lpfc vport structure pointer.
3619 *
3620 * Description:
3621 * Update all the ndlp's dev loss tmo with the vport devloss tmo value.
3622 **/
James Smart7054a602007-04-25 09:52:34 -04003623static void
James Smart3de2a652007-08-02 11:09:59 -04003624lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
James Smart7054a602007-04-25 09:52:34 -04003625{
James Smart858c9f62007-06-17 19:56:39 -05003626 struct Scsi_Host *shost;
James Smart7054a602007-04-25 09:52:34 -04003627 struct lpfc_nodelist *ndlp;
James Smart01466022018-04-09 14:24:27 -07003628#if (IS_ENABLED(CONFIG_NVME_FC))
3629 struct lpfc_nvme_rport *rport;
James Smart9e210172018-09-13 15:41:10 -07003630 struct nvme_fc_remote_port *remoteport = NULL;
James Smart01466022018-04-09 14:24:27 -07003631#endif
James Smart7054a602007-04-25 09:52:34 -04003632
James Smart51ef4c22007-08-02 11:10:31 -04003633 shost = lpfc_shost_from_vport(vport);
3634 spin_lock_irq(shost->host_lock);
James Smart7a06dcd2017-06-01 21:06:55 -07003635 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart7a06dcd2017-06-01 21:06:55 -07003636 if (ndlp->rport)
James Smart51ef4c22007-08-02 11:10:31 -04003637 ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
James Smart6ddcf0a2017-11-03 09:33:30 -07003638#if (IS_ENABLED(CONFIG_NVME_FC))
James Smartc6adba12020-11-15 11:26:34 -08003639 spin_lock(&ndlp->lock);
James Smart01466022018-04-09 14:24:27 -07003640 rport = lpfc_ndlp_get_nrport(ndlp);
3641 if (rport)
James Smart9e210172018-09-13 15:41:10 -07003642 remoteport = rport->remoteport;
James Smartc6adba12020-11-15 11:26:34 -08003643 spin_unlock(&ndlp->lock);
James Smart07f50992019-08-14 16:56:45 -07003644 if (rport && remoteport)
3645 nvme_fc_set_remoteport_devloss(remoteport,
James Smart6ddcf0a2017-11-03 09:33:30 -07003646 vport->cfg_devloss_tmo);
3647#endif
James Smart7a06dcd2017-06-01 21:06:55 -07003648 }
James Smart51ef4c22007-08-02 11:10:31 -04003649 spin_unlock_irq(shost->host_lock);
James Smart7054a602007-04-25 09:52:34 -04003650}
3651
James Smarte59058c2008-08-24 21:49:00 -04003652/**
James Smart3621a712009-04-06 18:47:14 -04003653 * lpfc_nodev_tmo_set - Set the vport nodev tmo and devloss tmo values
James Smarte59058c2008-08-24 21:49:00 -04003654 * @vport: lpfc vport structure pointer.
3655 * @val: contains the tmo value.
3656 *
3657 * Description:
3658 * If the devloss tmo is already set or the vport dev loss tmo has changed
3659 * then a kernel error message is printed and zero is returned.
3660 * Else if val is in range then nodev tmo and devloss tmo are set to val.
3661 * Otherwise nodev tmo is set to the default value.
3662 *
3663 * Returns:
3664 * zero if already set or if val is in range
3665 * -EINVAL val out of range
3666 **/
James Smartc01f3202006-08-18 17:47:08 -04003667static int
James Smart3de2a652007-08-02 11:09:59 -04003668lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003669{
James Smart3de2a652007-08-02 11:09:59 -04003670 if (vport->dev_loss_tmo_changed ||
3671 (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
James Smarte8b62012007-08-02 11:10:09 -04003672 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003673 "0401 Ignoring change to lpfc_nodev_tmo "
3674 "because lpfc_devloss_tmo is set.\n");
James Smartc01f3202006-08-18 17:47:08 -04003675 return 0;
3676 }
James Smartc01f3202006-08-18 17:47:08 -04003677 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003678 vport->cfg_nodev_tmo = val;
3679 vport->cfg_devloss_tmo = val;
Mike Christie0af5d702010-09-15 16:52:31 -05003680 /*
3681 * For compat: set the fc_host dev loss so new rports
3682 * will get the value.
3683 */
3684 fc_host_dev_loss_tmo(lpfc_shost_from_vport(vport)) = val;
James Smart3de2a652007-08-02 11:09:59 -04003685 lpfc_update_rport_devloss_tmo(vport);
James Smartc01f3202006-08-18 17:47:08 -04003686 return 0;
3687 }
James Smarte8b62012007-08-02 11:10:09 -04003688 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003689 "0403 lpfc_nodev_tmo attribute cannot be set to "
James Smarte8b62012007-08-02 11:10:09 -04003690 "%d, allowed range is [%d, %d]\n",
3691 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smartc01f3202006-08-18 17:47:08 -04003692 return -EINVAL;
3693}
3694
James Smart3de2a652007-08-02 11:09:59 -04003695lpfc_vport_param_store(nodev_tmo)
James Smartc01f3202006-08-18 17:47:08 -04003696
Joe Perchesb6b996b2017-12-19 10:15:07 -08003697static DEVICE_ATTR_RW(lpfc_nodev_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003698
3699/*
3700# lpfc_devloss_tmo: If set, it will hold all I/O errors on devices that
3701# disappear until the timer expires. Value range is [0,255]. Default
3702# value is 30.
3703*/
James Smartab56dc22011-02-16 12:39:57 -05003704module_param(lpfc_devloss_tmo, int, S_IRUGO);
James Smartc01f3202006-08-18 17:47:08 -04003705MODULE_PARM_DESC(lpfc_devloss_tmo,
3706 "Seconds driver will hold I/O waiting "
3707 "for a device to come back");
James Smart3de2a652007-08-02 11:09:59 -04003708lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
3709 LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
3710lpfc_vport_param_show(devloss_tmo)
James Smarte59058c2008-08-24 21:49:00 -04003711
3712/**
James Smart3621a712009-04-06 18:47:14 -04003713 * lpfc_devloss_tmo_set - Sets vport nodev tmo, devloss tmo values, changed bit
James Smarte59058c2008-08-24 21:49:00 -04003714 * @vport: lpfc vport structure pointer.
3715 * @val: contains the tmo value.
3716 *
3717 * Description:
3718 * If val is in a valid range then set the vport nodev tmo,
3719 * devloss tmo, also set the vport dev loss tmo changed flag.
3720 * Else a kernel error message is printed.
3721 *
3722 * Returns:
3723 * zero if val is in range
3724 * -EINVAL val out of range
3725 **/
James Smartc01f3202006-08-18 17:47:08 -04003726static int
James Smart3de2a652007-08-02 11:09:59 -04003727lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003728{
3729 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003730 vport->cfg_nodev_tmo = val;
3731 vport->cfg_devloss_tmo = val;
3732 vport->dev_loss_tmo_changed = 1;
Mike Christie0af5d702010-09-15 16:52:31 -05003733 fc_host_dev_loss_tmo(lpfc_shost_from_vport(vport)) = val;
James Smart3de2a652007-08-02 11:09:59 -04003734 lpfc_update_rport_devloss_tmo(vport);
James Smartc01f3202006-08-18 17:47:08 -04003735 return 0;
3736 }
3737
James Smarte8b62012007-08-02 11:10:09 -04003738 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003739 "0404 lpfc_devloss_tmo attribute cannot be set to "
3740 "%d, allowed range is [%d, %d]\n",
James Smarte8b62012007-08-02 11:10:09 -04003741 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smartc01f3202006-08-18 17:47:08 -04003742 return -EINVAL;
3743}
3744
James Smart3de2a652007-08-02 11:09:59 -04003745lpfc_vport_param_store(devloss_tmo)
Joe Perchesb6b996b2017-12-19 10:15:07 -08003746static DEVICE_ATTR_RW(lpfc_devloss_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003747
3748/*
James Smartf358dd02017-02-12 13:52:34 -08003749 * lpfc_suppress_rsp: Enable suppress rsp feature is firmware supports it
3750 * lpfc_suppress_rsp = 0 Disable
3751 * lpfc_suppress_rsp = 1 Enable (default)
3752 *
3753 */
3754LPFC_ATTR_R(suppress_rsp, 1, 0, 1,
3755 "Enable suppress rsp feature is firmware supports it");
3756
3757/*
James Smart2d7dbc42017-02-12 13:52:35 -08003758 * lpfc_nvmet_mrq: Specify number of RQ pairs for processing NVMET cmds
James Smartbcb24f62017-11-20 16:00:36 -08003759 * lpfc_nvmet_mrq = 0 driver will calcualte optimal number of RQ pairs
James Smart2d7dbc42017-02-12 13:52:35 -08003760 * lpfc_nvmet_mrq = 1 use a single RQ pair
3761 * lpfc_nvmet_mrq >= 2 use specified RQ pairs for MRQ
3762 *
3763 */
3764LPFC_ATTR_R(nvmet_mrq,
James Smartbcb24f62017-11-20 16:00:36 -08003765 LPFC_NVMET_MRQ_AUTO, LPFC_NVMET_MRQ_AUTO, LPFC_NVMET_MRQ_MAX,
James Smart2d7dbc42017-02-12 13:52:35 -08003766 "Specify number of RQ pairs for processing NVMET cmds");
3767
3768/*
James Smart2448e482018-04-09 14:24:24 -07003769 * lpfc_nvmet_mrq_post: Specify number of RQ buffer to initially post
3770 * to each NVMET RQ. Range 64 to 2048, default is 512.
3771 */
3772LPFC_ATTR_R(nvmet_mrq_post,
3773 LPFC_NVMET_RQE_DEF_POST, LPFC_NVMET_RQE_MIN_POST,
3774 LPFC_NVMET_RQE_DEF_COUNT,
3775 "Specify number of RQ buffers to initially post");
3776
3777/*
James Smart895427b2017-02-12 13:52:30 -08003778 * lpfc_enable_fc4_type: Defines what FC4 types are supported.
3779 * Supported Values: 1 - register just FCP
3780 * 3 - register both FCP and NVME
James Smartb1684a02019-01-28 11:14:36 -08003781 * Supported values are [1,3]. Default value is 3
James Smart895427b2017-02-12 13:52:30 -08003782 */
James Smartb1684a02019-01-28 11:14:36 -08003783LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_BOTH,
James Smart895427b2017-02-12 13:52:30 -08003784 LPFC_ENABLE_FCP, LPFC_ENABLE_BOTH,
Dick Kennedycf4c8c82017-09-29 17:34:38 -07003785 "Enable FC4 Protocol support - FCP / NVME");
James Smart895427b2017-02-12 13:52:30 -08003786
3787/*
dea31012005-04-17 16:05:31 -05003788# lpfc_log_verbose: Only turn this flag on if you are willing to risk being
3789# deluged with LOTS of information.
3790# You can set a bit mask to record specific types of verbose messages:
James Smartf4b4c682009-05-22 14:53:12 -04003791# See lpfc_logmsh.h for definitions.
dea31012005-04-17 16:05:31 -05003792*/
James Smartf4b4c682009-05-22 14:53:12 -04003793LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffffffff,
James Smarte8b62012007-08-02 11:10:09 -04003794 "Verbose logging bit-mask");
dea31012005-04-17 16:05:31 -05003795
3796/*
James Smart7ee5d432007-10-27 13:37:17 -04003797# lpfc_enable_da_id: This turns on the DA_ID CT command that deregisters
3798# objects that have been registered with the nameserver after login.
3799*/
James Smartcf971242012-03-01 22:37:32 -05003800LPFC_VPORT_ATTR_R(enable_da_id, 1, 0, 1,
James Smart7ee5d432007-10-27 13:37:17 -04003801 "Deregister nameserver objects before LOGO");
3802
3803/*
dea31012005-04-17 16:05:31 -05003804# lun_queue_depth: This parameter is used to limit the number of outstanding
Dick Kennedy763a18c2020-03-23 09:19:35 -07003805# commands per FCP LUN.
dea31012005-04-17 16:05:31 -05003806*/
Dick Kennedy763a18c2020-03-23 09:19:35 -07003807LPFC_VPORT_ATTR_R(lun_queue_depth, 64, 1, 512,
James Smart3de2a652007-08-02 11:09:59 -04003808 "Max number of FCP commands we can queue to a specific LUN");
dea31012005-04-17 16:05:31 -05003809
3810/*
James Smart7dc517d2010-07-14 15:32:10 -04003811# tgt_queue_depth: This parameter is used to limit the number of outstanding
3812# commands per target port. Value range is [10,65535]. Default value is 65535.
3813*/
James Smartf91bc592018-04-09 14:24:22 -07003814static uint lpfc_tgt_queue_depth = LPFC_MAX_TGT_QDEPTH;
3815module_param(lpfc_tgt_queue_depth, uint, 0444);
3816MODULE_PARM_DESC(lpfc_tgt_queue_depth, "Set max Target queue depth");
3817lpfc_vport_param_show(tgt_queue_depth);
3818lpfc_vport_param_init(tgt_queue_depth, LPFC_MAX_TGT_QDEPTH,
3819 LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH);
3820
3821/**
3822 * lpfc_tgt_queue_depth_store: Sets an attribute value.
Lee Jonesa738bd92020-11-02 14:23:45 +00003823 * @vport: lpfc vport structure pointer.
James Smartf91bc592018-04-09 14:24:22 -07003824 * @val: integer attribute value.
3825 *
3826 * Description: Sets the parameter to the new value.
3827 *
3828 * Returns:
3829 * zero on success
3830 * -EINVAL if val is invalid
3831 */
3832static int
3833lpfc_tgt_queue_depth_set(struct lpfc_vport *vport, uint val)
3834{
3835 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3836 struct lpfc_nodelist *ndlp;
3837
3838 if (!lpfc_rangecheck(val, LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH))
3839 return -EINVAL;
3840
3841 if (val == vport->cfg_tgt_queue_depth)
3842 return 0;
3843
3844 spin_lock_irq(shost->host_lock);
3845 vport->cfg_tgt_queue_depth = val;
3846
3847 /* Next loop thru nodelist and change cmd_qdepth */
3848 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp)
3849 ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
3850
3851 spin_unlock_irq(shost->host_lock);
3852 return 0;
3853}
3854
3855lpfc_vport_param_store(tgt_queue_depth);
3856static DEVICE_ATTR_RW(lpfc_tgt_queue_depth);
James Smart7dc517d2010-07-14 15:32:10 -04003857
3858/*
Jamie Wellnitzb28485a2006-02-28 19:25:21 -05003859# hba_queue_depth: This parameter is used to limit the number of outstanding
3860# commands per lpfc HBA. Value range is [32,8192]. If this parameter
3861# value is greater than the maximum number of exchanges supported by the HBA,
3862# then maximum number of exchanges supported by the HBA is used to determine
3863# the hba_queue_depth.
3864*/
3865LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192,
3866 "Max number of FCP commands we can queue to a lpfc HBA");
3867
3868/*
James Smart92d7f7b2007-06-17 19:56:38 -05003869# peer_port_login: This parameter allows/prevents logins
3870# between peer ports hosted on the same physical port.
3871# When this parameter is set 0 peer ports of same physical port
3872# are not allowed to login to each other.
3873# When this parameter is set 1 peer ports of same physical port
3874# are allowed to login to each other.
3875# Default value of this parameter is 0.
3876*/
James Smart3de2a652007-08-02 11:09:59 -04003877LPFC_VPORT_ATTR_R(peer_port_login, 0, 0, 1,
3878 "Allow peer ports on the same physical port to login to each "
3879 "other.");
James Smart92d7f7b2007-06-17 19:56:38 -05003880
3881/*
James Smart3de2a652007-08-02 11:09:59 -04003882# restrict_login: This parameter allows/prevents logins
James Smart92d7f7b2007-06-17 19:56:38 -05003883# between Virtual Ports and remote initiators.
3884# When this parameter is not set (0) Virtual Ports will accept PLOGIs from
3885# other initiators and will attempt to PLOGI all remote ports.
3886# When this parameter is set (1) Virtual Ports will reject PLOGIs from
3887# remote ports and will not attempt to PLOGI to other initiators.
3888# This parameter does not restrict to the physical port.
3889# This parameter does not restrict logins to Fabric resident remote ports.
3890# Default value of this parameter is 1.
3891*/
James Smart3de2a652007-08-02 11:09:59 -04003892static int lpfc_restrict_login = 1;
James Smartab56dc22011-02-16 12:39:57 -05003893module_param(lpfc_restrict_login, int, S_IRUGO);
James Smart3de2a652007-08-02 11:09:59 -04003894MODULE_PARM_DESC(lpfc_restrict_login,
3895 "Restrict virtual ports login to remote initiators.");
3896lpfc_vport_param_show(restrict_login);
3897
James Smarte59058c2008-08-24 21:49:00 -04003898/**
James Smart3621a712009-04-06 18:47:14 -04003899 * lpfc_restrict_login_init - Set the vport restrict login flag
James Smarte59058c2008-08-24 21:49:00 -04003900 * @vport: lpfc vport structure pointer.
3901 * @val: contains the restrict login value.
3902 *
3903 * Description:
3904 * If val is not in a valid range then log a kernel error message and set
3905 * the vport restrict login to one.
3906 * If the port type is physical clear the restrict login flag and return.
3907 * Else set the restrict login flag to val.
3908 *
3909 * Returns:
3910 * zero if val is in range
3911 * -EINVAL val out of range
3912 **/
James Smart3de2a652007-08-02 11:09:59 -04003913static int
3914lpfc_restrict_login_init(struct lpfc_vport *vport, int val)
3915{
3916 if (val < 0 || val > 1) {
James Smarte8b62012007-08-02 11:10:09 -04003917 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartd7c255b2008-08-24 21:50:00 -04003918 "0422 lpfc_restrict_login attribute cannot "
James Smarte8b62012007-08-02 11:10:09 -04003919 "be set to %d, allowed range is [0, 1]\n",
3920 val);
James Smart3de2a652007-08-02 11:09:59 -04003921 vport->cfg_restrict_login = 1;
3922 return -EINVAL;
3923 }
3924 if (vport->port_type == LPFC_PHYSICAL_PORT) {
3925 vport->cfg_restrict_login = 0;
3926 return 0;
3927 }
3928 vport->cfg_restrict_login = val;
3929 return 0;
3930}
3931
James Smarte59058c2008-08-24 21:49:00 -04003932/**
James Smart3621a712009-04-06 18:47:14 -04003933 * lpfc_restrict_login_set - Set the vport restrict login flag
James Smarte59058c2008-08-24 21:49:00 -04003934 * @vport: lpfc vport structure pointer.
3935 * @val: contains the restrict login value.
3936 *
3937 * Description:
3938 * If val is not in a valid range then log a kernel error message and set
3939 * the vport restrict login to one.
3940 * If the port type is physical and the val is not zero log a kernel
3941 * error message, clear the restrict login flag and return zero.
3942 * Else set the restrict login flag to val.
3943 *
3944 * Returns:
3945 * zero if val is in range
3946 * -EINVAL val out of range
3947 **/
James Smart3de2a652007-08-02 11:09:59 -04003948static int
3949lpfc_restrict_login_set(struct lpfc_vport *vport, int val)
3950{
3951 if (val < 0 || val > 1) {
James Smarte8b62012007-08-02 11:10:09 -04003952 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartd7c255b2008-08-24 21:50:00 -04003953 "0425 lpfc_restrict_login attribute cannot "
James Smarte8b62012007-08-02 11:10:09 -04003954 "be set to %d, allowed range is [0, 1]\n",
3955 val);
James Smart3de2a652007-08-02 11:09:59 -04003956 vport->cfg_restrict_login = 1;
3957 return -EINVAL;
3958 }
3959 if (vport->port_type == LPFC_PHYSICAL_PORT && val != 0) {
James Smarte8b62012007-08-02 11:10:09 -04003960 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3961 "0468 lpfc_restrict_login must be 0 for "
3962 "Physical ports.\n");
James Smart3de2a652007-08-02 11:09:59 -04003963 vport->cfg_restrict_login = 0;
3964 return 0;
3965 }
3966 vport->cfg_restrict_login = val;
3967 return 0;
3968}
3969lpfc_vport_param_store(restrict_login);
Joe Perchesb6b996b2017-12-19 10:15:07 -08003970static DEVICE_ATTR_RW(lpfc_restrict_login);
James Smart92d7f7b2007-06-17 19:56:38 -05003971
3972/*
dea31012005-04-17 16:05:31 -05003973# Some disk devices have a "select ID" or "select Target" capability.
3974# From a protocol standpoint "select ID" usually means select the
3975# Fibre channel "ALPA". In the FC-AL Profile there is an "informative
3976# annex" which contains a table that maps a "select ID" (a number
3977# between 0 and 7F) to an ALPA. By default, for compatibility with
3978# older drivers, the lpfc driver scans this table from low ALPA to high
3979# ALPA.
3980#
3981# Turning on the scan-down variable (on = 1, off = 0) will
3982# cause the lpfc driver to use an inverted table, effectively
3983# scanning ALPAs from high to low. Value range is [0,1]. Default value is 1.
3984#
3985# (Note: This "select ID" functionality is a LOOP ONLY characteristic
3986# and will not work across a fabric. Also this parameter will take
3987# effect only in the case when ALPA map is not available.)
3988*/
James Smart3de2a652007-08-02 11:09:59 -04003989LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1,
3990 "Start scanning for devices from highest ALPA to lowest");
dea31012005-04-17 16:05:31 -05003991
3992/*
dea31012005-04-17 16:05:31 -05003993# lpfc_topology: link topology for init link
3994# 0x0 = attempt loop mode then point-to-point
Jamie Wellnitz367c2712006-02-28 19:25:32 -05003995# 0x01 = internal loopback mode
dea31012005-04-17 16:05:31 -05003996# 0x02 = attempt point-to-point mode only
3997# 0x04 = attempt loop mode only
3998# 0x06 = attempt point-to-point mode then loop
3999# Set point-to-point mode if you want to run as an N_Port.
4000# Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
4001# Default value is 0.
4002*/
James Smart0a035432016-10-13 15:06:10 -07004003LPFC_ATTR(topology, 0, 0, 6,
4004 "Select Fibre Channel topology");
James Smarte59058c2008-08-24 21:49:00 -04004005
4006/**
James Smart3621a712009-04-06 18:47:14 -04004007 * lpfc_topology_set - Set the adapters topology field
Lee Jonesa738bd92020-11-02 14:23:45 +00004008 * @dev: class device that is converted into a scsi_host.
4009 * @attr:device attribute, not used.
4010 * @buf: buffer for passing information.
4011 * @count: size of the data buffer.
James Smarte59058c2008-08-24 21:49:00 -04004012 *
4013 * Description:
4014 * If val is in a valid range then set the adapter's topology field and
4015 * issue a lip; if the lip fails reset the topology to the old value.
4016 *
4017 * If the value is not in range log a kernel error message and return an error.
4018 *
4019 * Returns:
4020 * zero if val is in range and lip okay
4021 * non-zero return value from lpfc_issue_lip()
4022 * -EINVAL val out of range
4023 **/
James Smarta257bf92009-04-06 18:48:10 -04004024static ssize_t
4025lpfc_topology_store(struct device *dev, struct device_attribute *attr,
4026 const char *buf, size_t count)
James Smart83108bd2008-01-11 01:53:09 -05004027{
James Smarta257bf92009-04-06 18:48:10 -04004028 struct Scsi_Host *shost = class_to_shost(dev);
4029 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4030 struct lpfc_hba *phba = vport->phba;
4031 int val = 0;
4032 int nolip = 0;
4033 const char *val_buf = buf;
James Smart83108bd2008-01-11 01:53:09 -05004034 int err;
4035 uint32_t prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004036
4037 if (!strncmp(buf, "nolip ", strlen("nolip "))) {
4038 nolip = 1;
4039 val_buf = &buf[strlen("nolip ")];
4040 }
4041
4042 if (!isdigit(val_buf[0]))
4043 return -EINVAL;
4044 if (sscanf(val_buf, "%i", &val) != 1)
4045 return -EINVAL;
4046
James Smart83108bd2008-01-11 01:53:09 -05004047 if (val >= 0 && val <= 6) {
4048 prev_val = phba->cfg_topology;
James Smartff78d8f2011-12-13 13:21:35 -05004049 if (phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G &&
4050 val == 4) {
4051 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4052 "3113 Loop mode not supported at speed %d\n",
James Smartd38dd522015-08-31 16:48:17 -04004053 val);
James Smartff78d8f2011-12-13 13:21:35 -05004054 return -EINVAL;
4055 }
James Smart83c6cb12019-10-18 14:18:30 -07004056 /*
4057 * The 'topology' is not a configurable parameter if :
4058 * - persistent topology enabled
James Smarta052ce82019-12-18 15:58:04 -08004059 * - G7/G6 with no private loop support
James Smart83c6cb12019-10-18 14:18:30 -07004060 */
4061
James Smarta052ce82019-12-18 15:58:04 -08004062 if ((phba->hba_flag & HBA_PERSISTENT_TOPO ||
James Smart83c6cb12019-10-18 14:18:30 -07004063 (!phba->sli4_hba.pc_sli4_params.pls &&
James Smarta052ce82019-12-18 15:58:04 -08004064 (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC ||
4065 phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC))) &&
James Smartf6978f42019-05-21 17:48:57 -07004066 val == 4) {
James Smartd38dd522015-08-31 16:48:17 -04004067 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartf6978f42019-05-21 17:48:57 -07004068 "3114 Loop mode not supported\n");
James Smartd38dd522015-08-31 16:48:17 -04004069 return -EINVAL;
4070 }
4071 phba->cfg_topology = val;
James Smarta257bf92009-04-06 18:48:10 -04004072 if (nolip)
4073 return strlen(buf);
4074
James Smart88a2cfb2011-07-22 18:36:33 -04004075 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4076 "3054 lpfc_topology changed from %d to %d\n",
4077 prev_val, val);
James Smarte74c03c2013-04-17 20:15:19 -04004078 if (prev_val != val && phba->sli_rev == LPFC_SLI_REV4)
4079 phba->fc_topology_changed = 1;
James Smart83108bd2008-01-11 01:53:09 -05004080 err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
James Smarta257bf92009-04-06 18:48:10 -04004081 if (err) {
James Smart83108bd2008-01-11 01:53:09 -05004082 phba->cfg_topology = prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004083 return -EINVAL;
4084 } else
4085 return strlen(buf);
James Smart83108bd2008-01-11 01:53:09 -05004086 }
4087 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4088 "%d:0467 lpfc_topology attribute cannot be set to %d, "
4089 "allowed range is [0, 6]\n",
4090 phba->brd_no, val);
4091 return -EINVAL;
4092}
James Smart0a035432016-10-13 15:06:10 -07004093
James Smart83108bd2008-01-11 01:53:09 -05004094lpfc_param_show(topology)
Joe Perchesb6b996b2017-12-19 10:15:07 -08004095static DEVICE_ATTR_RW(lpfc_topology);
dea31012005-04-17 16:05:31 -05004096
James Smart21e9a0a2009-05-22 14:53:21 -04004097/**
4098 * lpfc_static_vport_show: Read callback function for
4099 * lpfc_static_vport sysfs file.
4100 * @dev: Pointer to class device object.
4101 * @attr: device attribute structure.
4102 * @buf: Data buffer.
4103 *
4104 * This function is the read call back function for
4105 * lpfc_static_vport sysfs file. The lpfc_static_vport
4106 * sysfs file report the mageability of the vport.
4107 **/
4108static ssize_t
4109lpfc_static_vport_show(struct device *dev, struct device_attribute *attr,
4110 char *buf)
4111{
4112 struct Scsi_Host *shost = class_to_shost(dev);
4113 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4114 if (vport->vport_flag & STATIC_VPORT)
4115 sprintf(buf, "1\n");
4116 else
4117 sprintf(buf, "0\n");
4118
4119 return strlen(buf);
4120}
4121
4122/*
4123 * Sysfs attribute to control the statistical data collection.
4124 */
Joe Perchesc828a892017-12-19 10:15:08 -08004125static DEVICE_ATTR_RO(lpfc_static_vport);
James Smartea2151b2008-09-07 11:52:10 -04004126
4127/**
James Smart3621a712009-04-06 18:47:14 -04004128 * lpfc_stat_data_ctrl_store - write call back for lpfc_stat_data_ctrl sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004129 * @dev: Pointer to class device.
Lee Jonesa738bd92020-11-02 14:23:45 +00004130 * @attr: Unused.
James Smartea2151b2008-09-07 11:52:10 -04004131 * @buf: Data buffer.
4132 * @count: Size of the data buffer.
4133 *
Masahiro Yamada9332ef92017-02-27 14:28:47 -08004134 * This function get called when a user write to the lpfc_stat_data_ctrl
James Smartea2151b2008-09-07 11:52:10 -04004135 * sysfs file. This function parse the command written to the sysfs file
4136 * and take appropriate action. These commands are used for controlling
4137 * driver statistical data collection.
4138 * Following are the command this function handles.
4139 *
4140 * setbucket <bucket_type> <base> <step>
4141 * = Set the latency buckets.
4142 * destroybucket = destroy all the buckets.
4143 * start = start data collection
4144 * stop = stop data collection
4145 * reset = reset the collected data
4146 **/
4147static ssize_t
4148lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
4149 const char *buf, size_t count)
4150{
4151 struct Scsi_Host *shost = class_to_shost(dev);
4152 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4153 struct lpfc_hba *phba = vport->phba;
4154#define LPFC_MAX_DATA_CTRL_LEN 1024
4155 static char bucket_data[LPFC_MAX_DATA_CTRL_LEN];
4156 unsigned long i;
4157 char *str_ptr, *token;
4158 struct lpfc_vport **vports;
4159 struct Scsi_Host *v_shost;
4160 char *bucket_type_str, *base_str, *step_str;
4161 unsigned long base, step, bucket_type;
4162
4163 if (!strncmp(buf, "setbucket", strlen("setbucket"))) {
James Smarta257bf92009-04-06 18:48:10 -04004164 if (strlen(buf) > (LPFC_MAX_DATA_CTRL_LEN - 1))
James Smartea2151b2008-09-07 11:52:10 -04004165 return -EINVAL;
4166
James Smarteb016562014-09-03 12:58:06 -04004167 strncpy(bucket_data, buf, LPFC_MAX_DATA_CTRL_LEN);
James Smartea2151b2008-09-07 11:52:10 -04004168 str_ptr = &bucket_data[0];
4169 /* Ignore this token - this is command token */
4170 token = strsep(&str_ptr, "\t ");
4171 if (!token)
4172 return -EINVAL;
4173
4174 bucket_type_str = strsep(&str_ptr, "\t ");
4175 if (!bucket_type_str)
4176 return -EINVAL;
4177
4178 if (!strncmp(bucket_type_str, "linear", strlen("linear")))
4179 bucket_type = LPFC_LINEAR_BUCKET;
4180 else if (!strncmp(bucket_type_str, "power2", strlen("power2")))
4181 bucket_type = LPFC_POWER2_BUCKET;
4182 else
4183 return -EINVAL;
4184
4185 base_str = strsep(&str_ptr, "\t ");
4186 if (!base_str)
4187 return -EINVAL;
4188 base = simple_strtoul(base_str, NULL, 0);
4189
4190 step_str = strsep(&str_ptr, "\t ");
4191 if (!step_str)
4192 return -EINVAL;
4193 step = simple_strtoul(step_str, NULL, 0);
4194 if (!step)
4195 return -EINVAL;
4196
4197 /* Block the data collection for every vport */
4198 vports = lpfc_create_vport_work_array(phba);
4199 if (vports == NULL)
4200 return -ENOMEM;
4201
James Smartf4b4c682009-05-22 14:53:12 -04004202 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004203 v_shost = lpfc_shost_from_vport(vports[i]);
4204 spin_lock_irq(v_shost->host_lock);
4205 /* Block and reset data collection */
4206 vports[i]->stat_data_blocked = 1;
4207 if (vports[i]->stat_data_enabled)
4208 lpfc_vport_reset_stat_data(vports[i]);
4209 spin_unlock_irq(v_shost->host_lock);
4210 }
4211
4212 /* Set the bucket attributes */
4213 phba->bucket_type = bucket_type;
4214 phba->bucket_base = base;
4215 phba->bucket_step = step;
4216
James Smartf4b4c682009-05-22 14:53:12 -04004217 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004218 v_shost = lpfc_shost_from_vport(vports[i]);
4219
4220 /* Unblock data collection */
4221 spin_lock_irq(v_shost->host_lock);
4222 vports[i]->stat_data_blocked = 0;
4223 spin_unlock_irq(v_shost->host_lock);
4224 }
4225 lpfc_destroy_vport_work_array(phba, vports);
4226 return strlen(buf);
4227 }
4228
4229 if (!strncmp(buf, "destroybucket", strlen("destroybucket"))) {
4230 vports = lpfc_create_vport_work_array(phba);
4231 if (vports == NULL)
4232 return -ENOMEM;
4233
James Smartf4b4c682009-05-22 14:53:12 -04004234 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004235 v_shost = lpfc_shost_from_vport(vports[i]);
4236 spin_lock_irq(shost->host_lock);
4237 vports[i]->stat_data_blocked = 1;
4238 lpfc_free_bucket(vport);
4239 vport->stat_data_enabled = 0;
4240 vports[i]->stat_data_blocked = 0;
4241 spin_unlock_irq(shost->host_lock);
4242 }
4243 lpfc_destroy_vport_work_array(phba, vports);
4244 phba->bucket_type = LPFC_NO_BUCKET;
4245 phba->bucket_base = 0;
4246 phba->bucket_step = 0;
4247 return strlen(buf);
4248 }
4249
4250 if (!strncmp(buf, "start", strlen("start"))) {
4251 /* If no buckets configured return error */
4252 if (phba->bucket_type == LPFC_NO_BUCKET)
4253 return -EINVAL;
4254 spin_lock_irq(shost->host_lock);
4255 if (vport->stat_data_enabled) {
4256 spin_unlock_irq(shost->host_lock);
4257 return strlen(buf);
4258 }
4259 lpfc_alloc_bucket(vport);
4260 vport->stat_data_enabled = 1;
4261 spin_unlock_irq(shost->host_lock);
4262 return strlen(buf);
4263 }
4264
4265 if (!strncmp(buf, "stop", strlen("stop"))) {
4266 spin_lock_irq(shost->host_lock);
4267 if (vport->stat_data_enabled == 0) {
4268 spin_unlock_irq(shost->host_lock);
4269 return strlen(buf);
4270 }
4271 lpfc_free_bucket(vport);
4272 vport->stat_data_enabled = 0;
4273 spin_unlock_irq(shost->host_lock);
4274 return strlen(buf);
4275 }
4276
4277 if (!strncmp(buf, "reset", strlen("reset"))) {
4278 if ((phba->bucket_type == LPFC_NO_BUCKET)
4279 || !vport->stat_data_enabled)
4280 return strlen(buf);
4281 spin_lock_irq(shost->host_lock);
4282 vport->stat_data_blocked = 1;
4283 lpfc_vport_reset_stat_data(vport);
4284 vport->stat_data_blocked = 0;
4285 spin_unlock_irq(shost->host_lock);
4286 return strlen(buf);
4287 }
4288 return -EINVAL;
4289}
4290
4291
4292/**
James Smart3621a712009-04-06 18:47:14 -04004293 * lpfc_stat_data_ctrl_show - Read function for lpfc_stat_data_ctrl sysfs file
Lee Jonesa738bd92020-11-02 14:23:45 +00004294 * @dev: Pointer to class device.
4295 * @attr: Unused.
James Smartea2151b2008-09-07 11:52:10 -04004296 * @buf: Data buffer.
4297 *
4298 * This function is the read call back function for
4299 * lpfc_stat_data_ctrl sysfs file. This function report the
4300 * current statistical data collection state.
4301 **/
4302static ssize_t
4303lpfc_stat_data_ctrl_show(struct device *dev, struct device_attribute *attr,
4304 char *buf)
4305{
4306 struct Scsi_Host *shost = class_to_shost(dev);
4307 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4308 struct lpfc_hba *phba = vport->phba;
4309 int index = 0;
4310 int i;
4311 char *bucket_type;
4312 unsigned long bucket_value;
4313
4314 switch (phba->bucket_type) {
4315 case LPFC_LINEAR_BUCKET:
4316 bucket_type = "linear";
4317 break;
4318 case LPFC_POWER2_BUCKET:
4319 bucket_type = "power2";
4320 break;
4321 default:
4322 bucket_type = "No Bucket";
4323 break;
4324 }
4325
4326 sprintf(&buf[index], "Statistical Data enabled :%d, "
4327 "blocked :%d, Bucket type :%s, Bucket base :%d,"
4328 " Bucket step :%d\nLatency Ranges :",
4329 vport->stat_data_enabled, vport->stat_data_blocked,
4330 bucket_type, phba->bucket_base, phba->bucket_step);
4331 index = strlen(buf);
4332 if (phba->bucket_type != LPFC_NO_BUCKET) {
4333 for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
4334 if (phba->bucket_type == LPFC_LINEAR_BUCKET)
4335 bucket_value = phba->bucket_base +
4336 phba->bucket_step * i;
4337 else
4338 bucket_value = phba->bucket_base +
4339 (1 << i) * phba->bucket_step;
4340
4341 if (index + 10 > PAGE_SIZE)
4342 break;
4343 sprintf(&buf[index], "%08ld ", bucket_value);
4344 index = strlen(buf);
4345 }
4346 }
4347 sprintf(&buf[index], "\n");
4348 return strlen(buf);
4349}
4350
4351/*
4352 * Sysfs attribute to control the statistical data collection.
4353 */
Joe Perchesb6b996b2017-12-19 10:15:07 -08004354static DEVICE_ATTR_RW(lpfc_stat_data_ctrl);
James Smartea2151b2008-09-07 11:52:10 -04004355
4356/*
4357 * lpfc_drvr_stat_data: sysfs attr to get driver statistical data.
4358 */
4359
4360/*
4361 * Each Bucket takes 11 characters and 1 new line + 17 bytes WWN
4362 * for each target.
4363 */
4364#define STAT_DATA_SIZE_PER_TARGET(NUM_BUCKETS) ((NUM_BUCKETS) * 11 + 18)
4365#define MAX_STAT_DATA_SIZE_PER_TARGET \
4366 STAT_DATA_SIZE_PER_TARGET(LPFC_MAX_BUCKET_COUNT)
4367
4368
4369/**
James Smart3621a712009-04-06 18:47:14 -04004370 * sysfs_drvr_stat_data_read - Read function for lpfc_drvr_stat_data attribute
Chris Wright2c3c8be2010-05-12 18:28:57 -07004371 * @filp: sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004372 * @kobj: Pointer to the kernel object
4373 * @bin_attr: Attribute object
Lee Jonesa738bd92020-11-02 14:23:45 +00004374 * @buf: Buffer pointer
James Smartea2151b2008-09-07 11:52:10 -04004375 * @off: File offset
4376 * @count: Buffer size
4377 *
4378 * This function is the read call back function for lpfc_drvr_stat_data
4379 * sysfs file. This function export the statistical data to user
4380 * applications.
4381 **/
4382static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07004383sysfs_drvr_stat_data_read(struct file *filp, struct kobject *kobj,
4384 struct bin_attribute *bin_attr,
James Smartea2151b2008-09-07 11:52:10 -04004385 char *buf, loff_t off, size_t count)
4386{
4387 struct device *dev = container_of(kobj, struct device,
4388 kobj);
4389 struct Scsi_Host *shost = class_to_shost(dev);
4390 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4391 struct lpfc_hba *phba = vport->phba;
4392 int i = 0, index = 0;
4393 unsigned long nport_index;
4394 struct lpfc_nodelist *ndlp = NULL;
4395 nport_index = (unsigned long)off /
4396 MAX_STAT_DATA_SIZE_PER_TARGET;
4397
4398 if (!vport->stat_data_enabled || vport->stat_data_blocked
4399 || (phba->bucket_type == LPFC_NO_BUCKET))
4400 return 0;
4401
4402 spin_lock_irq(shost->host_lock);
4403 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart307e3382020-11-15 11:26:30 -08004404 if (!ndlp->lat_data)
James Smartea2151b2008-09-07 11:52:10 -04004405 continue;
4406
4407 if (nport_index > 0) {
4408 nport_index--;
4409 continue;
4410 }
4411
4412 if ((index + MAX_STAT_DATA_SIZE_PER_TARGET)
4413 > count)
4414 break;
4415
4416 if (!ndlp->lat_data)
4417 continue;
4418
4419 /* Print the WWN */
4420 sprintf(&buf[index], "%02x%02x%02x%02x%02x%02x%02x%02x:",
4421 ndlp->nlp_portname.u.wwn[0],
4422 ndlp->nlp_portname.u.wwn[1],
4423 ndlp->nlp_portname.u.wwn[2],
4424 ndlp->nlp_portname.u.wwn[3],
4425 ndlp->nlp_portname.u.wwn[4],
4426 ndlp->nlp_portname.u.wwn[5],
4427 ndlp->nlp_portname.u.wwn[6],
4428 ndlp->nlp_portname.u.wwn[7]);
4429
4430 index = strlen(buf);
4431
4432 for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
4433 sprintf(&buf[index], "%010u,",
4434 ndlp->lat_data[i].cmd_count);
4435 index = strlen(buf);
4436 }
4437 sprintf(&buf[index], "\n");
4438 index = strlen(buf);
4439 }
4440 spin_unlock_irq(shost->host_lock);
4441 return index;
4442}
4443
4444static struct bin_attribute sysfs_drvr_stat_data_attr = {
4445 .attr = {
4446 .name = "lpfc_drvr_stat_data",
4447 .mode = S_IRUSR,
James Smartea2151b2008-09-07 11:52:10 -04004448 },
4449 .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET,
4450 .read = sysfs_drvr_stat_data_read,
4451 .write = NULL,
4452};
4453
dea31012005-04-17 16:05:31 -05004454/*
4455# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
4456# connection.
James Smart76a95d72010-11-20 23:11:48 -05004457# Value range is [0,16]. Default value is 0.
dea31012005-04-17 16:05:31 -05004458*/
James Smarte59058c2008-08-24 21:49:00 -04004459/**
James Smart3621a712009-04-06 18:47:14 -04004460 * lpfc_link_speed_set - Set the adapters link speed
Lee Jonesa738bd92020-11-02 14:23:45 +00004461 * @dev: Pointer to class device.
4462 * @attr: Unused.
4463 * @buf: Data buffer.
4464 * @count: Size of the data buffer.
James Smarte59058c2008-08-24 21:49:00 -04004465 *
4466 * Description:
4467 * If val is in a valid range then set the adapter's link speed field and
4468 * issue a lip; if the lip fails reset the link speed to the old value.
4469 *
4470 * Notes:
4471 * If the value is not in range log a kernel error message and return an error.
4472 *
4473 * Returns:
4474 * zero if val is in range and lip okay.
4475 * non-zero return value from lpfc_issue_lip()
4476 * -EINVAL val out of range
4477 **/
James Smarta257bf92009-04-06 18:48:10 -04004478static ssize_t
4479lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
4480 const char *buf, size_t count)
James Smart83108bd2008-01-11 01:53:09 -05004481{
James Smarta257bf92009-04-06 18:48:10 -04004482 struct Scsi_Host *shost = class_to_shost(dev);
4483 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4484 struct lpfc_hba *phba = vport->phba;
James Smart76a95d72010-11-20 23:11:48 -05004485 int val = LPFC_USER_LINK_SPEED_AUTO;
James Smarta257bf92009-04-06 18:48:10 -04004486 int nolip = 0;
4487 const char *val_buf = buf;
James Smart83108bd2008-01-11 01:53:09 -05004488 int err;
James Smartc6918162016-10-13 15:06:16 -07004489 uint32_t prev_val, if_type;
4490
4491 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
James Smart719162b2018-12-10 19:37:01 -08004492 if (if_type >= LPFC_SLI_INTF_IF_TYPE_2 &&
James Smartc6918162016-10-13 15:06:16 -07004493 phba->hba_flag & HBA_FORCED_LINK_SPEED)
4494 return -EPERM;
James Smart83108bd2008-01-11 01:53:09 -05004495
James Smarta257bf92009-04-06 18:48:10 -04004496 if (!strncmp(buf, "nolip ", strlen("nolip "))) {
4497 nolip = 1;
4498 val_buf = &buf[strlen("nolip ")];
4499 }
4500
4501 if (!isdigit(val_buf[0]))
4502 return -EINVAL;
4503 if (sscanf(val_buf, "%i", &val) != 1)
4504 return -EINVAL;
4505
James Smart88a2cfb2011-07-22 18:36:33 -04004506 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4507 "3055 lpfc_link_speed changed from %d to %d %s\n",
4508 phba->cfg_link_speed, val, nolip ? "(nolip)" : "(lip)");
4509
James Smart76a95d72010-11-20 23:11:48 -05004510 if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
4511 ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
4512 ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
4513 ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
4514 ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
James Smartd38dd522015-08-31 16:48:17 -04004515 ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
James Smartfbd8a6b2018-02-22 08:18:45 -08004516 ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
4517 ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
James Smart76a95d72010-11-20 23:11:48 -05004518 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4519 "2879 lpfc_link_speed attribute cannot be set "
4520 "to %d. Speed is not supported by this port.\n",
4521 val);
James Smart83108bd2008-01-11 01:53:09 -05004522 return -EINVAL;
James Smart76a95d72010-11-20 23:11:48 -05004523 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004524 if (val >= LPFC_USER_LINK_SPEED_16G &&
4525 phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smartff78d8f2011-12-13 13:21:35 -05004526 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4527 "3112 lpfc_link_speed attribute cannot be set "
4528 "to %d. Speed is not supported in loop mode.\n",
4529 val);
4530 return -EINVAL;
4531 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004532
4533 switch (val) {
4534 case LPFC_USER_LINK_SPEED_AUTO:
4535 case LPFC_USER_LINK_SPEED_1G:
4536 case LPFC_USER_LINK_SPEED_2G:
4537 case LPFC_USER_LINK_SPEED_4G:
4538 case LPFC_USER_LINK_SPEED_8G:
4539 case LPFC_USER_LINK_SPEED_16G:
4540 case LPFC_USER_LINK_SPEED_32G:
4541 case LPFC_USER_LINK_SPEED_64G:
James Smart83108bd2008-01-11 01:53:09 -05004542 prev_val = phba->cfg_link_speed;
4543 phba->cfg_link_speed = val;
James Smarta257bf92009-04-06 18:48:10 -04004544 if (nolip)
4545 return strlen(buf);
4546
James Smart83108bd2008-01-11 01:53:09 -05004547 err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
James Smarta257bf92009-04-06 18:48:10 -04004548 if (err) {
James Smart83108bd2008-01-11 01:53:09 -05004549 phba->cfg_link_speed = prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004550 return -EINVAL;
James Smartfbd8a6b2018-02-22 08:18:45 -08004551 }
4552 return strlen(buf);
4553 default:
4554 break;
James Smart83108bd2008-01-11 01:53:09 -05004555 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004556
James Smart83108bd2008-01-11 01:53:09 -05004557 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smartfbd8a6b2018-02-22 08:18:45 -08004558 "0469 lpfc_link_speed attribute cannot be set to %d, "
4559 "allowed values are [%s]\n",
4560 val, LPFC_LINK_SPEED_STRING);
James Smart83108bd2008-01-11 01:53:09 -05004561 return -EINVAL;
James Smartfbd8a6b2018-02-22 08:18:45 -08004562
James Smart83108bd2008-01-11 01:53:09 -05004563}
4564
4565static int lpfc_link_speed = 0;
James Smartab56dc22011-02-16 12:39:57 -05004566module_param(lpfc_link_speed, int, S_IRUGO);
James Smart83108bd2008-01-11 01:53:09 -05004567MODULE_PARM_DESC(lpfc_link_speed, "Select link speed");
4568lpfc_param_show(link_speed)
James Smarte59058c2008-08-24 21:49:00 -04004569
4570/**
James Smart3621a712009-04-06 18:47:14 -04004571 * lpfc_link_speed_init - Set the adapters link speed
James Smarte59058c2008-08-24 21:49:00 -04004572 * @phba: lpfc_hba pointer.
4573 * @val: link speed value.
4574 *
4575 * Description:
4576 * If val is in a valid range then set the adapter's link speed field.
4577 *
4578 * Notes:
4579 * If the value is not in range log a kernel error message, clear the link
4580 * speed and return an error.
4581 *
4582 * Returns:
4583 * zero if val saved.
4584 * -EINVAL val out of range
4585 **/
James Smart83108bd2008-01-11 01:53:09 -05004586static int
4587lpfc_link_speed_init(struct lpfc_hba *phba, int val)
4588{
James Smartfbd8a6b2018-02-22 08:18:45 -08004589 if (val >= LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) {
James Smartff78d8f2011-12-13 13:21:35 -05004590 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4591 "3111 lpfc_link_speed of %d cannot "
4592 "support loop mode, setting topology to default.\n",
4593 val);
4594 phba->cfg_topology = 0;
4595 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004596
4597 switch (val) {
4598 case LPFC_USER_LINK_SPEED_AUTO:
4599 case LPFC_USER_LINK_SPEED_1G:
4600 case LPFC_USER_LINK_SPEED_2G:
4601 case LPFC_USER_LINK_SPEED_4G:
4602 case LPFC_USER_LINK_SPEED_8G:
4603 case LPFC_USER_LINK_SPEED_16G:
4604 case LPFC_USER_LINK_SPEED_32G:
4605 case LPFC_USER_LINK_SPEED_64G:
James Smart83108bd2008-01-11 01:53:09 -05004606 phba->cfg_link_speed = val;
4607 return 0;
James Smartfbd8a6b2018-02-22 08:18:45 -08004608 default:
4609 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4610 "0405 lpfc_link_speed attribute cannot "
4611 "be set to %d, allowed values are "
4612 "["LPFC_LINK_SPEED_STRING"]\n", val);
4613 phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
4614 return -EINVAL;
James Smart83108bd2008-01-11 01:53:09 -05004615 }
James Smart83108bd2008-01-11 01:53:09 -05004616}
4617
Joe Perchesb6b996b2017-12-19 10:15:07 -08004618static DEVICE_ATTR_RW(lpfc_link_speed);
dea31012005-04-17 16:05:31 -05004619
4620/*
James Smart0d878412009-10-02 15:16:56 -04004621# lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
4622# 0 = aer disabled or not supported
4623# 1 = aer supported and enabled (default)
4624# Value range is [0,1]. Default value is 1.
4625*/
James Smart506139a2016-10-13 15:06:09 -07004626LPFC_ATTR(aer_support, 1, 0, 1,
4627 "Enable PCIe device AER support");
4628lpfc_param_show(aer_support)
James Smart0d878412009-10-02 15:16:56 -04004629
4630/**
4631 * lpfc_aer_support_store - Set the adapter for aer support
4632 *
4633 * @dev: class device that is converted into a Scsi_host.
4634 * @attr: device attribute, not used.
James Smart912e3ac2011-05-24 11:42:11 -04004635 * @buf: containing enable or disable aer flag.
James Smart0d878412009-10-02 15:16:56 -04004636 * @count: unused variable.
4637 *
4638 * Description:
4639 * If the val is 1 and currently the device's AER capability was not
4640 * enabled, invoke the kernel's enable AER helper routine, trying to
4641 * enable the device's AER capability. If the helper routine enabling
4642 * AER returns success, update the device's cfg_aer_support flag to
4643 * indicate AER is supported by the device; otherwise, if the device
4644 * AER capability is already enabled to support AER, then do nothing.
4645 *
4646 * If the val is 0 and currently the device's AER support was enabled,
4647 * invoke the kernel's disable AER helper routine. After that, update
4648 * the device's cfg_aer_support flag to indicate AER is not supported
4649 * by the device; otherwise, if the device AER capability is already
4650 * disabled from supporting AER, then do nothing.
4651 *
4652 * Returns:
4653 * length of the buf on success if val is in range the intended mode
4654 * is supported.
4655 * -EINVAL if val out of range or intended mode is not supported.
4656 **/
4657static ssize_t
4658lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
4659 const char *buf, size_t count)
4660{
4661 struct Scsi_Host *shost = class_to_shost(dev);
4662 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4663 struct lpfc_hba *phba = vport->phba;
4664 int val = 0, rc = -EINVAL;
4665
4666 if (!isdigit(buf[0]))
4667 return -EINVAL;
4668 if (sscanf(buf, "%i", &val) != 1)
4669 return -EINVAL;
4670
4671 switch (val) {
4672 case 0:
4673 if (phba->hba_flag & HBA_AER_ENABLED) {
4674 rc = pci_disable_pcie_error_reporting(phba->pcidev);
4675 if (!rc) {
4676 spin_lock_irq(&phba->hbalock);
4677 phba->hba_flag &= ~HBA_AER_ENABLED;
4678 spin_unlock_irq(&phba->hbalock);
4679 phba->cfg_aer_support = 0;
4680 rc = strlen(buf);
4681 } else
James Smart891478a2009-11-18 15:40:23 -05004682 rc = -EPERM;
4683 } else {
James Smart0d878412009-10-02 15:16:56 -04004684 phba->cfg_aer_support = 0;
James Smart891478a2009-11-18 15:40:23 -05004685 rc = strlen(buf);
4686 }
James Smart0d878412009-10-02 15:16:56 -04004687 break;
4688 case 1:
4689 if (!(phba->hba_flag & HBA_AER_ENABLED)) {
4690 rc = pci_enable_pcie_error_reporting(phba->pcidev);
4691 if (!rc) {
4692 spin_lock_irq(&phba->hbalock);
4693 phba->hba_flag |= HBA_AER_ENABLED;
4694 spin_unlock_irq(&phba->hbalock);
4695 phba->cfg_aer_support = 1;
4696 rc = strlen(buf);
4697 } else
James Smart891478a2009-11-18 15:40:23 -05004698 rc = -EPERM;
4699 } else {
James Smart0d878412009-10-02 15:16:56 -04004700 phba->cfg_aer_support = 1;
James Smart891478a2009-11-18 15:40:23 -05004701 rc = strlen(buf);
4702 }
James Smart0d878412009-10-02 15:16:56 -04004703 break;
4704 default:
4705 rc = -EINVAL;
4706 break;
4707 }
4708 return rc;
4709}
4710
Joe Perchesb6b996b2017-12-19 10:15:07 -08004711static DEVICE_ATTR_RW(lpfc_aer_support);
James Smart0d878412009-10-02 15:16:56 -04004712
4713/**
4714 * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device
4715 * @dev: class device that is converted into a Scsi_host.
4716 * @attr: device attribute, not used.
James Smart912e3ac2011-05-24 11:42:11 -04004717 * @buf: containing flag 1 for aer cleanup state.
James Smart0d878412009-10-02 15:16:56 -04004718 * @count: unused variable.
4719 *
4720 * Description:
4721 * If the @buf contains 1 and the device currently has the AER support
4722 * enabled, then invokes the kernel AER helper routine
Kuppuswamy Sathyanarayanan894020f2020-03-23 17:26:08 -07004723 * pci_aer_clear_nonfatal_status() to clean up the uncorrectable
James Smart0d878412009-10-02 15:16:56 -04004724 * error status register.
4725 *
4726 * Notes:
4727 *
4728 * Returns:
4729 * -EINVAL if the buf does not contain the 1 or the device is not currently
4730 * enabled with the AER support.
4731 **/
4732static ssize_t
4733lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr,
4734 const char *buf, size_t count)
4735{
4736 struct Scsi_Host *shost = class_to_shost(dev);
4737 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4738 struct lpfc_hba *phba = vport->phba;
4739 int val, rc = -1;
4740
4741 if (!isdigit(buf[0]))
4742 return -EINVAL;
4743 if (sscanf(buf, "%i", &val) != 1)
4744 return -EINVAL;
James Smart891478a2009-11-18 15:40:23 -05004745 if (val != 1)
4746 return -EINVAL;
James Smart0d878412009-10-02 15:16:56 -04004747
James Smart891478a2009-11-18 15:40:23 -05004748 if (phba->hba_flag & HBA_AER_ENABLED)
Kuppuswamy Sathyanarayanan894020f2020-03-23 17:26:08 -07004749 rc = pci_aer_clear_nonfatal_status(phba->pcidev);
James Smart0d878412009-10-02 15:16:56 -04004750
4751 if (rc == 0)
4752 return strlen(buf);
4753 else
James Smart891478a2009-11-18 15:40:23 -05004754 return -EPERM;
James Smart0d878412009-10-02 15:16:56 -04004755}
4756
4757static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
4758 lpfc_aer_cleanup_state);
4759
James Smart912e3ac2011-05-24 11:42:11 -04004760/**
4761 * lpfc_sriov_nr_virtfn_store - Enable the adapter for sr-iov virtual functions
4762 *
4763 * @dev: class device that is converted into a Scsi_host.
4764 * @attr: device attribute, not used.
4765 * @buf: containing the string the number of vfs to be enabled.
4766 * @count: unused variable.
4767 *
4768 * Description:
4769 * When this api is called either through user sysfs, the driver shall
4770 * try to enable or disable SR-IOV virtual functions according to the
4771 * following:
4772 *
4773 * If zero virtual function has been enabled to the physical function,
4774 * the driver shall invoke the pci enable virtual function api trying
4775 * to enable the virtual functions. If the nr_vfn provided is greater
4776 * than the maximum supported, the maximum virtual function number will
4777 * be used for invoking the api; otherwise, the nr_vfn provided shall
4778 * be used for invoking the api. If the api call returned success, the
4779 * actual number of virtual functions enabled will be set to the driver
4780 * cfg_sriov_nr_virtfn; otherwise, -EINVAL shall be returned and driver
4781 * cfg_sriov_nr_virtfn remains zero.
4782 *
4783 * If none-zero virtual functions have already been enabled to the
4784 * physical function, as reflected by the driver's cfg_sriov_nr_virtfn,
4785 * -EINVAL will be returned and the driver does nothing;
4786 *
4787 * If the nr_vfn provided is zero and none-zero virtual functions have
4788 * been enabled, as indicated by the driver's cfg_sriov_nr_virtfn, the
4789 * disabling virtual function api shall be invoded to disable all the
4790 * virtual functions and driver's cfg_sriov_nr_virtfn shall be set to
4791 * zero. Otherwise, if zero virtual function has been enabled, do
4792 * nothing.
4793 *
4794 * Returns:
4795 * length of the buf on success if val is in range the intended mode
4796 * is supported.
4797 * -EINVAL if val out of range or intended mode is not supported.
4798 **/
4799static ssize_t
4800lpfc_sriov_nr_virtfn_store(struct device *dev, struct device_attribute *attr,
4801 const char *buf, size_t count)
4802{
4803 struct Scsi_Host *shost = class_to_shost(dev);
4804 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4805 struct lpfc_hba *phba = vport->phba;
4806 struct pci_dev *pdev = phba->pcidev;
4807 int val = 0, rc = -EINVAL;
4808
4809 /* Sanity check on user data */
4810 if (!isdigit(buf[0]))
4811 return -EINVAL;
4812 if (sscanf(buf, "%i", &val) != 1)
4813 return -EINVAL;
4814 if (val < 0)
4815 return -EINVAL;
4816
4817 /* Request disabling virtual functions */
4818 if (val == 0) {
4819 if (phba->cfg_sriov_nr_virtfn > 0) {
4820 pci_disable_sriov(pdev);
4821 phba->cfg_sriov_nr_virtfn = 0;
4822 }
4823 return strlen(buf);
4824 }
4825
4826 /* Request enabling virtual functions */
4827 if (phba->cfg_sriov_nr_virtfn > 0) {
4828 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4829 "3018 There are %d virtual functions "
4830 "enabled on physical function.\n",
4831 phba->cfg_sriov_nr_virtfn);
4832 return -EEXIST;
4833 }
4834
4835 if (val <= LPFC_MAX_VFN_PER_PFN)
4836 phba->cfg_sriov_nr_virtfn = val;
4837 else {
4838 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4839 "3019 Enabling %d virtual functions is not "
4840 "allowed.\n", val);
4841 return -EINVAL;
4842 }
4843
4844 rc = lpfc_sli_probe_sriov_nr_virtfn(phba, phba->cfg_sriov_nr_virtfn);
4845 if (rc) {
4846 phba->cfg_sriov_nr_virtfn = 0;
4847 rc = -EPERM;
4848 } else
4849 rc = strlen(buf);
4850
4851 return rc;
4852}
4853
James Smart0cfbbf22016-10-13 15:06:12 -07004854LPFC_ATTR(sriov_nr_virtfn, LPFC_DEF_VFN_PER_PFN, 0, LPFC_MAX_VFN_PER_PFN,
4855 "Enable PCIe device SR-IOV virtual fn");
4856
James Smart912e3ac2011-05-24 11:42:11 -04004857lpfc_param_show(sriov_nr_virtfn)
Joe Perchesb6b996b2017-12-19 10:15:07 -08004858static DEVICE_ATTR_RW(lpfc_sriov_nr_virtfn);
James Smart912e3ac2011-05-24 11:42:11 -04004859
James Smart173edbb2012-06-12 13:54:50 -04004860/**
James Smartc71ab862012-10-31 14:44:33 -04004861 * lpfc_request_firmware_store - Request for Linux generic firmware upgrade
4862 *
4863 * @dev: class device that is converted into a Scsi_host.
4864 * @attr: device attribute, not used.
4865 * @buf: containing the string the number of vfs to be enabled.
4866 * @count: unused variable.
4867 *
4868 * Description:
4869 *
4870 * Returns:
4871 * length of the buf on success if val is in range the intended mode
4872 * is supported.
4873 * -EINVAL if val out of range or intended mode is not supported.
4874 **/
4875static ssize_t
4876lpfc_request_firmware_upgrade_store(struct device *dev,
4877 struct device_attribute *attr,
4878 const char *buf, size_t count)
4879{
4880 struct Scsi_Host *shost = class_to_shost(dev);
4881 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4882 struct lpfc_hba *phba = vport->phba;
Colin Ian King6e27a862020-05-07 21:31:11 +01004883 int val = 0, rc;
James Smartc71ab862012-10-31 14:44:33 -04004884
4885 /* Sanity check on user data */
4886 if (!isdigit(buf[0]))
4887 return -EINVAL;
4888 if (sscanf(buf, "%i", &val) != 1)
4889 return -EINVAL;
4890 if (val != 1)
4891 return -EINVAL;
4892
4893 rc = lpfc_sli4_request_firmware_update(phba, RUN_FW_UPGRADE);
4894 if (rc)
4895 rc = -EPERM;
4896 else
4897 rc = strlen(buf);
4898 return rc;
4899}
4900
4901static int lpfc_req_fw_upgrade;
4902module_param(lpfc_req_fw_upgrade, int, S_IRUGO|S_IWUSR);
4903MODULE_PARM_DESC(lpfc_req_fw_upgrade, "Enable Linux generic firmware upgrade");
4904lpfc_param_show(request_firmware_upgrade)
4905
4906/**
4907 * lpfc_request_firmware_upgrade_init - Enable initial linux generic fw upgrade
4908 * @phba: lpfc_hba pointer.
4909 * @val: 0 or 1.
4910 *
4911 * Description:
4912 * Set the initial Linux generic firmware upgrade enable or disable flag.
4913 *
4914 * Returns:
4915 * zero if val saved.
4916 * -EINVAL val out of range
4917 **/
4918static int
4919lpfc_request_firmware_upgrade_init(struct lpfc_hba *phba, int val)
4920{
4921 if (val >= 0 && val <= 1) {
4922 phba->cfg_request_firmware_upgrade = val;
4923 return 0;
4924 }
4925 return -EINVAL;
4926}
4927static DEVICE_ATTR(lpfc_req_fw_upgrade, S_IRUGO | S_IWUSR,
4928 lpfc_request_firmware_upgrade_show,
4929 lpfc_request_firmware_upgrade_store);
4930
4931/**
James Smart41b194b2019-05-14 14:58:08 -07004932 * lpfc_force_rscn_store
4933 *
4934 * @dev: class device that is converted into a Scsi_host.
4935 * @attr: device attribute, not used.
4936 * @buf: unused string
4937 * @count: unused variable.
4938 *
4939 * Description:
4940 * Force the switch to send a RSCN to all other NPorts in our zone
4941 * If we are direct connect pt2pt, build the RSCN command ourself
4942 * and send to the other NPort. Not supported for private loop.
4943 *
4944 * Returns:
4945 * 0 - on success
4946 * -EIO - if command is not sent
4947 **/
4948static ssize_t
4949lpfc_force_rscn_store(struct device *dev, struct device_attribute *attr,
4950 const char *buf, size_t count)
4951{
4952 struct Scsi_Host *shost = class_to_shost(dev);
4953 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4954 int i;
4955
4956 i = lpfc_issue_els_rscn(vport, 0);
4957 if (i)
4958 return -EIO;
4959 return strlen(buf);
4960}
4961
4962/*
4963 * lpfc_force_rscn: Force an RSCN to be sent to all remote NPorts
4964 * connected to the HBA.
4965 *
4966 * Value range is any ascii value
4967 */
4968static int lpfc_force_rscn;
4969module_param(lpfc_force_rscn, int, 0644);
4970MODULE_PARM_DESC(lpfc_force_rscn,
4971 "Force an RSCN to be sent to all remote NPorts");
4972lpfc_param_show(force_rscn)
4973
4974/**
4975 * lpfc_force_rscn_init - Force an RSCN to be sent to all remote NPorts
4976 * @phba: lpfc_hba pointer.
4977 * @val: unused value.
4978 *
4979 * Returns:
4980 * zero if val saved.
4981 **/
4982static int
4983lpfc_force_rscn_init(struct lpfc_hba *phba, int val)
4984{
4985 return 0;
4986}
4987static DEVICE_ATTR_RW(lpfc_force_rscn);
4988
4989/**
James Smart173edbb2012-06-12 13:54:50 -04004990 * lpfc_fcp_imax_store
4991 *
4992 * @dev: class device that is converted into a Scsi_host.
4993 * @attr: device attribute, not used.
4994 * @buf: string with the number of fast-path FCP interrupts per second.
4995 * @count: unused variable.
4996 *
4997 * Description:
4998 * If val is in a valid range [636,651042], then set the adapter's
4999 * maximum number of fast-path FCP interrupts per second.
5000 *
5001 * Returns:
5002 * length of the buf on success if val is in range the intended mode
5003 * is supported.
5004 * -EINVAL if val out of range or intended mode is not supported.
5005 **/
5006static ssize_t
5007lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr,
5008 const char *buf, size_t count)
5009{
5010 struct Scsi_Host *shost = class_to_shost(dev);
5011 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5012 struct lpfc_hba *phba = vport->phba;
James Smart32517fc2019-01-28 11:14:33 -08005013 struct lpfc_eq_intr_info *eqi;
James Smartcb733e32019-01-28 11:14:32 -08005014 uint32_t usdelay;
James Smart173edbb2012-06-12 13:54:50 -04005015 int val = 0, i;
5016
James Smartbf8dae82012-08-03 12:36:24 -04005017 /* fcp_imax is only valid for SLI4 */
5018 if (phba->sli_rev != LPFC_SLI_REV4)
5019 return -EINVAL;
5020
James Smart173edbb2012-06-12 13:54:50 -04005021 /* Sanity check on user data */
5022 if (!isdigit(buf[0]))
5023 return -EINVAL;
5024 if (sscanf(buf, "%i", &val) != 1)
5025 return -EINVAL;
5026
James Smartbf8dae82012-08-03 12:36:24 -04005027 /*
5028 * Value range for the HBA is [5000,5000000]
5029 * The value for each EQ depends on how many EQs are configured.
James Smart895427b2017-02-12 13:52:30 -08005030 * Allow value == 0
James Smartbf8dae82012-08-03 12:36:24 -04005031 */
James Smart895427b2017-02-12 13:52:30 -08005032 if (val && (val < LPFC_MIN_IMAX || val > LPFC_MAX_IMAX))
James Smart173edbb2012-06-12 13:54:50 -04005033 return -EINVAL;
5034
James Smart32517fc2019-01-28 11:14:33 -08005035 phba->cfg_auto_imax = (val) ? 0 : 1;
5036 if (phba->cfg_fcp_imax && !val) {
5037 queue_delayed_work(phba->wq, &phba->eq_delay_work,
5038 msecs_to_jiffies(LPFC_EQ_DELAY_MSECS));
5039
5040 for_each_present_cpu(i) {
5041 eqi = per_cpu_ptr(phba->sli4_hba.eq_info, i);
5042 eqi->icnt = 0;
5043 }
5044 }
5045
James Smart173edbb2012-06-12 13:54:50 -04005046 phba->cfg_fcp_imax = (uint32_t)val;
James Smart43140ca2017-03-04 09:30:34 -08005047
James Smartcb733e32019-01-28 11:14:32 -08005048 if (phba->cfg_fcp_imax)
5049 usdelay = LPFC_SEC_TO_USEC / phba->cfg_fcp_imax;
5050 else
5051 usdelay = 0;
5052
James Smart6a828b02019-01-28 11:14:31 -08005053 for (i = 0; i < phba->cfg_irq_chann; i += LPFC_MAX_EQ_DELAY_EQID_CNT)
James Smart0cf07f842017-06-01 21:07:10 -07005054 lpfc_modify_hba_eq_delay(phba, i, LPFC_MAX_EQ_DELAY_EQID_CNT,
James Smartcb733e32019-01-28 11:14:32 -08005055 usdelay);
James Smart173edbb2012-06-12 13:54:50 -04005056
5057 return strlen(buf);
5058}
5059
5060/*
5061# lpfc_fcp_imax: The maximum number of fast-path FCP interrupts per second
James Smartbf8dae82012-08-03 12:36:24 -04005062# for the HBA.
James Smart173edbb2012-06-12 13:54:50 -04005063#
James Smartbf8dae82012-08-03 12:36:24 -04005064# Value range is [5,000 to 5,000,000]. Default value is 50,000.
James Smart173edbb2012-06-12 13:54:50 -04005065*/
James Smartbf8dae82012-08-03 12:36:24 -04005066static int lpfc_fcp_imax = LPFC_DEF_IMAX;
James Smart173edbb2012-06-12 13:54:50 -04005067module_param(lpfc_fcp_imax, int, S_IRUGO|S_IWUSR);
5068MODULE_PARM_DESC(lpfc_fcp_imax,
James Smartbf8dae82012-08-03 12:36:24 -04005069 "Set the maximum number of FCP interrupts per second per HBA");
James Smart173edbb2012-06-12 13:54:50 -04005070lpfc_param_show(fcp_imax)
5071
5072/**
5073 * lpfc_fcp_imax_init - Set the initial sr-iov virtual function enable
5074 * @phba: lpfc_hba pointer.
5075 * @val: link speed value.
5076 *
5077 * Description:
5078 * If val is in a valid range [636,651042], then initialize the adapter's
5079 * maximum number of fast-path FCP interrupts per second.
5080 *
5081 * Returns:
5082 * zero if val saved.
5083 * -EINVAL val out of range
5084 **/
5085static int
5086lpfc_fcp_imax_init(struct lpfc_hba *phba, int val)
5087{
James Smartbf8dae82012-08-03 12:36:24 -04005088 if (phba->sli_rev != LPFC_SLI_REV4) {
5089 phba->cfg_fcp_imax = 0;
5090 return 0;
5091 }
5092
James Smart895427b2017-02-12 13:52:30 -08005093 if ((val >= LPFC_MIN_IMAX && val <= LPFC_MAX_IMAX) ||
5094 (val == 0)) {
James Smart173edbb2012-06-12 13:54:50 -04005095 phba->cfg_fcp_imax = val;
5096 return 0;
5097 }
5098
5099 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07005100 "3016 lpfc_fcp_imax: %d out of range, using default\n",
5101 val);
James Smartbf8dae82012-08-03 12:36:24 -04005102 phba->cfg_fcp_imax = LPFC_DEF_IMAX;
James Smart173edbb2012-06-12 13:54:50 -04005103
5104 return 0;
5105}
5106
Joe Perchesb6b996b2017-12-19 10:15:07 -08005107static DEVICE_ATTR_RW(lpfc_fcp_imax);
James Smart173edbb2012-06-12 13:54:50 -04005108
James Smart32517fc2019-01-28 11:14:33 -08005109/**
5110 * lpfc_cq_max_proc_limit_store
5111 *
5112 * @dev: class device that is converted into a Scsi_host.
5113 * @attr: device attribute, not used.
5114 * @buf: string with the cq max processing limit of cqes
5115 * @count: unused variable.
5116 *
5117 * Description:
5118 * If val is in a valid range, then set value on each cq
5119 *
5120 * Returns:
5121 * The length of the buf: if successful
5122 * -ERANGE: if val is not in the valid range
5123 * -EINVAL: if bad value format or intended mode is not supported.
5124 **/
5125static ssize_t
5126lpfc_cq_max_proc_limit_store(struct device *dev, struct device_attribute *attr,
5127 const char *buf, size_t count)
5128{
5129 struct Scsi_Host *shost = class_to_shost(dev);
5130 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5131 struct lpfc_hba *phba = vport->phba;
5132 struct lpfc_queue *eq, *cq;
5133 unsigned long val;
5134 int i;
5135
5136 /* cq_max_proc_limit is only valid for SLI4 */
5137 if (phba->sli_rev != LPFC_SLI_REV4)
5138 return -EINVAL;
5139
5140 /* Sanity check on user data */
5141 if (!isdigit(buf[0]))
5142 return -EINVAL;
5143 if (kstrtoul(buf, 0, &val))
5144 return -EINVAL;
5145
5146 if (val < LPFC_CQ_MIN_PROC_LIMIT || val > LPFC_CQ_MAX_PROC_LIMIT)
5147 return -ERANGE;
5148
5149 phba->cfg_cq_max_proc_limit = (uint32_t)val;
5150
5151 /* set the values on the cq's */
5152 for (i = 0; i < phba->cfg_irq_chann; i++) {
James Smart657add42019-05-21 17:49:06 -07005153 /* Get the EQ corresponding to the IRQ vector */
5154 eq = phba->sli4_hba.hba_eq_hdl[i].eq;
James Smart32517fc2019-01-28 11:14:33 -08005155 if (!eq)
5156 continue;
5157
5158 list_for_each_entry(cq, &eq->child_list, list)
5159 cq->max_proc_limit = min(phba->cfg_cq_max_proc_limit,
5160 cq->entry_count);
5161 }
5162
5163 return strlen(buf);
5164}
5165
James Smart0cf07f842017-06-01 21:07:10 -07005166/*
James Smart32517fc2019-01-28 11:14:33 -08005167 * lpfc_cq_max_proc_limit: The maximum number CQE entries processed in an
5168 * itteration of CQ processing.
James Smart0cf07f842017-06-01 21:07:10 -07005169 */
James Smart32517fc2019-01-28 11:14:33 -08005170static int lpfc_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
5171module_param(lpfc_cq_max_proc_limit, int, 0644);
5172MODULE_PARM_DESC(lpfc_cq_max_proc_limit,
5173 "Set the maximum number CQEs processed in an iteration of "
5174 "CQ processing");
5175lpfc_param_show(cq_max_proc_limit)
5176
5177/*
5178 * lpfc_cq_poll_threshold: Set the threshold of CQE completions in a
5179 * single handler call which should request a polled completion rather
5180 * than re-enabling interrupts.
5181 */
5182LPFC_ATTR_RW(cq_poll_threshold, LPFC_CQ_DEF_THRESHOLD_TO_POLL,
5183 LPFC_CQ_MIN_THRESHOLD_TO_POLL,
5184 LPFC_CQ_MAX_THRESHOLD_TO_POLL,
5185 "CQE Processing Threshold to enable Polling");
5186
5187/**
5188 * lpfc_cq_max_proc_limit_init - Set the initial cq max_proc_limit
5189 * @phba: lpfc_hba pointer.
5190 * @val: entry limit
5191 *
5192 * Description:
5193 * If val is in a valid range, then initialize the adapter's maximum
5194 * value.
5195 *
5196 * Returns:
5197 * Always returns 0 for success, even if value not always set to
5198 * requested value. If value out of range or not supported, will fall
5199 * back to default.
5200 **/
5201static int
5202lpfc_cq_max_proc_limit_init(struct lpfc_hba *phba, int val)
5203{
5204 phba->cfg_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
5205
5206 if (phba->sli_rev != LPFC_SLI_REV4)
5207 return 0;
5208
5209 if (val >= LPFC_CQ_MIN_PROC_LIMIT && val <= LPFC_CQ_MAX_PROC_LIMIT) {
5210 phba->cfg_cq_max_proc_limit = val;
5211 return 0;
5212 }
5213
5214 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
5215 "0371 "LPFC_DRIVER_NAME"_cq_max_proc_limit: "
5216 "%d out of range, using default\n",
5217 phba->cfg_cq_max_proc_limit);
5218
5219 return 0;
5220}
5221
5222static DEVICE_ATTR_RW(lpfc_cq_max_proc_limit);
James Smart0cf07f842017-06-01 21:07:10 -07005223
James Smart7bb03bb2013-04-17 20:19:16 -04005224/**
5225 * lpfc_state_show - Display current driver CPU affinity
5226 * @dev: class converted to a Scsi_host structure.
5227 * @attr: device attribute, not used.
5228 * @buf: on return contains text describing the state of the link.
5229 *
5230 * Returns: size of formatted string.
5231 **/
5232static ssize_t
5233lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr,
5234 char *buf)
5235{
5236 struct Scsi_Host *shost = class_to_shost(dev);
5237 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5238 struct lpfc_hba *phba = vport->phba;
5239 struct lpfc_vector_map_info *cpup;
James Smart76fd07a2014-02-20 09:57:18 -05005240 int len = 0;
James Smart7bb03bb2013-04-17 20:19:16 -04005241
5242 if ((phba->sli_rev != LPFC_SLI_REV4) ||
5243 (phba->intr_type != MSIX))
5244 return len;
5245
5246 switch (phba->cfg_fcp_cpu_map) {
5247 case 0:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005248 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart7bb03bb2013-04-17 20:19:16 -04005249 "fcp_cpu_map: No mapping (%d)\n",
5250 phba->cfg_fcp_cpu_map);
5251 return len;
5252 case 1:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005253 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart7bb03bb2013-04-17 20:19:16 -04005254 "fcp_cpu_map: HBA centric mapping (%d): "
James Smart222e9232019-01-28 11:14:35 -08005255 "%d of %d CPUs online from %d possible CPUs\n",
5256 phba->cfg_fcp_cpu_map, num_online_cpus(),
5257 num_present_cpus(),
5258 phba->sli4_hba.num_possible_cpu);
James Smart7bb03bb2013-04-17 20:19:16 -04005259 break;
James Smart7bb03bb2013-04-17 20:19:16 -04005260 }
5261
James Smart222e9232019-01-28 11:14:35 -08005262 while (phba->sli4_hba.curr_disp_cpu <
5263 phba->sli4_hba.num_possible_cpu) {
James Smart76fd07a2014-02-20 09:57:18 -05005264 cpup = &phba->sli4_hba.cpu_map[phba->sli4_hba.curr_disp_cpu];
5265
James Smart222e9232019-01-28 11:14:35 -08005266 if (!cpu_present(phba->sli4_hba.curr_disp_cpu))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005267 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart222e9232019-01-28 11:14:35 -08005268 "CPU %02d not present\n",
5269 phba->sli4_hba.curr_disp_cpu);
James Smartdcaa2132019-11-04 16:57:06 -08005270 else if (cpup->eq == LPFC_VECTOR_MAP_EMPTY) {
James Smartb3295c22019-01-28 11:14:30 -08005271 if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005272 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005273 buf + len, PAGE_SIZE - len,
5274 "CPU %02d hdwq None "
James Smartd9954a22019-05-21 17:49:05 -07005275 "physid %d coreid %d ht %d ua %d\n",
James Smart76fd07a2014-02-20 09:57:18 -05005276 phba->sli4_hba.curr_disp_cpu,
James Smartd9954a22019-05-21 17:49:05 -07005277 cpup->phys_id, cpup->core_id,
5278 (cpup->flag & LPFC_CPU_MAP_HYPER),
5279 (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
James Smartb3295c22019-01-28 11:14:30 -08005280 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005281 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005282 buf + len, PAGE_SIZE - len,
James Smartdcaa2132019-11-04 16:57:06 -08005283 "CPU %02d EQ None hdwq %04d "
James Smartd9954a22019-05-21 17:49:05 -07005284 "physid %d coreid %d ht %d ua %d\n",
James Smartb3295c22019-01-28 11:14:30 -08005285 phba->sli4_hba.curr_disp_cpu,
James Smartdcaa2132019-11-04 16:57:06 -08005286 cpup->hdwq, cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005287 cpup->core_id,
5288 (cpup->flag & LPFC_CPU_MAP_HYPER),
5289 (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
James Smartb3295c22019-01-28 11:14:30 -08005290 } else {
5291 if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005292 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005293 buf + len, PAGE_SIZE - len,
5294 "CPU %02d hdwq None "
James Smartd9954a22019-05-21 17:49:05 -07005295 "physid %d coreid %d ht %d ua %d IRQ %d\n",
James Smart76fd07a2014-02-20 09:57:18 -05005296 phba->sli4_hba.curr_disp_cpu,
James Smartb3295c22019-01-28 11:14:30 -08005297 cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005298 cpup->core_id,
5299 (cpup->flag & LPFC_CPU_MAP_HYPER),
5300 (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
James Smartdcaa2132019-11-04 16:57:06 -08005301 lpfc_get_irq(cpup->eq));
James Smartb3295c22019-01-28 11:14:30 -08005302 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005303 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005304 buf + len, PAGE_SIZE - len,
James Smart6a828b02019-01-28 11:14:31 -08005305 "CPU %02d EQ %04d hdwq %04d "
James Smartd9954a22019-05-21 17:49:05 -07005306 "physid %d coreid %d ht %d ua %d IRQ %d\n",
James Smartb3295c22019-01-28 11:14:30 -08005307 phba->sli4_hba.curr_disp_cpu,
James Smart6a828b02019-01-28 11:14:31 -08005308 cpup->eq, cpup->hdwq, cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005309 cpup->core_id,
5310 (cpup->flag & LPFC_CPU_MAP_HYPER),
5311 (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
James Smartdcaa2132019-11-04 16:57:06 -08005312 lpfc_get_irq(cpup->eq));
James Smartb3295c22019-01-28 11:14:30 -08005313 }
James Smart7bb03bb2013-04-17 20:19:16 -04005314
James Smart76fd07a2014-02-20 09:57:18 -05005315 phba->sli4_hba.curr_disp_cpu++;
5316
5317 /* display max number of CPUs keeping some margin */
5318 if (phba->sli4_hba.curr_disp_cpu <
James Smart222e9232019-01-28 11:14:35 -08005319 phba->sli4_hba.num_possible_cpu &&
James Smart76fd07a2014-02-20 09:57:18 -05005320 (len >= (PAGE_SIZE - 64))) {
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005321 len += scnprintf(buf + len,
James Smart222e9232019-01-28 11:14:35 -08005322 PAGE_SIZE - len, "more...\n");
James Smart76fd07a2014-02-20 09:57:18 -05005323 break;
5324 }
James Smart7bb03bb2013-04-17 20:19:16 -04005325 }
James Smart76fd07a2014-02-20 09:57:18 -05005326
James Smart222e9232019-01-28 11:14:35 -08005327 if (phba->sli4_hba.curr_disp_cpu == phba->sli4_hba.num_possible_cpu)
James Smart76fd07a2014-02-20 09:57:18 -05005328 phba->sli4_hba.curr_disp_cpu = 0;
5329
James Smart7bb03bb2013-04-17 20:19:16 -04005330 return len;
5331}
5332
5333/**
5334 * lpfc_fcp_cpu_map_store - Change CPU affinity of driver vectors
5335 * @dev: class device that is converted into a Scsi_host.
5336 * @attr: device attribute, not used.
5337 * @buf: one or more lpfc_polling_flags values.
5338 * @count: not used.
5339 *
5340 * Returns:
5341 * -EINVAL - Not implemented yet.
5342 **/
5343static ssize_t
5344lpfc_fcp_cpu_map_store(struct device *dev, struct device_attribute *attr,
5345 const char *buf, size_t count)
5346{
Ye Bin37fa4292020-09-16 10:28:59 +08005347 return -EINVAL;
James Smart7bb03bb2013-04-17 20:19:16 -04005348}
5349
5350/*
5351# lpfc_fcp_cpu_map: Defines how to map CPUs to IRQ vectors
5352# for the HBA.
5353#
James Smart6a828b02019-01-28 11:14:31 -08005354# Value range is [0 to 1]. Default value is LPFC_HBA_CPU_MAP (1).
James Smart7bb03bb2013-04-17 20:19:16 -04005355# 0 - Do not affinitze IRQ vectors
5356# 1 - Affintize HBA vectors with respect to each HBA
5357# (start with CPU0 for each HBA)
James Smart6a828b02019-01-28 11:14:31 -08005358# This also defines how Hardware Queues are mapped to specific CPUs.
James Smart7bb03bb2013-04-17 20:19:16 -04005359*/
James Smart6a828b02019-01-28 11:14:31 -08005360static int lpfc_fcp_cpu_map = LPFC_HBA_CPU_MAP;
James Smart7bb03bb2013-04-17 20:19:16 -04005361module_param(lpfc_fcp_cpu_map, int, S_IRUGO|S_IWUSR);
5362MODULE_PARM_DESC(lpfc_fcp_cpu_map,
5363 "Defines how to map CPUs to IRQ vectors per HBA");
5364
5365/**
5366 * lpfc_fcp_cpu_map_init - Set the initial sr-iov virtual function enable
5367 * @phba: lpfc_hba pointer.
5368 * @val: link speed value.
5369 *
5370 * Description:
5371 * If val is in a valid range [0-2], then affinitze the adapter's
5372 * MSIX vectors.
5373 *
5374 * Returns:
5375 * zero if val saved.
5376 * -EINVAL val out of range
5377 **/
5378static int
5379lpfc_fcp_cpu_map_init(struct lpfc_hba *phba, int val)
5380{
5381 if (phba->sli_rev != LPFC_SLI_REV4) {
5382 phba->cfg_fcp_cpu_map = 0;
5383 return 0;
5384 }
5385
5386 if (val >= LPFC_MIN_CPU_MAP && val <= LPFC_MAX_CPU_MAP) {
5387 phba->cfg_fcp_cpu_map = val;
5388 return 0;
5389 }
5390
5391 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07005392 "3326 lpfc_fcp_cpu_map: %d out of range, using "
5393 "default\n", val);
James Smart6a828b02019-01-28 11:14:31 -08005394 phba->cfg_fcp_cpu_map = LPFC_HBA_CPU_MAP;
James Smart7bb03bb2013-04-17 20:19:16 -04005395
5396 return 0;
5397}
5398
Joe Perchesb6b996b2017-12-19 10:15:07 -08005399static DEVICE_ATTR_RW(lpfc_fcp_cpu_map);
James Smart7bb03bb2013-04-17 20:19:16 -04005400
James Smart0d878412009-10-02 15:16:56 -04005401/*
dea31012005-04-17 16:05:31 -05005402# lpfc_fcp_class: Determines FC class to use for the FCP protocol.
5403# Value range is [2,3]. Default value is 3.
5404*/
James Smart3de2a652007-08-02 11:09:59 -04005405LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3,
5406 "Select Fibre Channel class of service for FCP sequences");
dea31012005-04-17 16:05:31 -05005407
5408/*
5409# lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
5410# is [0,1]. Default value is 0.
5411*/
James Smart3de2a652007-08-02 11:09:59 -04005412LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1,
5413 "Use ADISC on rediscovery to authenticate FCP devices");
dea31012005-04-17 16:05:31 -05005414
5415/*
James Smart3cb01c52013-07-15 18:35:04 -04005416# lpfc_first_burst_size: First burst size to use on the NPorts
5417# that support first burst.
5418# Value range is [0,65536]. Default value is 0.
5419*/
5420LPFC_VPORT_ATTR_RW(first_burst_size, 0, 0, 65536,
5421 "First burst size for Targets that support first burst");
5422
5423/*
James Smart2d7dbc42017-02-12 13:52:35 -08005424* lpfc_nvmet_fb_size: NVME Target mode supported first burst size.
5425* When the driver is configured as an NVME target, this value is
5426* communicated to the NVME initiator in the PRLI response. It is
5427* used only when the lpfc_nvme_enable_fb and lpfc_nvmet_support
5428* parameters are set and the target is sending the PRLI RSP.
James Smart895427b2017-02-12 13:52:30 -08005429* Parameter supported on physical port only - no NPIV support.
James Smart2d7dbc42017-02-12 13:52:35 -08005430* Value range is [0,65536]. Default value is 0.
James Smart895427b2017-02-12 13:52:30 -08005431*/
James Smart2d7dbc42017-02-12 13:52:35 -08005432LPFC_ATTR_RW(nvmet_fb_size, 0, 0, 65536,
5433 "NVME Target mode first burst size in 512B increments.");
5434
5435/*
5436 * lpfc_nvme_enable_fb: Enable NVME first burst on I and T functions.
5437 * For the Initiator (I), enabling this parameter means that an NVMET
5438 * PRLI response with FBA enabled and an FB_SIZE set to a nonzero value will be
James Smartdb197bc2019-08-14 16:57:03 -07005439 * processed by the initiator for subsequent NVME FCP IO.
5440 * Currently, this feature is not supported on the NVME target
James Smart2d7dbc42017-02-12 13:52:35 -08005441 * Value range is [0,1]. Default value is 0 (disabled).
5442 */
James Smart895427b2017-02-12 13:52:30 -08005443LPFC_ATTR_RW(nvme_enable_fb, 0, 0, 1,
James Smartdb197bc2019-08-14 16:57:03 -07005444 "Enable First Burst feature for NVME Initiator.");
James Smart895427b2017-02-12 13:52:30 -08005445
5446/*
James Smart977b5a02008-09-07 11:52:04 -04005447# lpfc_max_scsicmpl_time: Use scsi command completion time to control I/O queue
5448# depth. Default value is 0. When the value of this parameter is zero the
5449# SCSI command completion time is not used for controlling I/O queue depth. When
5450# the parameter is set to a non-zero value, the I/O queue depth is controlled
5451# to limit the I/O completion time to the parameter value.
5452# The value is set in milliseconds.
5453*/
James Smarted5b1522016-10-13 15:06:11 -07005454LPFC_VPORT_ATTR(max_scsicmpl_time, 0, 0, 60000,
James Smart977b5a02008-09-07 11:52:04 -04005455 "Use command completion time to control queue depth");
James Smarted5b1522016-10-13 15:06:11 -07005456
James Smart977b5a02008-09-07 11:52:04 -04005457lpfc_vport_param_show(max_scsicmpl_time);
James Smart977b5a02008-09-07 11:52:04 -04005458static int
5459lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val)
5460{
5461 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5462 struct lpfc_nodelist *ndlp, *next_ndlp;
5463
5464 if (val == vport->cfg_max_scsicmpl_time)
5465 return 0;
5466 if ((val < 0) || (val > 60000))
5467 return -EINVAL;
5468 vport->cfg_max_scsicmpl_time = val;
5469
5470 spin_lock_irq(shost->host_lock);
5471 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
James Smart977b5a02008-09-07 11:52:04 -04005472 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
5473 continue;
James Smart7dc517d2010-07-14 15:32:10 -04005474 ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
James Smart977b5a02008-09-07 11:52:04 -04005475 }
5476 spin_unlock_irq(shost->host_lock);
5477 return 0;
5478}
5479lpfc_vport_param_store(max_scsicmpl_time);
Joe Perchesb6b996b2017-12-19 10:15:07 -08005480static DEVICE_ATTR_RW(lpfc_max_scsicmpl_time);
James Smart977b5a02008-09-07 11:52:04 -04005481
5482/*
dea31012005-04-17 16:05:31 -05005483# lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
5484# range is [0,1]. Default value is 0.
5485*/
5486LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
5487
5488/*
James Smartc4908502019-01-28 11:14:28 -08005489# lpfc_xri_rebalancing: enable or disable XRI rebalancing feature
5490# range is [0,1]. Default value is 1.
5491*/
5492LPFC_ATTR_R(xri_rebalancing, 1, 0, 1, "Enable/Disable XRI rebalancing");
5493
5494/*
James Smart895427b2017-02-12 13:52:30 -08005495 * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds
5496 * range is [0,1]. Default value is 0.
James Smart45aa3122019-01-28 11:14:29 -08005497 * For [0], FCP commands are issued to Work Queues based on upper layer
5498 * hardware queue index.
James Smart895427b2017-02-12 13:52:30 -08005499 * For [1], FCP commands are issued to a Work Queue associated with the
5500 * current CPU.
5501 *
James Smart45aa3122019-01-28 11:14:29 -08005502 * LPFC_FCP_SCHED_BY_HDWQ == 0
James Smart895427b2017-02-12 13:52:30 -08005503 * LPFC_FCP_SCHED_BY_CPU == 1
5504 *
5505 * The driver dynamically sets this to 1 (BY_CPU) if it's able to set up cpu
5506 * affinity for FCP/NVME I/Os through Work Queues associated with the current
5507 * CPU. Otherwise, the default 0 (Round Robin) scheduling of FCP/NVME I/Os
5508 * through WQs will be used.
5509 */
James Smart6a828b02019-01-28 11:14:31 -08005510LPFC_ATTR_RW(fcp_io_sched, LPFC_FCP_SCHED_BY_CPU,
James Smart45aa3122019-01-28 11:14:29 -08005511 LPFC_FCP_SCHED_BY_HDWQ,
James Smart895427b2017-02-12 13:52:30 -08005512 LPFC_FCP_SCHED_BY_CPU,
5513 "Determine scheduling algorithm for "
James Smart45aa3122019-01-28 11:14:29 -08005514 "issuing commands [0] - Hardware Queue, [1] - Current CPU");
James Smart49aa1432012-08-03 12:36:42 -04005515
5516/*
James Smart7ea92eb2018-10-23 13:41:10 -07005517 * lpfc_ns_query: Determine algrithmn for NameServer queries after RSCN
5518 * range is [0,1]. Default value is 0.
5519 * For [0], GID_FT is used for NameServer queries after RSCN (default)
5520 * For [1], GID_PT is used for NameServer queries after RSCN
5521 *
5522 */
5523LPFC_ATTR_RW(ns_query, LPFC_NS_QUERY_GID_FT,
5524 LPFC_NS_QUERY_GID_FT, LPFC_NS_QUERY_GID_PT,
5525 "Determine algorithm NameServer queries after RSCN "
5526 "[0] - GID_FT, [1] - GID_PT");
5527
5528/*
James Smarta6571c62012-10-31 14:44:42 -04005529# lpfc_fcp2_no_tgt_reset: Determine bus reset behavior
5530# range is [0,1]. Default value is 0.
5531# For [0], bus reset issues target reset to ALL devices
5532# For [1], bus reset issues target reset to non-FCP2 devices
5533*/
5534LPFC_ATTR_RW(fcp2_no_tgt_reset, 0, 0, 1, "Determine bus reset behavior for "
5535 "FCP2 devices [0] - issue tgt reset, [1] - no tgt reset");
5536
5537
5538/*
dea31012005-04-17 16:05:31 -05005539# lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
5540# cr_delay (msec) or cr_count outstanding commands. cr_delay can take
James Smart7054a602007-04-25 09:52:34 -04005541# value [0,63]. cr_count can take value [1,255]. Default value of cr_delay
dea31012005-04-17 16:05:31 -05005542# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
5543# cr_delay is set to 0.
5544*/
Jamie Wellnitz8189fd12006-02-28 19:25:35 -05005545LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an "
dea31012005-04-17 16:05:31 -05005546 "interrupt response is generated");
5547
Jamie Wellnitz8189fd12006-02-28 19:25:35 -05005548LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "
dea31012005-04-17 16:05:31 -05005549 "interrupt response is generated");
5550
5551/*
Jamie Wellnitzcf5bf972006-02-28 22:33:08 -05005552# lpfc_multi_ring_support: Determines how many rings to spread available
5553# cmd/rsp IOCB entries across.
5554# Value range is [1,2]. Default value is 1.
5555*/
5556LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
5557 "SLI rings to spread IOCB entries across");
5558
5559/*
James Smarta4bc3372006-12-02 13:34:16 -05005560# lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this
5561# identifies what rctl value to configure the additional ring for.
5562# Value range is [1,0xff]. Default value is 4 (Unsolicated Data).
5563*/
James Smart6a9c52c2009-10-02 15:16:51 -04005564LPFC_ATTR_R(multi_ring_rctl, FC_RCTL_DD_UNSOL_DATA, 1,
James Smarta4bc3372006-12-02 13:34:16 -05005565 255, "Identifies RCTL for additional ring configuration");
5566
5567/*
5568# lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this
5569# identifies what type value to configure the additional ring for.
5570# Value range is [1,0xff]. Default value is 5 (LLC/SNAP).
5571*/
James Smart6a9c52c2009-10-02 15:16:51 -04005572LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP, 1,
James Smarta4bc3372006-12-02 13:34:16 -05005573 255, "Identifies TYPE for additional ring configuration");
5574
5575/*
James Smart4258e982015-12-16 18:11:58 -05005576# lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN
5577# 0 = SmartSAN functionality disabled (default)
5578# 1 = SmartSAN functionality enabled
5579# This parameter will override the value of lpfc_fdmi_on module parameter.
5580# Value range is [0,1]. Default value is 0.
dea31012005-04-17 16:05:31 -05005581*/
James Smart4258e982015-12-16 18:11:58 -05005582LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality");
5583
5584/*
5585# lpfc_fdmi_on: Controls FDMI support.
James Smart9abd9992018-08-14 12:55:05 -07005586# 0 No FDMI support
5587# 1 Traditional FDMI support (default)
James Smart8663cbb2016-03-31 14:12:33 -07005588# Traditional FDMI support means the driver will assume FDMI-2 support;
5589# however, if that fails, it will fallback to FDMI-1.
5590# If lpfc_enable_SmartSAN is set to 1, the driver ignores lpfc_fdmi_on.
5591# If lpfc_enable_SmartSAN is set 0, the driver uses the current value of
5592# lpfc_fdmi_on.
James Smart9abd9992018-08-14 12:55:05 -07005593# Value range [0,1]. Default value is 1.
James Smart4258e982015-12-16 18:11:58 -05005594*/
James Smart9abd9992018-08-14 12:55:05 -07005595LPFC_ATTR_R(fdmi_on, 1, 0, 1, "Enable FDMI support");
dea31012005-04-17 16:05:31 -05005596
5597/*
5598# Specifies the maximum number of ELS cmds we can have outstanding (for
5599# discovery). Value range is [1,64]. Default value = 32.
5600*/
James Smart3de2a652007-08-02 11:09:59 -04005601LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
dea31012005-04-17 16:05:31 -05005602 "during discovery");
5603
5604/*
James Smartc4a7c922013-05-31 17:04:59 -04005605# lpfc_max_luns: maximum allowed LUN ID. This is the highest LUN ID that
5606# will be scanned by the SCSI midlayer when sequential scanning is
5607# used; and is also the highest LUN ID allowed when the SCSI midlayer
5608# parses REPORT_LUN responses. The lpfc driver has no LUN count or
5609# LUN ID limit, but the SCSI midlayer requires this field for the uses
5610# above. The lpfc driver limits the default value to 255 for two reasons.
5611# As it bounds the sequential scan loop, scanning for thousands of luns
5612# on a target can take minutes of wall clock time. Additionally,
5613# there are FC targets, such as JBODs, that only recognize 8-bits of
5614# LUN ID. When they receive a value greater than 8 bits, they chop off
5615# the high order bits. In other words, they see LUN IDs 0, 256, 512,
5616# and so on all as LUN ID 0. This causes the linux kernel, which sees
5617# valid responses at each of the LUN IDs, to believe there are multiple
5618# devices present, when in fact, there is only 1.
5619# A customer that is aware of their target behaviors, and the results as
5620# indicated above, is welcome to increase the lpfc_max_luns value.
5621# As mentioned, this value is not used by the lpfc driver, only the
5622# SCSI midlayer.
James Smart65a29c12006-07-06 15:50:50 -04005623# Value range is [0,65535]. Default value is 255.
5624# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
dea31012005-04-17 16:05:31 -05005625*/
Hannes Reinecke1abf6352014-06-25 15:27:38 +02005626LPFC_VPORT_ULL_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN ID");
dea31012005-04-17 16:05:31 -05005627
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05005628/*
5629# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
5630# Value range is [1,255], default value is 10.
5631*/
5632LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
5633 "Milliseconds driver will wait between polling FCP ring");
5634
James Smart4ff43242006-12-02 13:34:56 -05005635/*
James Smart0c411222013-09-06 12:22:46 -04005636# lpfc_task_mgmt_tmo: Maximum time to wait for task management commands
5637# to complete in seconds. Value range is [5,180], default value is 60.
5638*/
5639LPFC_ATTR_RW(task_mgmt_tmo, 60, 5, 180,
5640 "Maximum time to wait for task management commands to complete");
5641/*
James Smart4ff43242006-12-02 13:34:56 -05005642# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
5643# support this feature
George Kadianakis8605c462010-01-17 21:19:31 +02005644# 0 = MSI disabled
James Smart4ff43242006-12-02 13:34:56 -05005645# 1 = MSI enabled
George Kadianakis8605c462010-01-17 21:19:31 +02005646# 2 = MSI-X enabled (default)
5647# Value range is [0,2]. Default value is 2.
James Smart4ff43242006-12-02 13:34:56 -05005648*/
George Kadianakis8605c462010-01-17 21:19:31 +02005649LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
James Smartdb2378e2008-02-08 18:49:51 -05005650 "MSI-X (2), if possible");
James Smart4ff43242006-12-02 13:34:56 -05005651
James Smart13815c82008-01-11 01:52:48 -05005652/*
James Smartf358dd02017-02-12 13:52:34 -08005653 * lpfc_nvme_oas: Use the oas bit when sending NVME/NVMET IOs
James Smart895427b2017-02-12 13:52:30 -08005654 *
5655 * 0 = NVME OAS disabled
5656 * 1 = NVME OAS enabled
5657 *
5658 * Value range is [0,1]. Default value is 0.
5659 */
5660LPFC_ATTR_RW(nvme_oas, 0, 0, 1,
5661 "Use OAS bit on NVME IOs");
5662
5663/*
James Smart4e565cf2018-02-22 08:18:50 -08005664 * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
5665 *
5666 * 0 = Put NVME Command in SGL
5667 * 1 = Embed NVME Command in WQE (unless G7)
5668 * 2 = Embed NVME Command in WQE (force)
5669 *
5670 * Value range is [0,2]. Default value is 1.
5671 */
5672LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
5673 "Embed NVME Command in WQE");
5674
5675/*
James Smart77ffd342019-08-15 19:36:49 -07005676 * lpfc_fcp_mq_threshold: Set the maximum number of Hardware Queues
5677 * the driver will advertise it supports to the SCSI layer.
5678 *
5679 * 0 = Set nr_hw_queues by the number of CPUs or HW queues.
James Smartdcaa2132019-11-04 16:57:06 -08005680 * 1,256 = Manually specify nr_hw_queue value to be advertised,
James Smart77ffd342019-08-15 19:36:49 -07005681 *
James Smart06228002019-08-27 14:28:23 -07005682 * Value range is [0,256]. Default value is 8.
James Smart77ffd342019-08-15 19:36:49 -07005683 */
5684LPFC_ATTR_R(fcp_mq_threshold, LPFC_FCP_MQ_THRESHOLD_DEF,
5685 LPFC_FCP_MQ_THRESHOLD_MIN, LPFC_FCP_MQ_THRESHOLD_MAX,
5686 "Set the number of SCSI Queues advertised");
5687
5688/*
James Smart6a828b02019-01-28 11:14:31 -08005689 * lpfc_hdw_queue: Set the number of Hardware Queues the driver
James Smartcdb42be2019-01-28 11:14:21 -08005690 * will advertise it supports to the NVME and SCSI layers. This also
James Smart6a828b02019-01-28 11:14:31 -08005691 * will map to the number of CQ/WQ pairs the driver will create.
James Smart895427b2017-02-12 13:52:30 -08005692 *
5693 * The NVME Layer will try to create this many, plus 1 administrative
5694 * hardware queue. The administrative queue will always map to WQ 0
James Smart6a828b02019-01-28 11:14:31 -08005695 * A hardware IO queue maps (qidx) to a specific driver CQ/WQ.
James Smart895427b2017-02-12 13:52:30 -08005696 *
James Smartcdb42be2019-01-28 11:14:21 -08005697 * 0 = Configure the number of hdw queues to the number of active CPUs.
James Smartdcaa2132019-11-04 16:57:06 -08005698 * 1,256 = Manually specify how many hdw queues to use.
James Smart895427b2017-02-12 13:52:30 -08005699 *
James Smartdcaa2132019-11-04 16:57:06 -08005700 * Value range is [0,256]. Default value is 0.
James Smart895427b2017-02-12 13:52:30 -08005701 */
James Smartcdb42be2019-01-28 11:14:21 -08005702LPFC_ATTR_R(hdw_queue,
5703 LPFC_HBA_HDWQ_DEF,
5704 LPFC_HBA_HDWQ_MIN, LPFC_HBA_HDWQ_MAX,
5705 "Set the number of I/O Hardware Queues");
James Smart895427b2017-02-12 13:52:30 -08005706
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005707#if IS_ENABLED(CONFIG_X86)
5708/**
5709 * lpfc_cpumask_irq_mode_init - initalizes cpumask of phba based on
5710 * irq_chann_mode
5711 * @phba: Pointer to HBA context object.
5712 **/
5713static void
5714lpfc_cpumask_irq_mode_init(struct lpfc_hba *phba)
5715{
5716 unsigned int cpu, first_cpu, numa_node = NUMA_NO_NODE;
5717 const struct cpumask *sibling_mask;
5718 struct cpumask *aff_mask = &phba->sli4_hba.irq_aff_mask;
5719
5720 cpumask_clear(aff_mask);
5721
5722 if (phba->irq_chann_mode == NUMA_MODE) {
5723 /* Check if we're a NUMA architecture */
5724 numa_node = dev_to_node(&phba->pcidev->dev);
5725 if (numa_node == NUMA_NO_NODE) {
5726 phba->irq_chann_mode = NORMAL_MODE;
5727 return;
5728 }
5729 }
5730
5731 for_each_possible_cpu(cpu) {
5732 switch (phba->irq_chann_mode) {
5733 case NUMA_MODE:
5734 if (cpu_to_node(cpu) == numa_node)
5735 cpumask_set_cpu(cpu, aff_mask);
5736 break;
5737 case NHT_MODE:
5738 sibling_mask = topology_sibling_cpumask(cpu);
5739 first_cpu = cpumask_first(sibling_mask);
5740 if (first_cpu < nr_cpu_ids)
5741 cpumask_set_cpu(first_cpu, aff_mask);
5742 break;
5743 default:
5744 break;
5745 }
5746 }
5747}
5748#endif
5749
5750static void
5751lpfc_assign_default_irq_chann(struct lpfc_hba *phba)
James Smartdcaa2132019-11-04 16:57:06 -08005752{
5753#if IS_ENABLED(CONFIG_X86)
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005754 switch (boot_cpu_data.x86_vendor) {
5755 case X86_VENDOR_AMD:
5756 /* If AMD architecture, then default is NUMA_MODE */
5757 phba->irq_chann_mode = NUMA_MODE;
5758 break;
5759 case X86_VENDOR_INTEL:
5760 /* If Intel architecture, then default is no hyperthread mode */
5761 phba->irq_chann_mode = NHT_MODE;
5762 break;
5763 default:
5764 phba->irq_chann_mode = NORMAL_MODE;
5765 break;
5766 }
5767 lpfc_cpumask_irq_mode_init(phba);
James Smartdcaa2132019-11-04 16:57:06 -08005768#else
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005769 phba->irq_chann_mode = NORMAL_MODE;
James Smartdcaa2132019-11-04 16:57:06 -08005770#endif
5771}
5772
James Smart895427b2017-02-12 13:52:30 -08005773/*
James Smart6a828b02019-01-28 11:14:31 -08005774 * lpfc_irq_chann: Set the number of IRQ vectors that are available
5775 * for Hardware Queues to utilize. This also will map to the number
5776 * of EQ / MSI-X vectors the driver will create. This should never be
5777 * more than the number of Hardware Queues
5778 *
James Smartdcaa2132019-11-04 16:57:06 -08005779 * 0 = Configure number of IRQ Channels to:
5780 * if AMD architecture, number of CPUs on HBA's NUMA node
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005781 * if Intel architecture, number of physical CPUs.
James Smartdcaa2132019-11-04 16:57:06 -08005782 * otherwise, number of active CPUs.
5783 * [1,256] = Manually specify how many IRQ Channels to use.
James Smart6a828b02019-01-28 11:14:31 -08005784 *
James Smartdcaa2132019-11-04 16:57:06 -08005785 * Value range is [0,256]. Default value is [0].
James Smart6a828b02019-01-28 11:14:31 -08005786 */
James Smartdcaa2132019-11-04 16:57:06 -08005787static uint lpfc_irq_chann = LPFC_IRQ_CHANN_DEF;
5788module_param(lpfc_irq_chann, uint, 0444);
5789MODULE_PARM_DESC(lpfc_irq_chann, "Set number of interrupt vectors to allocate");
5790
5791/* lpfc_irq_chann_init - Set the hba irq_chann initial value
5792 * @phba: lpfc_hba pointer.
5793 * @val: contains the initial value
5794 *
5795 * Description:
5796 * Validates the initial value is within range and assigns it to the
5797 * adapter. If not in range, an error message is posted and the
5798 * default value is assigned.
5799 *
5800 * Returns:
5801 * zero if value is in range and is set
5802 * -EINVAL if value was out of range
5803 **/
5804static int
5805lpfc_irq_chann_init(struct lpfc_hba *phba, uint32_t val)
5806{
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005807 const struct cpumask *aff_mask;
James Smartdcaa2132019-11-04 16:57:06 -08005808
5809 if (phba->cfg_use_msi != 2) {
5810 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5811 "8532 use_msi = %u ignoring cfg_irq_numa\n",
5812 phba->cfg_use_msi);
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005813 phba->irq_chann_mode = NORMAL_MODE;
5814 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005815 return 0;
5816 }
5817
5818 /* Check if default setting was passed */
5819 if (val == LPFC_IRQ_CHANN_DEF)
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005820 lpfc_assign_default_irq_chann(phba);
James Smartdcaa2132019-11-04 16:57:06 -08005821
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005822 if (phba->irq_chann_mode != NORMAL_MODE) {
5823 aff_mask = &phba->sli4_hba.irq_aff_mask;
James Smartdcaa2132019-11-04 16:57:06 -08005824
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005825 if (cpumask_empty(aff_mask)) {
James Smartdcaa2132019-11-04 16:57:06 -08005826 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005827 "8533 Could not identify CPUS for "
5828 "mode %d, ignoring\n",
5829 phba->irq_chann_mode);
5830 phba->irq_chann_mode = NORMAL_MODE;
5831 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005832 } else {
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005833 phba->cfg_irq_chann = cpumask_weight(aff_mask);
5834
5835 /* If no hyperthread mode, then set hdwq count to
5836 * aff_mask weight as well
5837 */
5838 if (phba->irq_chann_mode == NHT_MODE)
5839 phba->cfg_hdw_queue = phba->cfg_irq_chann;
5840
James Smartdcaa2132019-11-04 16:57:06 -08005841 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5842 "8543 lpfc_irq_chann set to %u "
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005843 "(mode: %d)\n", phba->cfg_irq_chann,
5844 phba->irq_chann_mode);
James Smartdcaa2132019-11-04 16:57:06 -08005845 }
5846 } else {
5847 if (val > LPFC_IRQ_CHANN_MAX) {
5848 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5849 "8545 lpfc_irq_chann attribute cannot "
5850 "be set to %u, allowed range is "
5851 "[%u,%u]\n",
5852 val,
5853 LPFC_IRQ_CHANN_MIN,
5854 LPFC_IRQ_CHANN_MAX);
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005855 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005856 return -EINVAL;
5857 }
5858 phba->cfg_irq_chann = val;
5859 }
5860
5861 return 0;
5862}
5863
5864/**
5865 * lpfc_irq_chann_show - Display value of irq_chann
5866 * @dev: class converted to a Scsi_host structure.
5867 * @attr: device attribute, not used.
5868 * @buf: on return contains a string with the list sizes
5869 *
5870 * Returns: size of formatted string.
5871 **/
5872static ssize_t
5873lpfc_irq_chann_show(struct device *dev, struct device_attribute *attr,
5874 char *buf)
5875{
5876 struct Scsi_Host *shost = class_to_shost(dev);
5877 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5878 struct lpfc_hba *phba = vport->phba;
5879
5880 return scnprintf(buf, PAGE_SIZE, "%u\n", phba->cfg_irq_chann);
5881}
5882
5883static DEVICE_ATTR_RO(lpfc_irq_chann);
James Smart6a828b02019-01-28 11:14:31 -08005884
5885/*
James Smart13815c82008-01-11 01:52:48 -05005886# lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware.
5887# 0 = HBA resets disabled
5888# 1 = HBA resets enabled (default)
James Smart50212672018-12-13 15:17:57 -08005889# 2 = HBA reset via PCI bus reset enabled
5890# Value range is [0,2]. Default value is 1.
James Smart13815c82008-01-11 01:52:48 -05005891*/
James Smart50212672018-12-13 15:17:57 -08005892LPFC_ATTR_RW(enable_hba_reset, 1, 0, 2, "Enable HBA resets from the driver.");
James Smartc3f28af2006-08-18 17:47:18 -04005893
James Smart13815c82008-01-11 01:52:48 -05005894/*
James Smarteb7a3392010-11-20 23:12:02 -05005895# lpfc_enable_hba_heartbeat: Disable HBA heartbeat timer..
James Smart13815c82008-01-11 01:52:48 -05005896# 0 = HBA Heartbeat disabled
5897# 1 = HBA Heartbeat enabled (default)
5898# Value range is [0,1]. Default value is 1.
5899*/
James Smarteb7a3392010-11-20 23:12:02 -05005900LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat.");
James Smart92d7f7b2007-06-17 19:56:38 -05005901
James Smart83108bd2008-01-11 01:53:09 -05005902/*
James Smart1ba981f2014-02-20 09:56:45 -05005903# lpfc_EnableXLane: Enable Express Lane Feature
5904# 0x0 Express Lane Feature disabled
5905# 0x1 Express Lane Feature enabled
5906# Value range is [0,1]. Default value is 0.
5907*/
5908LPFC_ATTR_R(EnableXLane, 0, 0, 1, "Enable Express Lane Feature.");
5909
5910/*
5911# lpfc_XLanePriority: Define CS_CTL priority for Express Lane Feature
5912# 0x0 - 0x7f = CS_CTL field in FC header (high 7 bits)
5913# Value range is [0x0,0x7f]. Default value is 0
5914*/
James Smart28d7f3d2014-05-21 08:05:28 -04005915LPFC_ATTR_RW(XLanePriority, 0, 0x0, 0x7f, "CS_CTL for Express Lane Feature.");
James Smart1ba981f2014-02-20 09:56:45 -05005916
5917/*
James Smart81301a92008-12-04 22:39:46 -05005918# lpfc_enable_bg: Enable BlockGuard (Emulex's Implementation of T10-DIF)
5919# 0 = BlockGuard disabled (default)
5920# 1 = BlockGuard enabled
5921# Value range is [0,1]. Default value is 0.
5922*/
5923LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
5924
James Smart6fb120a2009-05-22 14:52:59 -04005925/*
James Smart81301a92008-12-04 22:39:46 -05005926# lpfc_prot_mask: i
5927# - Bit mask of host protection capabilities used to register with the
5928# SCSI mid-layer
5929# - Only meaningful if BG is turned on (lpfc_enable_bg=1).
5930# - Allows you to ultimately specify which profiles to use
5931# - Default will result in registering capabilities for all profiles.
James Smart005ffa72012-09-29 11:29:17 -04005932# - SHOST_DIF_TYPE1_PROTECTION 1
5933# HBA supports T10 DIF Type 1: HBA to Target Type 1 Protection
5934# - SHOST_DIX_TYPE0_PROTECTION 8
5935# HBA supports DIX Type 0: Host to HBA protection only
5936# - SHOST_DIX_TYPE1_PROTECTION 16
5937# HBA supports DIX Type 1: Host to HBA Type 1 protection
James Smart81301a92008-12-04 22:39:46 -05005938#
5939*/
James Smartb3b98b72016-10-13 15:06:06 -07005940LPFC_ATTR(prot_mask,
5941 (SHOST_DIF_TYPE1_PROTECTION |
5942 SHOST_DIX_TYPE0_PROTECTION |
5943 SHOST_DIX_TYPE1_PROTECTION),
5944 0,
5945 (SHOST_DIF_TYPE1_PROTECTION |
5946 SHOST_DIX_TYPE0_PROTECTION |
5947 SHOST_DIX_TYPE1_PROTECTION),
5948 "T10-DIF host protection capabilities mask");
James Smart81301a92008-12-04 22:39:46 -05005949
5950/*
5951# lpfc_prot_guard: i
5952# - Bit mask of protection guard types to register with the SCSI mid-layer
James Smart005ffa72012-09-29 11:29:17 -04005953# - Guard types are currently either 1) T10-DIF CRC 2) IP checksum
James Smart81301a92008-12-04 22:39:46 -05005954# - Allows you to ultimately specify which profiles to use
5955# - Default will result in registering capabilities for all guard types
5956#
5957*/
James Smartb3b98b72016-10-13 15:06:06 -07005958LPFC_ATTR(prot_guard,
5959 SHOST_DIX_GUARD_IP, SHOST_DIX_GUARD_CRC, SHOST_DIX_GUARD_IP,
5960 "T10-DIF host protection guard type");
James Smart81301a92008-12-04 22:39:46 -05005961
James Smart92494142011-02-16 12:39:44 -05005962/*
5963 * Delay initial NPort discovery when Clean Address bit is cleared in
5964 * FLOGI/FDISC accept and FCID/Fabric name/Fabric portname is changed.
5965 * This parameter can have value 0 or 1.
5966 * When this parameter is set to 0, no delay is added to the initial
5967 * discovery.
5968 * When this parameter is set to non-zero value, initial Nport discovery is
5969 * delayed by ra_tov seconds when Clean Address bit is cleared in FLOGI/FDISC
5970 * accept and FCID/Fabric name/Fabric portname is changed.
5971 * Driver always delay Nport discovery for subsequent FLOGI/FDISC completion
5972 * when Clean Address bit is cleared in FLOGI/FDISC
5973 * accept and FCID/Fabric name/Fabric portname is changed.
5974 * Default value is 0.
5975 */
James Smart8eb8b962016-07-06 12:36:08 -07005976LPFC_ATTR(delay_discovery, 0, 0, 1,
5977 "Delay NPort discovery when Clean Address bit is cleared.");
James Smart81301a92008-12-04 22:39:46 -05005978
5979/*
James Smart3621a712009-04-06 18:47:14 -04005980 * lpfc_sg_seg_cnt - Initial Maximum DMA Segment Count
James Smart5b9e70b2018-09-10 10:30:42 -07005981 * This value can be set to values between 64 and 4096. The default value
5982 * is 64, but may be increased to allow for larger Max I/O sizes. The scsi
5983 * and nvme layers will allow I/O sizes up to (MAX_SEG_COUNT * SEG_SIZE).
James Smart96f70772013-04-17 20:16:15 -04005984 * Because of the additional overhead involved in setting up T10-DIF,
5985 * this parameter will be limited to 128 if BlockGuard is enabled under SLI4
5986 * and will be limited to 512 if BlockGuard is enabled under SLI3.
James Smart83108bd2008-01-11 01:53:09 -05005987 */
James Smart5b9e70b2018-09-10 10:30:42 -07005988static uint lpfc_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
5989module_param(lpfc_sg_seg_cnt, uint, 0444);
5990MODULE_PARM_DESC(lpfc_sg_seg_cnt, "Max Scatter Gather Segment Count");
5991
5992/**
5993 * lpfc_sg_seg_cnt_show - Display the scatter/gather list sizes
5994 * configured for the adapter
5995 * @dev: class converted to a Scsi_host structure.
5996 * @attr: device attribute, not used.
5997 * @buf: on return contains a string with the list sizes
5998 *
5999 * Returns: size of formatted string.
6000 **/
6001static ssize_t
6002lpfc_sg_seg_cnt_show(struct device *dev, struct device_attribute *attr,
6003 char *buf)
6004{
6005 struct Scsi_Host *shost = class_to_shost(dev);
6006 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
6007 struct lpfc_hba *phba = vport->phba;
6008 int len;
6009
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07006010 len = scnprintf(buf, PAGE_SIZE, "SGL sz: %d total SGEs: %d\n",
James Smart5b9e70b2018-09-10 10:30:42 -07006011 phba->cfg_sg_dma_buf_size, phba->cfg_total_seg_cnt);
6012
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07006013 len += scnprintf(buf + len, PAGE_SIZE, "Cfg: %d SCSI: %d NVME: %d\n",
James Smart5b9e70b2018-09-10 10:30:42 -07006014 phba->cfg_sg_seg_cnt, phba->cfg_scsi_seg_cnt,
6015 phba->cfg_nvme_seg_cnt);
6016 return len;
6017}
6018
6019static DEVICE_ATTR_RO(lpfc_sg_seg_cnt);
6020
6021/**
6022 * lpfc_sg_seg_cnt_init - Set the hba sg_seg_cnt initial value
6023 * @phba: lpfc_hba pointer.
6024 * @val: contains the initial value
6025 *
6026 * Description:
6027 * Validates the initial value is within range and assigns it to the
6028 * adapter. If not in range, an error message is posted and the
6029 * default value is assigned.
6030 *
6031 * Returns:
6032 * zero if value is in range and is set
6033 * -EINVAL if value was out of range
6034 **/
6035static int
6036lpfc_sg_seg_cnt_init(struct lpfc_hba *phba, int val)
6037{
6038 if (val >= LPFC_MIN_SG_SEG_CNT && val <= LPFC_MAX_SG_SEG_CNT) {
6039 phba->cfg_sg_seg_cnt = val;
6040 return 0;
6041 }
6042 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
6043 "0409 "LPFC_DRIVER_NAME"_sg_seg_cnt attribute cannot "
6044 "be set to %d, allowed range is [%d, %d]\n",
6045 val, LPFC_MIN_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT);
6046 phba->cfg_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
6047 return -EINVAL;
6048}
James Smart83108bd2008-01-11 01:53:09 -05006049
James Smart96f70772013-04-17 20:16:15 -04006050/*
James Smart7bdedb32016-07-06 12:36:00 -07006051 * lpfc_enable_mds_diags: Enable MDS Diagnostics
6052 * 0 = MDS Diagnostics disabled (default)
6053 * 1 = MDS Diagnostics enabled
6054 * Value range is [0,1]. Default value is 0.
6055 */
James Smarte62245d2019-08-14 16:57:08 -07006056LPFC_ATTR_RW(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");
James Smart7bdedb32016-07-06 12:36:00 -07006057
James Smart44fd7fe2017-08-23 16:55:47 -07006058/*
James Smartd2cc9bc2018-09-10 10:30:50 -07006059 * lpfc_ras_fwlog_buffsize: Firmware logging host buffer size
6060 * 0 = Disable firmware logging (default)
6061 * [1-4] = Multiple of 1/4th Mb of host memory for FW logging
6062 * Value range [0..4]. Default value is 0
6063 */
James Smart95bfc6d2019-10-18 14:18:27 -07006064LPFC_ATTR(ras_fwlog_buffsize, 0, 0, 4, "Host memory for FW logging");
6065lpfc_param_show(ras_fwlog_buffsize);
6066
6067static ssize_t
6068lpfc_ras_fwlog_buffsize_set(struct lpfc_hba *phba, uint val)
6069{
6070 int ret = 0;
6071 enum ras_state state;
6072
6073 if (!lpfc_rangecheck(val, 0, 4))
6074 return -EINVAL;
6075
6076 if (phba->cfg_ras_fwlog_buffsize == val)
6077 return 0;
6078
James Smartdda5bdf2019-11-04 16:57:02 -08006079 if (phba->cfg_ras_fwlog_func != PCI_FUNC(phba->pcidev->devfn))
James Smart95bfc6d2019-10-18 14:18:27 -07006080 return -EINVAL;
6081
6082 spin_lock_irq(&phba->hbalock);
6083 state = phba->ras_fwlog.state;
6084 spin_unlock_irq(&phba->hbalock);
6085
6086 if (state == REG_INPROGRESS) {
6087 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "6147 RAS Logging "
6088 "registration is in progress\n");
6089 return -EBUSY;
6090 }
6091
6092 /* For disable logging: stop the logs and free the DMA.
6093 * For ras_fwlog_buffsize size change we still need to free and
6094 * reallocate the DMA in lpfc_sli4_ras_fwlog_init.
6095 */
6096 phba->cfg_ras_fwlog_buffsize = val;
6097 if (state == ACTIVE) {
6098 lpfc_ras_stop_fwlog(phba);
6099 lpfc_sli4_ras_dma_free(phba);
6100 }
6101
6102 lpfc_sli4_ras_init(phba);
6103 if (phba->ras_fwlog.ras_enabled)
6104 ret = lpfc_sli4_ras_fwlog_init(phba, phba->cfg_ras_fwlog_level,
6105 LPFC_RAS_ENABLE_LOGGING);
6106 return ret;
6107}
6108
6109lpfc_param_store(ras_fwlog_buffsize);
6110static DEVICE_ATTR_RW(lpfc_ras_fwlog_buffsize);
James Smartd2cc9bc2018-09-10 10:30:50 -07006111
6112/*
6113 * lpfc_ras_fwlog_level: Firmware logging verbosity level
6114 * Valid only if firmware logging is enabled
6115 * 0(Least Verbosity) 4 (most verbosity)
6116 * Value range is [0..4]. Default value is 0
6117 */
6118LPFC_ATTR_RW(ras_fwlog_level, 0, 0, 4, "Firmware Logging Level");
6119
6120/*
6121 * lpfc_ras_fwlog_func: Firmware logging enabled on function number
6122 * Default function which has RAS support : 0
6123 * Value Range is [0..7].
6124 * FW logging is a global action and enablement is via a specific
6125 * port.
6126 */
6127LPFC_ATTR_RW(ras_fwlog_func, 0, 0, 7, "Firmware Logging Enabled on Function");
6128
6129/*
James Smart44fd7fe2017-08-23 16:55:47 -07006130 * lpfc_enable_bbcr: Enable BB Credit Recovery
6131 * 0 = BB Credit Recovery disabled
6132 * 1 = BB Credit Recovery enabled (default)
6133 * Value range is [0,1]. Default value is 1.
6134 */
6135LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
6136
James Smart1351e692018-02-22 08:18:43 -08006137/*
6138 * lpfc_enable_dpp: Enable DPP on G7
6139 * 0 = DPP on G7 disabled
6140 * 1 = DPP on G7 enabled (default)
6141 * Value range is [0,1]. Default value is 1.
6142 */
6143LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
6144
James Smart8aaa7bc2020-10-20 13:27:17 -07006145/*
6146 * lpfc_enable_mi: Enable FDMI MIB
6147 * 0 = disabled
6148 * 1 = enabled (default)
6149 * Value range is [0,1].
6150 */
6151LPFC_ATTR_R(enable_mi, 1, 0, 1, "Enable MI");
6152
Tony Jonesee959b02008-02-22 00:13:36 +01006153struct device_attribute *lpfc_hba_attrs[] = {
James Smart895427b2017-02-12 13:52:30 -08006154 &dev_attr_nvme_info,
James Smart4c47efc2019-01-28 11:14:25 -08006155 &dev_attr_scsi_stat,
James Smart81301a92008-12-04 22:39:46 -05006156 &dev_attr_bg_info,
6157 &dev_attr_bg_guard_err,
6158 &dev_attr_bg_apptag_err,
6159 &dev_attr_bg_reftag_err,
Tony Jonesee959b02008-02-22 00:13:36 +01006160 &dev_attr_info,
6161 &dev_attr_serialnum,
6162 &dev_attr_modeldesc,
6163 &dev_attr_modelname,
6164 &dev_attr_programtype,
6165 &dev_attr_portnum,
6166 &dev_attr_fwrev,
6167 &dev_attr_hdw,
6168 &dev_attr_option_rom_version,
Hannes Reineckebbd1ae42008-03-18 14:32:28 +01006169 &dev_attr_link_state,
Tony Jonesee959b02008-02-22 00:13:36 +01006170 &dev_attr_num_discovered_ports,
James Smart84774a42008-08-24 21:50:06 -04006171 &dev_attr_menlo_mgmt_mode,
Tony Jonesee959b02008-02-22 00:13:36 +01006172 &dev_attr_lpfc_drvr_version,
James Smart45ed1192009-10-02 15:17:02 -04006173 &dev_attr_lpfc_enable_fip,
Tony Jonesee959b02008-02-22 00:13:36 +01006174 &dev_attr_lpfc_temp_sensor,
6175 &dev_attr_lpfc_log_verbose,
6176 &dev_attr_lpfc_lun_queue_depth,
James Smart7dc517d2010-07-14 15:32:10 -04006177 &dev_attr_lpfc_tgt_queue_depth,
Tony Jonesee959b02008-02-22 00:13:36 +01006178 &dev_attr_lpfc_hba_queue_depth,
6179 &dev_attr_lpfc_peer_port_login,
6180 &dev_attr_lpfc_nodev_tmo,
6181 &dev_attr_lpfc_devloss_tmo,
James Smart895427b2017-02-12 13:52:30 -08006182 &dev_attr_lpfc_enable_fc4_type,
Tony Jonesee959b02008-02-22 00:13:36 +01006183 &dev_attr_lpfc_fcp_class,
6184 &dev_attr_lpfc_use_adisc,
James Smart3cb01c52013-07-15 18:35:04 -04006185 &dev_attr_lpfc_first_burst_size,
Tony Jonesee959b02008-02-22 00:13:36 +01006186 &dev_attr_lpfc_ack0,
James Smartc4908502019-01-28 11:14:28 -08006187 &dev_attr_lpfc_xri_rebalancing,
Tony Jonesee959b02008-02-22 00:13:36 +01006188 &dev_attr_lpfc_topology,
6189 &dev_attr_lpfc_scan_down,
6190 &dev_attr_lpfc_link_speed,
James Smart49aa1432012-08-03 12:36:42 -04006191 &dev_attr_lpfc_fcp_io_sched,
James Smart7ea92eb2018-10-23 13:41:10 -07006192 &dev_attr_lpfc_ns_query,
James Smarta6571c62012-10-31 14:44:42 -04006193 &dev_attr_lpfc_fcp2_no_tgt_reset,
Tony Jonesee959b02008-02-22 00:13:36 +01006194 &dev_attr_lpfc_cr_delay,
6195 &dev_attr_lpfc_cr_count,
6196 &dev_attr_lpfc_multi_ring_support,
6197 &dev_attr_lpfc_multi_ring_rctl,
6198 &dev_attr_lpfc_multi_ring_type,
6199 &dev_attr_lpfc_fdmi_on,
James Smart4258e982015-12-16 18:11:58 -05006200 &dev_attr_lpfc_enable_SmartSAN,
Tony Jonesee959b02008-02-22 00:13:36 +01006201 &dev_attr_lpfc_max_luns,
6202 &dev_attr_lpfc_enable_npiv,
James Smart7d791df2011-07-22 18:37:52 -04006203 &dev_attr_lpfc_fcf_failover_policy,
James Smart19ca7602010-11-20 23:11:55 -05006204 &dev_attr_lpfc_enable_rrq,
Tony Jonesee959b02008-02-22 00:13:36 +01006205 &dev_attr_nport_evt_cnt,
6206 &dev_attr_board_mode,
6207 &dev_attr_max_vpi,
6208 &dev_attr_used_vpi,
6209 &dev_attr_max_rpi,
6210 &dev_attr_used_rpi,
6211 &dev_attr_max_xri,
6212 &dev_attr_used_xri,
6213 &dev_attr_npiv_info,
6214 &dev_attr_issue_reset,
6215 &dev_attr_lpfc_poll,
6216 &dev_attr_lpfc_poll_tmo,
James Smart0c411222013-09-06 12:22:46 -04006217 &dev_attr_lpfc_task_mgmt_tmo,
Tony Jonesee959b02008-02-22 00:13:36 +01006218 &dev_attr_lpfc_use_msi,
James Smart895427b2017-02-12 13:52:30 -08006219 &dev_attr_lpfc_nvme_oas,
James Smart4e565cf2018-02-22 08:18:50 -08006220 &dev_attr_lpfc_nvme_embed_cmd,
James Smartda0436e2009-05-22 14:51:39 -04006221 &dev_attr_lpfc_fcp_imax,
James Smart41b194b2019-05-14 14:58:08 -07006222 &dev_attr_lpfc_force_rscn,
James Smart32517fc2019-01-28 11:14:33 -08006223 &dev_attr_lpfc_cq_poll_threshold,
6224 &dev_attr_lpfc_cq_max_proc_limit,
James Smart7bb03bb2013-04-17 20:19:16 -04006225 &dev_attr_lpfc_fcp_cpu_map,
James Smart77ffd342019-08-15 19:36:49 -07006226 &dev_attr_lpfc_fcp_mq_threshold,
James Smartcdb42be2019-01-28 11:14:21 -08006227 &dev_attr_lpfc_hdw_queue,
James Smart6a828b02019-01-28 11:14:31 -08006228 &dev_attr_lpfc_irq_chann,
James Smartf358dd02017-02-12 13:52:34 -08006229 &dev_attr_lpfc_suppress_rsp,
James Smart2d7dbc42017-02-12 13:52:35 -08006230 &dev_attr_lpfc_nvmet_mrq,
James Smart2448e482018-04-09 14:24:24 -07006231 &dev_attr_lpfc_nvmet_mrq_post,
James Smart895427b2017-02-12 13:52:30 -08006232 &dev_attr_lpfc_nvme_enable_fb,
James Smart2d7dbc42017-02-12 13:52:35 -08006233 &dev_attr_lpfc_nvmet_fb_size,
James Smart81301a92008-12-04 22:39:46 -05006234 &dev_attr_lpfc_enable_bg,
James Smart352e5fd2016-12-30 06:57:47 -08006235 &dev_attr_lpfc_soft_wwnn,
6236 &dev_attr_lpfc_soft_wwpn,
6237 &dev_attr_lpfc_soft_wwn_enable,
Tony Jonesee959b02008-02-22 00:13:36 +01006238 &dev_attr_lpfc_enable_hba_reset,
6239 &dev_attr_lpfc_enable_hba_heartbeat,
James Smart1ba981f2014-02-20 09:56:45 -05006240 &dev_attr_lpfc_EnableXLane,
6241 &dev_attr_lpfc_XLanePriority,
6242 &dev_attr_lpfc_xlane_lun,
6243 &dev_attr_lpfc_xlane_tgt,
6244 &dev_attr_lpfc_xlane_vpt,
6245 &dev_attr_lpfc_xlane_lun_state,
6246 &dev_attr_lpfc_xlane_lun_status,
James Smartc92c8412016-07-06 12:36:05 -07006247 &dev_attr_lpfc_xlane_priority,
Tony Jonesee959b02008-02-22 00:13:36 +01006248 &dev_attr_lpfc_sg_seg_cnt,
James Smart977b5a02008-09-07 11:52:04 -04006249 &dev_attr_lpfc_max_scsicmpl_time,
James Smartea2151b2008-09-07 11:52:10 -04006250 &dev_attr_lpfc_stat_data_ctrl,
James Smart0d878412009-10-02 15:16:56 -04006251 &dev_attr_lpfc_aer_support,
6252 &dev_attr_lpfc_aer_state_cleanup,
James Smart912e3ac2011-05-24 11:42:11 -04006253 &dev_attr_lpfc_sriov_nr_virtfn,
James Smartc71ab862012-10-31 14:44:33 -04006254 &dev_attr_lpfc_req_fw_upgrade,
James Smart84d1b002010-02-12 14:42:33 -05006255 &dev_attr_lpfc_suppress_link_up,
James Smart2a9bf3d2010-06-07 15:24:45 -04006256 &dev_attr_iocb_hw,
James Smart83c6cb12019-10-18 14:18:30 -07006257 &dev_attr_pls,
6258 &dev_attr_pt,
James Smart2a9bf3d2010-06-07 15:24:45 -04006259 &dev_attr_txq_hw,
6260 &dev_attr_txcmplq_hw,
James Smart912e3ac2011-05-24 11:42:11 -04006261 &dev_attr_lpfc_sriov_hw_max_virtfn,
James Smart026abb82011-12-13 13:20:45 -05006262 &dev_attr_protocol,
James Smart1ba981f2014-02-20 09:56:45 -05006263 &dev_attr_lpfc_xlane_supported,
James Smart7bdedb32016-07-06 12:36:00 -07006264 &dev_attr_lpfc_enable_mds_diags,
James Smartd2cc9bc2018-09-10 10:30:50 -07006265 &dev_attr_lpfc_ras_fwlog_buffsize,
6266 &dev_attr_lpfc_ras_fwlog_level,
6267 &dev_attr_lpfc_ras_fwlog_func,
James Smart44fd7fe2017-08-23 16:55:47 -07006268 &dev_attr_lpfc_enable_bbcr,
James Smart1351e692018-02-22 08:18:43 -08006269 &dev_attr_lpfc_enable_dpp,
James Smart8aaa7bc2020-10-20 13:27:17 -07006270 &dev_attr_lpfc_enable_mi,
dea31012005-04-17 16:05:31 -05006271 NULL,
6272};
6273
Tony Jonesee959b02008-02-22 00:13:36 +01006274struct device_attribute *lpfc_vport_attrs[] = {
6275 &dev_attr_info,
Hannes Reineckebbd1ae42008-03-18 14:32:28 +01006276 &dev_attr_link_state,
Tony Jonesee959b02008-02-22 00:13:36 +01006277 &dev_attr_num_discovered_ports,
6278 &dev_attr_lpfc_drvr_version,
6279 &dev_attr_lpfc_log_verbose,
6280 &dev_attr_lpfc_lun_queue_depth,
James Smart7dc517d2010-07-14 15:32:10 -04006281 &dev_attr_lpfc_tgt_queue_depth,
Tony Jonesee959b02008-02-22 00:13:36 +01006282 &dev_attr_lpfc_nodev_tmo,
6283 &dev_attr_lpfc_devloss_tmo,
6284 &dev_attr_lpfc_hba_queue_depth,
6285 &dev_attr_lpfc_peer_port_login,
6286 &dev_attr_lpfc_restrict_login,
6287 &dev_attr_lpfc_fcp_class,
6288 &dev_attr_lpfc_use_adisc,
James Smart3cb01c52013-07-15 18:35:04 -04006289 &dev_attr_lpfc_first_burst_size,
Tony Jonesee959b02008-02-22 00:13:36 +01006290 &dev_attr_lpfc_max_luns,
6291 &dev_attr_nport_evt_cnt,
6292 &dev_attr_npiv_info,
6293 &dev_attr_lpfc_enable_da_id,
James Smartea2151b2008-09-07 11:52:10 -04006294 &dev_attr_lpfc_max_scsicmpl_time,
6295 &dev_attr_lpfc_stat_data_ctrl,
James Smart21e9a0a2009-05-22 14:53:21 -04006296 &dev_attr_lpfc_static_vport,
James Smart3de2a652007-08-02 11:09:59 -04006297 NULL,
6298};
6299
James Smarte59058c2008-08-24 21:49:00 -04006300/**
James Smart3621a712009-04-06 18:47:14 -04006301 * sysfs_ctlreg_write - Write method for writing to ctlreg
Chris Wright2c3c8be2010-05-12 18:28:57 -07006302 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006303 * @kobj: kernel kobject that contains the kernel class device.
6304 * @bin_attr: kernel attributes passed to us.
6305 * @buf: contains the data to be written to the adapter IOREG space.
6306 * @off: offset into buffer to beginning of data.
6307 * @count: bytes to transfer.
6308 *
6309 * Description:
6310 * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
6311 * Uses the adapter io control registers to send buf contents to the adapter.
6312 *
6313 * Returns:
6314 * -ERANGE off and count combo out of range
6315 * -EINVAL off, count or buff address invalid
6316 * -EPERM adapter is offline
6317 * value of count, buf contents written
6318 **/
dea31012005-04-17 16:05:31 -05006319static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006320sysfs_ctlreg_write(struct file *filp, struct kobject *kobj,
6321 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006322 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006323{
6324 size_t buf_off;
Tony Jonesee959b02008-02-22 00:13:36 +01006325 struct device *dev = container_of(kobj, struct device, kobj);
6326 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05006327 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6328 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006329
James Smartf1126682009-06-10 17:22:44 -04006330 if (phba->sli_rev >= LPFC_SLI_REV4)
6331 return -EPERM;
6332
dea31012005-04-17 16:05:31 -05006333 if ((off + count) > FF_REG_AREA_SIZE)
6334 return -ERANGE;
6335
James Smartf7a919b2011-08-21 21:49:16 -04006336 if (count <= LPFC_REG_WRITE_KEY_SIZE)
6337 return 0;
dea31012005-04-17 16:05:31 -05006338
6339 if (off % 4 || count % 4 || (unsigned long)buf % 4)
6340 return -EINVAL;
6341
James Smartf7a919b2011-08-21 21:49:16 -04006342 /* This is to protect HBA registers from accidental writes. */
6343 if (memcmp(buf, LPFC_REG_WRITE_KEY, LPFC_REG_WRITE_KEY_SIZE))
6344 return -EINVAL;
6345
6346 if (!(vport->fc_flag & FC_OFFLINE_MODE))
dea31012005-04-17 16:05:31 -05006347 return -EPERM;
dea31012005-04-17 16:05:31 -05006348
James Smart2e0fef82007-06-17 19:56:36 -05006349 spin_lock_irq(&phba->hbalock);
James Smartf7a919b2011-08-21 21:49:16 -04006350 for (buf_off = 0; buf_off < count - LPFC_REG_WRITE_KEY_SIZE;
6351 buf_off += sizeof(uint32_t))
6352 writel(*((uint32_t *)(buf + buf_off + LPFC_REG_WRITE_KEY_SIZE)),
dea31012005-04-17 16:05:31 -05006353 phba->ctrl_regs_memmap_p + off + buf_off);
6354
James Smart2e0fef82007-06-17 19:56:36 -05006355 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006356
6357 return count;
6358}
6359
James Smarte59058c2008-08-24 21:49:00 -04006360/**
James Smart3621a712009-04-06 18:47:14 -04006361 * sysfs_ctlreg_read - Read method for reading from ctlreg
Chris Wright2c3c8be2010-05-12 18:28:57 -07006362 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006363 * @kobj: kernel kobject that contains the kernel class device.
6364 * @bin_attr: kernel attributes passed to us.
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02006365 * @buf: if successful contains the data from the adapter IOREG space.
James Smarte59058c2008-08-24 21:49:00 -04006366 * @off: offset into buffer to beginning of data.
6367 * @count: bytes to transfer.
6368 *
6369 * Description:
6370 * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
6371 * Uses the adapter io control registers to read data into buf.
6372 *
6373 * Returns:
6374 * -ERANGE off and count combo out of range
6375 * -EINVAL off, count or buff address invalid
6376 * value of count, buf contents read
6377 **/
dea31012005-04-17 16:05:31 -05006378static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006379sysfs_ctlreg_read(struct file *filp, struct kobject *kobj,
6380 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006381 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006382{
6383 size_t buf_off;
6384 uint32_t * tmp_ptr;
Tony Jonesee959b02008-02-22 00:13:36 +01006385 struct device *dev = container_of(kobj, struct device, kobj);
6386 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05006387 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6388 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006389
James Smartf1126682009-06-10 17:22:44 -04006390 if (phba->sli_rev >= LPFC_SLI_REV4)
6391 return -EPERM;
6392
dea31012005-04-17 16:05:31 -05006393 if (off > FF_REG_AREA_SIZE)
6394 return -ERANGE;
6395
6396 if ((off + count) > FF_REG_AREA_SIZE)
6397 count = FF_REG_AREA_SIZE - off;
6398
6399 if (count == 0) return 0;
6400
6401 if (off % 4 || count % 4 || (unsigned long)buf % 4)
6402 return -EINVAL;
6403
James Smart2e0fef82007-06-17 19:56:36 -05006404 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006405
6406 for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {
6407 tmp_ptr = (uint32_t *)(buf + buf_off);
6408 *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);
6409 }
6410
James Smart2e0fef82007-06-17 19:56:36 -05006411 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006412
6413 return count;
6414}
6415
6416static struct bin_attribute sysfs_ctlreg_attr = {
6417 .attr = {
6418 .name = "ctlreg",
6419 .mode = S_IRUSR | S_IWUSR,
dea31012005-04-17 16:05:31 -05006420 },
6421 .size = 256,
6422 .read = sysfs_ctlreg_read,
6423 .write = sysfs_ctlreg_write,
6424};
6425
James Smarte59058c2008-08-24 21:49:00 -04006426/**
James Smart3621a712009-04-06 18:47:14 -04006427 * sysfs_mbox_write - Write method for writing information via mbox
Chris Wright2c3c8be2010-05-12 18:28:57 -07006428 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006429 * @kobj: kernel kobject that contains the kernel class device.
6430 * @bin_attr: kernel attributes passed to us.
6431 * @buf: contains the data to be written to sysfs mbox.
6432 * @off: offset into buffer to beginning of data.
6433 * @count: bytes to transfer.
6434 *
6435 * Description:
James Smart026abb82011-12-13 13:20:45 -05006436 * Deprecated function. All mailbox access from user space is performed via the
6437 * bsg interface.
James Smarte59058c2008-08-24 21:49:00 -04006438 *
6439 * Returns:
James Smart026abb82011-12-13 13:20:45 -05006440 * -EPERM operation not permitted
James Smarte59058c2008-08-24 21:49:00 -04006441 **/
dea31012005-04-17 16:05:31 -05006442static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006443sysfs_mbox_write(struct file *filp, struct kobject *kobj,
6444 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006445 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006446{
James Smart026abb82011-12-13 13:20:45 -05006447 return -EPERM;
dea31012005-04-17 16:05:31 -05006448}
6449
James Smarte59058c2008-08-24 21:49:00 -04006450/**
James Smart3621a712009-04-06 18:47:14 -04006451 * sysfs_mbox_read - Read method for reading information via mbox
Chris Wright2c3c8be2010-05-12 18:28:57 -07006452 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006453 * @kobj: kernel kobject that contains the kernel class device.
6454 * @bin_attr: kernel attributes passed to us.
6455 * @buf: contains the data to be read from sysfs mbox.
6456 * @off: offset into buffer to beginning of data.
6457 * @count: bytes to transfer.
6458 *
6459 * Description:
James Smart026abb82011-12-13 13:20:45 -05006460 * Deprecated function. All mailbox access from user space is performed via the
6461 * bsg interface.
James Smarte59058c2008-08-24 21:49:00 -04006462 *
6463 * Returns:
James Smart026abb82011-12-13 13:20:45 -05006464 * -EPERM operation not permitted
James Smarte59058c2008-08-24 21:49:00 -04006465 **/
dea31012005-04-17 16:05:31 -05006466static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006467sysfs_mbox_read(struct file *filp, struct kobject *kobj,
6468 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006469 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006470{
James Smart026abb82011-12-13 13:20:45 -05006471 return -EPERM;
dea31012005-04-17 16:05:31 -05006472}
6473
6474static struct bin_attribute sysfs_mbox_attr = {
6475 .attr = {
6476 .name = "mbox",
6477 .mode = S_IRUSR | S_IWUSR,
dea31012005-04-17 16:05:31 -05006478 },
James Smartc0c11512011-05-24 11:41:34 -04006479 .size = MAILBOX_SYSFS_MAX,
dea31012005-04-17 16:05:31 -05006480 .read = sysfs_mbox_read,
6481 .write = sysfs_mbox_write,
6482};
6483
James Smarte59058c2008-08-24 21:49:00 -04006484/**
James Smart3621a712009-04-06 18:47:14 -04006485 * lpfc_alloc_sysfs_attr - Creates the ctlreg and mbox entries
James Smarte59058c2008-08-24 21:49:00 -04006486 * @vport: address of lpfc vport structure.
6487 *
6488 * Return codes:
6489 * zero on success
6490 * error return code from sysfs_create_bin_file()
6491 **/
dea31012005-04-17 16:05:31 -05006492int
James Smart2e0fef82007-06-17 19:56:36 -05006493lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05006494{
James Smart2e0fef82007-06-17 19:56:36 -05006495 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05006496 int error;
6497
Tony Jonesee959b02008-02-22 00:13:36 +01006498 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smarteada2722008-12-04 22:39:13 -05006499 &sysfs_drvr_stat_data_attr);
6500
6501 /* Virtual ports do not need ctrl_reg and mbox */
6502 if (error || vport->port_type == LPFC_NPIV_PORT)
6503 goto out;
6504
6505 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smart92d7f7b2007-06-17 19:56:38 -05006506 &sysfs_ctlreg_attr);
dea31012005-04-17 16:05:31 -05006507 if (error)
James Smarteada2722008-12-04 22:39:13 -05006508 goto out_remove_stat_attr;
dea31012005-04-17 16:05:31 -05006509
Tony Jonesee959b02008-02-22 00:13:36 +01006510 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smart92d7f7b2007-06-17 19:56:38 -05006511 &sysfs_mbox_attr);
dea31012005-04-17 16:05:31 -05006512 if (error)
6513 goto out_remove_ctlreg_attr;
6514
6515 return 0;
6516out_remove_ctlreg_attr:
Tony Jonesee959b02008-02-22 00:13:36 +01006517 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
James Smarteada2722008-12-04 22:39:13 -05006518out_remove_stat_attr:
6519 sysfs_remove_bin_file(&shost->shost_dev.kobj,
6520 &sysfs_drvr_stat_data_attr);
dea31012005-04-17 16:05:31 -05006521out:
6522 return error;
6523}
6524
James Smarte59058c2008-08-24 21:49:00 -04006525/**
James Smart3621a712009-04-06 18:47:14 -04006526 * lpfc_free_sysfs_attr - Removes the ctlreg and mbox entries
James Smarte59058c2008-08-24 21:49:00 -04006527 * @vport: address of lpfc vport structure.
6528 **/
dea31012005-04-17 16:05:31 -05006529void
James Smart2e0fef82007-06-17 19:56:36 -05006530lpfc_free_sysfs_attr(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05006531{
James Smart2e0fef82007-06-17 19:56:36 -05006532 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smartea2151b2008-09-07 11:52:10 -04006533 sysfs_remove_bin_file(&shost->shost_dev.kobj,
6534 &sysfs_drvr_stat_data_attr);
James Smarteada2722008-12-04 22:39:13 -05006535 /* Virtual ports do not need ctrl_reg and mbox */
6536 if (vport->port_type == LPFC_NPIV_PORT)
6537 return;
Tony Jonesee959b02008-02-22 00:13:36 +01006538 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
6539 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
dea31012005-04-17 16:05:31 -05006540}
6541
dea31012005-04-17 16:05:31 -05006542/*
6543 * Dynamic FC Host Attributes Support
6544 */
6545
James Smarte59058c2008-08-24 21:49:00 -04006546/**
James Smart6c9231f2016-12-19 15:07:24 -08006547 * lpfc_get_host_symbolic_name - Copy symbolic name into the scsi host
6548 * @shost: kernel scsi host pointer.
6549 **/
6550static void
6551lpfc_get_host_symbolic_name(struct Scsi_Host *shost)
6552{
6553 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
6554
6555 lpfc_vport_symbolic_node_name(vport, fc_host_symbolic_name(shost),
6556 sizeof fc_host_symbolic_name(shost));
6557}
6558
6559/**
James Smart3621a712009-04-06 18:47:14 -04006560 * lpfc_get_host_port_id - Copy the vport DID into the scsi host port id
James Smarte59058c2008-08-24 21:49:00 -04006561 * @shost: kernel scsi host pointer.
6562 **/
dea31012005-04-17 16:05:31 -05006563static void
6564lpfc_get_host_port_id(struct Scsi_Host *shost)
6565{
James Smart2e0fef82007-06-17 19:56:36 -05006566 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6567
dea31012005-04-17 16:05:31 -05006568 /* note: fc_myDID already in cpu endianness */
James Smart2e0fef82007-06-17 19:56:36 -05006569 fc_host_port_id(shost) = vport->fc_myDID;
dea31012005-04-17 16:05:31 -05006570}
6571
James Smarte59058c2008-08-24 21:49:00 -04006572/**
James Smart3621a712009-04-06 18:47:14 -04006573 * lpfc_get_host_port_type - Set the value of the scsi host port type
James Smarte59058c2008-08-24 21:49:00 -04006574 * @shost: kernel scsi host pointer.
6575 **/
dea31012005-04-17 16:05:31 -05006576static void
6577lpfc_get_host_port_type(struct Scsi_Host *shost)
6578{
James Smart2e0fef82007-06-17 19:56:36 -05006579 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6580 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006581
6582 spin_lock_irq(shost->host_lock);
6583
James Smart92d7f7b2007-06-17 19:56:38 -05006584 if (vport->port_type == LPFC_NPIV_PORT) {
6585 fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
6586 } else if (lpfc_is_link_up(phba)) {
James Smart76a95d72010-11-20 23:11:48 -05006587 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smart2e0fef82007-06-17 19:56:36 -05006588 if (vport->fc_flag & FC_PUBLIC_LOOP)
dea31012005-04-17 16:05:31 -05006589 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
6590 else
6591 fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
6592 } else {
James Smart2e0fef82007-06-17 19:56:36 -05006593 if (vport->fc_flag & FC_FABRIC)
dea31012005-04-17 16:05:31 -05006594 fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
6595 else
6596 fc_host_port_type(shost) = FC_PORTTYPE_PTP;
6597 }
6598 } else
6599 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
6600
6601 spin_unlock_irq(shost->host_lock);
6602}
6603
James Smarte59058c2008-08-24 21:49:00 -04006604/**
James Smart3621a712009-04-06 18:47:14 -04006605 * lpfc_get_host_port_state - Set the value of the scsi host port state
James Smarte59058c2008-08-24 21:49:00 -04006606 * @shost: kernel scsi host pointer.
6607 **/
dea31012005-04-17 16:05:31 -05006608static void
6609lpfc_get_host_port_state(struct Scsi_Host *shost)
6610{
James Smart2e0fef82007-06-17 19:56:36 -05006611 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6612 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006613
6614 spin_lock_irq(shost->host_lock);
6615
James Smart2e0fef82007-06-17 19:56:36 -05006616 if (vport->fc_flag & FC_OFFLINE_MODE)
dea31012005-04-17 16:05:31 -05006617 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
6618 else {
James Smart2e0fef82007-06-17 19:56:36 -05006619 switch (phba->link_state) {
6620 case LPFC_LINK_UNKNOWN:
dea31012005-04-17 16:05:31 -05006621 case LPFC_LINK_DOWN:
6622 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
6623 break;
6624 case LPFC_LINK_UP:
dea31012005-04-17 16:05:31 -05006625 case LPFC_CLEAR_LA:
6626 case LPFC_HBA_READY:
James Smart026abb82011-12-13 13:20:45 -05006627 /* Links up, reports port state accordingly */
6628 if (vport->port_state < LPFC_VPORT_READY)
6629 fc_host_port_state(shost) =
6630 FC_PORTSTATE_BYPASSED;
6631 else
6632 fc_host_port_state(shost) =
6633 FC_PORTSTATE_ONLINE;
dea31012005-04-17 16:05:31 -05006634 break;
6635 case LPFC_HBA_ERROR:
6636 fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
6637 break;
6638 default:
6639 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
6640 break;
6641 }
6642 }
6643
6644 spin_unlock_irq(shost->host_lock);
6645}
6646
James Smarte59058c2008-08-24 21:49:00 -04006647/**
James Smart3621a712009-04-06 18:47:14 -04006648 * lpfc_get_host_speed - Set the value of the scsi host speed
James Smarte59058c2008-08-24 21:49:00 -04006649 * @shost: kernel scsi host pointer.
6650 **/
dea31012005-04-17 16:05:31 -05006651static void
6652lpfc_get_host_speed(struct Scsi_Host *shost)
6653{
James Smart2e0fef82007-06-17 19:56:36 -05006654 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6655 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006656
6657 spin_lock_irq(shost->host_lock);
6658
James Smarta085e872015-12-16 18:12:02 -05006659 if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) {
dea31012005-04-17 16:05:31 -05006660 switch(phba->fc_linkspeed) {
James Smart76a95d72010-11-20 23:11:48 -05006661 case LPFC_LINK_SPEED_1GHZ:
6662 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
dea31012005-04-17 16:05:31 -05006663 break;
James Smart76a95d72010-11-20 23:11:48 -05006664 case LPFC_LINK_SPEED_2GHZ:
6665 fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
dea31012005-04-17 16:05:31 -05006666 break;
James Smart76a95d72010-11-20 23:11:48 -05006667 case LPFC_LINK_SPEED_4GHZ:
6668 fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
dea31012005-04-17 16:05:31 -05006669 break;
James Smart76a95d72010-11-20 23:11:48 -05006670 case LPFC_LINK_SPEED_8GHZ:
6671 fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
James Smartb87eab32007-04-25 09:53:28 -04006672 break;
James Smart76a95d72010-11-20 23:11:48 -05006673 case LPFC_LINK_SPEED_10GHZ:
6674 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
James Smartf4b4c682009-05-22 14:53:12 -04006675 break;
James Smart76a95d72010-11-20 23:11:48 -05006676 case LPFC_LINK_SPEED_16GHZ:
6677 fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
6678 break;
James Smartd38dd522015-08-31 16:48:17 -04006679 case LPFC_LINK_SPEED_32GHZ:
6680 fc_host_speed(shost) = FC_PORTSPEED_32GBIT;
6681 break;
James Smartfbd8a6b2018-02-22 08:18:45 -08006682 case LPFC_LINK_SPEED_64GHZ:
6683 fc_host_speed(shost) = FC_PORTSPEED_64GBIT;
6684 break;
James Smart1dc5ec22018-10-23 13:41:11 -07006685 case LPFC_LINK_SPEED_128GHZ:
6686 fc_host_speed(shost) = FC_PORTSPEED_128GBIT;
6687 break;
James Smart76a95d72010-11-20 23:11:48 -05006688 default:
6689 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
dea31012005-04-17 16:05:31 -05006690 break;
6691 }
James Smartb615a202018-07-31 17:23:19 -07006692 } else if (lpfc_is_link_up(phba) && (phba->hba_flag & HBA_FCOE_MODE)) {
6693 switch (phba->fc_linkspeed) {
Dick Kennedya1e4d3d2020-08-03 14:02:22 -07006694 case LPFC_ASYNC_LINK_SPEED_1GBPS:
6695 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
6696 break;
James Smartb615a202018-07-31 17:23:19 -07006697 case LPFC_ASYNC_LINK_SPEED_10GBPS:
6698 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
6699 break;
Dick Kennedya1e4d3d2020-08-03 14:02:22 -07006700 case LPFC_ASYNC_LINK_SPEED_20GBPS:
6701 fc_host_speed(shost) = FC_PORTSPEED_20GBIT;
6702 break;
James Smartb615a202018-07-31 17:23:19 -07006703 case LPFC_ASYNC_LINK_SPEED_25GBPS:
6704 fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
6705 break;
6706 case LPFC_ASYNC_LINK_SPEED_40GBPS:
6707 fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
6708 break;
6709 case LPFC_ASYNC_LINK_SPEED_100GBPS:
6710 fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
6711 break;
6712 default:
6713 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
6714 break;
6715 }
James Smart09372822008-01-11 01:52:54 -05006716 } else
6717 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
dea31012005-04-17 16:05:31 -05006718
6719 spin_unlock_irq(shost->host_lock);
6720}
6721
James Smarte59058c2008-08-24 21:49:00 -04006722/**
James Smart3621a712009-04-06 18:47:14 -04006723 * lpfc_get_host_fabric_name - Set the value of the scsi host fabric name
James Smarte59058c2008-08-24 21:49:00 -04006724 * @shost: kernel scsi host pointer.
6725 **/
dea31012005-04-17 16:05:31 -05006726static void
6727lpfc_get_host_fabric_name (struct Scsi_Host *shost)
6728{
James Smart2e0fef82007-06-17 19:56:36 -05006729 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6730 struct lpfc_hba *phba = vport->phba;
Andrew Vasquezf631b4b2005-08-31 15:23:12 -07006731 u64 node_name;
dea31012005-04-17 16:05:31 -05006732
6733 spin_lock_irq(shost->host_lock);
6734
James Smart73d91e52011-10-10 21:32:10 -04006735 if ((vport->port_state > LPFC_FLOGI) &&
6736 ((vport->fc_flag & FC_FABRIC) ||
6737 ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
6738 (vport->fc_flag & FC_PUBLIC_LOOP))))
Andrew Morton68ce1eb2005-09-21 09:46:54 -07006739 node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
dea31012005-04-17 16:05:31 -05006740 else
6741 /* fabric is local port if there is no F/FL_Port */
James Smart09372822008-01-11 01:52:54 -05006742 node_name = 0;
dea31012005-04-17 16:05:31 -05006743
6744 spin_unlock_irq(shost->host_lock);
6745
Andrew Vasquezf631b4b2005-08-31 15:23:12 -07006746 fc_host_fabric_name(shost) = node_name;
dea31012005-04-17 16:05:31 -05006747}
6748
James Smarte59058c2008-08-24 21:49:00 -04006749/**
James Smart3621a712009-04-06 18:47:14 -04006750 * lpfc_get_stats - Return statistical information about the adapter
James Smarte59058c2008-08-24 21:49:00 -04006751 * @shost: kernel scsi host pointer.
6752 *
6753 * Notes:
6754 * NULL on error for link down, no mbox pool, sli2 active,
6755 * management not allowed, memory allocation error, or mbox error.
6756 *
6757 * Returns:
6758 * NULL for error
6759 * address of the adapter host statistics
6760 **/
dea31012005-04-17 16:05:31 -05006761static struct fc_host_statistics *
6762lpfc_get_stats(struct Scsi_Host *shost)
6763{
James Smart2e0fef82007-06-17 19:56:36 -05006764 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6765 struct lpfc_hba *phba = vport->phba;
6766 struct lpfc_sli *psli = &phba->sli;
James.Smart@Emulex.Comf888ba32005-08-10 15:03:01 -04006767 struct fc_host_statistics *hs = &phba->link_stats;
James Smart64ba8812006-08-02 15:24:34 -04006768 struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
dea31012005-04-17 16:05:31 -05006769 LPFC_MBOXQ_t *pmboxq;
6770 MAILBOX_t *pmb;
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006771 int rc = 0;
dea31012005-04-17 16:05:31 -05006772
James Smart92d7f7b2007-06-17 19:56:38 -05006773 /*
6774 * prevent udev from issuing mailbox commands until the port is
6775 * configured.
6776 */
James Smart2e0fef82007-06-17 19:56:36 -05006777 if (phba->link_state < LPFC_LINK_DOWN ||
6778 !phba->mbox_mem_pool ||
James Smartf4b4c682009-05-22 14:53:12 -04006779 (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
James Smart92d7f7b2007-06-17 19:56:38 -05006780 return NULL;
James Smart2e0fef82007-06-17 19:56:36 -05006781
6782 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
James Smart46fa3112007-04-25 09:51:45 -04006783 return NULL;
6784
dea31012005-04-17 16:05:31 -05006785 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
6786 if (!pmboxq)
6787 return NULL;
6788 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
6789
James Smart04c68492009-05-22 14:52:52 -04006790 pmb = &pmboxq->u.mb;
dea31012005-04-17 16:05:31 -05006791 pmb->mbxCommand = MBX_READ_STATUS;
6792 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006793 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006794 pmboxq->vport = vport;
dea31012005-04-17 16:05:31 -05006795
James Smart75baf692010-06-08 18:31:21 -04006796 if (vport->fc_flag & FC_OFFLINE_MODE)
dea31012005-04-17 16:05:31 -05006797 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006798 else
dea31012005-04-17 16:05:31 -05006799 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6800
6801 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05006802 if (rc != MBX_TIMEOUT)
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006803 mempool_free(pmboxq, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05006804 return NULL;
6805 }
6806
James.Smart@Emulex.Comf888ba32005-08-10 15:03:01 -04006807 memset(hs, 0, sizeof (struct fc_host_statistics));
6808
dea31012005-04-17 16:05:31 -05006809 hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
James Smart73d91e52011-10-10 21:32:10 -04006810 /*
6811 * The MBX_READ_STATUS returns tx_k_bytes which has to
6812 * converted to words
6813 */
6814 hs->tx_words = (uint64_t)
6815 ((uint64_t)pmb->un.varRdStatus.xmitByteCnt
6816 * (uint64_t)256);
dea31012005-04-17 16:05:31 -05006817 hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
James Smart73d91e52011-10-10 21:32:10 -04006818 hs->rx_words = (uint64_t)
6819 ((uint64_t)pmb->un.varRdStatus.rcvByteCnt
6820 * (uint64_t)256);
dea31012005-04-17 16:05:31 -05006821
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006822 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
dea31012005-04-17 16:05:31 -05006823 pmb->mbxCommand = MBX_READ_LNK_STAT;
6824 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006825 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006826 pmboxq->vport = vport;
dea31012005-04-17 16:05:31 -05006827
James Smart75baf692010-06-08 18:31:21 -04006828 if (vport->fc_flag & FC_OFFLINE_MODE)
dea31012005-04-17 16:05:31 -05006829 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006830 else
dea31012005-04-17 16:05:31 -05006831 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6832
6833 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05006834 if (rc != MBX_TIMEOUT)
James Smart92d7f7b2007-06-17 19:56:38 -05006835 mempool_free(pmboxq, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05006836 return NULL;
6837 }
6838
6839 hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
6840 hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
6841 hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
6842 hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
6843 hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
6844 hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
6845 hs->error_frames = pmb->un.varRdLnk.crcCnt;
6846
James Smart64ba8812006-08-02 15:24:34 -04006847 hs->link_failure_count -= lso->link_failure_count;
6848 hs->loss_of_sync_count -= lso->loss_of_sync_count;
6849 hs->loss_of_signal_count -= lso->loss_of_signal_count;
6850 hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count;
6851 hs->invalid_tx_word_count -= lso->invalid_tx_word_count;
6852 hs->invalid_crc_count -= lso->invalid_crc_count;
6853 hs->error_frames -= lso->error_frames;
6854
James Smart76a95d72010-11-20 23:11:48 -05006855 if (phba->hba_flag & HBA_FCOE_MODE) {
James Smart4d9ab992009-10-02 15:16:39 -04006856 hs->lip_count = -1;
6857 hs->nos_count = (phba->link_events >> 1);
6858 hs->nos_count -= lso->link_events;
James Smart76a95d72010-11-20 23:11:48 -05006859 } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
dea31012005-04-17 16:05:31 -05006860 hs->lip_count = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006861 hs->lip_count -= lso->link_events;
dea31012005-04-17 16:05:31 -05006862 hs->nos_count = -1;
6863 } else {
6864 hs->lip_count = -1;
6865 hs->nos_count = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006866 hs->nos_count -= lso->link_events;
dea31012005-04-17 16:05:31 -05006867 }
6868
6869 hs->dumped_frames = -1;
6870
Arnd Bergmannc4d6204d2018-06-18 17:28:23 +02006871 hs->seconds_since_last_reset = ktime_get_seconds() - psli->stats_start;
dea31012005-04-17 16:05:31 -05006872
James Smart1dcb58e2007-04-25 09:51:30 -04006873 mempool_free(pmboxq, phba->mbox_mem_pool);
6874
dea31012005-04-17 16:05:31 -05006875 return hs;
6876}
6877
James Smarte59058c2008-08-24 21:49:00 -04006878/**
James Smart3621a712009-04-06 18:47:14 -04006879 * lpfc_reset_stats - Copy the adapter link stats information
James Smarte59058c2008-08-24 21:49:00 -04006880 * @shost: kernel scsi host pointer.
6881 **/
James Smart64ba8812006-08-02 15:24:34 -04006882static void
6883lpfc_reset_stats(struct Scsi_Host *shost)
6884{
James Smart2e0fef82007-06-17 19:56:36 -05006885 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6886 struct lpfc_hba *phba = vport->phba;
6887 struct lpfc_sli *psli = &phba->sli;
6888 struct lpfc_lnk_stat *lso = &psli->lnk_stat_offsets;
James Smart64ba8812006-08-02 15:24:34 -04006889 LPFC_MBOXQ_t *pmboxq;
6890 MAILBOX_t *pmb;
6891 int rc = 0;
6892
James Smart2e0fef82007-06-17 19:56:36 -05006893 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
James Smart46fa3112007-04-25 09:51:45 -04006894 return;
6895
James Smart64ba8812006-08-02 15:24:34 -04006896 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
6897 if (!pmboxq)
6898 return;
6899 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
6900
James Smart04c68492009-05-22 14:52:52 -04006901 pmb = &pmboxq->u.mb;
James Smart64ba8812006-08-02 15:24:34 -04006902 pmb->mbxCommand = MBX_READ_STATUS;
6903 pmb->mbxOwner = OWN_HOST;
6904 pmb->un.varWords[0] = 0x1; /* reset request */
James Smart3e1f0712018-11-29 16:09:29 -08006905 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006906 pmboxq->vport = vport;
James Smart64ba8812006-08-02 15:24:34 -04006907
James Smart2e0fef82007-06-17 19:56:36 -05006908 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smartf4b4c682009-05-22 14:53:12 -04006909 (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
James Smart64ba8812006-08-02 15:24:34 -04006910 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
6911 else
6912 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6913
6914 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05006915 if (rc != MBX_TIMEOUT)
James Smart64ba8812006-08-02 15:24:34 -04006916 mempool_free(pmboxq, phba->mbox_mem_pool);
6917 return;
6918 }
6919
6920 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
6921 pmb->mbxCommand = MBX_READ_LNK_STAT;
6922 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006923 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006924 pmboxq->vport = vport;
James Smart64ba8812006-08-02 15:24:34 -04006925
James Smart2e0fef82007-06-17 19:56:36 -05006926 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smartf4b4c682009-05-22 14:53:12 -04006927 (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
James Smart64ba8812006-08-02 15:24:34 -04006928 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
6929 else
6930 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6931
6932 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05006933 if (rc != MBX_TIMEOUT)
James Smart64ba8812006-08-02 15:24:34 -04006934 mempool_free( pmboxq, phba->mbox_mem_pool);
6935 return;
6936 }
6937
6938 lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
6939 lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
6940 lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
6941 lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
6942 lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
6943 lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
6944 lso->error_frames = pmb->un.varRdLnk.crcCnt;
James Smart76a95d72010-11-20 23:11:48 -05006945 if (phba->hba_flag & HBA_FCOE_MODE)
James Smart4d9ab992009-10-02 15:16:39 -04006946 lso->link_events = (phba->link_events >> 1);
6947 else
6948 lso->link_events = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006949
Arnd Bergmannc4d6204d2018-06-18 17:28:23 +02006950 psli->stats_start = ktime_get_seconds();
James Smart64ba8812006-08-02 15:24:34 -04006951
James Smart1dcb58e2007-04-25 09:51:30 -04006952 mempool_free(pmboxq, phba->mbox_mem_pool);
6953
James Smart64ba8812006-08-02 15:24:34 -04006954 return;
6955}
dea31012005-04-17 16:05:31 -05006956
6957/*
6958 * The LPFC driver treats linkdown handling as target loss events so there
6959 * are no sysfs handlers for link_down_tmo.
6960 */
James Smart685f0bf2007-04-25 09:53:08 -04006961
James Smarte59058c2008-08-24 21:49:00 -04006962/**
James Smart3621a712009-04-06 18:47:14 -04006963 * lpfc_get_node_by_target - Return the nodelist for a target
James Smarte59058c2008-08-24 21:49:00 -04006964 * @starget: kernel scsi target pointer.
6965 *
6966 * Returns:
6967 * address of the node list if found
6968 * NULL target not found
6969 **/
James Smart685f0bf2007-04-25 09:53:08 -04006970static struct lpfc_nodelist *
6971lpfc_get_node_by_target(struct scsi_target *starget)
dea31012005-04-17 16:05:31 -05006972{
James Smart2e0fef82007-06-17 19:56:36 -05006973 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
6974 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
James Smart685f0bf2007-04-25 09:53:08 -04006975 struct lpfc_nodelist *ndlp;
dea31012005-04-17 16:05:31 -05006976
6977 spin_lock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04006978 /* Search for this, mapped, target ID */
James Smart2e0fef82007-06-17 19:56:36 -05006979 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart307e3382020-11-15 11:26:30 -08006980 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
James Smart685f0bf2007-04-25 09:53:08 -04006981 starget->id == ndlp->nlp_sid) {
6982 spin_unlock_irq(shost->host_lock);
6983 return ndlp;
dea31012005-04-17 16:05:31 -05006984 }
6985 }
6986 spin_unlock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04006987 return NULL;
6988}
dea31012005-04-17 16:05:31 -05006989
James Smarte59058c2008-08-24 21:49:00 -04006990/**
James Smart3621a712009-04-06 18:47:14 -04006991 * lpfc_get_starget_port_id - Set the target port id to the ndlp DID or -1
James Smarte59058c2008-08-24 21:49:00 -04006992 * @starget: kernel scsi target pointer.
6993 **/
James Smart685f0bf2007-04-25 09:53:08 -04006994static void
6995lpfc_get_starget_port_id(struct scsi_target *starget)
6996{
6997 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
6998
6999 fc_starget_port_id(starget) = ndlp ? ndlp->nlp_DID : -1;
dea31012005-04-17 16:05:31 -05007000}
7001
James Smarte59058c2008-08-24 21:49:00 -04007002/**
James Smart3621a712009-04-06 18:47:14 -04007003 * lpfc_get_starget_node_name - Set the target node name
James Smarte59058c2008-08-24 21:49:00 -04007004 * @starget: kernel scsi target pointer.
7005 *
7006 * Description: Set the target node name to the ndlp node name wwn or zero.
7007 **/
dea31012005-04-17 16:05:31 -05007008static void
7009lpfc_get_starget_node_name(struct scsi_target *starget)
7010{
James Smart685f0bf2007-04-25 09:53:08 -04007011 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
dea31012005-04-17 16:05:31 -05007012
James Smart685f0bf2007-04-25 09:53:08 -04007013 fc_starget_node_name(starget) =
7014 ndlp ? wwn_to_u64(ndlp->nlp_nodename.u.wwn) : 0;
dea31012005-04-17 16:05:31 -05007015}
7016
James Smarte59058c2008-08-24 21:49:00 -04007017/**
James Smart3621a712009-04-06 18:47:14 -04007018 * lpfc_get_starget_port_name - Set the target port name
James Smarte59058c2008-08-24 21:49:00 -04007019 * @starget: kernel scsi target pointer.
7020 *
7021 * Description: set the target port name to the ndlp port name wwn or zero.
7022 **/
dea31012005-04-17 16:05:31 -05007023static void
7024lpfc_get_starget_port_name(struct scsi_target *starget)
7025{
James Smart685f0bf2007-04-25 09:53:08 -04007026 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
dea31012005-04-17 16:05:31 -05007027
James Smart685f0bf2007-04-25 09:53:08 -04007028 fc_starget_port_name(starget) =
7029 ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0;
dea31012005-04-17 16:05:31 -05007030}
7031
James Smarte59058c2008-08-24 21:49:00 -04007032/**
James Smart3621a712009-04-06 18:47:14 -04007033 * lpfc_set_rport_loss_tmo - Set the rport dev loss tmo
James Smarte59058c2008-08-24 21:49:00 -04007034 * @rport: fc rport address.
7035 * @timeout: new value for dev loss tmo.
7036 *
7037 * Description:
7038 * If timeout is non zero set the dev_loss_tmo to timeout, else set
7039 * dev_loss_tmo to one.
7040 **/
dea31012005-04-17 16:05:31 -05007041static void
dea31012005-04-17 16:05:31 -05007042lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
7043{
James Smarta643c6d2019-08-14 16:56:48 -07007044 struct lpfc_rport_data *rdata = rport->dd_data;
7045 struct lpfc_nodelist *ndlp = rdata->pnode;
7046#if (IS_ENABLED(CONFIG_NVME_FC))
7047 struct lpfc_nvme_rport *nrport = NULL;
7048#endif
7049
dea31012005-04-17 16:05:31 -05007050 if (timeout)
James Smartc01f3202006-08-18 17:47:08 -04007051 rport->dev_loss_tmo = timeout;
dea31012005-04-17 16:05:31 -05007052 else
James Smartc01f3202006-08-18 17:47:08 -04007053 rport->dev_loss_tmo = 1;
James Smarta643c6d2019-08-14 16:56:48 -07007054
James Smart307e3382020-11-15 11:26:30 -08007055 if (!ndlp) {
James Smarta643c6d2019-08-14 16:56:48 -07007056 dev_info(&rport->dev, "Cannot find remote node to "
7057 "set rport dev loss tmo, port_id x%x\n",
7058 rport->port_id);
7059 return;
7060 }
7061
7062#if (IS_ENABLED(CONFIG_NVME_FC))
7063 nrport = lpfc_ndlp_get_nrport(ndlp);
7064
7065 if (nrport && nrport->remoteport)
7066 nvme_fc_set_remoteport_devloss(nrport->remoteport,
7067 rport->dev_loss_tmo);
7068#endif
dea31012005-04-17 16:05:31 -05007069}
7070
Lee Jones9176ad22020-11-02 14:23:44 +00007071/*
James Smart3621a712009-04-06 18:47:14 -04007072 * lpfc_rport_show_function - Return rport target information
James Smarte59058c2008-08-24 21:49:00 -04007073 *
7074 * Description:
7075 * Macro that uses field to generate a function with the name lpfc_show_rport_
7076 *
7077 * lpfc_show_rport_##field: returns the bytes formatted in buf
7078 * @cdev: class converted to an fc_rport.
7079 * @buf: on return contains the target_field or zero.
7080 *
7081 * Returns: size of formatted string.
7082 **/
dea31012005-04-17 16:05:31 -05007083#define lpfc_rport_show_function(field, format_string, sz, cast) \
7084static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01007085lpfc_show_rport_##field (struct device *dev, \
7086 struct device_attribute *attr, \
7087 char *buf) \
dea31012005-04-17 16:05:31 -05007088{ \
Tony Jonesee959b02008-02-22 00:13:36 +01007089 struct fc_rport *rport = transport_class_to_rport(dev); \
dea31012005-04-17 16:05:31 -05007090 struct lpfc_rport_data *rdata = rport->hostdata; \
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07007091 return scnprintf(buf, sz, format_string, \
dea31012005-04-17 16:05:31 -05007092 (rdata->target) ? cast rdata->target->field : 0); \
7093}
7094
7095#define lpfc_rport_rd_attr(field, format_string, sz) \
7096 lpfc_rport_show_function(field, format_string, sz, ) \
7097static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
7098
James Smarteada2722008-12-04 22:39:13 -05007099/**
James Smart3621a712009-04-06 18:47:14 -04007100 * lpfc_set_vport_symbolic_name - Set the vport's symbolic name
James Smarteada2722008-12-04 22:39:13 -05007101 * @fc_vport: The fc_vport who's symbolic name has been changed.
7102 *
7103 * Description:
7104 * This function is called by the transport after the @fc_vport's symbolic name
7105 * has been changed. This function re-registers the symbolic name with the
Lucas De Marchi25985ed2011-03-30 22:57:33 -03007106 * switch to propagate the change into the fabric if the vport is active.
James Smarteada2722008-12-04 22:39:13 -05007107 **/
7108static void
7109lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport)
7110{
7111 struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
7112
7113 if (vport->port_state == LPFC_VPORT_READY)
7114 lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
7115}
dea31012005-04-17 16:05:31 -05007116
James Smartf4b4c682009-05-22 14:53:12 -04007117/**
7118 * lpfc_hba_log_verbose_init - Set hba's log verbose level
7119 * @phba: Pointer to lpfc_hba struct.
Lee Jonesa738bd92020-11-02 14:23:45 +00007120 * @verbose: Verbose level to set.
James Smartf4b4c682009-05-22 14:53:12 -04007121 *
7122 * This function is called by the lpfc_get_cfgparam() routine to set the
7123 * module lpfc_log_verbose into the @phba cfg_log_verbose for use with
Justin P. Mattock70f23fd2011-05-10 10:16:21 +02007124 * log message according to the module's lpfc_log_verbose parameter setting
James Smartf4b4c682009-05-22 14:53:12 -04007125 * before hba port or vport created.
7126 **/
7127static void
7128lpfc_hba_log_verbose_init(struct lpfc_hba *phba, uint32_t verbose)
7129{
7130 phba->cfg_log_verbose = verbose;
7131}
7132
dea31012005-04-17 16:05:31 -05007133struct fc_function_template lpfc_transport_functions = {
7134 /* fixed attributes the driver supports */
7135 .show_host_node_name = 1,
7136 .show_host_port_name = 1,
7137 .show_host_supported_classes = 1,
7138 .show_host_supported_fc4s = 1,
dea31012005-04-17 16:05:31 -05007139 .show_host_supported_speeds = 1,
7140 .show_host_maxframe_size = 1,
James Smart6c9231f2016-12-19 15:07:24 -08007141
7142 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
James Smarteada2722008-12-04 22:39:13 -05007143 .show_host_symbolic_name = 1,
dea31012005-04-17 16:05:31 -05007144
7145 /* dynamic attributes the driver supports */
7146 .get_host_port_id = lpfc_get_host_port_id,
7147 .show_host_port_id = 1,
7148
7149 .get_host_port_type = lpfc_get_host_port_type,
7150 .show_host_port_type = 1,
7151
7152 .get_host_port_state = lpfc_get_host_port_state,
7153 .show_host_port_state = 1,
7154
7155 /* active_fc4s is shown but doesn't change (thus no get function) */
7156 .show_host_active_fc4s = 1,
7157
7158 .get_host_speed = lpfc_get_host_speed,
7159 .show_host_speed = 1,
7160
7161 .get_host_fabric_name = lpfc_get_host_fabric_name,
7162 .show_host_fabric_name = 1,
7163
7164 /*
7165 * The LPFC driver treats linkdown handling as target loss events
7166 * so there are no sysfs handlers for link_down_tmo.
7167 */
7168
7169 .get_fc_host_stats = lpfc_get_stats,
James Smart64ba8812006-08-02 15:24:34 -04007170 .reset_fc_host_stats = lpfc_reset_stats,
dea31012005-04-17 16:05:31 -05007171
7172 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
7173 .show_rport_maxframe_size = 1,
7174 .show_rport_supported_classes = 1,
7175
dea31012005-04-17 16:05:31 -05007176 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
7177 .show_rport_dev_loss_tmo = 1,
7178
7179 .get_starget_port_id = lpfc_get_starget_port_id,
7180 .show_starget_port_id = 1,
7181
7182 .get_starget_node_name = lpfc_get_starget_node_name,
7183 .show_starget_node_name = 1,
7184
7185 .get_starget_port_name = lpfc_get_starget_port_name,
7186 .show_starget_port_name = 1,
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07007187
7188 .issue_fc_host_lip = lpfc_issue_lip,
James Smartc01f3202006-08-18 17:47:08 -04007189 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
7190 .terminate_rport_io = lpfc_terminate_rport_io,
James Smart92d7f7b2007-06-17 19:56:38 -05007191
James Smart92d7f7b2007-06-17 19:56:38 -05007192 .dd_fcvport_size = sizeof(struct lpfc_vport *),
James Smarteada2722008-12-04 22:39:13 -05007193
7194 .vport_disable = lpfc_vport_disable,
7195
7196 .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
James Smartf1c3b0f2009-07-19 10:01:32 -04007197
7198 .bsg_request = lpfc_bsg_request,
7199 .bsg_timeout = lpfc_bsg_timeout,
James Smart92d7f7b2007-06-17 19:56:38 -05007200};
7201
James Smart98c9ea52007-10-27 13:37:33 -04007202struct fc_function_template lpfc_vport_transport_functions = {
7203 /* fixed attributes the driver supports */
7204 .show_host_node_name = 1,
7205 .show_host_port_name = 1,
7206 .show_host_supported_classes = 1,
7207 .show_host_supported_fc4s = 1,
7208 .show_host_supported_speeds = 1,
7209 .show_host_maxframe_size = 1,
James Smart6c9231f2016-12-19 15:07:24 -08007210
7211 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
James Smarteada2722008-12-04 22:39:13 -05007212 .show_host_symbolic_name = 1,
James Smart98c9ea52007-10-27 13:37:33 -04007213
7214 /* dynamic attributes the driver supports */
7215 .get_host_port_id = lpfc_get_host_port_id,
7216 .show_host_port_id = 1,
7217
7218 .get_host_port_type = lpfc_get_host_port_type,
7219 .show_host_port_type = 1,
7220
7221 .get_host_port_state = lpfc_get_host_port_state,
7222 .show_host_port_state = 1,
7223
7224 /* active_fc4s is shown but doesn't change (thus no get function) */
7225 .show_host_active_fc4s = 1,
7226
7227 .get_host_speed = lpfc_get_host_speed,
7228 .show_host_speed = 1,
7229
7230 .get_host_fabric_name = lpfc_get_host_fabric_name,
7231 .show_host_fabric_name = 1,
7232
7233 /*
7234 * The LPFC driver treats linkdown handling as target loss events
7235 * so there are no sysfs handlers for link_down_tmo.
7236 */
7237
7238 .get_fc_host_stats = lpfc_get_stats,
7239 .reset_fc_host_stats = lpfc_reset_stats,
7240
7241 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
7242 .show_rport_maxframe_size = 1,
7243 .show_rport_supported_classes = 1,
7244
7245 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
7246 .show_rport_dev_loss_tmo = 1,
7247
7248 .get_starget_port_id = lpfc_get_starget_port_id,
7249 .show_starget_port_id = 1,
7250
7251 .get_starget_node_name = lpfc_get_starget_node_name,
7252 .show_starget_node_name = 1,
7253
7254 .get_starget_port_name = lpfc_get_starget_port_name,
7255 .show_starget_port_name = 1,
7256
7257 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
7258 .terminate_rport_io = lpfc_terminate_rport_io,
7259
7260 .vport_disable = lpfc_vport_disable,
James Smarteada2722008-12-04 22:39:13 -05007261
7262 .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
James Smart98c9ea52007-10-27 13:37:33 -04007263};
7264
James Smarte59058c2008-08-24 21:49:00 -04007265/**
James Smart4945c0f2019-08-14 16:57:02 -07007266 * lpfc_get_hba_function_mode - Used to determine the HBA function in FCoE
7267 * Mode
7268 * @phba: lpfc_hba pointer.
7269 **/
7270static void
7271lpfc_get_hba_function_mode(struct lpfc_hba *phba)
7272{
James Smart412e7372019-09-21 20:59:04 -07007273 /* If the adapter supports FCoE mode */
7274 switch (phba->pcidev->device) {
7275 case PCI_DEVICE_ID_SKYHAWK:
7276 case PCI_DEVICE_ID_SKYHAWK_VF:
7277 case PCI_DEVICE_ID_LANCER_FCOE:
7278 case PCI_DEVICE_ID_LANCER_FCOE_VF:
7279 case PCI_DEVICE_ID_ZEPHYR_DCSP:
7280 case PCI_DEVICE_ID_HORNET:
7281 case PCI_DEVICE_ID_TIGERSHARK:
7282 case PCI_DEVICE_ID_TOMCAT:
James Smart4945c0f2019-08-14 16:57:02 -07007283 phba->hba_flag |= HBA_FCOE_MODE;
James Smart412e7372019-09-21 20:59:04 -07007284 break;
7285 default:
7286 /* for others, clear the flag */
James Smart4945c0f2019-08-14 16:57:02 -07007287 phba->hba_flag &= ~HBA_FCOE_MODE;
James Smart412e7372019-09-21 20:59:04 -07007288 }
James Smart4945c0f2019-08-14 16:57:02 -07007289}
7290
7291/**
James Smart3621a712009-04-06 18:47:14 -04007292 * lpfc_get_cfgparam - Used during probe_one to init the adapter structure
James Smarte59058c2008-08-24 21:49:00 -04007293 * @phba: lpfc_hba pointer.
7294 **/
dea31012005-04-17 16:05:31 -05007295void
7296lpfc_get_cfgparam(struct lpfc_hba *phba)
7297{
James Smartdcaa2132019-11-04 16:57:06 -08007298 lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
James Smart49aa1432012-08-03 12:36:42 -04007299 lpfc_fcp_io_sched_init(phba, lpfc_fcp_io_sched);
James Smart7ea92eb2018-10-23 13:41:10 -07007300 lpfc_ns_query_init(phba, lpfc_ns_query);
James Smarta6571c62012-10-31 14:44:42 -04007301 lpfc_fcp2_no_tgt_reset_init(phba, lpfc_fcp2_no_tgt_reset);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007302 lpfc_cr_delay_init(phba, lpfc_cr_delay);
7303 lpfc_cr_count_init(phba, lpfc_cr_count);
Jamie Wellnitzcf5bf972006-02-28 22:33:08 -05007304 lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
James Smarta4bc3372006-12-02 13:34:16 -05007305 lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
7306 lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007307 lpfc_ack0_init(phba, lpfc_ack0);
James Smartc4908502019-01-28 11:14:28 -08007308 lpfc_xri_rebalancing_init(phba, lpfc_xri_rebalancing);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007309 lpfc_topology_init(phba, lpfc_topology);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007310 lpfc_link_speed_init(phba, lpfc_link_speed);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05007311 lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
James Smart0c411222013-09-06 12:22:46 -04007312 lpfc_task_mgmt_tmo_init(phba, lpfc_task_mgmt_tmo);
James Smart78b2d852007-08-02 11:10:21 -04007313 lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
James Smart7d791df2011-07-22 18:37:52 -04007314 lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy);
James Smart19ca7602010-11-20 23:11:55 -05007315 lpfc_enable_rrq_init(phba, lpfc_enable_rrq);
James Smart4258e982015-12-16 18:11:58 -05007316 lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
7317 lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
James Smart4ff43242006-12-02 13:34:56 -05007318 lpfc_use_msi_init(phba, lpfc_use_msi);
James Smart895427b2017-02-12 13:52:30 -08007319 lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
James Smart4e565cf2018-02-22 08:18:50 -08007320 lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
James Smartda0436e2009-05-22 14:51:39 -04007321 lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
James Smart41b194b2019-05-14 14:58:08 -07007322 lpfc_force_rscn_init(phba, lpfc_force_rscn);
James Smart32517fc2019-01-28 11:14:33 -08007323 lpfc_cq_poll_threshold_init(phba, lpfc_cq_poll_threshold);
7324 lpfc_cq_max_proc_limit_init(phba, lpfc_cq_max_proc_limit);
James Smart7bb03bb2013-04-17 20:19:16 -04007325 lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
James Smart13815c82008-01-11 01:52:48 -05007326 lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
7327 lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
James Smart2ea259e2017-02-12 13:52:27 -08007328
James Smart1ba981f2014-02-20 09:56:45 -05007329 lpfc_EnableXLane_init(phba, lpfc_EnableXLane);
7330 if (phba->sli_rev != LPFC_SLI_REV4)
7331 phba->cfg_EnableXLane = 0;
7332 lpfc_XLanePriority_init(phba, lpfc_XLanePriority);
James Smart2ea259e2017-02-12 13:52:27 -08007333
James Smart1ba981f2014-02-20 09:56:45 -05007334 memset(phba->cfg_oas_tgt_wwpn, 0, (8 * sizeof(uint8_t)));
7335 memset(phba->cfg_oas_vpt_wwpn, 0, (8 * sizeof(uint8_t)));
7336 phba->cfg_oas_lun_state = 0;
7337 phba->cfg_oas_lun_status = 0;
7338 phba->cfg_oas_flags = 0;
James Smartc92c8412016-07-06 12:36:05 -07007339 phba->cfg_oas_priority = 0;
James Smart81301a92008-12-04 22:39:46 -05007340 lpfc_enable_bg_init(phba, lpfc_enable_bg);
James Smartb3b98b72016-10-13 15:06:06 -07007341 lpfc_prot_mask_init(phba, lpfc_prot_mask);
7342 lpfc_prot_guard_init(phba, lpfc_prot_guard);
James Smart45ed1192009-10-02 15:17:02 -04007343 if (phba->sli_rev == LPFC_SLI_REV4)
7344 phba->cfg_poll = 0;
7345 else
James Smart1ba981f2014-02-20 09:56:45 -05007346 phba->cfg_poll = lpfc_poll;
James Smartf44ac122018-03-05 12:04:08 -08007347
James Smart4945c0f2019-08-14 16:57:02 -07007348 /* Get the function mode */
7349 lpfc_get_hba_function_mode(phba);
7350
7351 /* BlockGuard allowed for FC only. */
7352 if (phba->cfg_enable_bg && phba->hba_flag & HBA_FCOE_MODE) {
7353 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
7354 "0581 BlockGuard feature not supported\n");
7355 /* If set, clear the BlockGuard support param */
7356 phba->cfg_enable_bg = 0;
7357 } else if (phba->cfg_enable_bg) {
James Smartf44ac122018-03-05 12:04:08 -08007358 phba->sli3_options |= LPFC_SLI3_BG_ENABLED;
James Smart4945c0f2019-08-14 16:57:02 -07007359 }
James Smartf44ac122018-03-05 12:04:08 -08007360
James Smartf358dd02017-02-12 13:52:34 -08007361 lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp);
James Smart4258e982015-12-16 18:11:58 -05007362
James Smart895427b2017-02-12 13:52:30 -08007363 lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type);
James Smart2d7dbc42017-02-12 13:52:35 -08007364 lpfc_nvmet_mrq_init(phba, lpfc_nvmet_mrq);
James Smart2448e482018-04-09 14:24:24 -07007365 lpfc_nvmet_mrq_post_init(phba, lpfc_nvmet_mrq_post);
James Smart895427b2017-02-12 13:52:30 -08007366
7367 /* Initialize first burst. Target vs Initiator are different. */
7368 lpfc_nvme_enable_fb_init(phba, lpfc_nvme_enable_fb);
James Smart2d7dbc42017-02-12 13:52:35 -08007369 lpfc_nvmet_fb_size_init(phba, lpfc_nvmet_fb_size);
James Smart77ffd342019-08-15 19:36:49 -07007370 lpfc_fcp_mq_threshold_init(phba, lpfc_fcp_mq_threshold);
James Smartcdb42be2019-01-28 11:14:21 -08007371 lpfc_hdw_queue_init(phba, lpfc_hdw_queue);
James Smart6a828b02019-01-28 11:14:31 -08007372 lpfc_irq_chann_init(phba, lpfc_irq_chann);
James Smart44fd7fe2017-08-23 16:55:47 -07007373 lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
James Smart1351e692018-02-22 08:18:43 -08007374 lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
James Smart8aaa7bc2020-10-20 13:27:17 -07007375 lpfc_enable_mi_init(phba, lpfc_enable_mi);
James Smart895427b2017-02-12 13:52:30 -08007376
7377 if (phba->sli_rev != LPFC_SLI_REV4) {
7378 /* NVME only supported on SLI4 */
7379 phba->nvmet_support = 0;
James Smart982ab122019-03-12 16:30:10 -07007380 phba->cfg_nvmet_mrq = 0;
James Smart895427b2017-02-12 13:52:30 -08007381 phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
James Smart44fd7fe2017-08-23 16:55:47 -07007382 phba->cfg_enable_bbcr = 0;
James Smartc4908502019-01-28 11:14:28 -08007383 phba->cfg_xri_rebalancing = 0;
James Smart895427b2017-02-12 13:52:30 -08007384 } else {
7385 /* We MUST have FCP support */
7386 if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
7387 phba->cfg_enable_fc4_type |= LPFC_ENABLE_FCP;
7388 }
7389
James Smart32517fc2019-01-28 11:14:33 -08007390 phba->cfg_auto_imax = (phba->cfg_fcp_imax) ? 0 : 1;
James Smart0cf07f842017-06-01 21:07:10 -07007391
James Smart06b6fa382018-07-31 17:23:24 -07007392 phba->cfg_enable_pbde = 0;
7393
James Smart895427b2017-02-12 13:52:30 -08007394 /* A value of 0 means use the number of CPUs found in the system */
James Smartcdb42be2019-01-28 11:14:21 -08007395 if (phba->cfg_hdw_queue == 0)
7396 phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
James Smart6a828b02019-01-28 11:14:31 -08007397 if (phba->cfg_irq_chann == 0)
7398 phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
7399 if (phba->cfg_irq_chann > phba->cfg_hdw_queue)
7400 phba->cfg_irq_chann = phba->cfg_hdw_queue;
James Smart4258e982015-12-16 18:11:58 -05007401
James Smart352e5fd2016-12-30 06:57:47 -08007402 phba->cfg_soft_wwnn = 0L;
7403 phba->cfg_soft_wwpn = 0L;
James Smart83108bd2008-01-11 01:53:09 -05007404 lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
James Smart7054a602007-04-25 09:52:34 -04007405 lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
James Smart0d878412009-10-02 15:16:56 -04007406 lpfc_aer_support_init(phba, lpfc_aer_support);
James Smart912e3ac2011-05-24 11:42:11 -04007407 lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn);
James Smartc71ab862012-10-31 14:44:33 -04007408 lpfc_request_firmware_upgrade_init(phba, lpfc_req_fw_upgrade);
James Smart84d1b002010-02-12 14:42:33 -05007409 lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up);
James Smart8eb8b962016-07-06 12:36:08 -07007410 lpfc_delay_discovery_init(phba, lpfc_delay_discovery);
James Smart12247e82016-07-06 12:36:09 -07007411 lpfc_sli_mode_init(phba, lpfc_sli_mode);
James Smart7bdedb32016-07-06 12:36:00 -07007412 lpfc_enable_mds_diags_init(phba, lpfc_enable_mds_diags);
James Smartd2cc9bc2018-09-10 10:30:50 -07007413 lpfc_ras_fwlog_buffsize_init(phba, lpfc_ras_fwlog_buffsize);
7414 lpfc_ras_fwlog_level_init(phba, lpfc_ras_fwlog_level);
7415 lpfc_ras_fwlog_func_init(phba, lpfc_ras_fwlog_func);
7416
James Smart3de2a652007-08-02 11:09:59 -04007417 return;
7418}
Jamie Wellnitzb28485a2006-02-28 19:25:21 -05007419
James Smarte59058c2008-08-24 21:49:00 -04007420/**
James Smart895427b2017-02-12 13:52:30 -08007421 * lpfc_nvme_mod_param_dep - Adjust module parameter value based on
7422 * dependencies between protocols and roles.
7423 * @phba: lpfc_hba pointer.
7424 **/
7425void
7426lpfc_nvme_mod_param_dep(struct lpfc_hba *phba)
7427{
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007428 int logit = 0;
7429
7430 if (phba->cfg_hdw_queue > phba->sli4_hba.num_present_cpu) {
James Smartcdb42be2019-01-28 11:14:21 -08007431 phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007432 logit = 1;
7433 }
7434 if (phba->cfg_irq_chann > phba->sli4_hba.num_present_cpu) {
James Smart6a828b02019-01-28 11:14:31 -08007435 phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007436 logit = 1;
7437 }
7438 if (phba->cfg_irq_chann > phba->cfg_hdw_queue) {
James Smart6a828b02019-01-28 11:14:31 -08007439 phba->cfg_irq_chann = phba->cfg_hdw_queue;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007440 logit = 1;
7441 }
7442 if (logit)
7443 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
7444 "2006 Reducing Queues - CPU limitation: "
7445 "IRQ %d HDWQ %d\n",
7446 phba->cfg_irq_chann,
7447 phba->cfg_hdw_queue);
James Smart895427b2017-02-12 13:52:30 -08007448
James Smartf358dd02017-02-12 13:52:34 -08007449 if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME &&
7450 phba->nvmet_support) {
7451 phba->cfg_enable_fc4_type &= ~LPFC_ENABLE_FCP;
James Smart2d7dbc42017-02-12 13:52:35 -08007452
7453 lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
7454 "6013 %s x%x fb_size x%x, fb_max x%x\n",
7455 "NVME Target PRLI ACC enable_fb ",
7456 phba->cfg_nvme_enable_fb,
7457 phba->cfg_nvmet_fb_size,
7458 LPFC_NVMET_FB_SZ_MAX);
7459
7460 if (phba->cfg_nvme_enable_fb == 0)
7461 phba->cfg_nvmet_fb_size = 0;
7462 else {
7463 if (phba->cfg_nvmet_fb_size > LPFC_NVMET_FB_SZ_MAX)
7464 phba->cfg_nvmet_fb_size = LPFC_NVMET_FB_SZ_MAX;
7465 }
7466
James Smartbcb24f62017-11-20 16:00:36 -08007467 if (!phba->cfg_nvmet_mrq)
James Smart97a9ed32019-10-18 14:18:17 -07007468 phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
James Smartbcb24f62017-11-20 16:00:36 -08007469
James Smart2d7dbc42017-02-12 13:52:35 -08007470 /* Adjust lpfc_nvmet_mrq to avoid running out of WQE slots */
James Smart97a9ed32019-10-18 14:18:17 -07007471 if (phba->cfg_nvmet_mrq > phba->cfg_hdw_queue) {
7472 phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
James Smart2d7dbc42017-02-12 13:52:35 -08007473 lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC,
7474 "6018 Adjust lpfc_nvmet_mrq to %d\n",
7475 phba->cfg_nvmet_mrq);
7476 }
James Smartbcb24f62017-11-20 16:00:36 -08007477 if (phba->cfg_nvmet_mrq > LPFC_NVMET_MRQ_MAX)
7478 phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_MAX;
7479
James Smart2d7dbc42017-02-12 13:52:35 -08007480 } else {
James Smartf358dd02017-02-12 13:52:34 -08007481 /* Not NVME Target mode. Turn off Target parameters. */
7482 phba->nvmet_support = 0;
James Smart982ab122019-03-12 16:30:10 -07007483 phba->cfg_nvmet_mrq = 0;
James Smart2d7dbc42017-02-12 13:52:35 -08007484 phba->cfg_nvmet_fb_size = 0;
7485 }
James Smart895427b2017-02-12 13:52:30 -08007486}
7487
7488/**
James Smart3621a712009-04-06 18:47:14 -04007489 * lpfc_get_vport_cfgparam - Used during port create, init the vport structure
James Smarte59058c2008-08-24 21:49:00 -04007490 * @vport: lpfc_vport pointer.
7491 **/
James Smart3de2a652007-08-02 11:09:59 -04007492void
7493lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
7494{
James Smarte8b62012007-08-02 11:10:09 -04007495 lpfc_log_verbose_init(vport, lpfc_log_verbose);
James Smart3de2a652007-08-02 11:09:59 -04007496 lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth);
James Smart7dc517d2010-07-14 15:32:10 -04007497 lpfc_tgt_queue_depth_init(vport, lpfc_tgt_queue_depth);
James Smart3de2a652007-08-02 11:09:59 -04007498 lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo);
7499 lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo);
7500 lpfc_peer_port_login_init(vport, lpfc_peer_port_login);
7501 lpfc_restrict_login_init(vport, lpfc_restrict_login);
7502 lpfc_fcp_class_init(vport, lpfc_fcp_class);
7503 lpfc_use_adisc_init(vport, lpfc_use_adisc);
James Smart3cb01c52013-07-15 18:35:04 -04007504 lpfc_first_burst_size_init(vport, lpfc_first_burst_size);
James Smart977b5a02008-09-07 11:52:04 -04007505 lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time);
James Smart3de2a652007-08-02 11:09:59 -04007506 lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
7507 lpfc_max_luns_init(vport, lpfc_max_luns);
7508 lpfc_scan_down_init(vport, lpfc_scan_down);
James Smart7ee5d432007-10-27 13:37:17 -04007509 lpfc_enable_da_id_init(vport, lpfc_enable_da_id);
dea31012005-04-17 16:05:31 -05007510 return;
7511}