blob: e723b716608a9468cafb38ddc864176db6f8c183 [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 Smart67073c62021-03-01 09:18:21 -08004 * Copyright (C) 2017-2021 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);
Arnd Bergmannada48ba2021-03-22 17:02:47 +0100515 strlcpy(buf + PAGE_SIZE - 1 - sizeof(LPFC_NVME_INFO_MORE_STR),
James Smartafff0d22018-06-26 08:24:22 -0700516 LPFC_NVME_INFO_MORE_STR,
Arnd Bergmannada48ba2021-03-22 17:02:47 +0100517 sizeof(LPFC_NVME_INFO_MORE_STR) + 1);
James Smartafff0d22018-06-26 08:24:22 -0700518 }
519
James Smart895427b2017-02-12 13:52:30 -0800520 return len;
521}
522
523static ssize_t
James Smart4c47efc2019-01-28 11:14:25 -0800524lpfc_scsi_stat_show(struct device *dev, struct device_attribute *attr,
525 char *buf)
526{
527 struct Scsi_Host *shost = class_to_shost(dev);
528 struct lpfc_vport *vport = shost_priv(shost);
529 struct lpfc_hba *phba = vport->phba;
530 int len;
531 struct lpfc_fc4_ctrl_stat *cstat;
532 u64 data1, data2, data3;
533 u64 tot, totin, totout;
534 int i;
535 char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
536
James Smartf6e84792019-01-28 11:14:38 -0800537 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
James Smart4c47efc2019-01-28 11:14:25 -0800538 (phba->sli_rev != LPFC_SLI_REV4))
539 return 0;
540
541 scnprintf(buf, PAGE_SIZE, "SCSI HDWQ Statistics\n");
542
543 totin = 0;
544 totout = 0;
545 for (i = 0; i < phba->cfg_hdw_queue; i++) {
546 cstat = &phba->sli4_hba.hdwq[i].scsi_cstat;
547 tot = cstat->io_cmpls;
548 totin += tot;
549 data1 = cstat->input_requests;
550 data2 = cstat->output_requests;
551 data3 = cstat->control_requests;
552 totout += (data1 + data2 + data3);
553
554 scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
555 "IO %016llx ", i, data1, data2, data3);
556 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
557 goto buffer_done;
558
559 scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
560 tot, ((data1 + data2 + data3) - tot));
561 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
562 goto buffer_done;
563 }
564 scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
565 "OutIO %016llx\n", totin, totout, totout - totin);
566 strlcat(buf, tmp, PAGE_SIZE);
567
568buffer_done:
569 len = strnlen(buf, PAGE_SIZE);
570
571 return len;
572}
573
574static ssize_t
James Smart81301a92008-12-04 22:39:46 -0500575lpfc_bg_info_show(struct device *dev, struct device_attribute *attr,
576 char *buf)
577{
578 struct Scsi_Host *shost = class_to_shost(dev);
579 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
580 struct lpfc_hba *phba = vport->phba;
581
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700582 if (phba->cfg_enable_bg) {
James Smart81301a92008-12-04 22:39:46 -0500583 if (phba->sli3_options & LPFC_SLI3_BG_ENABLED)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700584 return scnprintf(buf, PAGE_SIZE,
585 "BlockGuard Enabled\n");
James Smart81301a92008-12-04 22:39:46 -0500586 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700587 return scnprintf(buf, PAGE_SIZE,
James Smart81301a92008-12-04 22:39:46 -0500588 "BlockGuard Not Supported\n");
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700589 } else
590 return scnprintf(buf, PAGE_SIZE,
James Smart81301a92008-12-04 22:39:46 -0500591 "BlockGuard Disabled\n");
592}
593
594static ssize_t
595lpfc_bg_guard_err_show(struct device *dev, struct device_attribute *attr,
596 char *buf)
597{
598 struct Scsi_Host *shost = class_to_shost(dev);
599 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
600 struct lpfc_hba *phba = vport->phba;
601
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700602 return scnprintf(buf, PAGE_SIZE, "%llu\n",
James Smart87b5c322008-12-16 10:34:09 -0500603 (unsigned long long)phba->bg_guard_err_cnt);
James Smart81301a92008-12-04 22:39:46 -0500604}
605
606static ssize_t
607lpfc_bg_apptag_err_show(struct device *dev, struct device_attribute *attr,
608 char *buf)
609{
610 struct Scsi_Host *shost = class_to_shost(dev);
611 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
612 struct lpfc_hba *phba = vport->phba;
613
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700614 return scnprintf(buf, PAGE_SIZE, "%llu\n",
James Smart87b5c322008-12-16 10:34:09 -0500615 (unsigned long long)phba->bg_apptag_err_cnt);
James Smart81301a92008-12-04 22:39:46 -0500616}
617
618static ssize_t
619lpfc_bg_reftag_err_show(struct device *dev, struct device_attribute *attr,
620 char *buf)
621{
622 struct Scsi_Host *shost = class_to_shost(dev);
623 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
624 struct lpfc_hba *phba = vport->phba;
625
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700626 return scnprintf(buf, PAGE_SIZE, "%llu\n",
James Smart87b5c322008-12-16 10:34:09 -0500627 (unsigned long long)phba->bg_reftag_err_cnt);
James Smart81301a92008-12-04 22:39:46 -0500628}
629
James Smarte59058c2008-08-24 21:49:00 -0400630/**
James Smart3621a712009-04-06 18:47:14 -0400631 * lpfc_info_show - Return some pci info about the host in ascii
James Smarte59058c2008-08-24 21:49:00 -0400632 * @dev: class converted to a Scsi_host structure.
633 * @attr: device attribute, not used.
634 * @buf: on return contains the formatted text from lpfc_info().
635 *
636 * Returns: size of formatted string.
637 **/
dea31012005-04-17 16:05:31 -0500638static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100639lpfc_info_show(struct device *dev, struct device_attribute *attr,
640 char *buf)
dea31012005-04-17 16:05:31 -0500641{
Tony Jonesee959b02008-02-22 00:13:36 +0100642 struct Scsi_Host *host = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500643
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700644 return scnprintf(buf, PAGE_SIZE, "%s\n", lpfc_info(host));
dea31012005-04-17 16:05:31 -0500645}
646
James Smarte59058c2008-08-24 21:49:00 -0400647/**
James Smart3621a712009-04-06 18:47:14 -0400648 * lpfc_serialnum_show - Return the hba serial number in ascii
James Smarte59058c2008-08-24 21:49:00 -0400649 * @dev: class converted to a Scsi_host structure.
650 * @attr: device attribute, not used.
651 * @buf: on return contains the formatted text serial number.
652 *
653 * Returns: size of formatted string.
654 **/
dea31012005-04-17 16:05:31 -0500655static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100656lpfc_serialnum_show(struct device *dev, struct device_attribute *attr,
657 char *buf)
dea31012005-04-17 16:05:31 -0500658{
Tony Jonesee959b02008-02-22 00:13:36 +0100659 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500660 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
661 struct lpfc_hba *phba = vport->phba;
662
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700663 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->SerialNumber);
dea31012005-04-17 16:05:31 -0500664}
665
James Smarte59058c2008-08-24 21:49:00 -0400666/**
James Smart3621a712009-04-06 18:47:14 -0400667 * lpfc_temp_sensor_show - Return the temperature sensor level
James Smarte59058c2008-08-24 21:49:00 -0400668 * @dev: class converted to a Scsi_host structure.
669 * @attr: device attribute, not used.
670 * @buf: on return contains the formatted support level.
671 *
672 * Description:
673 * Returns a number indicating the temperature sensor level currently
674 * supported, zero or one in ascii.
675 *
676 * Returns: size of formatted string.
677 **/
dea31012005-04-17 16:05:31 -0500678static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100679lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr,
680 char *buf)
James Smart57127f12007-10-27 13:37:05 -0400681{
Tony Jonesee959b02008-02-22 00:13:36 +0100682 struct Scsi_Host *shost = class_to_shost(dev);
James Smart57127f12007-10-27 13:37:05 -0400683 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
684 struct lpfc_hba *phba = vport->phba;
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700685 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->temp_sensor_support);
James Smart57127f12007-10-27 13:37:05 -0400686}
687
James Smarte59058c2008-08-24 21:49:00 -0400688/**
James Smart3621a712009-04-06 18:47:14 -0400689 * lpfc_modeldesc_show - Return the model description of the hba
James Smarte59058c2008-08-24 21:49:00 -0400690 * @dev: class converted to a Scsi_host structure.
691 * @attr: device attribute, not used.
692 * @buf: on return contains the scsi vpd model description.
693 *
694 * Returns: size of formatted string.
695 **/
James Smart57127f12007-10-27 13:37:05 -0400696static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100697lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr,
698 char *buf)
dea31012005-04-17 16:05:31 -0500699{
Tony Jonesee959b02008-02-22 00:13:36 +0100700 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500701 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
702 struct lpfc_hba *phba = vport->phba;
703
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700704 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ModelDesc);
dea31012005-04-17 16:05:31 -0500705}
706
James Smarte59058c2008-08-24 21:49:00 -0400707/**
James Smart3621a712009-04-06 18:47:14 -0400708 * lpfc_modelname_show - Return the model name of the hba
James Smarte59058c2008-08-24 21:49:00 -0400709 * @dev: class converted to a Scsi_host structure.
710 * @attr: device attribute, not used.
711 * @buf: on return contains the scsi vpd model name.
712 *
713 * Returns: size of formatted string.
714 **/
dea31012005-04-17 16:05:31 -0500715static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100716lpfc_modelname_show(struct device *dev, struct device_attribute *attr,
717 char *buf)
dea31012005-04-17 16:05:31 -0500718{
Tony Jonesee959b02008-02-22 00:13:36 +0100719 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500720 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
721 struct lpfc_hba *phba = vport->phba;
722
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700723 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ModelName);
dea31012005-04-17 16:05:31 -0500724}
725
James Smarte59058c2008-08-24 21:49:00 -0400726/**
James Smart3621a712009-04-06 18:47:14 -0400727 * lpfc_programtype_show - Return the program type of the hba
James Smarte59058c2008-08-24 21:49:00 -0400728 * @dev: class converted to a Scsi_host structure.
729 * @attr: device attribute, not used.
730 * @buf: on return contains the scsi vpd program type.
731 *
732 * Returns: size of formatted string.
733 **/
dea31012005-04-17 16:05:31 -0500734static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100735lpfc_programtype_show(struct device *dev, struct device_attribute *attr,
736 char *buf)
dea31012005-04-17 16:05:31 -0500737{
Tony Jonesee959b02008-02-22 00:13:36 +0100738 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500739 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
740 struct lpfc_hba *phba = vport->phba;
741
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700742 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ProgramType);
dea31012005-04-17 16:05:31 -0500743}
744
James Smarte59058c2008-08-24 21:49:00 -0400745/**
James Smart3621a712009-04-06 18:47:14 -0400746 * lpfc_mlomgmt_show - Return the Menlo Maintenance sli flag
James Smart84774a42008-08-24 21:50:06 -0400747 * @dev: class converted to a Scsi_host structure.
748 * @attr: device attribute, not used.
749 * @buf: on return contains the Menlo Maintenance sli flag.
750 *
751 * Returns: size of formatted string.
752 **/
753static ssize_t
754lpfc_mlomgmt_show(struct device *dev, struct device_attribute *attr, char *buf)
755{
756 struct Scsi_Host *shost = class_to_shost(dev);
757 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
758 struct lpfc_hba *phba = vport->phba;
759
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700760 return scnprintf(buf, PAGE_SIZE, "%d\n",
James Smart84774a42008-08-24 21:50:06 -0400761 (phba->sli.sli_flag & LPFC_MENLO_MAINT));
762}
763
764/**
James Smart3621a712009-04-06 18:47:14 -0400765 * lpfc_vportnum_show - Return the port number in ascii of the hba
James Smarte59058c2008-08-24 21:49:00 -0400766 * @dev: class converted to a Scsi_host structure.
767 * @attr: device attribute, not used.
768 * @buf: on return contains scsi vpd program type.
769 *
770 * Returns: size of formatted string.
771 **/
dea31012005-04-17 16:05:31 -0500772static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100773lpfc_vportnum_show(struct device *dev, struct device_attribute *attr,
774 char *buf)
dea31012005-04-17 16:05:31 -0500775{
Tony Jonesee959b02008-02-22 00:13:36 +0100776 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500777 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
778 struct lpfc_hba *phba = vport->phba;
779
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700780 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->Port);
dea31012005-04-17 16:05:31 -0500781}
782
James Smarte59058c2008-08-24 21:49:00 -0400783/**
James Smart3621a712009-04-06 18:47:14 -0400784 * lpfc_fwrev_show - Return the firmware rev running in the hba
James Smarte59058c2008-08-24 21:49:00 -0400785 * @dev: class converted to a Scsi_host structure.
786 * @attr: device attribute, not used.
787 * @buf: on return contains the scsi vpd program type.
788 *
789 * Returns: size of formatted string.
790 **/
dea31012005-04-17 16:05:31 -0500791static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100792lpfc_fwrev_show(struct device *dev, struct device_attribute *attr,
793 char *buf)
dea31012005-04-17 16:05:31 -0500794{
Tony Jonesee959b02008-02-22 00:13:36 +0100795 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500796 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
797 struct lpfc_hba *phba = vport->phba;
James Smart026abb82011-12-13 13:20:45 -0500798 uint32_t if_type;
799 uint8_t sli_family;
James Smart6b5151f2012-01-18 16:24:06 -0500800 char fwrev[FW_REV_STR_SIZE];
James Smart026abb82011-12-13 13:20:45 -0500801 int len;
James Smart2e0fef82007-06-17 19:56:36 -0500802
dea31012005-04-17 16:05:31 -0500803 lpfc_decode_firmware_rev(phba, fwrev, 1);
James Smart026abb82011-12-13 13:20:45 -0500804 if_type = phba->sli4_hba.pc_sli4_params.if_type;
805 sli_family = phba->sli4_hba.pc_sli4_params.sli_family;
806
807 if (phba->sli_rev < LPFC_SLI_REV4)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700808 len = scnprintf(buf, PAGE_SIZE, "%s, sli-%d\n",
James Smart026abb82011-12-13 13:20:45 -0500809 fwrev, phba->sli_rev);
810 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700811 len = scnprintf(buf, PAGE_SIZE, "%s, sli-%d:%d:%x\n",
James Smart026abb82011-12-13 13:20:45 -0500812 fwrev, phba->sli_rev, if_type, sli_family);
813
814 return len;
dea31012005-04-17 16:05:31 -0500815}
816
James Smarte59058c2008-08-24 21:49:00 -0400817/**
James Smart3621a712009-04-06 18:47:14 -0400818 * lpfc_hdw_show - Return the jedec information about the hba
James Smarte59058c2008-08-24 21:49:00 -0400819 * @dev: class converted to a Scsi_host structure.
820 * @attr: device attribute, not used.
821 * @buf: on return contains the scsi vpd program type.
822 *
823 * Returns: size of formatted string.
824 **/
dea31012005-04-17 16:05:31 -0500825static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100826lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf)
dea31012005-04-17 16:05:31 -0500827{
828 char hdw[9];
Tony Jonesee959b02008-02-22 00:13:36 +0100829 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500830 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
831 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -0500832 lpfc_vpd_t *vp = &phba->vpd;
James Smart2e0fef82007-06-17 19:56:36 -0500833
dea31012005-04-17 16:05:31 -0500834 lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
James Smartec762422019-08-14 16:57:07 -0700835 return scnprintf(buf, PAGE_SIZE, "%s %08x %08x\n", hdw,
836 vp->rev.smRev, vp->rev.smFwRev);
dea31012005-04-17 16:05:31 -0500837}
James Smarte59058c2008-08-24 21:49:00 -0400838
839/**
James Smart3621a712009-04-06 18:47:14 -0400840 * lpfc_option_rom_version_show - Return the adapter ROM FCode version
James Smarte59058c2008-08-24 21:49:00 -0400841 * @dev: class converted to a Scsi_host structure.
842 * @attr: device attribute, not used.
843 * @buf: on return contains the ROM and FCode ascii strings.
844 *
845 * Returns: size of formatted string.
846 **/
dea31012005-04-17 16:05:31 -0500847static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100848lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr,
849 char *buf)
dea31012005-04-17 16:05:31 -0500850{
Tony Jonesee959b02008-02-22 00:13:36 +0100851 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500852 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
853 struct lpfc_hba *phba = vport->phba;
James Smarta0683bf2015-04-07 15:07:16 -0400854 char fwrev[FW_REV_STR_SIZE];
James Smart2e0fef82007-06-17 19:56:36 -0500855
James Smarta0683bf2015-04-07 15:07:16 -0400856 if (phba->sli_rev < LPFC_SLI_REV4)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700857 return scnprintf(buf, PAGE_SIZE, "%s\n",
858 phba->OptionROMVersion);
James Smarta0683bf2015-04-07 15:07:16 -0400859
860 lpfc_decode_firmware_rev(phba, fwrev, 1);
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700861 return scnprintf(buf, PAGE_SIZE, "%s\n", fwrev);
dea31012005-04-17 16:05:31 -0500862}
James Smarte59058c2008-08-24 21:49:00 -0400863
864/**
Lee Jonesa3dbf512021-03-12 09:47:12 +0000865 * lpfc_link_state_show - Return the link state of the port
James Smarte59058c2008-08-24 21:49:00 -0400866 * @dev: class converted to a Scsi_host structure.
867 * @attr: device attribute, not used.
868 * @buf: on return contains text describing the state of the link.
869 *
870 * Notes:
871 * The switch statement has no default so zero will be returned.
872 *
873 * Returns: size of formatted string.
874 **/
dea31012005-04-17 16:05:31 -0500875static ssize_t
Hannes Reineckebbd1ae42008-03-18 14:32:28 +0100876lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
877 char *buf)
dea31012005-04-17 16:05:31 -0500878{
Tony Jonesee959b02008-02-22 00:13:36 +0100879 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500880 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
881 struct lpfc_hba *phba = vport->phba;
882 int len = 0;
883
884 switch (phba->link_state) {
885 case LPFC_LINK_UNKNOWN:
Jamie Wellnitz41415862006-02-28 19:25:27 -0500886 case LPFC_WARM_START:
dea31012005-04-17 16:05:31 -0500887 case LPFC_INIT_START:
888 case LPFC_INIT_MBX_CMDS:
889 case LPFC_LINK_DOWN:
James Smart2e0fef82007-06-17 19:56:36 -0500890 case LPFC_HBA_ERROR:
James Smarta0c87cb2009-07-19 10:01:10 -0400891 if (phba->hba_flag & LINK_DISABLED)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700892 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smarta0c87cb2009-07-19 10:01:10 -0400893 "Link Down - User disabled\n");
894 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700895 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smarta0c87cb2009-07-19 10:01:10 -0400896 "Link Down\n");
dea31012005-04-17 16:05:31 -0500897 break;
898 case LPFC_LINK_UP:
dea31012005-04-17 16:05:31 -0500899 case LPFC_CLEAR_LA:
dea31012005-04-17 16:05:31 -0500900 case LPFC_HBA_READY:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700901 len += scnprintf(buf + len, PAGE_SIZE-len, "Link Up - ");
James Smart2e0fef82007-06-17 19:56:36 -0500902
903 switch (vport->port_state) {
James Smart2e0fef82007-06-17 19:56:36 -0500904 case LPFC_LOCAL_CFG_LINK:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700905 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart92d7f7b2007-06-17 19:56:38 -0500906 "Configuring Link\n");
James Smart2e0fef82007-06-17 19:56:36 -0500907 break;
James Smart92d7f7b2007-06-17 19:56:38 -0500908 case LPFC_FDISC:
James Smart2e0fef82007-06-17 19:56:36 -0500909 case LPFC_FLOGI:
910 case LPFC_FABRIC_CFG_LINK:
911 case LPFC_NS_REG:
912 case LPFC_NS_QRY:
913 case LPFC_BUILD_DISC_LIST:
914 case LPFC_DISC_AUTH:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700915 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart2e0fef82007-06-17 19:56:36 -0500916 "Discovery\n");
917 break;
918 case LPFC_VPORT_READY:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700919 len += scnprintf(buf + len, PAGE_SIZE - len,
920 "Ready\n");
James Smart2e0fef82007-06-17 19:56:36 -0500921 break;
922
James Smart92d7f7b2007-06-17 19:56:38 -0500923 case LPFC_VPORT_FAILED:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700924 len += scnprintf(buf + len, PAGE_SIZE - len,
925 "Failed\n");
James Smart92d7f7b2007-06-17 19:56:38 -0500926 break;
927
928 case LPFC_VPORT_UNKNOWN:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700929 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart2e0fef82007-06-17 19:56:36 -0500930 "Unknown\n");
931 break;
932 }
James Smart84774a42008-08-24 21:50:06 -0400933 if (phba->sli.sli_flag & LPFC_MENLO_MAINT)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700934 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart84774a42008-08-24 21:50:06 -0400935 " Menlo Maint Mode\n");
James Smart76a95d72010-11-20 23:11:48 -0500936 else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smart2e0fef82007-06-17 19:56:36 -0500937 if (vport->fc_flag & FC_PUBLIC_LOOP)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700938 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500939 " Public Loop\n");
940 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700941 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500942 " Private Loop\n");
943 } else {
James Smart2e0fef82007-06-17 19:56:36 -0500944 if (vport->fc_flag & FC_FABRIC)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700945 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500946 " Fabric\n");
947 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700948 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500949 " Point-2-Point\n");
950 }
951 }
James Smart2e0fef82007-06-17 19:56:36 -0500952
James Smart1dc5ec22018-10-23 13:41:11 -0700953 if ((phba->sli_rev == LPFC_SLI_REV4) &&
954 ((bf_get(lpfc_sli_intf_if_type,
955 &phba->sli4_hba.sli_intf) ==
956 LPFC_SLI_INTF_IF_TYPE_6))) {
957 struct lpfc_trunk_link link = phba->trunk_link;
958
959 if (bf_get(lpfc_conf_trunk_port0, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700960 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700961 "Trunk port 0: Link %s %s\n",
962 (link.link0.state == LPFC_LINK_UP) ?
963 "Up" : "Down. ",
964 trunk_errmsg[link.link0.fault]);
965
966 if (bf_get(lpfc_conf_trunk_port1, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700967 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700968 "Trunk port 1: Link %s %s\n",
969 (link.link1.state == LPFC_LINK_UP) ?
970 "Up" : "Down. ",
971 trunk_errmsg[link.link1.fault]);
972
973 if (bf_get(lpfc_conf_trunk_port2, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700974 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700975 "Trunk port 2: Link %s %s\n",
976 (link.link2.state == LPFC_LINK_UP) ?
977 "Up" : "Down. ",
978 trunk_errmsg[link.link2.fault]);
979
980 if (bf_get(lpfc_conf_trunk_port3, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700981 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700982 "Trunk port 3: Link %s %s\n",
983 (link.link3.state == LPFC_LINK_UP) ?
984 "Up" : "Down. ",
985 trunk_errmsg[link.link3.fault]);
986
987 }
988
dea31012005-04-17 16:05:31 -0500989 return len;
990}
991
James Smarte59058c2008-08-24 21:49:00 -0400992/**
James Smart026abb82011-12-13 13:20:45 -0500993 * lpfc_sli4_protocol_show - Return the fip mode of the HBA
994 * @dev: class unused variable.
995 * @attr: device attribute, not used.
996 * @buf: on return contains the module description text.
997 *
998 * Returns: size of formatted string.
999 **/
1000static ssize_t
1001lpfc_sli4_protocol_show(struct device *dev, struct device_attribute *attr,
1002 char *buf)
1003{
1004 struct Scsi_Host *shost = class_to_shost(dev);
1005 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1006 struct lpfc_hba *phba = vport->phba;
1007
1008 if (phba->sli_rev < LPFC_SLI_REV4)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001009 return scnprintf(buf, PAGE_SIZE, "fc\n");
James Smart026abb82011-12-13 13:20:45 -05001010
1011 if (phba->sli4_hba.lnk_info.lnk_dv == LPFC_LNK_DAT_VAL) {
1012 if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_GE)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001013 return scnprintf(buf, PAGE_SIZE, "fcoe\n");
James Smart026abb82011-12-13 13:20:45 -05001014 if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001015 return scnprintf(buf, PAGE_SIZE, "fc\n");
James Smart026abb82011-12-13 13:20:45 -05001016 }
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001017 return scnprintf(buf, PAGE_SIZE, "unknown\n");
James Smart026abb82011-12-13 13:20:45 -05001018}
1019
1020/**
James Smart1ba981f2014-02-20 09:56:45 -05001021 * lpfc_oas_supported_show - Return whether or not Optimized Access Storage
1022 * (OAS) is supported.
1023 * @dev: class unused variable.
1024 * @attr: device attribute, not used.
1025 * @buf: on return contains the module description text.
1026 *
1027 * Returns: size of formatted string.
1028 **/
1029static ssize_t
1030lpfc_oas_supported_show(struct device *dev, struct device_attribute *attr,
1031 char *buf)
1032{
1033 struct Scsi_Host *shost = class_to_shost(dev);
1034 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
1035 struct lpfc_hba *phba = vport->phba;
1036
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001037 return scnprintf(buf, PAGE_SIZE, "%d\n",
James Smart1ba981f2014-02-20 09:56:45 -05001038 phba->sli4_hba.pc_sli4_params.oas_supported);
1039}
1040
1041/**
James Smart84d1b002010-02-12 14:42:33 -05001042 * lpfc_link_state_store - Transition the link_state on an HBA port
1043 * @dev: class device that is converted into a Scsi_host.
1044 * @attr: device attribute, not used.
1045 * @buf: one or more lpfc_polling_flags values.
1046 * @count: not used.
1047 *
1048 * Returns:
1049 * -EINVAL if the buffer is not "up" or "down"
1050 * return from link state change function if non-zero
1051 * length of the buf on success
1052 **/
1053static ssize_t
1054lpfc_link_state_store(struct device *dev, struct device_attribute *attr,
1055 const char *buf, size_t count)
1056{
1057 struct Scsi_Host *shost = class_to_shost(dev);
1058 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1059 struct lpfc_hba *phba = vport->phba;
1060
1061 int status = -EINVAL;
1062
1063 if ((strncmp(buf, "up", sizeof("up") - 1) == 0) &&
1064 (phba->link_state == LPFC_LINK_DOWN))
James Smart6e7288d2010-06-07 15:23:35 -04001065 status = phba->lpfc_hba_init_link(phba, MBX_NOWAIT);
James Smart84d1b002010-02-12 14:42:33 -05001066 else if ((strncmp(buf, "down", sizeof("down") - 1) == 0) &&
1067 (phba->link_state >= LPFC_LINK_UP))
James Smart6e7288d2010-06-07 15:23:35 -04001068 status = phba->lpfc_hba_down_link(phba, MBX_NOWAIT);
James Smart84d1b002010-02-12 14:42:33 -05001069
1070 if (status == 0)
1071 return strlen(buf);
1072 else
1073 return status;
1074}
1075
1076/**
James Smart3621a712009-04-06 18:47:14 -04001077 * lpfc_num_discovered_ports_show - Return sum of mapped and unmapped vports
James Smarte59058c2008-08-24 21:49:00 -04001078 * @dev: class device that is converted into a Scsi_host.
1079 * @attr: device attribute, not used.
1080 * @buf: on return contains the sum of fc mapped and unmapped.
1081 *
1082 * Description:
1083 * Returns the ascii text number of the sum of the fc mapped and unmapped
1084 * vport counts.
1085 *
1086 * Returns: size of formatted string.
1087 **/
dea31012005-04-17 16:05:31 -05001088static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001089lpfc_num_discovered_ports_show(struct device *dev,
1090 struct device_attribute *attr, char *buf)
dea31012005-04-17 16:05:31 -05001091{
Tony Jonesee959b02008-02-22 00:13:36 +01001092 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001093 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1094
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001095 return scnprintf(buf, PAGE_SIZE, "%d\n",
James Smart2e0fef82007-06-17 19:56:36 -05001096 vport->fc_map_cnt + vport->fc_unmap_cnt);
dea31012005-04-17 16:05:31 -05001097}
1098
James Smarte59058c2008-08-24 21:49:00 -04001099/**
James Smart3621a712009-04-06 18:47:14 -04001100 * lpfc_issue_lip - Misnomer, name carried over from long ago
James Smarte59058c2008-08-24 21:49:00 -04001101 * @shost: Scsi_Host pointer.
1102 *
1103 * Description:
1104 * Bring the link down gracefully then re-init the link. The firmware will
1105 * re-init the fiber channel interface as required. Does not issue a LIP.
1106 *
1107 * Returns:
1108 * -EPERM port offline or management commands are being blocked
1109 * -ENOMEM cannot allocate memory for the mailbox command
1110 * -EIO error sending the mailbox command
1111 * zero for success
1112 **/
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07001113static int
James Smart2e0fef82007-06-17 19:56:36 -05001114lpfc_issue_lip(struct Scsi_Host *shost)
dea31012005-04-17 16:05:31 -05001115{
James Smart2e0fef82007-06-17 19:56:36 -05001116 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1117 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05001118 LPFC_MBOXQ_t *pmboxq;
1119 int mbxstatus = MBXERR_ERROR;
1120
James Smart2289e952018-01-30 15:58:55 -08001121 /*
1122 * If the link is offline, disabled or BLOCK_MGMT_IO
1123 * it doesn't make any sense to allow issue_lip
1124 */
James Smart2e0fef82007-06-17 19:56:36 -05001125 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smart2289e952018-01-30 15:58:55 -08001126 (phba->hba_flag & LINK_DISABLED) ||
James Smart83108bd2008-01-11 01:53:09 -05001127 (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO))
dea31012005-04-17 16:05:31 -05001128 return -EPERM;
1129
1130 pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);
1131
1132 if (!pmboxq)
1133 return -ENOMEM;
1134
1135 memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
James Smart04c68492009-05-22 14:52:52 -04001136 pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK;
1137 pmboxq->u.mb.mbxOwner = OWN_HOST;
James Smart4db621e2006-07-06 15:49:49 -04001138
James Smart33ccf8d2006-08-17 11:57:58 -04001139 mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2);
dea31012005-04-17 16:05:31 -05001140
James Smart04c68492009-05-22 14:52:52 -04001141 if ((mbxstatus == MBX_SUCCESS) &&
1142 (pmboxq->u.mb.mbxStatus == 0 ||
1143 pmboxq->u.mb.mbxStatus == MBXERR_LINK_DOWN)) {
James Smart4db621e2006-07-06 15:49:49 -04001144 memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
1145 lpfc_init_link(phba, pmboxq, phba->cfg_topology,
1146 phba->cfg_link_speed);
1147 mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq,
1148 phba->fc_ratov * 2);
James Smartdcf2a4e2010-09-29 11:18:53 -04001149 if ((mbxstatus == MBX_SUCCESS) &&
1150 (pmboxq->u.mb.mbxStatus == MBXERR_SEC_NO_PERMISSION))
1151 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
1152 "2859 SLI authentication is required "
1153 "for INIT_LINK but has not done yet\n");
James Smart4db621e2006-07-06 15:49:49 -04001154 }
1155
James Smart5b8bd0c2007-04-25 09:52:49 -04001156 lpfc_set_loopback_flag(phba);
James Smart858c9f62007-06-17 19:56:39 -05001157 if (mbxstatus != MBX_TIMEOUT)
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04001158 mempool_free(pmboxq, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05001159
1160 if (mbxstatus == MBXERR_ERROR)
1161 return -EIO;
1162
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07001163 return 0;
dea31012005-04-17 16:05:31 -05001164}
1165
James Smart895427b2017-02-12 13:52:30 -08001166int
1167lpfc_emptyq_wait(struct lpfc_hba *phba, struct list_head *q, spinlock_t *lock)
1168{
1169 int cnt = 0;
1170
1171 spin_lock_irq(lock);
1172 while (!list_empty(q)) {
1173 spin_unlock_irq(lock);
1174 msleep(20);
1175 if (cnt++ > 250) { /* 5 secs */
1176 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
1177 "0466 %s %s\n",
1178 "Outstanding IO when ",
1179 "bringing Adapter offline\n");
1180 return 0;
1181 }
1182 spin_lock_irq(lock);
1183 }
1184 spin_unlock_irq(lock);
1185 return 1;
1186}
1187
James Smarte59058c2008-08-24 21:49:00 -04001188/**
James Smart3621a712009-04-06 18:47:14 -04001189 * lpfc_do_offline - Issues a mailbox command to bring the link down
James Smarte59058c2008-08-24 21:49:00 -04001190 * @phba: lpfc_hba pointer.
1191 * @type: LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL.
1192 *
1193 * Notes:
1194 * Assumes any error from lpfc_do_offline() will be negative.
1195 * Can wait up to 5 seconds for the port ring buffers count
1196 * to reach zero, prints a warning if it is not zero and continues.
James Smart3621a712009-04-06 18:47:14 -04001197 * lpfc_workq_post_event() returns a non-zero return code if call fails.
James Smarte59058c2008-08-24 21:49:00 -04001198 *
1199 * Returns:
1200 * -EIO error posting the event
1201 * zero for success
1202 **/
James Smart40496f02006-07-06 15:50:22 -04001203static int
James Smart46fa3112007-04-25 09:51:45 -04001204lpfc_do_offline(struct lpfc_hba *phba, uint32_t type)
1205{
1206 struct completion online_compl;
James Smart895427b2017-02-12 13:52:30 -08001207 struct lpfc_queue *qp = NULL;
James Smart46fa3112007-04-25 09:51:45 -04001208 struct lpfc_sli_ring *pring;
1209 struct lpfc_sli *psli;
1210 int status = 0;
James Smart46fa3112007-04-25 09:51:45 -04001211 int i;
James Smartfedd3b72011-02-16 12:39:24 -05001212 int rc;
James Smart46fa3112007-04-25 09:51:45 -04001213
1214 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001215 rc = lpfc_workq_post_event(phba, &status, &online_compl,
James Smart46fa3112007-04-25 09:51:45 -04001216 LPFC_EVT_OFFLINE_PREP);
James Smartfedd3b72011-02-16 12:39:24 -05001217 if (rc == 0)
1218 return -ENOMEM;
1219
James Smart46fa3112007-04-25 09:51:45 -04001220 wait_for_completion(&online_compl);
1221
1222 if (status != 0)
1223 return -EIO;
1224
1225 psli = &phba->sli;
1226
James Smart4645f7b2019-03-12 16:30:14 -07001227 /*
1228 * If freeing the queues have already started, don't access them.
1229 * Otherwise set FREE_WAIT to indicate that queues are being used
1230 * to hold the freeing process until we finish.
1231 */
1232 spin_lock_irq(&phba->hbalock);
1233 if (!(psli->sli_flag & LPFC_QUEUE_FREE_INIT)) {
1234 psli->sli_flag |= LPFC_QUEUE_FREE_WAIT;
1235 } else {
1236 spin_unlock_irq(&phba->hbalock);
1237 goto skip_wait;
1238 }
1239 spin_unlock_irq(&phba->hbalock);
1240
James Smart09372822008-01-11 01:52:54 -05001241 /* Wait a little for things to settle down, but not
1242 * long enough for dev loss timeout to expire.
1243 */
James Smart895427b2017-02-12 13:52:30 -08001244 if (phba->sli_rev != LPFC_SLI_REV4) {
1245 for (i = 0; i < psli->num_rings; i++) {
1246 pring = &psli->sli3_ring[i];
1247 if (!lpfc_emptyq_wait(phba, &pring->txcmplq,
1248 &phba->hbalock))
1249 goto out;
1250 }
1251 } else {
1252 list_for_each_entry(qp, &phba->sli4_hba.lpfc_wq_list, wq_list) {
1253 pring = qp->pring;
1254 if (!pring)
1255 continue;
1256 if (!lpfc_emptyq_wait(phba, &pring->txcmplq,
1257 &pring->ring_lock))
1258 goto out;
James Smart46fa3112007-04-25 09:51:45 -04001259 }
1260 }
James Smart895427b2017-02-12 13:52:30 -08001261out:
James Smart4645f7b2019-03-12 16:30:14 -07001262 spin_lock_irq(&phba->hbalock);
1263 psli->sli_flag &= ~LPFC_QUEUE_FREE_WAIT;
1264 spin_unlock_irq(&phba->hbalock);
1265
1266skip_wait:
James Smart46fa3112007-04-25 09:51:45 -04001267 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001268 rc = lpfc_workq_post_event(phba, &status, &online_compl, type);
1269 if (rc == 0)
1270 return -ENOMEM;
1271
James Smart46fa3112007-04-25 09:51:45 -04001272 wait_for_completion(&online_compl);
1273
1274 if (status != 0)
1275 return -EIO;
1276
1277 return 0;
1278}
1279
James Smarte59058c2008-08-24 21:49:00 -04001280/**
James Smart50212672018-12-13 15:17:57 -08001281 * lpfc_reset_pci_bus - resets PCI bridge controller's secondary bus of an HBA
1282 * @phba: lpfc_hba pointer.
1283 *
1284 * Description:
1285 * Issues a PCI secondary bus reset for the phba->pcidev.
1286 *
1287 * Notes:
1288 * First walks the bus_list to ensure only PCI devices with Emulex
1289 * vendor id, device ids that support hot reset, only one occurrence
1290 * of function 0, and all ports on the bus are in offline mode to ensure the
1291 * hot reset only affects one valid HBA.
1292 *
1293 * Returns:
1294 * -ENOTSUPP, cfg_enable_hba_reset must be of value 2
1295 * -ENODEV, NULL ptr to pcidev
1296 * -EBADSLT, detected invalid device
1297 * -EBUSY, port is not in offline state
1298 * 0, successful
1299 */
Bart Van Assche3999df72019-03-28 11:06:16 -07001300static int
James Smart50212672018-12-13 15:17:57 -08001301lpfc_reset_pci_bus(struct lpfc_hba *phba)
1302{
1303 struct pci_dev *pdev = phba->pcidev;
1304 struct Scsi_Host *shost = NULL;
1305 struct lpfc_hba *phba_other = NULL;
1306 struct pci_dev *ptr = NULL;
1307 int res;
1308
1309 if (phba->cfg_enable_hba_reset != 2)
1310 return -ENOTSUPP;
1311
1312 if (!pdev) {
1313 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "8345 pdev NULL!\n");
1314 return -ENODEV;
1315 }
1316
1317 res = lpfc_check_pci_resettable(phba);
1318 if (res)
1319 return res;
1320
1321 /* Walk the list of devices on the pci_dev's bus */
1322 list_for_each_entry(ptr, &pdev->bus->devices, bus_list) {
1323 /* Check port is offline */
1324 shost = pci_get_drvdata(ptr);
1325 if (shost) {
1326 phba_other =
1327 ((struct lpfc_vport *)shost->hostdata)->phba;
1328 if (!(phba_other->pport->fc_flag & FC_OFFLINE_MODE)) {
1329 lpfc_printf_log(phba_other, KERN_INFO, LOG_INIT,
1330 "8349 WWPN = 0x%02x%02x%02x%02x"
1331 "%02x%02x%02x%02x is not "
1332 "offline!\n",
1333 phba_other->wwpn[0],
1334 phba_other->wwpn[1],
1335 phba_other->wwpn[2],
1336 phba_other->wwpn[3],
1337 phba_other->wwpn[4],
1338 phba_other->wwpn[5],
1339 phba_other->wwpn[6],
1340 phba_other->wwpn[7]);
1341 return -EBUSY;
1342 }
1343 }
1344 }
1345
1346 /* Issue PCI bus reset */
1347 res = pci_reset_bus(pdev);
1348 if (res) {
1349 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1350 "8350 PCI reset bus failed: %d\n", res);
1351 }
1352
1353 return res;
1354}
1355
1356/**
James Smart3621a712009-04-06 18:47:14 -04001357 * lpfc_selective_reset - Offline then onlines the port
James Smarte59058c2008-08-24 21:49:00 -04001358 * @phba: lpfc_hba pointer.
1359 *
1360 * Description:
1361 * If the port is configured to allow a reset then the hba is brought
1362 * offline then online.
1363 *
1364 * Notes:
1365 * Assumes any error from lpfc_do_offline() will be negative.
James Smartab56dc22011-02-16 12:39:57 -05001366 * Do not make this function static.
James Smarte59058c2008-08-24 21:49:00 -04001367 *
1368 * Returns:
1369 * lpfc_do_offline() return code if not zero
1370 * -EIO reset not configured or error posting the event
1371 * zero for success
1372 **/
James Smart7f860592011-03-11 16:05:52 -05001373int
James Smart40496f02006-07-06 15:50:22 -04001374lpfc_selective_reset(struct lpfc_hba *phba)
1375{
1376 struct completion online_compl;
1377 int status = 0;
James Smartfedd3b72011-02-16 12:39:24 -05001378 int rc;
James Smart40496f02006-07-06 15:50:22 -04001379
James Smart71157c92013-07-15 18:34:36 -04001380 if (!phba->cfg_enable_hba_reset)
James Smartf7a919b2011-08-21 21:49:16 -04001381 return -EACCES;
James Smart13815c82008-01-11 01:52:48 -05001382
James Smart71157c92013-07-15 18:34:36 -04001383 if (!(phba->pport->fc_flag & FC_OFFLINE_MODE)) {
1384 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
James Smart40496f02006-07-06 15:50:22 -04001385
James Smart71157c92013-07-15 18:34:36 -04001386 if (status != 0)
1387 return status;
1388 }
James Smart40496f02006-07-06 15:50:22 -04001389
1390 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001391 rc = lpfc_workq_post_event(phba, &status, &online_compl,
James Smart40496f02006-07-06 15:50:22 -04001392 LPFC_EVT_ONLINE);
James Smartfedd3b72011-02-16 12:39:24 -05001393 if (rc == 0)
1394 return -ENOMEM;
1395
James Smart40496f02006-07-06 15:50:22 -04001396 wait_for_completion(&online_compl);
1397
1398 if (status != 0)
1399 return -EIO;
1400
1401 return 0;
1402}
1403
James Smarte59058c2008-08-24 21:49:00 -04001404/**
James Smart3621a712009-04-06 18:47:14 -04001405 * lpfc_issue_reset - Selectively resets an adapter
James Smarte59058c2008-08-24 21:49:00 -04001406 * @dev: class device that is converted into a Scsi_host.
1407 * @attr: device attribute, not used.
1408 * @buf: containing the string "selective".
1409 * @count: unused variable.
1410 *
1411 * Description:
1412 * If the buf contains the string "selective" then lpfc_selective_reset()
1413 * is called to perform the reset.
1414 *
1415 * Notes:
1416 * Assumes any error from lpfc_selective_reset() will be negative.
1417 * If lpfc_selective_reset() returns zero then the length of the buffer
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02001418 * is returned which indicates success
James Smarte59058c2008-08-24 21:49:00 -04001419 *
1420 * Returns:
1421 * -EINVAL if the buffer does not contain the string "selective"
1422 * length of buf if lpfc-selective_reset() if the call succeeds
1423 * return value of lpfc_selective_reset() if the call fails
1424**/
James Smart40496f02006-07-06 15:50:22 -04001425static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001426lpfc_issue_reset(struct device *dev, struct device_attribute *attr,
1427 const char *buf, size_t count)
James Smart40496f02006-07-06 15:50:22 -04001428{
Tony Jonesee959b02008-02-22 00:13:36 +01001429 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001430 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1431 struct lpfc_hba *phba = vport->phba;
James Smart40496f02006-07-06 15:50:22 -04001432 int status = -EINVAL;
1433
James Smart73d91e52011-10-10 21:32:10 -04001434 if (!phba->cfg_enable_hba_reset)
1435 return -EACCES;
1436
James Smart40496f02006-07-06 15:50:22 -04001437 if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
James Smart7f860592011-03-11 16:05:52 -05001438 status = phba->lpfc_selective_reset(phba);
James Smart40496f02006-07-06 15:50:22 -04001439
1440 if (status == 0)
1441 return strlen(buf);
1442 else
1443 return status;
1444}
1445
James Smarte59058c2008-08-24 21:49:00 -04001446/**
James Smart88a2cfb2011-07-22 18:36:33 -04001447 * lpfc_sli4_pdev_status_reg_wait - Wait for pdev status register for readyness
1448 * @phba: lpfc_hba pointer.
1449 *
1450 * Description:
1451 * SLI4 interface type-2 device to wait on the sliport status register for
1452 * the readyness after performing a firmware reset.
1453 *
1454 * Returns:
Masanari Iida0b1587b2013-07-17 04:37:44 +09001455 * zero for success, -EPERM when port does not have privilege to perform the
James Smart026abb82011-12-13 13:20:45 -05001456 * reset, -EIO when port timeout from recovering from the reset.
1457 *
1458 * Note:
1459 * As the caller will interpret the return code by value, be careful in making
1460 * change or addition to return codes.
James Smart88a2cfb2011-07-22 18:36:33 -04001461 **/
James Smart73d91e52011-10-10 21:32:10 -04001462int
James Smart88a2cfb2011-07-22 18:36:33 -04001463lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba)
1464{
James Smartf7a919b2011-08-21 21:49:16 -04001465 struct lpfc_register portstat_reg = {0};
James Smart88a2cfb2011-07-22 18:36:33 -04001466 int i;
1467
James Smartf7a919b2011-08-21 21:49:16 -04001468 msleep(100);
James Smartb7b95fb2019-09-21 20:58:49 -07001469 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
1470 &portstat_reg.word0))
1471 return -EIO;
James Smart88a2cfb2011-07-22 18:36:33 -04001472
Masanari Iida0b1587b2013-07-17 04:37:44 +09001473 /* verify if privileged for the request operation */
James Smartf7a919b2011-08-21 21:49:16 -04001474 if (!bf_get(lpfc_sliport_status_rn, &portstat_reg) &&
1475 !bf_get(lpfc_sliport_status_err, &portstat_reg))
1476 return -EPERM;
1477
James Smart88a2cfb2011-07-22 18:36:33 -04001478 /* wait for the SLI port firmware ready after firmware reset */
1479 for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) {
1480 msleep(10);
James Smartb7b95fb2019-09-21 20:58:49 -07001481 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
1482 &portstat_reg.word0))
1483 continue;
James Smart88a2cfb2011-07-22 18:36:33 -04001484 if (!bf_get(lpfc_sliport_status_err, &portstat_reg))
1485 continue;
1486 if (!bf_get(lpfc_sliport_status_rn, &portstat_reg))
1487 continue;
1488 if (!bf_get(lpfc_sliport_status_rdy, &portstat_reg))
1489 continue;
1490 break;
1491 }
1492
1493 if (i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT)
1494 return 0;
1495 else
1496 return -EIO;
1497}
1498
1499/**
James Smart52d52442011-05-24 11:42:45 -04001500 * lpfc_sli4_pdev_reg_request - Request physical dev to perform a register acc
James Smartc0c11512011-05-24 11:41:34 -04001501 * @phba: lpfc_hba pointer.
Lee Jones9176ad22020-11-02 14:23:44 +00001502 * @opcode: The sli4 config command opcode.
James Smartc0c11512011-05-24 11:41:34 -04001503 *
1504 * Description:
James Smart52d52442011-05-24 11:42:45 -04001505 * Request SLI4 interface type-2 device to perform a physical register set
1506 * access.
James Smartc0c11512011-05-24 11:41:34 -04001507 *
1508 * Returns:
1509 * zero for success
1510 **/
1511static ssize_t
James Smart52d52442011-05-24 11:42:45 -04001512lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
James Smartc0c11512011-05-24 11:41:34 -04001513{
1514 struct completion online_compl;
James Smartb76f2dc2011-07-22 18:37:42 -04001515 struct pci_dev *pdev = phba->pcidev;
James Smart026abb82011-12-13 13:20:45 -05001516 uint32_t before_fc_flag;
1517 uint32_t sriov_nr_virtfn;
James Smartc0c11512011-05-24 11:41:34 -04001518 uint32_t reg_val;
James Smart026abb82011-12-13 13:20:45 -05001519 int status = 0, rc = 0;
1520 int job_posted = 1, sriov_err;
James Smartc0c11512011-05-24 11:41:34 -04001521
1522 if (!phba->cfg_enable_hba_reset)
James Smartf7a919b2011-08-21 21:49:16 -04001523 return -EACCES;
James Smartc0c11512011-05-24 11:41:34 -04001524
James Smart52d52442011-05-24 11:42:45 -04001525 if ((phba->sli_rev < LPFC_SLI_REV4) ||
James Smart719162b2018-12-10 19:37:01 -08001526 (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
James Smart52d52442011-05-24 11:42:45 -04001527 LPFC_SLI_INTF_IF_TYPE_2))
1528 return -EPERM;
1529
James Smart026abb82011-12-13 13:20:45 -05001530 /* Keep state if we need to restore back */
1531 before_fc_flag = phba->pport->fc_flag;
1532 sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn;
1533
James Smartb76f2dc2011-07-22 18:37:42 -04001534 /* Disable SR-IOV virtual functions if enabled */
1535 if (phba->cfg_sriov_nr_virtfn) {
1536 pci_disable_sriov(pdev);
1537 phba->cfg_sriov_nr_virtfn = 0;
1538 }
James Smart229adb02013-04-17 20:16:51 -04001539
James Smart02936352014-04-04 13:52:12 -04001540 if (opcode == LPFC_FW_DUMP)
1541 phba->hba_flag |= HBA_FW_DUMP_OP;
1542
James Smartc0c11512011-05-24 11:41:34 -04001543 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
1544
James Smart02936352014-04-04 13:52:12 -04001545 if (status != 0) {
1546 phba->hba_flag &= ~HBA_FW_DUMP_OP;
James Smartc0c11512011-05-24 11:41:34 -04001547 return status;
James Smart02936352014-04-04 13:52:12 -04001548 }
James Smartc0c11512011-05-24 11:41:34 -04001549
1550 /* wait for the device to be quiesced before firmware reset */
1551 msleep(100);
1552
1553 reg_val = readl(phba->sli4_hba.conf_regs_memmap_p +
1554 LPFC_CTL_PDEV_CTL_OFFSET);
James Smart52d52442011-05-24 11:42:45 -04001555
1556 if (opcode == LPFC_FW_DUMP)
1557 reg_val |= LPFC_FW_DUMP_REQUEST;
1558 else if (opcode == LPFC_FW_RESET)
1559 reg_val |= LPFC_CTL_PDEV_CTL_FRST;
1560 else if (opcode == LPFC_DV_RESET)
1561 reg_val |= LPFC_CTL_PDEV_CTL_DRST;
1562
James Smartc0c11512011-05-24 11:41:34 -04001563 writel(reg_val, phba->sli4_hba.conf_regs_memmap_p +
1564 LPFC_CTL_PDEV_CTL_OFFSET);
1565 /* flush */
1566 readl(phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET);
1567
1568 /* delay driver action following IF_TYPE_2 reset */
James Smart88a2cfb2011-07-22 18:36:33 -04001569 rc = lpfc_sli4_pdev_status_reg_wait(phba);
1570
James Smart026abb82011-12-13 13:20:45 -05001571 if (rc == -EPERM) {
Masanari Iida0b1587b2013-07-17 04:37:44 +09001572 /* no privilege for reset */
James Smart6b5151f2012-01-18 16:24:06 -05001573 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
Masanari Iida0b1587b2013-07-17 04:37:44 +09001574 "3150 No privilege to perform the requested "
James Smart6b5151f2012-01-18 16:24:06 -05001575 "access: x%x\n", reg_val);
James Smart026abb82011-12-13 13:20:45 -05001576 } else if (rc == -EIO) {
1577 /* reset failed, there is nothing more we can do */
James Smart6b5151f2012-01-18 16:24:06 -05001578 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
1579 "3153 Fail to perform the requested "
1580 "access: x%x\n", reg_val);
James Smartf7a919b2011-08-21 21:49:16 -04001581 return rc;
James Smart026abb82011-12-13 13:20:45 -05001582 }
1583
1584 /* keep the original port state */
1585 if (before_fc_flag & FC_OFFLINE_MODE)
1586 goto out;
James Smartc0c11512011-05-24 11:41:34 -04001587
1588 init_completion(&online_compl);
James Smart026abb82011-12-13 13:20:45 -05001589 job_posted = lpfc_workq_post_event(phba, &status, &online_compl,
1590 LPFC_EVT_ONLINE);
1591 if (!job_posted)
1592 goto out;
James Smartc0c11512011-05-24 11:41:34 -04001593
1594 wait_for_completion(&online_compl);
1595
James Smart026abb82011-12-13 13:20:45 -05001596out:
1597 /* in any case, restore the virtual functions enabled as before */
1598 if (sriov_nr_virtfn) {
1599 sriov_err =
1600 lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn);
1601 if (!sriov_err)
1602 phba->cfg_sriov_nr_virtfn = sriov_nr_virtfn;
1603 }
James Smartc0c11512011-05-24 11:41:34 -04001604
James Smart026abb82011-12-13 13:20:45 -05001605 /* return proper error code */
1606 if (!rc) {
1607 if (!job_posted)
1608 rc = -ENOMEM;
1609 else if (status)
1610 rc = -EIO;
1611 }
1612 return rc;
James Smartc0c11512011-05-24 11:41:34 -04001613}
1614
1615/**
James Smart3621a712009-04-06 18:47:14 -04001616 * lpfc_nport_evt_cnt_show - Return the number of nport events
James Smarte59058c2008-08-24 21:49:00 -04001617 * @dev: class device that is converted into a Scsi_host.
1618 * @attr: device attribute, not used.
1619 * @buf: on return contains the ascii number of nport events.
1620 *
1621 * Returns: size of formatted string.
1622 **/
dea31012005-04-17 16:05:31 -05001623static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001624lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr,
1625 char *buf)
dea31012005-04-17 16:05:31 -05001626{
Tony Jonesee959b02008-02-22 00:13:36 +01001627 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001628 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1629 struct lpfc_hba *phba = vport->phba;
1630
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001631 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
dea31012005-04-17 16:05:31 -05001632}
1633
Bart Van Assche3999df72019-03-28 11:06:16 -07001634static int
James Smart1dc5ec22018-10-23 13:41:11 -07001635lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out)
1636{
1637 LPFC_MBOXQ_t *mbox = NULL;
1638 unsigned long val = 0;
Saurav Girepunje2c7fb462019-10-24 08:27:29 +05301639 char *pval = NULL;
James Smart1dc5ec22018-10-23 13:41:11 -07001640 int rc = 0;
1641
1642 if (!strncmp("enable", buff_out,
1643 strlen("enable"))) {
1644 pval = buff_out + strlen("enable") + 1;
1645 rc = kstrtoul(pval, 0, &val);
1646 if (rc)
1647 return rc; /* Invalid number */
1648 } else if (!strncmp("disable", buff_out,
1649 strlen("disable"))) {
1650 val = 0;
1651 } else {
1652 return -EINVAL; /* Invalid command */
1653 }
1654
1655 switch (val) {
1656 case 0:
1657 val = 0x0; /* Disable */
1658 break;
1659 case 2:
1660 val = 0x1; /* Enable two port trunk */
1661 break;
1662 case 4:
1663 val = 0x2; /* Enable four port trunk */
1664 break;
1665 default:
1666 return -EINVAL;
1667 }
1668
1669 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1670 "0070 Set trunk mode with val %ld ", val);
1671
1672 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1673 if (!mbox)
1674 return -ENOMEM;
1675
1676 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
1677 LPFC_MBOX_OPCODE_FCOE_FC_SET_TRUNK_MODE,
1678 12, LPFC_SLI4_MBX_EMBED);
1679
1680 bf_set(lpfc_mbx_set_trunk_mode,
1681 &mbox->u.mqe.un.set_trunk_mode,
1682 val);
1683 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
1684 if (rc)
1685 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1686 "0071 Set trunk mode failed with status: %d",
1687 rc);
James Smart304ee432021-04-11 18:31:17 -07001688 mempool_free(mbox, phba->mbox_mem_pool);
James Smart1dc5ec22018-10-23 13:41:11 -07001689
1690 return 0;
1691}
1692
James Smarte59058c2008-08-24 21:49:00 -04001693/**
James Smart3621a712009-04-06 18:47:14 -04001694 * lpfc_board_mode_show - Return the state of the board
James Smarte59058c2008-08-24 21:49:00 -04001695 * @dev: class device that is converted into a Scsi_host.
1696 * @attr: device attribute, not used.
1697 * @buf: on return contains the state of the adapter.
1698 *
1699 * Returns: size of formatted string.
1700 **/
dea31012005-04-17 16:05:31 -05001701static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001702lpfc_board_mode_show(struct device *dev, struct device_attribute *attr,
1703 char *buf)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001704{
Tony Jonesee959b02008-02-22 00:13:36 +01001705 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001706 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1707 struct lpfc_hba *phba = vport->phba;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001708 char * state;
1709
James Smart2e0fef82007-06-17 19:56:36 -05001710 if (phba->link_state == LPFC_HBA_ERROR)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001711 state = "error";
James Smart2e0fef82007-06-17 19:56:36 -05001712 else if (phba->link_state == LPFC_WARM_START)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001713 state = "warm start";
James Smart2e0fef82007-06-17 19:56:36 -05001714 else if (phba->link_state == LPFC_INIT_START)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001715 state = "offline";
1716 else
1717 state = "online";
1718
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001719 return scnprintf(buf, PAGE_SIZE, "%s\n", state);
Jamie Wellnitz41415862006-02-28 19:25:27 -05001720}
1721
James Smarte59058c2008-08-24 21:49:00 -04001722/**
James Smart3621a712009-04-06 18:47:14 -04001723 * lpfc_board_mode_store - Puts the hba in online, offline, warm or error state
James Smarte59058c2008-08-24 21:49:00 -04001724 * @dev: class device that is converted into a Scsi_host.
1725 * @attr: device attribute, not used.
1726 * @buf: containing one of the strings "online", "offline", "warm" or "error".
1727 * @count: unused variable.
1728 *
1729 * Returns:
1730 * -EACCES if enable hba reset not enabled
1731 * -EINVAL if the buffer does not contain a valid string (see above)
1732 * -EIO if lpfc_workq_post_event() or lpfc_do_offline() fails
1733 * buf length greater than zero indicates success
1734 **/
Jamie Wellnitz41415862006-02-28 19:25:27 -05001735static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001736lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
1737 const char *buf, size_t count)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001738{
Tony Jonesee959b02008-02-22 00:13:36 +01001739 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001740 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1741 struct lpfc_hba *phba = vport->phba;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001742 struct completion online_compl;
James Smart026abb82011-12-13 13:20:45 -05001743 char *board_mode_str = NULL;
1744 int status = 0;
James Smartfedd3b72011-02-16 12:39:24 -05001745 int rc;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001746
James Smart026abb82011-12-13 13:20:45 -05001747 if (!phba->cfg_enable_hba_reset) {
1748 status = -EACCES;
1749 goto board_mode_out;
1750 }
James Smart88a2cfb2011-07-22 18:36:33 -04001751
1752 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart026abb82011-12-13 13:20:45 -05001753 "3050 lpfc_board_mode set to %s\n", buf);
James Smart88a2cfb2011-07-22 18:36:33 -04001754
Jamie Wellnitz41415862006-02-28 19:25:27 -05001755 init_completion(&online_compl);
1756
James Smart46fa3112007-04-25 09:51:45 -04001757 if(strncmp(buf, "online", sizeof("online") - 1) == 0) {
James Smartfedd3b72011-02-16 12:39:24 -05001758 rc = lpfc_workq_post_event(phba, &status, &online_compl,
Jamie Wellnitz41415862006-02-28 19:25:27 -05001759 LPFC_EVT_ONLINE);
James Smart026abb82011-12-13 13:20:45 -05001760 if (rc == 0) {
1761 status = -ENOMEM;
1762 goto board_mode_out;
1763 }
James Smart46fa3112007-04-25 09:51:45 -04001764 wait_for_completion(&online_compl);
James Smart522dcee2017-06-01 21:07:03 -07001765 if (status)
1766 status = -EIO;
James Smart46fa3112007-04-25 09:51:45 -04001767 } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
1768 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
Jamie Wellnitz41415862006-02-28 19:25:27 -05001769 else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0)
James Smart6a9c52c2009-10-02 15:16:51 -04001770 if (phba->sli_rev == LPFC_SLI_REV4)
James Smart026abb82011-12-13 13:20:45 -05001771 status = -EINVAL;
James Smart6a9c52c2009-10-02 15:16:51 -04001772 else
1773 status = lpfc_do_offline(phba, LPFC_EVT_WARM_START);
James Smart46fa3112007-04-25 09:51:45 -04001774 else if (strncmp(buf, "error", sizeof("error") - 1) == 0)
James Smart6a9c52c2009-10-02 15:16:51 -04001775 if (phba->sli_rev == LPFC_SLI_REV4)
James Smart026abb82011-12-13 13:20:45 -05001776 status = -EINVAL;
James Smart6a9c52c2009-10-02 15:16:51 -04001777 else
1778 status = lpfc_do_offline(phba, LPFC_EVT_KILL);
James Smartc0c11512011-05-24 11:41:34 -04001779 else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0)
James Smart52d52442011-05-24 11:42:45 -04001780 status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_DUMP);
1781 else if (strncmp(buf, "fw_reset", sizeof("fw_reset") - 1) == 0)
1782 status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_RESET);
1783 else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0)
1784 status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET);
James Smart50212672018-12-13 15:17:57 -08001785 else if (strncmp(buf, "pci_bus_reset", sizeof("pci_bus_reset") - 1)
1786 == 0)
1787 status = lpfc_reset_pci_bus(phba);
James Smarta22d73b2021-01-04 10:02:38 -08001788 else if (strncmp(buf, "heartbeat", sizeof("heartbeat") - 1) == 0)
1789 lpfc_issue_hb_tmo(phba);
James Smart1dc5ec22018-10-23 13:41:11 -07001790 else if (strncmp(buf, "trunk", sizeof("trunk") - 1) == 0)
1791 status = lpfc_set_trunking(phba, (char *)buf + sizeof("trunk"));
Jamie Wellnitz41415862006-02-28 19:25:27 -05001792 else
James Smart026abb82011-12-13 13:20:45 -05001793 status = -EINVAL;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001794
James Smart026abb82011-12-13 13:20:45 -05001795board_mode_out:
Jamie Wellnitz41415862006-02-28 19:25:27 -05001796 if (!status)
1797 return strlen(buf);
James Smart026abb82011-12-13 13:20:45 -05001798 else {
1799 board_mode_str = strchr(buf, '\n');
1800 if (board_mode_str)
1801 *board_mode_str = '\0';
1802 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1803 "3097 Failed \"%s\", status(%d), "
1804 "fc_flag(x%x)\n",
1805 buf, status, phba->pport->fc_flag);
James Smartf7a919b2011-08-21 21:49:16 -04001806 return status;
James Smart026abb82011-12-13 13:20:45 -05001807 }
Jamie Wellnitz41415862006-02-28 19:25:27 -05001808}
1809
James Smarte59058c2008-08-24 21:49:00 -04001810/**
James Smart3621a712009-04-06 18:47:14 -04001811 * lpfc_get_hba_info - Return various bits of informaton about the adapter
James Smarte59058c2008-08-24 21:49:00 -04001812 * @phba: pointer to the adapter structure.
James Smart3621a712009-04-06 18:47:14 -04001813 * @mxri: max xri count.
1814 * @axri: available xri count.
1815 * @mrpi: max rpi count.
1816 * @arpi: available rpi count.
1817 * @mvpi: max vpi count.
1818 * @avpi: available vpi count.
James Smarte59058c2008-08-24 21:49:00 -04001819 *
1820 * Description:
1821 * If an integer pointer for an count is not null then the value for the
1822 * count is returned.
1823 *
1824 * Returns:
1825 * zero on error
1826 * one for success
1827 **/
James Smart311464e2007-08-02 11:10:37 -04001828static int
James Smart858c9f62007-06-17 19:56:39 -05001829lpfc_get_hba_info(struct lpfc_hba *phba,
1830 uint32_t *mxri, uint32_t *axri,
1831 uint32_t *mrpi, uint32_t *arpi,
1832 uint32_t *mvpi, uint32_t *avpi)
James Smart92d7f7b2007-06-17 19:56:38 -05001833{
James Smart04c68492009-05-22 14:52:52 -04001834 struct lpfc_mbx_read_config *rd_config;
James Smart92d7f7b2007-06-17 19:56:38 -05001835 LPFC_MBOXQ_t *pmboxq;
1836 MAILBOX_t *pmb;
1837 int rc = 0;
James Smart15672312010-04-06 14:49:03 -04001838 uint32_t max_vpi;
James Smart92d7f7b2007-06-17 19:56:38 -05001839
1840 /*
1841 * prevent udev from issuing mailbox commands until the port is
1842 * configured.
1843 */
1844 if (phba->link_state < LPFC_LINK_DOWN ||
1845 !phba->mbox_mem_pool ||
James Smartf4b4c682009-05-22 14:53:12 -04001846 (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
James Smart92d7f7b2007-06-17 19:56:38 -05001847 return 0;
1848
1849 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
1850 return 0;
1851
1852 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1853 if (!pmboxq)
1854 return 0;
1855 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
1856
James Smart04c68492009-05-22 14:52:52 -04001857 pmb = &pmboxq->u.mb;
James Smart92d7f7b2007-06-17 19:56:38 -05001858 pmb->mbxCommand = MBX_READ_CONFIG;
1859 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08001860 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05001861
James Smart75baf692010-06-08 18:31:21 -04001862 if (phba->pport->fc_flag & FC_OFFLINE_MODE)
James Smart92d7f7b2007-06-17 19:56:38 -05001863 rc = MBX_NOT_FINISHED;
1864 else
1865 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1866
1867 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05001868 if (rc != MBX_TIMEOUT)
James Smart92d7f7b2007-06-17 19:56:38 -05001869 mempool_free(pmboxq, phba->mbox_mem_pool);
1870 return 0;
1871 }
1872
James Smartda0436e2009-05-22 14:51:39 -04001873 if (phba->sli_rev == LPFC_SLI_REV4) {
1874 rd_config = &pmboxq->u.mqe.un.rd_config;
1875 if (mrpi)
1876 *mrpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config);
1877 if (arpi)
1878 *arpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config) -
1879 phba->sli4_hba.max_cfg_param.rpi_used;
1880 if (mxri)
1881 *mxri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
1882 if (axri)
1883 *axri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config) -
1884 phba->sli4_hba.max_cfg_param.xri_used;
James Smart15672312010-04-06 14:49:03 -04001885
1886 /* Account for differences with SLI-3. Get vpi count from
1887 * mailbox data and subtract one for max vpi value.
1888 */
1889 max_vpi = (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) > 0) ?
1890 (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) - 1) : 0;
1891
James Smart8b47ae62018-11-29 16:09:33 -08001892 /* Limit the max we support */
1893 if (max_vpi > LPFC_MAX_VPI)
1894 max_vpi = LPFC_MAX_VPI;
James Smartda0436e2009-05-22 14:51:39 -04001895 if (mvpi)
James Smart15672312010-04-06 14:49:03 -04001896 *mvpi = max_vpi;
James Smartda0436e2009-05-22 14:51:39 -04001897 if (avpi)
James Smart15672312010-04-06 14:49:03 -04001898 *avpi = max_vpi - phba->sli4_hba.max_cfg_param.vpi_used;
James Smartda0436e2009-05-22 14:51:39 -04001899 } else {
1900 if (mrpi)
1901 *mrpi = pmb->un.varRdConfig.max_rpi;
1902 if (arpi)
1903 *arpi = pmb->un.varRdConfig.avail_rpi;
1904 if (mxri)
1905 *mxri = pmb->un.varRdConfig.max_xri;
1906 if (axri)
1907 *axri = pmb->un.varRdConfig.avail_xri;
1908 if (mvpi)
1909 *mvpi = pmb->un.varRdConfig.max_vpi;
James Smart8b47ae62018-11-29 16:09:33 -08001910 if (avpi) {
1911 /* avail_vpi is only valid if link is up and ready */
1912 if (phba->link_state == LPFC_HBA_READY)
1913 *avpi = pmb->un.varRdConfig.avail_vpi;
1914 else
1915 *avpi = pmb->un.varRdConfig.max_vpi;
1916 }
James Smartda0436e2009-05-22 14:51:39 -04001917 }
James Smart92d7f7b2007-06-17 19:56:38 -05001918
1919 mempool_free(pmboxq, phba->mbox_mem_pool);
1920 return 1;
1921}
1922
James Smarte59058c2008-08-24 21:49:00 -04001923/**
James Smart3621a712009-04-06 18:47:14 -04001924 * lpfc_max_rpi_show - Return maximum rpi
James Smarte59058c2008-08-24 21:49:00 -04001925 * @dev: class device that is converted into a Scsi_host.
1926 * @attr: device attribute, not used.
1927 * @buf: on return contains the maximum rpi count in decimal or "Unknown".
1928 *
1929 * Description:
1930 * Calls lpfc_get_hba_info() asking for just the mrpi count.
1931 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1932 * to "Unknown" and the buffer length is returned, therefore the caller
1933 * must check for "Unknown" in the buffer to detect a failure.
1934 *
1935 * Returns: size of formatted string.
1936 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001937static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001938lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr,
1939 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001940{
Tony Jonesee959b02008-02-22 00:13:36 +01001941 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05001942 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1943 struct lpfc_hba *phba = vport->phba;
1944 uint32_t cnt;
1945
James Smart858c9f62007-06-17 19:56:39 -05001946 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001947 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
1948 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001949}
1950
James Smarte59058c2008-08-24 21:49:00 -04001951/**
James Smart3621a712009-04-06 18:47:14 -04001952 * lpfc_used_rpi_show - Return maximum rpi minus available rpi
James Smarte59058c2008-08-24 21:49:00 -04001953 * @dev: class device that is converted into a Scsi_host.
1954 * @attr: device attribute, not used.
1955 * @buf: containing the used rpi count in decimal or "Unknown".
1956 *
1957 * Description:
1958 * Calls lpfc_get_hba_info() asking for just the mrpi and arpi counts.
1959 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1960 * to "Unknown" and the buffer length is returned, therefore the caller
1961 * must check for "Unknown" in the buffer to detect a failure.
1962 *
1963 * Returns: size of formatted string.
1964 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001965static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001966lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr,
1967 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001968{
Tony Jonesee959b02008-02-22 00:13:36 +01001969 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05001970 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1971 struct lpfc_hba *phba = vport->phba;
1972 uint32_t cnt, acnt;
1973
James Smart858c9f62007-06-17 19:56:39 -05001974 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001975 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
1976 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001977}
1978
James Smarte59058c2008-08-24 21:49:00 -04001979/**
James Smart3621a712009-04-06 18:47:14 -04001980 * lpfc_max_xri_show - Return maximum xri
James Smarte59058c2008-08-24 21:49:00 -04001981 * @dev: class device that is converted into a Scsi_host.
1982 * @attr: device attribute, not used.
1983 * @buf: on return contains the maximum xri count in decimal or "Unknown".
1984 *
1985 * Description:
1986 * Calls lpfc_get_hba_info() asking for just the mrpi count.
1987 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1988 * to "Unknown" and the buffer length is returned, therefore the caller
1989 * must check for "Unknown" in the buffer to detect a failure.
1990 *
1991 * Returns: size of formatted string.
1992 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001993static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001994lpfc_max_xri_show(struct device *dev, struct device_attribute *attr,
1995 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001996{
Tony Jonesee959b02008-02-22 00:13:36 +01001997 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05001998 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1999 struct lpfc_hba *phba = vport->phba;
2000 uint32_t cnt;
2001
James Smart858c9f62007-06-17 19:56:39 -05002002 if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002003 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
2004 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002005}
2006
James Smarte59058c2008-08-24 21:49:00 -04002007/**
James Smart3621a712009-04-06 18:47:14 -04002008 * lpfc_used_xri_show - Return maximum xpi minus the available xpi
James Smarte59058c2008-08-24 21:49:00 -04002009 * @dev: class device that is converted into a Scsi_host.
2010 * @attr: device attribute, not used.
2011 * @buf: on return contains the used xri count in decimal or "Unknown".
2012 *
2013 * Description:
2014 * Calls lpfc_get_hba_info() asking for just the mxri and axri counts.
2015 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2016 * to "Unknown" and the buffer length is returned, therefore the caller
2017 * must check for "Unknown" in the buffer to detect a failure.
2018 *
2019 * Returns: size of formatted string.
2020 **/
James Smart92d7f7b2007-06-17 19:56:38 -05002021static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002022lpfc_used_xri_show(struct device *dev, struct device_attribute *attr,
2023 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05002024{
Tony Jonesee959b02008-02-22 00:13:36 +01002025 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05002026 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2027 struct lpfc_hba *phba = vport->phba;
2028 uint32_t cnt, acnt;
2029
James Smart858c9f62007-06-17 19:56:39 -05002030 if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002031 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
2032 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart858c9f62007-06-17 19:56:39 -05002033}
2034
James Smarte59058c2008-08-24 21:49:00 -04002035/**
James Smart3621a712009-04-06 18:47:14 -04002036 * lpfc_max_vpi_show - Return maximum vpi
James Smarte59058c2008-08-24 21:49:00 -04002037 * @dev: class device that is converted into a Scsi_host.
2038 * @attr: device attribute, not used.
2039 * @buf: on return contains the maximum vpi count in decimal or "Unknown".
2040 *
2041 * Description:
2042 * Calls lpfc_get_hba_info() asking for just the mvpi count.
2043 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2044 * to "Unknown" and the buffer length is returned, therefore the caller
2045 * must check for "Unknown" in the buffer to detect a failure.
2046 *
2047 * Returns: size of formatted string.
2048 **/
James Smart858c9f62007-06-17 19:56:39 -05002049static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002050lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr,
2051 char *buf)
James Smart858c9f62007-06-17 19:56:39 -05002052{
Tony Jonesee959b02008-02-22 00:13:36 +01002053 struct Scsi_Host *shost = class_to_shost(dev);
James Smart858c9f62007-06-17 19:56:39 -05002054 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2055 struct lpfc_hba *phba = vport->phba;
2056 uint32_t cnt;
2057
2058 if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002059 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
2060 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart858c9f62007-06-17 19:56:39 -05002061}
2062
James Smarte59058c2008-08-24 21:49:00 -04002063/**
James Smart3621a712009-04-06 18:47:14 -04002064 * lpfc_used_vpi_show - Return maximum vpi minus the available vpi
James Smarte59058c2008-08-24 21:49:00 -04002065 * @dev: class device that is converted into a Scsi_host.
2066 * @attr: device attribute, not used.
2067 * @buf: on return contains the used vpi count in decimal or "Unknown".
2068 *
2069 * Description:
2070 * Calls lpfc_get_hba_info() asking for just the mvpi and avpi counts.
2071 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2072 * to "Unknown" and the buffer length is returned, therefore the caller
2073 * must check for "Unknown" in the buffer to detect a failure.
2074 *
2075 * Returns: size of formatted string.
2076 **/
James Smart858c9f62007-06-17 19:56:39 -05002077static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002078lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr,
2079 char *buf)
James Smart858c9f62007-06-17 19:56:39 -05002080{
Tony Jonesee959b02008-02-22 00:13:36 +01002081 struct Scsi_Host *shost = class_to_shost(dev);
James Smart858c9f62007-06-17 19:56:39 -05002082 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2083 struct lpfc_hba *phba = vport->phba;
2084 uint32_t cnt, acnt;
2085
2086 if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, &acnt))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002087 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
2088 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002089}
2090
James Smarte59058c2008-08-24 21:49:00 -04002091/**
James Smart3621a712009-04-06 18:47:14 -04002092 * lpfc_npiv_info_show - Return text about NPIV support for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002093 * @dev: class device that is converted into a Scsi_host.
2094 * @attr: device attribute, not used.
2095 * @buf: text that must be interpreted to determine if npiv is supported.
2096 *
2097 * Description:
2098 * Buffer will contain text indicating npiv is not suppoerted on the port,
2099 * the port is an NPIV physical port, or it is an npiv virtual port with
2100 * the id of the vport.
2101 *
2102 * Returns: size of formatted string.
2103 **/
James Smart92d7f7b2007-06-17 19:56:38 -05002104static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002105lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr,
2106 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05002107{
Tony Jonesee959b02008-02-22 00:13:36 +01002108 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05002109 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2110 struct lpfc_hba *phba = vport->phba;
2111
2112 if (!(phba->max_vpi))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002113 return scnprintf(buf, PAGE_SIZE, "NPIV Not Supported\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002114 if (vport->port_type == LPFC_PHYSICAL_PORT)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002115 return scnprintf(buf, PAGE_SIZE, "NPIV Physical\n");
2116 return scnprintf(buf, PAGE_SIZE, "NPIV Virtual (VPI %d)\n", vport->vpi);
James Smart92d7f7b2007-06-17 19:56:38 -05002117}
2118
James Smarte59058c2008-08-24 21:49:00 -04002119/**
James Smart3621a712009-04-06 18:47:14 -04002120 * lpfc_poll_show - Return text about poll support for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002121 * @dev: class device that is converted into a Scsi_host.
2122 * @attr: device attribute, not used.
2123 * @buf: on return contains the cfg_poll in hex.
2124 *
2125 * Notes:
2126 * cfg_poll should be a lpfc_polling_flags type.
2127 *
2128 * Returns: size of formatted string.
2129 **/
Jamie Wellnitz41415862006-02-28 19:25:27 -05002130static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002131lpfc_poll_show(struct device *dev, struct device_attribute *attr,
2132 char *buf)
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002133{
Tony Jonesee959b02008-02-22 00:13:36 +01002134 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05002135 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2136 struct lpfc_hba *phba = vport->phba;
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002137
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002138 return scnprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002139}
2140
James Smarte59058c2008-08-24 21:49:00 -04002141/**
James Smart3621a712009-04-06 18:47:14 -04002142 * lpfc_poll_store - Set the value of cfg_poll for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002143 * @dev: class device that is converted into a Scsi_host.
2144 * @attr: device attribute, not used.
2145 * @buf: one or more lpfc_polling_flags values.
2146 * @count: not used.
2147 *
2148 * Notes:
2149 * buf contents converted to integer and checked for a valid value.
2150 *
2151 * Returns:
2152 * -EINVAL if the buffer connot be converted or is out of range
2153 * length of the buf on success
2154 **/
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002155static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002156lpfc_poll_store(struct device *dev, struct device_attribute *attr,
2157 const char *buf, size_t count)
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002158{
Tony Jonesee959b02008-02-22 00:13:36 +01002159 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05002160 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2161 struct lpfc_hba *phba = vport->phba;
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002162 uint32_t creg_val;
2163 uint32_t old_val;
2164 int val=0;
2165
2166 if (!isdigit(buf[0]))
2167 return -EINVAL;
2168
2169 if (sscanf(buf, "%i", &val) != 1)
2170 return -EINVAL;
2171
2172 if ((val & 0x3) != val)
2173 return -EINVAL;
2174
James Smart45ed1192009-10-02 15:17:02 -04002175 if (phba->sli_rev == LPFC_SLI_REV4)
2176 val = 0;
2177
James Smart88a2cfb2011-07-22 18:36:33 -04002178 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
2179 "3051 lpfc_poll changed from %d to %d\n",
2180 phba->cfg_poll, val);
2181
James Smart2e0fef82007-06-17 19:56:36 -05002182 spin_lock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002183
2184 old_val = phba->cfg_poll;
2185
2186 if (val & ENABLE_FCP_RING_POLLING) {
2187 if ((val & DISABLE_FCP_RING_INT) &&
2188 !(old_val & DISABLE_FCP_RING_INT)) {
James Smart9940b972011-03-11 16:06:12 -05002189 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
2190 spin_unlock_irq(&phba->hbalock);
2191 return -EINVAL;
2192 }
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002193 creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
2194 writel(creg_val, phba->HCregaddr);
2195 readl(phba->HCregaddr); /* flush */
2196
2197 lpfc_poll_start_timer(phba);
2198 }
2199 } else if (val != 0x0) {
James Smart2e0fef82007-06-17 19:56:36 -05002200 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002201 return -EINVAL;
2202 }
2203
2204 if (!(val & DISABLE_FCP_RING_INT) &&
2205 (old_val & DISABLE_FCP_RING_INT))
2206 {
James Smart2e0fef82007-06-17 19:56:36 -05002207 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002208 del_timer(&phba->fcp_poll_timer);
James Smart2e0fef82007-06-17 19:56:36 -05002209 spin_lock_irq(&phba->hbalock);
James Smart9940b972011-03-11 16:06:12 -05002210 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
2211 spin_unlock_irq(&phba->hbalock);
2212 return -EINVAL;
2213 }
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002214 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
2215 writel(creg_val, phba->HCregaddr);
2216 readl(phba->HCregaddr); /* flush */
2217 }
2218
2219 phba->cfg_poll = val;
2220
James Smart2e0fef82007-06-17 19:56:36 -05002221 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002222
2223 return strlen(buf);
2224}
dea31012005-04-17 16:05:31 -05002225
James Smarte59058c2008-08-24 21:49:00 -04002226/**
James Smart912e3ac2011-05-24 11:42:11 -04002227 * lpfc_sriov_hw_max_virtfn_show - Return maximum number of virtual functions
2228 * @dev: class converted to a Scsi_host structure.
2229 * @attr: device attribute, not used.
2230 * @buf: on return contains the formatted support level.
2231 *
2232 * Description:
2233 * Returns the maximum number of virtual functions a physical function can
2234 * support, 0 will be returned if called on virtual function.
2235 *
2236 * Returns: size of formatted string.
2237 **/
2238static ssize_t
2239lpfc_sriov_hw_max_virtfn_show(struct device *dev,
2240 struct device_attribute *attr,
2241 char *buf)
2242{
2243 struct Scsi_Host *shost = class_to_shost(dev);
2244 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2245 struct lpfc_hba *phba = vport->phba;
James Smart0a96e972011-07-22 18:37:28 -04002246 uint16_t max_nr_virtfn;
James Smart912e3ac2011-05-24 11:42:11 -04002247
James Smart0a96e972011-07-22 18:37:28 -04002248 max_nr_virtfn = lpfc_sli_sriov_nr_virtfn_get(phba);
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002249 return scnprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn);
James Smart912e3ac2011-05-24 11:42:11 -04002250}
2251
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002252static inline bool lpfc_rangecheck(uint val, uint min, uint max)
2253{
2254 return val >= min && val <= max;
2255}
2256
James Smart912e3ac2011-05-24 11:42:11 -04002257/**
James Smart44fd7fe2017-08-23 16:55:47 -07002258 * lpfc_enable_bbcr_set: Sets an attribute value.
2259 * @phba: pointer the the adapter structure.
2260 * @val: integer attribute value.
2261 *
2262 * Description:
2263 * Validates the min and max values then sets the
2264 * adapter config field if in the valid range. prints error message
2265 * and does not set the parameter if invalid.
2266 *
2267 * Returns:
2268 * zero on success
2269 * -EINVAL if val is invalid
2270 */
2271static ssize_t
2272lpfc_enable_bbcr_set(struct lpfc_hba *phba, uint val)
2273{
2274 if (lpfc_rangecheck(val, 0, 1) && phba->sli_rev == LPFC_SLI_REV4) {
2275 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2276 "3068 %s_enable_bbcr changed from %d to %d\n",
2277 LPFC_DRIVER_NAME, phba->cfg_enable_bbcr, val);
2278 phba->cfg_enable_bbcr = val;
2279 return 0;
2280 }
2281 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2282 "0451 %s_enable_bbcr cannot set to %d, range is 0, 1\n",
2283 LPFC_DRIVER_NAME, val);
2284 return -EINVAL;
2285}
2286
Lee Jones9176ad22020-11-02 14:23:44 +00002287/*
James Smart3621a712009-04-06 18:47:14 -04002288 * lpfc_param_show - Return a cfg attribute value in decimal
James Smarte59058c2008-08-24 21:49:00 -04002289 *
2290 * Description:
2291 * Macro that given an attr e.g. hba_queue_depth expands
2292 * into a function with the name lpfc_hba_queue_depth_show.
2293 *
2294 * lpfc_##attr##_show: Return the decimal value of an adapters cfg_xxx field.
2295 * @dev: class device that is converted into a Scsi_host.
2296 * @attr: device attribute, not used.
2297 * @buf: on return contains the attribute value in decimal.
2298 *
2299 * Returns: size of formatted string.
2300 **/
dea31012005-04-17 16:05:31 -05002301#define lpfc_param_show(attr) \
2302static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002303lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2304 char *buf) \
dea31012005-04-17 16:05:31 -05002305{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002306 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002307 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2308 struct lpfc_hba *phba = vport->phba;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002309 return scnprintf(buf, PAGE_SIZE, "%d\n",\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002310 phba->cfg_##attr);\
dea31012005-04-17 16:05:31 -05002311}
2312
Lee Jones9176ad22020-11-02 14:23:44 +00002313/*
James Smart3621a712009-04-06 18:47:14 -04002314 * lpfc_param_hex_show - Return a cfg attribute value in hex
James Smarte59058c2008-08-24 21:49:00 -04002315 *
2316 * Description:
2317 * Macro that given an attr e.g. hba_queue_depth expands
2318 * into a function with the name lpfc_hba_queue_depth_show
2319 *
2320 * lpfc_##attr##_show: Return the hex value of an adapters cfg_xxx field.
2321 * @dev: class device that is converted into a Scsi_host.
2322 * @attr: device attribute, not used.
James Smart3621a712009-04-06 18:47:14 -04002323 * @buf: on return contains the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002324 *
2325 * Returns: size of formatted string.
2326 **/
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002327#define lpfc_param_hex_show(attr) \
2328static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002329lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2330 char *buf) \
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002331{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002332 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002333 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2334 struct lpfc_hba *phba = vport->phba;\
James Smart84d1b002010-02-12 14:42:33 -05002335 uint val = 0;\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002336 val = phba->cfg_##attr;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002337 return scnprintf(buf, PAGE_SIZE, "%#x\n",\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002338 phba->cfg_##attr);\
2339}
2340
Lee Jones9176ad22020-11-02 14:23:44 +00002341/*
Uwe Kleine-Königb5950762010-11-01 15:38:34 -04002342 * lpfc_param_init - Initializes a cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002343 *
2344 * Description:
2345 * Macro that given an attr e.g. hba_queue_depth expands
2346 * into a function with the name lpfc_hba_queue_depth_init. The macro also
2347 * takes a default argument, a minimum and maximum argument.
2348 *
2349 * lpfc_##attr##_init: Initializes an attribute.
2350 * @phba: pointer the the adapter structure.
2351 * @val: integer attribute value.
2352 *
2353 * Validates the min and max values then sets the adapter config field
2354 * accordingly, or uses the default if out of range and prints an error message.
2355 *
2356 * Returns:
2357 * zero on success
2358 * -EINVAL if default used
2359 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002360#define lpfc_param_init(attr, default, minval, maxval) \
2361static int \
James Smart84d1b002010-02-12 14:42:33 -05002362lpfc_##attr##_init(struct lpfc_hba *phba, uint val) \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002363{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002364 if (lpfc_rangecheck(val, minval, maxval)) {\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002365 phba->cfg_##attr = val;\
2366 return 0;\
2367 }\
2368 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
James Smarte8b62012007-08-02 11:10:09 -04002369 "0449 lpfc_"#attr" attribute cannot be set to %d, "\
2370 "allowed range is ["#minval", "#maxval"]\n", val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002371 phba->cfg_##attr = default;\
2372 return -EINVAL;\
2373}
2374
Lee Jones9176ad22020-11-02 14:23:44 +00002375/*
James Smart3621a712009-04-06 18:47:14 -04002376 * lpfc_param_set - Set a cfg attribute value
James Smarte59058c2008-08-24 21:49:00 -04002377 *
2378 * Description:
2379 * Macro that given an attr e.g. hba_queue_depth expands
2380 * into a function with the name lpfc_hba_queue_depth_set
2381 *
2382 * lpfc_##attr##_set: Sets an attribute value.
2383 * @phba: pointer the the adapter structure.
2384 * @val: integer attribute value.
2385 *
2386 * Description:
2387 * Validates the min and max values then sets the
2388 * adapter config field if in the valid range. prints error message
2389 * and does not set the parameter if invalid.
2390 *
2391 * Returns:
2392 * zero on success
2393 * -EINVAL if val is invalid
2394 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002395#define lpfc_param_set(attr, default, minval, maxval) \
2396static int \
James Smart84d1b002010-02-12 14:42:33 -05002397lpfc_##attr##_set(struct lpfc_hba *phba, uint val) \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002398{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002399 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart88a2cfb2011-07-22 18:36:33 -04002400 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
2401 "3052 lpfc_" #attr " changed from %d to %d\n", \
2402 phba->cfg_##attr, val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002403 phba->cfg_##attr = val;\
2404 return 0;\
2405 }\
2406 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
James Smarte8b62012007-08-02 11:10:09 -04002407 "0450 lpfc_"#attr" attribute cannot be set to %d, "\
2408 "allowed range is ["#minval", "#maxval"]\n", val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002409 return -EINVAL;\
2410}
2411
Lee Jones9176ad22020-11-02 14:23:44 +00002412/*
James Smart3621a712009-04-06 18:47:14 -04002413 * lpfc_param_store - Set a vport attribute value
James Smarte59058c2008-08-24 21:49:00 -04002414 *
2415 * Description:
2416 * Macro that given an attr e.g. hba_queue_depth expands
2417 * into a function with the name lpfc_hba_queue_depth_store.
2418 *
2419 * lpfc_##attr##_store: Set an sttribute value.
2420 * @dev: class device that is converted into a Scsi_host.
2421 * @attr: device attribute, not used.
2422 * @buf: contains the attribute value in ascii.
2423 * @count: not used.
2424 *
2425 * Description:
2426 * Convert the ascii text number to an integer, then
2427 * use the lpfc_##attr##_set function to set the value.
2428 *
2429 * Returns:
2430 * -EINVAL if val is invalid or lpfc_##attr##_set() fails
2431 * length of buffer upon success.
2432 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002433#define lpfc_param_store(attr) \
dea31012005-04-17 16:05:31 -05002434static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002435lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
2436 const char *buf, size_t count) \
dea31012005-04-17 16:05:31 -05002437{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002438 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002439 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2440 struct lpfc_hba *phba = vport->phba;\
James Smart84d1b002010-02-12 14:42:33 -05002441 uint val = 0;\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002442 if (!isdigit(buf[0]))\
2443 return -EINVAL;\
2444 if (sscanf(buf, "%i", &val) != 1)\
2445 return -EINVAL;\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002446 if (lpfc_##attr##_set(phba, val) == 0) \
James.Smart@Emulex.Com755c0d02005-10-28 20:29:06 -04002447 return strlen(buf);\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002448 else \
2449 return -EINVAL;\
dea31012005-04-17 16:05:31 -05002450}
2451
Lee Jones9176ad22020-11-02 14:23:44 +00002452/*
James Smart3621a712009-04-06 18:47:14 -04002453 * lpfc_vport_param_show - Return decimal formatted cfg attribute value
James Smarte59058c2008-08-24 21:49:00 -04002454 *
2455 * Description:
2456 * Macro that given an attr e.g. hba_queue_depth expands
2457 * into a function with the name lpfc_hba_queue_depth_show
2458 *
2459 * lpfc_##attr##_show: prints the attribute value in decimal.
2460 * @dev: class device that is converted into a Scsi_host.
2461 * @attr: device attribute, not used.
2462 * @buf: on return contains the attribute value in decimal.
2463 *
2464 * Returns: length of formatted string.
2465 **/
James Smart3de2a652007-08-02 11:09:59 -04002466#define lpfc_vport_param_show(attr) \
2467static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002468lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2469 char *buf) \
James Smart3de2a652007-08-02 11:09:59 -04002470{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002471 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002472 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002473 return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\
James Smart3de2a652007-08-02 11:09:59 -04002474}
2475
Lee Jones9176ad22020-11-02 14:23:44 +00002476/*
James Smart3621a712009-04-06 18:47:14 -04002477 * lpfc_vport_param_hex_show - Return hex formatted attribute value
James Smarte59058c2008-08-24 21:49:00 -04002478 *
2479 * Description:
2480 * Macro that given an attr e.g.
2481 * hba_queue_depth expands into a function with the name
2482 * lpfc_hba_queue_depth_show
2483 *
James Smart3621a712009-04-06 18:47:14 -04002484 * lpfc_##attr##_show: prints the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002485 * @dev: class device that is converted into a Scsi_host.
2486 * @attr: device attribute, not used.
James Smart3621a712009-04-06 18:47:14 -04002487 * @buf: on return contains the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002488 *
2489 * Returns: length of formatted string.
2490 **/
James Smart3de2a652007-08-02 11:09:59 -04002491#define lpfc_vport_param_hex_show(attr) \
2492static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002493lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2494 char *buf) \
James Smart3de2a652007-08-02 11:09:59 -04002495{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002496 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002497 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002498 return scnprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\
James Smart3de2a652007-08-02 11:09:59 -04002499}
2500
Lee Jones9176ad22020-11-02 14:23:44 +00002501/*
James Smart3621a712009-04-06 18:47:14 -04002502 * lpfc_vport_param_init - Initialize a vport cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002503 *
2504 * Description:
2505 * Macro that given an attr e.g. hba_queue_depth expands
2506 * into a function with the name lpfc_hba_queue_depth_init. The macro also
2507 * takes a default argument, a minimum and maximum argument.
2508 *
2509 * lpfc_##attr##_init: validates the min and max values then sets the
2510 * adapter config field accordingly, or uses the default if out of range
2511 * and prints an error message.
2512 * @phba: pointer the the adapter structure.
2513 * @val: integer attribute value.
2514 *
2515 * Returns:
2516 * zero on success
2517 * -EINVAL if default used
2518 **/
James Smart3de2a652007-08-02 11:09:59 -04002519#define lpfc_vport_param_init(attr, default, minval, maxval) \
2520static int \
James Smart84d1b002010-02-12 14:42:33 -05002521lpfc_##attr##_init(struct lpfc_vport *vport, uint val) \
James Smart3de2a652007-08-02 11:09:59 -04002522{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002523 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart3de2a652007-08-02 11:09:59 -04002524 vport->cfg_##attr = val;\
2525 return 0;\
2526 }\
James Smarte8b62012007-08-02 11:10:09 -04002527 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smartd7c255b2008-08-24 21:50:00 -04002528 "0423 lpfc_"#attr" attribute cannot be set to %d, "\
James Smarte8b62012007-08-02 11:10:09 -04002529 "allowed range is ["#minval", "#maxval"]\n", val); \
James Smart3de2a652007-08-02 11:09:59 -04002530 vport->cfg_##attr = default;\
2531 return -EINVAL;\
2532}
2533
Lee Jones9176ad22020-11-02 14:23:44 +00002534/*
James Smart3621a712009-04-06 18:47:14 -04002535 * lpfc_vport_param_set - Set a vport cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002536 *
2537 * Description:
2538 * Macro that given an attr e.g. hba_queue_depth expands
2539 * into a function with the name lpfc_hba_queue_depth_set
2540 *
2541 * lpfc_##attr##_set: validates the min and max values then sets the
2542 * adapter config field if in the valid range. prints error message
2543 * and does not set the parameter if invalid.
2544 * @phba: pointer the the adapter structure.
2545 * @val: integer attribute value.
2546 *
2547 * Returns:
2548 * zero on success
2549 * -EINVAL if val is invalid
2550 **/
James Smart3de2a652007-08-02 11:09:59 -04002551#define lpfc_vport_param_set(attr, default, minval, maxval) \
2552static int \
James Smart84d1b002010-02-12 14:42:33 -05002553lpfc_##attr##_set(struct lpfc_vport *vport, uint val) \
James Smart3de2a652007-08-02 11:09:59 -04002554{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002555 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart88a2cfb2011-07-22 18:36:33 -04002556 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smart14660f42013-09-06 12:20:20 -04002557 "3053 lpfc_" #attr \
2558 " changed from %d (x%x) to %d (x%x)\n", \
2559 vport->cfg_##attr, vport->cfg_##attr, \
2560 val, val); \
James Smart3de2a652007-08-02 11:09:59 -04002561 vport->cfg_##attr = val;\
2562 return 0;\
2563 }\
James Smarte8b62012007-08-02 11:10:09 -04002564 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smartd7c255b2008-08-24 21:50:00 -04002565 "0424 lpfc_"#attr" attribute cannot be set to %d, "\
James Smarte8b62012007-08-02 11:10:09 -04002566 "allowed range is ["#minval", "#maxval"]\n", val); \
James Smart3de2a652007-08-02 11:09:59 -04002567 return -EINVAL;\
2568}
2569
Lee Jones9176ad22020-11-02 14:23:44 +00002570/*
James Smart3621a712009-04-06 18:47:14 -04002571 * lpfc_vport_param_store - Set a vport attribute
James Smarte59058c2008-08-24 21:49:00 -04002572 *
2573 * Description:
2574 * Macro that given an attr e.g. hba_queue_depth
2575 * expands into a function with the name lpfc_hba_queue_depth_store
2576 *
2577 * lpfc_##attr##_store: convert the ascii text number to an integer, then
2578 * use the lpfc_##attr##_set function to set the value.
2579 * @cdev: class device that is converted into a Scsi_host.
2580 * @buf: contains the attribute value in decimal.
2581 * @count: not used.
2582 *
2583 * Returns:
2584 * -EINVAL if val is invalid or lpfc_##attr##_set() fails
2585 * length of buffer upon success.
2586 **/
James Smart3de2a652007-08-02 11:09:59 -04002587#define lpfc_vport_param_store(attr) \
2588static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002589lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
2590 const char *buf, size_t count) \
James Smart3de2a652007-08-02 11:09:59 -04002591{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002592 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002593 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
James Smart84d1b002010-02-12 14:42:33 -05002594 uint val = 0;\
James Smart3de2a652007-08-02 11:09:59 -04002595 if (!isdigit(buf[0]))\
2596 return -EINVAL;\
2597 if (sscanf(buf, "%i", &val) != 1)\
2598 return -EINVAL;\
2599 if (lpfc_##attr##_set(vport, val) == 0) \
2600 return strlen(buf);\
2601 else \
2602 return -EINVAL;\
2603}
2604
2605
James Smart895427b2017-02-12 13:52:30 -08002606static DEVICE_ATTR(nvme_info, 0444, lpfc_nvme_info_show, NULL);
James Smart4c47efc2019-01-28 11:14:25 -08002607static DEVICE_ATTR(scsi_stat, 0444, lpfc_scsi_stat_show, NULL);
James Smart81301a92008-12-04 22:39:46 -05002608static DEVICE_ATTR(bg_info, S_IRUGO, lpfc_bg_info_show, NULL);
2609static DEVICE_ATTR(bg_guard_err, S_IRUGO, lpfc_bg_guard_err_show, NULL);
2610static DEVICE_ATTR(bg_apptag_err, S_IRUGO, lpfc_bg_apptag_err_show, NULL);
2611static DEVICE_ATTR(bg_reftag_err, S_IRUGO, lpfc_bg_reftag_err_show, NULL);
Tony Jonesee959b02008-02-22 00:13:36 +01002612static DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
2613static DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
2614static DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
2615static DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL);
2616static DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);
2617static DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL);
2618static DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);
2619static DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);
James Smart84d1b002010-02-12 14:42:33 -05002620static DEVICE_ATTR(link_state, S_IRUGO | S_IWUSR, lpfc_link_state_show,
2621 lpfc_link_state_store);
Tony Jonesee959b02008-02-22 00:13:36 +01002622static DEVICE_ATTR(option_rom_version, S_IRUGO,
2623 lpfc_option_rom_version_show, NULL);
2624static DEVICE_ATTR(num_discovered_ports, S_IRUGO,
2625 lpfc_num_discovered_ports_show, NULL);
James Smart84774a42008-08-24 21:50:06 -04002626static DEVICE_ATTR(menlo_mgmt_mode, S_IRUGO, lpfc_mlomgmt_show, NULL);
Tony Jonesee959b02008-02-22 00:13:36 +01002627static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
Joe Perchesc828a892017-12-19 10:15:08 -08002628static DEVICE_ATTR_RO(lpfc_drvr_version);
2629static DEVICE_ATTR_RO(lpfc_enable_fip);
Tony Jonesee959b02008-02-22 00:13:36 +01002630static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
2631 lpfc_board_mode_show, lpfc_board_mode_store);
2632static DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
2633static DEVICE_ATTR(max_vpi, S_IRUGO, lpfc_max_vpi_show, NULL);
2634static DEVICE_ATTR(used_vpi, S_IRUGO, lpfc_used_vpi_show, NULL);
2635static DEVICE_ATTR(max_rpi, S_IRUGO, lpfc_max_rpi_show, NULL);
2636static DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL);
2637static DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL);
2638static DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL);
2639static DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL);
Joe Perchesc828a892017-12-19 10:15:08 -08002640static DEVICE_ATTR_RO(lpfc_temp_sensor);
Joe Perchesc828a892017-12-19 10:15:08 -08002641static DEVICE_ATTR_RO(lpfc_sriov_hw_max_virtfn);
James Smart026abb82011-12-13 13:20:45 -05002642static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL);
James Smart1ba981f2014-02-20 09:56:45 -05002643static DEVICE_ATTR(lpfc_xlane_supported, S_IRUGO, lpfc_oas_supported_show,
2644 NULL);
James Smartc3f28af2006-08-18 17:47:18 -04002645
James Smart352e5fd2016-12-30 06:57:47 -08002646static char *lpfc_soft_wwn_key = "C99G71SL8032A";
James Smart1ba981f2014-02-20 09:56:45 -05002647#define WWN_SZ 8
2648/**
2649 * lpfc_wwn_set - Convert string to the 8 byte WWN value.
2650 * @buf: WWN string.
2651 * @cnt: Length of string.
2652 * @wwn: Array to receive converted wwn value.
2653 *
2654 * Returns:
2655 * -EINVAL if the buffer does not contain a valid wwn
2656 * 0 success
2657 **/
2658static size_t
2659lpfc_wwn_set(const char *buf, size_t cnt, char wwn[])
2660{
2661 unsigned int i, j;
James Smartc3f28af2006-08-18 17:47:18 -04002662
James Smart1ba981f2014-02-20 09:56:45 -05002663 /* Count may include a LF at end of string */
2664 if (buf[cnt-1] == '\n')
2665 cnt--;
2666
2667 if ((cnt < 16) || (cnt > 18) || ((cnt == 17) && (*buf++ != 'x')) ||
2668 ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
2669 return -EINVAL;
2670
2671 memset(wwn, 0, WWN_SZ);
2672
2673 /* Validate and store the new name */
2674 for (i = 0, j = 0; i < 16; i++) {
2675 if ((*buf >= 'a') && (*buf <= 'f'))
2676 j = ((j << 4) | ((*buf++ - 'a') + 10));
2677 else if ((*buf >= 'A') && (*buf <= 'F'))
2678 j = ((j << 4) | ((*buf++ - 'A') + 10));
2679 else if ((*buf >= '0') && (*buf <= '9'))
2680 j = ((j << 4) | (*buf++ - '0'));
2681 else
2682 return -EINVAL;
2683 if (i % 2) {
2684 wwn[i/2] = j & 0xff;
2685 j = 0;
2686 }
2687 }
2688 return 0;
2689}
James Smart352e5fd2016-12-30 06:57:47 -08002690/**
2691 * lpfc_soft_wwn_enable_store - Allows setting of the wwn if the key is valid
2692 * @dev: class device that is converted into a Scsi_host.
2693 * @attr: device attribute, not used.
2694 * @buf: containing the string lpfc_soft_wwn_key.
2695 * @count: must be size of lpfc_soft_wwn_key.
2696 *
2697 * Returns:
2698 * -EINVAL if the buffer does not contain lpfc_soft_wwn_key
2699 * length of buf indicates success
2700 **/
2701static ssize_t
2702lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr,
2703 const char *buf, size_t count)
2704{
2705 struct Scsi_Host *shost = class_to_shost(dev);
2706 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2707 struct lpfc_hba *phba = vport->phba;
2708 unsigned int cnt = count;
James Smartaeb3c812017-04-21 16:05:02 -07002709 uint8_t vvvl = vport->fc_sparam.cmn.valid_vendor_ver_level;
2710 u32 *fawwpn_key = (uint32_t *)&vport->fc_sparam.un.vendorVersion[0];
James Smart352e5fd2016-12-30 06:57:47 -08002711
2712 /*
2713 * We're doing a simple sanity check for soft_wwpn setting.
2714 * We require that the user write a specific key to enable
2715 * the soft_wwpn attribute to be settable. Once the attribute
2716 * is written, the enable key resets. If further updates are
2717 * desired, the key must be written again to re-enable the
2718 * attribute.
2719 *
2720 * The "key" is not secret - it is a hardcoded string shown
2721 * here. The intent is to protect against the random user or
2722 * application that is just writing attributes.
2723 */
James Smartaeb3c812017-04-21 16:05:02 -07002724 if (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR) {
2725 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2726 "0051 "LPFC_DRIVER_NAME" soft wwpn can not"
2727 " be enabled: fawwpn is enabled\n");
2728 return -EINVAL;
2729 }
James Smart352e5fd2016-12-30 06:57:47 -08002730
2731 /* count may include a LF at end of string */
2732 if (buf[cnt-1] == '\n')
2733 cnt--;
2734
2735 if ((cnt != strlen(lpfc_soft_wwn_key)) ||
2736 (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0))
2737 return -EINVAL;
2738
2739 phba->soft_wwn_enable = 1;
2740
2741 dev_printk(KERN_WARNING, &phba->pcidev->dev,
2742 "lpfc%d: soft_wwpn assignment has been enabled.\n",
2743 phba->brd_no);
2744 dev_printk(KERN_WARNING, &phba->pcidev->dev,
2745 " The soft_wwpn feature is not supported by Broadcom.");
2746
2747 return count;
2748}
Joe Perches6cbaefb2017-12-19 10:15:09 -08002749static DEVICE_ATTR_WO(lpfc_soft_wwn_enable);
James Smart352e5fd2016-12-30 06:57:47 -08002750
2751/**
2752 * lpfc_soft_wwpn_show - Return the cfg soft ww port name of the adapter
2753 * @dev: class device that is converted into a Scsi_host.
2754 * @attr: device attribute, not used.
2755 * @buf: on return contains the wwpn in hexadecimal.
2756 *
2757 * Returns: size of formatted string.
2758 **/
2759static ssize_t
2760lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr,
2761 char *buf)
2762{
2763 struct Scsi_Host *shost = class_to_shost(dev);
2764 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2765 struct lpfc_hba *phba = vport->phba;
2766
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002767 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart352e5fd2016-12-30 06:57:47 -08002768 (unsigned long long)phba->cfg_soft_wwpn);
2769}
2770
2771/**
2772 * lpfc_soft_wwpn_store - Set the ww port name of the adapter
Lee Jonesa738bd92020-11-02 14:23:45 +00002773 * @dev: class device that is converted into a Scsi_host.
James Smart352e5fd2016-12-30 06:57:47 -08002774 * @attr: device attribute, not used.
2775 * @buf: contains the wwpn in hexadecimal.
2776 * @count: number of wwpn bytes in buf
2777 *
2778 * Returns:
2779 * -EACCES hba reset not enabled, adapter over temp
2780 * -EINVAL soft wwn not enabled, count is invalid, invalid wwpn byte invalid
2781 * -EIO error taking adapter offline or online
2782 * value of count on success
2783 **/
2784static ssize_t
2785lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr,
2786 const char *buf, size_t count)
2787{
2788 struct Scsi_Host *shost = class_to_shost(dev);
2789 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2790 struct lpfc_hba *phba = vport->phba;
2791 struct completion online_compl;
2792 int stat1 = 0, stat2 = 0;
2793 unsigned int cnt = count;
2794 u8 wwpn[WWN_SZ];
2795 int rc;
2796
2797 if (!phba->cfg_enable_hba_reset)
2798 return -EACCES;
2799 spin_lock_irq(&phba->hbalock);
2800 if (phba->over_temp_state == HBA_OVER_TEMP) {
2801 spin_unlock_irq(&phba->hbalock);
2802 return -EACCES;
2803 }
2804 spin_unlock_irq(&phba->hbalock);
2805 /* count may include a LF at end of string */
2806 if (buf[cnt-1] == '\n')
2807 cnt--;
2808
2809 if (!phba->soft_wwn_enable)
2810 return -EINVAL;
2811
2812 /* lock setting wwpn, wwnn down */
2813 phba->soft_wwn_enable = 0;
2814
2815 rc = lpfc_wwn_set(buf, cnt, wwpn);
James Smarte2934ed2017-01-17 12:31:56 -08002816 if (rc) {
James Smart352e5fd2016-12-30 06:57:47 -08002817 /* not able to set wwpn, unlock it */
2818 phba->soft_wwn_enable = 1;
2819 return rc;
2820 }
2821
2822 phba->cfg_soft_wwpn = wwn_to_u64(wwpn);
2823 fc_host_port_name(shost) = phba->cfg_soft_wwpn;
2824 if (phba->cfg_soft_wwnn)
2825 fc_host_node_name(shost) = phba->cfg_soft_wwnn;
2826
2827 dev_printk(KERN_NOTICE, &phba->pcidev->dev,
2828 "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no);
2829
2830 stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
2831 if (stat1)
2832 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2833 "0463 lpfc_soft_wwpn attribute set failed to "
2834 "reinit adapter - %d\n", stat1);
2835 init_completion(&online_compl);
2836 rc = lpfc_workq_post_event(phba, &stat2, &online_compl,
2837 LPFC_EVT_ONLINE);
2838 if (rc == 0)
2839 return -ENOMEM;
2840
2841 wait_for_completion(&online_compl);
2842 if (stat2)
2843 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2844 "0464 lpfc_soft_wwpn attribute set failed to "
2845 "reinit adapter - %d\n", stat2);
2846 return (stat1 || stat2) ? -EIO : count;
2847}
Joe Perchesb6b996b2017-12-19 10:15:07 -08002848static DEVICE_ATTR_RW(lpfc_soft_wwpn);
James Smart352e5fd2016-12-30 06:57:47 -08002849
2850/**
2851 * lpfc_soft_wwnn_show - Return the cfg soft ww node name for the adapter
2852 * @dev: class device that is converted into a Scsi_host.
2853 * @attr: device attribute, not used.
2854 * @buf: on return contains the wwnn in hexadecimal.
2855 *
2856 * Returns: size of formatted string.
2857 **/
2858static ssize_t
2859lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr,
2860 char *buf)
2861{
2862 struct Scsi_Host *shost = class_to_shost(dev);
2863 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002864 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart352e5fd2016-12-30 06:57:47 -08002865 (unsigned long long)phba->cfg_soft_wwnn);
2866}
2867
2868/**
2869 * lpfc_soft_wwnn_store - sets the ww node name of the adapter
Lee Jonesa738bd92020-11-02 14:23:45 +00002870 * @dev: class device that is converted into a Scsi_host.
2871 * @attr: device attribute, not used.
James Smart352e5fd2016-12-30 06:57:47 -08002872 * @buf: contains the ww node name in hexadecimal.
2873 * @count: number of wwnn bytes in buf.
2874 *
2875 * Returns:
2876 * -EINVAL soft wwn not enabled, count is invalid, invalid wwnn byte invalid
2877 * value of count on success
2878 **/
2879static ssize_t
2880lpfc_soft_wwnn_store(struct device *dev, struct device_attribute *attr,
2881 const char *buf, size_t count)
2882{
2883 struct Scsi_Host *shost = class_to_shost(dev);
2884 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2885 unsigned int cnt = count;
2886 u8 wwnn[WWN_SZ];
2887 int rc;
2888
2889 /* count may include a LF at end of string */
2890 if (buf[cnt-1] == '\n')
2891 cnt--;
2892
2893 if (!phba->soft_wwn_enable)
2894 return -EINVAL;
2895
2896 rc = lpfc_wwn_set(buf, cnt, wwnn);
James Smarte2934ed2017-01-17 12:31:56 -08002897 if (rc) {
James Smart352e5fd2016-12-30 06:57:47 -08002898 /* Allow wwnn to be set many times, as long as the enable
2899 * is set. However, once the wwpn is set, everything locks.
2900 */
2901 return rc;
2902 }
2903
2904 phba->cfg_soft_wwnn = wwn_to_u64(wwnn);
2905
2906 dev_printk(KERN_NOTICE, &phba->pcidev->dev,
2907 "lpfc%d: soft_wwnn set. Value will take effect upon "
2908 "setting of the soft_wwpn\n", phba->brd_no);
2909
2910 return count;
2911}
Joe Perchesb6b996b2017-12-19 10:15:07 -08002912static DEVICE_ATTR_RW(lpfc_soft_wwnn);
James Smarta12e07b2006-12-02 13:35:30 -05002913
James Smart1ba981f2014-02-20 09:56:45 -05002914/**
2915 * lpfc_oas_tgt_show - Return wwpn of target whose luns maybe enabled for
2916 * Optimized Access Storage (OAS) operations.
2917 * @dev: class device that is converted into a Scsi_host.
2918 * @attr: device attribute, not used.
2919 * @buf: buffer for passing information.
2920 *
2921 * Returns:
2922 * value of count
2923 **/
2924static ssize_t
2925lpfc_oas_tgt_show(struct device *dev, struct device_attribute *attr,
2926 char *buf)
2927{
2928 struct Scsi_Host *shost = class_to_shost(dev);
2929 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2930
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002931 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart1ba981f2014-02-20 09:56:45 -05002932 wwn_to_u64(phba->cfg_oas_tgt_wwpn));
2933}
2934
2935/**
2936 * lpfc_oas_tgt_store - Store wwpn of target whose luns maybe enabled for
2937 * Optimized Access Storage (OAS) operations.
2938 * @dev: class device that is converted into a Scsi_host.
2939 * @attr: device attribute, not used.
2940 * @buf: buffer for passing information.
2941 * @count: Size of the data buffer.
2942 *
2943 * Returns:
2944 * -EINVAL count is invalid, invalid wwpn byte invalid
2945 * -EPERM oas is not supported by hba
2946 * value of count on success
2947 **/
2948static ssize_t
2949lpfc_oas_tgt_store(struct device *dev, struct device_attribute *attr,
2950 const char *buf, size_t count)
2951{
2952 struct Scsi_Host *shost = class_to_shost(dev);
2953 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2954 unsigned int cnt = count;
2955 uint8_t wwpn[WWN_SZ];
2956 int rc;
2957
James Smartf38fa0b2014-04-04 13:52:21 -04002958 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05002959 return -EPERM;
2960
2961 /* count may include a LF at end of string */
2962 if (buf[cnt-1] == '\n')
2963 cnt--;
2964
2965 rc = lpfc_wwn_set(buf, cnt, wwpn);
2966 if (rc)
2967 return rc;
2968
2969 memcpy(phba->cfg_oas_tgt_wwpn, wwpn, (8 * sizeof(uint8_t)));
2970 memcpy(phba->sli4_hba.oas_next_tgt_wwpn, wwpn, (8 * sizeof(uint8_t)));
2971 if (wwn_to_u64(wwpn) == 0)
2972 phba->cfg_oas_flags |= OAS_FIND_ANY_TARGET;
2973 else
2974 phba->cfg_oas_flags &= ~OAS_FIND_ANY_TARGET;
2975 phba->cfg_oas_flags &= ~OAS_LUN_VALID;
2976 phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
2977 return count;
2978}
2979static DEVICE_ATTR(lpfc_xlane_tgt, S_IRUGO | S_IWUSR,
2980 lpfc_oas_tgt_show, lpfc_oas_tgt_store);
2981
2982/**
James Smartc92c8412016-07-06 12:36:05 -07002983 * lpfc_oas_priority_show - Return wwpn of target whose luns maybe enabled for
2984 * Optimized Access Storage (OAS) operations.
2985 * @dev: class device that is converted into a Scsi_host.
2986 * @attr: device attribute, not used.
2987 * @buf: buffer for passing information.
2988 *
2989 * Returns:
2990 * value of count
2991 **/
2992static ssize_t
2993lpfc_oas_priority_show(struct device *dev, struct device_attribute *attr,
2994 char *buf)
2995{
2996 struct Scsi_Host *shost = class_to_shost(dev);
2997 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2998
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002999 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_priority);
James Smartc92c8412016-07-06 12:36:05 -07003000}
3001
3002/**
3003 * lpfc_oas_priority_store - Store wwpn of target whose luns maybe enabled for
3004 * Optimized Access Storage (OAS) operations.
3005 * @dev: class device that is converted into a Scsi_host.
3006 * @attr: device attribute, not used.
3007 * @buf: buffer for passing information.
3008 * @count: Size of the data buffer.
3009 *
3010 * Returns:
3011 * -EINVAL count is invalid, invalid wwpn byte invalid
3012 * -EPERM oas is not supported by hba
3013 * value of count on success
3014 **/
3015static ssize_t
3016lpfc_oas_priority_store(struct device *dev, struct device_attribute *attr,
3017 const char *buf, size_t count)
3018{
3019 struct Scsi_Host *shost = class_to_shost(dev);
3020 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3021 unsigned int cnt = count;
3022 unsigned long val;
3023 int ret;
3024
3025 if (!phba->cfg_fof)
3026 return -EPERM;
3027
3028 /* count may include a LF at end of string */
3029 if (buf[cnt-1] == '\n')
3030 cnt--;
3031
3032 ret = kstrtoul(buf, 0, &val);
3033 if (ret || (val > 0x7f))
3034 return -EINVAL;
3035
3036 if (val)
3037 phba->cfg_oas_priority = (uint8_t)val;
3038 else
3039 phba->cfg_oas_priority = phba->cfg_XLanePriority;
3040 return count;
3041}
3042static DEVICE_ATTR(lpfc_xlane_priority, S_IRUGO | S_IWUSR,
3043 lpfc_oas_priority_show, lpfc_oas_priority_store);
3044
3045/**
James Smart1ba981f2014-02-20 09:56:45 -05003046 * lpfc_oas_vpt_show - Return wwpn of vport whose targets maybe enabled
3047 * for Optimized Access Storage (OAS) operations.
3048 * @dev: class device that is converted into a Scsi_host.
3049 * @attr: device attribute, not used.
3050 * @buf: buffer for passing information.
3051 *
3052 * Returns:
3053 * value of count on success
3054 **/
3055static ssize_t
3056lpfc_oas_vpt_show(struct device *dev, struct device_attribute *attr,
3057 char *buf)
3058{
3059 struct Scsi_Host *shost = class_to_shost(dev);
3060 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3061
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003062 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart1ba981f2014-02-20 09:56:45 -05003063 wwn_to_u64(phba->cfg_oas_vpt_wwpn));
3064}
3065
3066/**
3067 * lpfc_oas_vpt_store - Store wwpn of vport whose targets maybe enabled
3068 * for Optimized Access Storage (OAS) operations.
3069 * @dev: class device that is converted into a Scsi_host.
3070 * @attr: device attribute, not used.
3071 * @buf: buffer for passing information.
3072 * @count: Size of the data buffer.
3073 *
3074 * Returns:
3075 * -EINVAL count is invalid, invalid wwpn byte invalid
3076 * -EPERM oas is not supported by hba
3077 * value of count on success
3078 **/
3079static ssize_t
3080lpfc_oas_vpt_store(struct device *dev, struct device_attribute *attr,
3081 const char *buf, size_t count)
3082{
3083 struct Scsi_Host *shost = class_to_shost(dev);
3084 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3085 unsigned int cnt = count;
3086 uint8_t wwpn[WWN_SZ];
3087 int rc;
3088
James Smartf38fa0b2014-04-04 13:52:21 -04003089 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003090 return -EPERM;
3091
3092 /* count may include a LF at end of string */
3093 if (buf[cnt-1] == '\n')
3094 cnt--;
3095
3096 rc = lpfc_wwn_set(buf, cnt, wwpn);
3097 if (rc)
3098 return rc;
3099
3100 memcpy(phba->cfg_oas_vpt_wwpn, wwpn, (8 * sizeof(uint8_t)));
3101 memcpy(phba->sli4_hba.oas_next_vpt_wwpn, wwpn, (8 * sizeof(uint8_t)));
3102 if (wwn_to_u64(wwpn) == 0)
3103 phba->cfg_oas_flags |= OAS_FIND_ANY_VPORT;
3104 else
3105 phba->cfg_oas_flags &= ~OAS_FIND_ANY_VPORT;
3106 phba->cfg_oas_flags &= ~OAS_LUN_VALID;
James Smartb5749fe2016-12-19 15:07:26 -08003107 if (phba->cfg_oas_priority == 0)
3108 phba->cfg_oas_priority = phba->cfg_XLanePriority;
James Smart1ba981f2014-02-20 09:56:45 -05003109 phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
3110 return count;
3111}
3112static DEVICE_ATTR(lpfc_xlane_vpt, S_IRUGO | S_IWUSR,
3113 lpfc_oas_vpt_show, lpfc_oas_vpt_store);
3114
3115/**
3116 * lpfc_oas_lun_state_show - Return the current state (enabled or disabled)
3117 * of whether luns will be enabled or disabled
3118 * for Optimized Access Storage (OAS) operations.
3119 * @dev: class device that is converted into a Scsi_host.
3120 * @attr: device attribute, not used.
3121 * @buf: buffer for passing information.
3122 *
3123 * Returns:
3124 * size of formatted string.
3125 **/
3126static ssize_t
3127lpfc_oas_lun_state_show(struct device *dev, struct device_attribute *attr,
3128 char *buf)
3129{
3130 struct Scsi_Host *shost = class_to_shost(dev);
3131 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3132
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003133 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_state);
James Smart1ba981f2014-02-20 09:56:45 -05003134}
3135
3136/**
3137 * lpfc_oas_lun_state_store - Store the state (enabled or disabled)
3138 * of whether luns will be enabled or disabled
3139 * for Optimized Access Storage (OAS) operations.
3140 * @dev: class device that is converted into a Scsi_host.
3141 * @attr: device attribute, not used.
3142 * @buf: buffer for passing information.
3143 * @count: Size of the data buffer.
3144 *
3145 * Returns:
3146 * -EINVAL count is invalid, invalid wwpn byte invalid
3147 * -EPERM oas is not supported by hba
3148 * value of count on success
3149 **/
3150static ssize_t
3151lpfc_oas_lun_state_store(struct device *dev, struct device_attribute *attr,
3152 const char *buf, size_t count)
3153{
3154 struct Scsi_Host *shost = class_to_shost(dev);
3155 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3156 int val = 0;
3157
James Smartf38fa0b2014-04-04 13:52:21 -04003158 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003159 return -EPERM;
3160
3161 if (!isdigit(buf[0]))
3162 return -EINVAL;
3163
3164 if (sscanf(buf, "%i", &val) != 1)
3165 return -EINVAL;
3166
3167 if ((val != 0) && (val != 1))
3168 return -EINVAL;
3169
3170 phba->cfg_oas_lun_state = val;
James Smart1ba981f2014-02-20 09:56:45 -05003171 return strlen(buf);
3172}
3173static DEVICE_ATTR(lpfc_xlane_lun_state, S_IRUGO | S_IWUSR,
3174 lpfc_oas_lun_state_show, lpfc_oas_lun_state_store);
3175
3176/**
3177 * lpfc_oas_lun_status_show - Return the status of the Optimized Access
3178 * Storage (OAS) lun returned by the
3179 * lpfc_oas_lun_show function.
3180 * @dev: class device that is converted into a Scsi_host.
3181 * @attr: device attribute, not used.
3182 * @buf: buffer for passing information.
3183 *
3184 * Returns:
3185 * size of formatted string.
3186 **/
3187static ssize_t
3188lpfc_oas_lun_status_show(struct device *dev, struct device_attribute *attr,
3189 char *buf)
3190{
3191 struct Scsi_Host *shost = class_to_shost(dev);
3192 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3193
3194 if (!(phba->cfg_oas_flags & OAS_LUN_VALID))
3195 return -EFAULT;
3196
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003197 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_status);
James Smart1ba981f2014-02-20 09:56:45 -05003198}
3199static DEVICE_ATTR(lpfc_xlane_lun_status, S_IRUGO,
3200 lpfc_oas_lun_status_show, NULL);
3201
3202
3203/**
3204 * lpfc_oas_lun_state_set - enable or disable a lun for Optimized Access Storage
3205 * (OAS) operations.
3206 * @phba: lpfc_hba pointer.
Lee Jonesa738bd92020-11-02 14:23:45 +00003207 * @vpt_wwpn: wwpn of the vport associated with the returned lun
3208 * @tgt_wwpn: wwpn of the target associated with the returned lun
James Smart1ba981f2014-02-20 09:56:45 -05003209 * @lun: the fc lun for setting oas state.
3210 * @oas_state: the oas state to be set to the lun.
Lee Jonesa738bd92020-11-02 14:23:45 +00003211 * @pri: priority
James Smart1ba981f2014-02-20 09:56:45 -05003212 *
3213 * Returns:
3214 * SUCCESS : 0
3215 * -EPERM OAS is not enabled or not supported by this port.
3216 *
3217 */
3218static size_t
3219lpfc_oas_lun_state_set(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
James Smartc92c8412016-07-06 12:36:05 -07003220 uint8_t tgt_wwpn[], uint64_t lun,
3221 uint32_t oas_state, uint8_t pri)
James Smart1ba981f2014-02-20 09:56:45 -05003222{
3223
3224 int rc = 0;
3225
James Smartf38fa0b2014-04-04 13:52:21 -04003226 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003227 return -EPERM;
3228
3229 if (oas_state) {
3230 if (!lpfc_enable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
James Smartc92c8412016-07-06 12:36:05 -07003231 (struct lpfc_name *)tgt_wwpn,
3232 lun, pri))
James Smart1ba981f2014-02-20 09:56:45 -05003233 rc = -ENOMEM;
3234 } else {
3235 lpfc_disable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003236 (struct lpfc_name *)tgt_wwpn, lun, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003237 }
3238 return rc;
3239
3240}
3241
3242/**
3243 * lpfc_oas_lun_get_next - get the next lun that has been enabled for Optimized
3244 * Access Storage (OAS) operations.
3245 * @phba: lpfc_hba pointer.
3246 * @vpt_wwpn: wwpn of the vport associated with the returned lun
3247 * @tgt_wwpn: wwpn of the target associated with the returned lun
3248 * @lun_status: status of the lun returned lun
Lee Jonesa738bd92020-11-02 14:23:45 +00003249 * @lun_pri: priority of the lun returned lun
James Smart1ba981f2014-02-20 09:56:45 -05003250 *
3251 * Returns the first or next lun enabled for OAS operations for the vport/target
3252 * specified. If a lun is found, its vport wwpn, target wwpn and status is
3253 * returned. If the lun is not found, NOT_OAS_ENABLED_LUN is returned.
3254 *
3255 * Return:
3256 * lun that is OAS enabled for the vport/target
3257 * NOT_OAS_ENABLED_LUN when no oas enabled lun found.
3258 */
3259static uint64_t
3260lpfc_oas_lun_get_next(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
James Smartb5749fe2016-12-19 15:07:26 -08003261 uint8_t tgt_wwpn[], uint32_t *lun_status,
3262 uint32_t *lun_pri)
James Smart1ba981f2014-02-20 09:56:45 -05003263{
3264 uint64_t found_lun;
3265
3266 if (unlikely(!phba) || !vpt_wwpn || !tgt_wwpn)
3267 return NOT_OAS_ENABLED_LUN;
3268 if (lpfc_find_next_oas_lun(phba, (struct lpfc_name *)
3269 phba->sli4_hba.oas_next_vpt_wwpn,
3270 (struct lpfc_name *)
3271 phba->sli4_hba.oas_next_tgt_wwpn,
3272 &phba->sli4_hba.oas_next_lun,
3273 (struct lpfc_name *)vpt_wwpn,
3274 (struct lpfc_name *)tgt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003275 &found_lun, lun_status, lun_pri))
James Smart1ba981f2014-02-20 09:56:45 -05003276 return found_lun;
3277 else
3278 return NOT_OAS_ENABLED_LUN;
3279}
3280
3281/**
3282 * lpfc_oas_lun_state_change - enable/disable a lun for OAS operations
3283 * @phba: lpfc_hba pointer.
3284 * @vpt_wwpn: vport wwpn by reference.
3285 * @tgt_wwpn: target wwpn by reference.
3286 * @lun: the fc lun for setting oas state.
3287 * @oas_state: the oas state to be set to the oas_lun.
Lee Jonesa738bd92020-11-02 14:23:45 +00003288 * @pri: priority
James Smart1ba981f2014-02-20 09:56:45 -05003289 *
3290 * This routine enables (OAS_LUN_ENABLE) or disables (OAS_LUN_DISABLE)
3291 * a lun for OAS operations.
3292 *
3293 * Return:
3294 * SUCCESS: 0
3295 * -ENOMEM: failed to enable an lun for OAS operations
3296 * -EPERM: OAS is not enabled
3297 */
3298static ssize_t
3299lpfc_oas_lun_state_change(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
3300 uint8_t tgt_wwpn[], uint64_t lun,
James Smartc92c8412016-07-06 12:36:05 -07003301 uint32_t oas_state, uint8_t pri)
James Smart1ba981f2014-02-20 09:56:45 -05003302{
3303
3304 int rc;
3305
3306 rc = lpfc_oas_lun_state_set(phba, vpt_wwpn, tgt_wwpn, lun,
James Smartc92c8412016-07-06 12:36:05 -07003307 oas_state, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003308 return rc;
3309}
3310
3311/**
3312 * lpfc_oas_lun_show - Return oas enabled luns from a chosen target
3313 * @dev: class device that is converted into a Scsi_host.
3314 * @attr: device attribute, not used.
3315 * @buf: buffer for passing information.
3316 *
3317 * This routine returns a lun enabled for OAS each time the function
3318 * is called.
3319 *
3320 * Returns:
3321 * SUCCESS: size of formatted string.
3322 * -EFAULT: target or vport wwpn was not set properly.
3323 * -EPERM: oas is not enabled.
3324 **/
3325static ssize_t
3326lpfc_oas_lun_show(struct device *dev, struct device_attribute *attr,
3327 char *buf)
3328{
3329 struct Scsi_Host *shost = class_to_shost(dev);
3330 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3331
3332 uint64_t oas_lun;
3333 int len = 0;
3334
James Smartf38fa0b2014-04-04 13:52:21 -04003335 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003336 return -EPERM;
3337
3338 if (wwn_to_u64(phba->cfg_oas_vpt_wwpn) == 0)
3339 if (!(phba->cfg_oas_flags & OAS_FIND_ANY_VPORT))
3340 return -EFAULT;
3341
3342 if (wwn_to_u64(phba->cfg_oas_tgt_wwpn) == 0)
3343 if (!(phba->cfg_oas_flags & OAS_FIND_ANY_TARGET))
3344 return -EFAULT;
3345
3346 oas_lun = lpfc_oas_lun_get_next(phba, phba->cfg_oas_vpt_wwpn,
3347 phba->cfg_oas_tgt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003348 &phba->cfg_oas_lun_status,
3349 &phba->cfg_oas_priority);
James Smart1ba981f2014-02-20 09:56:45 -05003350 if (oas_lun != NOT_OAS_ENABLED_LUN)
3351 phba->cfg_oas_flags |= OAS_LUN_VALID;
3352
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003353 len += scnprintf(buf + len, PAGE_SIZE-len, "0x%llx", oas_lun);
James Smart1ba981f2014-02-20 09:56:45 -05003354
3355 return len;
3356}
3357
3358/**
3359 * lpfc_oas_lun_store - Sets the OAS state for lun
3360 * @dev: class device that is converted into a Scsi_host.
3361 * @attr: device attribute, not used.
3362 * @buf: buffer for passing information.
Lee Jonesa738bd92020-11-02 14:23:45 +00003363 * @count: size of the formatting string
James Smart1ba981f2014-02-20 09:56:45 -05003364 *
3365 * This function sets the OAS state for lun. Before this function is called,
3366 * the vport wwpn, target wwpn, and oas state need to be set.
3367 *
3368 * Returns:
3369 * SUCCESS: size of formatted string.
3370 * -EFAULT: target or vport wwpn was not set properly.
3371 * -EPERM: oas is not enabled.
3372 * size of formatted string.
3373 **/
3374static ssize_t
3375lpfc_oas_lun_store(struct device *dev, struct device_attribute *attr,
3376 const char *buf, size_t count)
3377{
3378 struct Scsi_Host *shost = class_to_shost(dev);
3379 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3380 uint64_t scsi_lun;
James Smartb5749fe2016-12-19 15:07:26 -08003381 uint32_t pri;
James Smart1ba981f2014-02-20 09:56:45 -05003382 ssize_t rc;
3383
James Smartf38fa0b2014-04-04 13:52:21 -04003384 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003385 return -EPERM;
3386
3387 if (wwn_to_u64(phba->cfg_oas_vpt_wwpn) == 0)
3388 return -EFAULT;
3389
3390 if (wwn_to_u64(phba->cfg_oas_tgt_wwpn) == 0)
3391 return -EFAULT;
3392
3393 if (!isdigit(buf[0]))
3394 return -EINVAL;
3395
3396 if (sscanf(buf, "0x%llx", &scsi_lun) != 1)
3397 return -EINVAL;
3398
James Smartb5749fe2016-12-19 15:07:26 -08003399 pri = phba->cfg_oas_priority;
3400 if (pri == 0)
3401 pri = phba->cfg_XLanePriority;
3402
James Smart1ba981f2014-02-20 09:56:45 -05003403 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
James Smartc92c8412016-07-06 12:36:05 -07003404 "3372 Try to set vport 0x%llx target 0x%llx lun:0x%llx "
3405 "priority 0x%x with oas state %d\n",
James Smart1ba981f2014-02-20 09:56:45 -05003406 wwn_to_u64(phba->cfg_oas_vpt_wwpn),
3407 wwn_to_u64(phba->cfg_oas_tgt_wwpn), scsi_lun,
James Smartb5749fe2016-12-19 15:07:26 -08003408 pri, phba->cfg_oas_lun_state);
James Smart1ba981f2014-02-20 09:56:45 -05003409
3410 rc = lpfc_oas_lun_state_change(phba, phba->cfg_oas_vpt_wwpn,
James Smartc92c8412016-07-06 12:36:05 -07003411 phba->cfg_oas_tgt_wwpn, scsi_lun,
James Smartb5749fe2016-12-19 15:07:26 -08003412 phba->cfg_oas_lun_state, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003413 if (rc)
3414 return rc;
3415
3416 return count;
3417}
3418static DEVICE_ATTR(lpfc_xlane_lun, S_IRUGO | S_IWUSR,
3419 lpfc_oas_lun_show, lpfc_oas_lun_store);
James Smartc3f28af2006-08-18 17:47:18 -04003420
James Smartf358dd02017-02-12 13:52:34 -08003421int lpfc_enable_nvmet_cnt;
3422unsigned long long lpfc_enable_nvmet[LPFC_NVMET_MAX_PORTS] = {
3423 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3424 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
3425module_param_array(lpfc_enable_nvmet, ullong, &lpfc_enable_nvmet_cnt, 0444);
3426MODULE_PARM_DESC(lpfc_enable_nvmet, "Enable HBA port(s) WWPN as a NVME Target");
3427
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05003428static int lpfc_poll = 0;
James Smartab56dc22011-02-16 12:39:57 -05003429module_param(lpfc_poll, int, S_IRUGO);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05003430MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
3431 " 0 - none,"
3432 " 1 - poll with interrupts enabled"
3433 " 3 - poll and disable FCP ring interrupts");
3434
Joe Perchesb6b996b2017-12-19 10:15:07 -08003435static DEVICE_ATTR_RW(lpfc_poll);
dea31012005-04-17 16:05:31 -05003436
James Smart96418b52017-03-04 09:30:31 -08003437int lpfc_no_hba_reset_cnt;
3438unsigned long lpfc_no_hba_reset[MAX_HBAS_NO_RESET] = {
3439 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
3440module_param_array(lpfc_no_hba_reset, ulong, &lpfc_no_hba_reset_cnt, 0444);
3441MODULE_PARM_DESC(lpfc_no_hba_reset, "WWPN of HBAs that should not be reset");
3442
James Smartd2f25472021-01-04 10:02:27 -08003443LPFC_ATTR(sli_mode, 3, 3, 3,
3444 "SLI mode selector: 3 - select SLI-3");
James Smart92d7f7b2007-06-17 19:56:38 -05003445
James Smart458c0832016-07-06 12:36:07 -07003446LPFC_ATTR_R(enable_npiv, 1, 0, 1,
3447 "Enable NPIV functionality");
James Smart92d7f7b2007-06-17 19:56:38 -05003448
James Smart7d791df2011-07-22 18:37:52 -04003449LPFC_ATTR_R(fcf_failover_policy, 1, 1, 2,
3450 "FCF Fast failover=1 Priority failover=2");
3451
James Smarte5771b42013-03-01 16:37:14 -05003452/*
3453# lpfc_enable_rrq: Track XRI/OXID reuse after IO failures
3454# 0x0 = disabled, XRI/OXID use not tracked.
3455# 0x1 = XRI/OXID reuse is timed with ratov, RRQ sent.
3456# 0x2 = XRI/OXID reuse is timed with ratov, No RRQ sent.
3457*/
James Smart31202b02016-10-13 15:06:08 -07003458LPFC_ATTR_R(enable_rrq, 2, 0, 2,
3459 "Enable RRQ functionality");
James Smart19ca7602010-11-20 23:11:55 -05003460
dea31012005-04-17 16:05:31 -05003461/*
James Smart84d1b002010-02-12 14:42:33 -05003462# lpfc_suppress_link_up: Bring link up at initialization
3463# 0x0 = bring link up (issue MBX_INIT_LINK)
3464# 0x1 = do NOT bring link up at initialization(MBX_INIT_LINK)
3465# 0x2 = never bring up link
3466# Default value is 0.
3467*/
James Smarte40a02c2010-02-26 14:13:54 -05003468LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK,
3469 LPFC_DELAY_INIT_LINK_INDEFINITELY,
3470 "Suppress Link Up at initialization");
James Smart83c6cb12019-10-18 14:18:30 -07003471
3472static ssize_t
3473lpfc_pls_show(struct device *dev, struct device_attribute *attr, char *buf)
3474{
3475 struct Scsi_Host *shost = class_to_shost(dev);
3476 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3477
3478 return scnprintf(buf, PAGE_SIZE, "%d\n",
3479 phba->sli4_hba.pc_sli4_params.pls);
3480}
3481static DEVICE_ATTR(pls, 0444,
3482 lpfc_pls_show, NULL);
3483
3484static ssize_t
3485lpfc_pt_show(struct device *dev, struct device_attribute *attr, char *buf)
3486{
3487 struct Scsi_Host *shost = class_to_shost(dev);
3488 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3489
3490 return scnprintf(buf, PAGE_SIZE, "%d\n",
3491 (phba->hba_flag & HBA_PERSISTENT_TOPO) ? 1 : 0);
3492}
3493static DEVICE_ATTR(pt, 0444,
3494 lpfc_pt_show, NULL);
3495
James Smart2a9bf3d2010-06-07 15:24:45 -04003496/*
3497# lpfc_cnt: Number of IOCBs allocated for ELS, CT, and ABTS
3498# 1 - (1024)
3499# 2 - (2048)
3500# 3 - (3072)
3501# 4 - (4096)
3502# 5 - (5120)
3503*/
3504static ssize_t
3505lpfc_iocb_hw_show(struct device *dev, struct device_attribute *attr, char *buf)
3506{
3507 struct Scsi_Host *shost = class_to_shost(dev);
3508 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
3509
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003510 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->iocb_max);
James Smart2a9bf3d2010-06-07 15:24:45 -04003511}
3512
3513static DEVICE_ATTR(iocb_hw, S_IRUGO,
3514 lpfc_iocb_hw_show, NULL);
3515static ssize_t
3516lpfc_txq_hw_show(struct device *dev, struct device_attribute *attr, char *buf)
3517{
3518 struct Scsi_Host *shost = class_to_shost(dev);
3519 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
James Smart895427b2017-02-12 13:52:30 -08003520 struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
James Smart2a9bf3d2010-06-07 15:24:45 -04003521
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003522 return scnprintf(buf, PAGE_SIZE, "%d\n",
Dick Kennedy1234a6d2017-09-29 17:34:29 -07003523 pring ? pring->txq_max : 0);
James Smart2a9bf3d2010-06-07 15:24:45 -04003524}
3525
3526static DEVICE_ATTR(txq_hw, S_IRUGO,
3527 lpfc_txq_hw_show, NULL);
3528static ssize_t
3529lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr,
3530 char *buf)
3531{
3532 struct Scsi_Host *shost = class_to_shost(dev);
3533 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
James Smart895427b2017-02-12 13:52:30 -08003534 struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
James Smart2a9bf3d2010-06-07 15:24:45 -04003535
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003536 return scnprintf(buf, PAGE_SIZE, "%d\n",
Dick Kennedy1234a6d2017-09-29 17:34:29 -07003537 pring ? pring->txcmplq_max : 0);
James Smart2a9bf3d2010-06-07 15:24:45 -04003538}
3539
3540static DEVICE_ATTR(txcmplq_hw, S_IRUGO,
3541 lpfc_txcmplq_hw_show, NULL);
3542
James Smart84d1b002010-02-12 14:42:33 -05003543/*
James Smartc01f3202006-08-18 17:47:08 -04003544# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
3545# until the timer expires. Value range is [0,255]. Default value is 30.
3546*/
3547static int lpfc_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
3548static int lpfc_devloss_tmo = LPFC_DEF_DEVLOSS_TMO;
3549module_param(lpfc_nodev_tmo, int, 0);
3550MODULE_PARM_DESC(lpfc_nodev_tmo,
3551 "Seconds driver will hold I/O waiting "
3552 "for a device to come back");
James Smarte59058c2008-08-24 21:49:00 -04003553
3554/**
James Smart3621a712009-04-06 18:47:14 -04003555 * lpfc_nodev_tmo_show - Return the hba dev loss timeout value
James Smarte59058c2008-08-24 21:49:00 -04003556 * @dev: class converted to a Scsi_host structure.
3557 * @attr: device attribute, not used.
3558 * @buf: on return contains the dev loss timeout in decimal.
3559 *
3560 * Returns: size of formatted string.
3561 **/
James Smartc01f3202006-08-18 17:47:08 -04003562static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01003563lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr,
3564 char *buf)
James Smartc01f3202006-08-18 17:47:08 -04003565{
Tony Jonesee959b02008-02-22 00:13:36 +01003566 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05003567 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
James Smarte40a02c2010-02-26 14:13:54 -05003568
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003569 return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003570}
3571
James Smarte59058c2008-08-24 21:49:00 -04003572/**
James Smart3621a712009-04-06 18:47:14 -04003573 * lpfc_nodev_tmo_init - Set the hba nodev timeout value
James Smarte59058c2008-08-24 21:49:00 -04003574 * @vport: lpfc vport structure pointer.
3575 * @val: contains the nodev timeout value.
3576 *
3577 * Description:
3578 * If the devloss tmo is already set then nodev tmo is set to devloss tmo,
3579 * a kernel error message is printed and zero is returned.
3580 * Else if val is in range then nodev tmo and devloss tmo are set to val.
3581 * Otherwise nodev tmo is set to the default value.
3582 *
3583 * Returns:
3584 * zero if already set or if val is in range
3585 * -EINVAL val out of range
3586 **/
James Smartc01f3202006-08-18 17:47:08 -04003587static int
James Smart3de2a652007-08-02 11:09:59 -04003588lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003589{
James Smart3de2a652007-08-02 11:09:59 -04003590 if (vport->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) {
3591 vport->cfg_nodev_tmo = vport->cfg_devloss_tmo;
3592 if (val != LPFC_DEF_DEVLOSS_TMO)
James Smarte8b62012007-08-02 11:10:09 -04003593 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003594 "0407 Ignoring lpfc_nodev_tmo module "
3595 "parameter because lpfc_devloss_tmo "
3596 "is set.\n");
James Smartc01f3202006-08-18 17:47:08 -04003597 return 0;
3598 }
3599
3600 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003601 vport->cfg_nodev_tmo = val;
3602 vport->cfg_devloss_tmo = val;
James Smartc01f3202006-08-18 17:47:08 -04003603 return 0;
3604 }
James Smarte8b62012007-08-02 11:10:09 -04003605 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3606 "0400 lpfc_nodev_tmo attribute cannot be set to"
3607 " %d, allowed range is [%d, %d]\n",
3608 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smart3de2a652007-08-02 11:09:59 -04003609 vport->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
James Smartc01f3202006-08-18 17:47:08 -04003610 return -EINVAL;
3611}
3612
James Smarte59058c2008-08-24 21:49:00 -04003613/**
James Smart3621a712009-04-06 18:47:14 -04003614 * lpfc_update_rport_devloss_tmo - Update dev loss tmo value
James Smarte59058c2008-08-24 21:49:00 -04003615 * @vport: lpfc vport structure pointer.
3616 *
3617 * Description:
3618 * Update all the ndlp's dev loss tmo with the vport devloss tmo value.
3619 **/
James Smart7054a602007-04-25 09:52:34 -04003620static void
James Smart3de2a652007-08-02 11:09:59 -04003621lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
James Smart7054a602007-04-25 09:52:34 -04003622{
James Smart858c9f62007-06-17 19:56:39 -05003623 struct Scsi_Host *shost;
James Smart7054a602007-04-25 09:52:34 -04003624 struct lpfc_nodelist *ndlp;
James Smart01466022018-04-09 14:24:27 -07003625#if (IS_ENABLED(CONFIG_NVME_FC))
3626 struct lpfc_nvme_rport *rport;
James Smart9e210172018-09-13 15:41:10 -07003627 struct nvme_fc_remote_port *remoteport = NULL;
James Smart01466022018-04-09 14:24:27 -07003628#endif
James Smart7054a602007-04-25 09:52:34 -04003629
James Smart51ef4c22007-08-02 11:10:31 -04003630 shost = lpfc_shost_from_vport(vport);
3631 spin_lock_irq(shost->host_lock);
James Smart7a06dcd2017-06-01 21:06:55 -07003632 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart7a06dcd2017-06-01 21:06:55 -07003633 if (ndlp->rport)
James Smart51ef4c22007-08-02 11:10:31 -04003634 ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
James Smart6ddcf0a2017-11-03 09:33:30 -07003635#if (IS_ENABLED(CONFIG_NVME_FC))
James Smartc6adba12020-11-15 11:26:34 -08003636 spin_lock(&ndlp->lock);
James Smart01466022018-04-09 14:24:27 -07003637 rport = lpfc_ndlp_get_nrport(ndlp);
3638 if (rport)
James Smart9e210172018-09-13 15:41:10 -07003639 remoteport = rport->remoteport;
James Smartc6adba12020-11-15 11:26:34 -08003640 spin_unlock(&ndlp->lock);
James Smart07f50992019-08-14 16:56:45 -07003641 if (rport && remoteport)
3642 nvme_fc_set_remoteport_devloss(remoteport,
James Smart6ddcf0a2017-11-03 09:33:30 -07003643 vport->cfg_devloss_tmo);
3644#endif
James Smart7a06dcd2017-06-01 21:06:55 -07003645 }
James Smart51ef4c22007-08-02 11:10:31 -04003646 spin_unlock_irq(shost->host_lock);
James Smart7054a602007-04-25 09:52:34 -04003647}
3648
James Smarte59058c2008-08-24 21:49:00 -04003649/**
James Smart3621a712009-04-06 18:47:14 -04003650 * lpfc_nodev_tmo_set - Set the vport nodev tmo and devloss tmo values
James Smarte59058c2008-08-24 21:49:00 -04003651 * @vport: lpfc vport structure pointer.
3652 * @val: contains the tmo value.
3653 *
3654 * Description:
3655 * If the devloss tmo is already set or the vport dev loss tmo has changed
3656 * then a kernel error message is printed and zero is returned.
3657 * Else if val is in range then nodev tmo and devloss tmo are set to val.
3658 * Otherwise nodev tmo is set to the default value.
3659 *
3660 * Returns:
3661 * zero if already set or if val is in range
3662 * -EINVAL val out of range
3663 **/
James Smartc01f3202006-08-18 17:47:08 -04003664static int
James Smart3de2a652007-08-02 11:09:59 -04003665lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003666{
James Smart3de2a652007-08-02 11:09:59 -04003667 if (vport->dev_loss_tmo_changed ||
3668 (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
James Smarte8b62012007-08-02 11:10:09 -04003669 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003670 "0401 Ignoring change to lpfc_nodev_tmo "
3671 "because lpfc_devloss_tmo is set.\n");
James Smartc01f3202006-08-18 17:47:08 -04003672 return 0;
3673 }
James Smartc01f3202006-08-18 17:47:08 -04003674 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003675 vport->cfg_nodev_tmo = val;
3676 vport->cfg_devloss_tmo = val;
Mike Christie0af5d702010-09-15 16:52:31 -05003677 /*
3678 * For compat: set the fc_host dev loss so new rports
3679 * will get the value.
3680 */
3681 fc_host_dev_loss_tmo(lpfc_shost_from_vport(vport)) = val;
James Smart3de2a652007-08-02 11:09:59 -04003682 lpfc_update_rport_devloss_tmo(vport);
James Smartc01f3202006-08-18 17:47:08 -04003683 return 0;
3684 }
James Smarte8b62012007-08-02 11:10:09 -04003685 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003686 "0403 lpfc_nodev_tmo attribute cannot be set to "
James Smarte8b62012007-08-02 11:10:09 -04003687 "%d, allowed range is [%d, %d]\n",
3688 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smartc01f3202006-08-18 17:47:08 -04003689 return -EINVAL;
3690}
3691
James Smart3de2a652007-08-02 11:09:59 -04003692lpfc_vport_param_store(nodev_tmo)
James Smartc01f3202006-08-18 17:47:08 -04003693
Joe Perchesb6b996b2017-12-19 10:15:07 -08003694static DEVICE_ATTR_RW(lpfc_nodev_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003695
3696/*
3697# lpfc_devloss_tmo: If set, it will hold all I/O errors on devices that
3698# disappear until the timer expires. Value range is [0,255]. Default
3699# value is 30.
3700*/
James Smartab56dc22011-02-16 12:39:57 -05003701module_param(lpfc_devloss_tmo, int, S_IRUGO);
James Smartc01f3202006-08-18 17:47:08 -04003702MODULE_PARM_DESC(lpfc_devloss_tmo,
3703 "Seconds driver will hold I/O waiting "
3704 "for a device to come back");
James Smart3de2a652007-08-02 11:09:59 -04003705lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
3706 LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
3707lpfc_vport_param_show(devloss_tmo)
James Smarte59058c2008-08-24 21:49:00 -04003708
3709/**
James Smart3621a712009-04-06 18:47:14 -04003710 * lpfc_devloss_tmo_set - Sets vport nodev tmo, devloss tmo values, changed bit
James Smarte59058c2008-08-24 21:49:00 -04003711 * @vport: lpfc vport structure pointer.
3712 * @val: contains the tmo value.
3713 *
3714 * Description:
3715 * If val is in a valid range then set the vport nodev tmo,
3716 * devloss tmo, also set the vport dev loss tmo changed flag.
3717 * Else a kernel error message is printed.
3718 *
3719 * Returns:
3720 * zero if val is in range
3721 * -EINVAL val out of range
3722 **/
James Smartc01f3202006-08-18 17:47:08 -04003723static int
James Smart3de2a652007-08-02 11:09:59 -04003724lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003725{
3726 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003727 vport->cfg_nodev_tmo = val;
3728 vport->cfg_devloss_tmo = val;
3729 vport->dev_loss_tmo_changed = 1;
Mike Christie0af5d702010-09-15 16:52:31 -05003730 fc_host_dev_loss_tmo(lpfc_shost_from_vport(vport)) = val;
James Smart3de2a652007-08-02 11:09:59 -04003731 lpfc_update_rport_devloss_tmo(vport);
James Smartc01f3202006-08-18 17:47:08 -04003732 return 0;
3733 }
3734
James Smarte8b62012007-08-02 11:10:09 -04003735 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003736 "0404 lpfc_devloss_tmo attribute cannot be set to "
3737 "%d, allowed range is [%d, %d]\n",
James Smarte8b62012007-08-02 11:10:09 -04003738 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smartc01f3202006-08-18 17:47:08 -04003739 return -EINVAL;
3740}
3741
James Smart3de2a652007-08-02 11:09:59 -04003742lpfc_vport_param_store(devloss_tmo)
Joe Perchesb6b996b2017-12-19 10:15:07 -08003743static DEVICE_ATTR_RW(lpfc_devloss_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003744
3745/*
James Smartf358dd02017-02-12 13:52:34 -08003746 * lpfc_suppress_rsp: Enable suppress rsp feature is firmware supports it
3747 * lpfc_suppress_rsp = 0 Disable
3748 * lpfc_suppress_rsp = 1 Enable (default)
3749 *
3750 */
3751LPFC_ATTR_R(suppress_rsp, 1, 0, 1,
3752 "Enable suppress rsp feature is firmware supports it");
3753
3754/*
James Smart2d7dbc42017-02-12 13:52:35 -08003755 * lpfc_nvmet_mrq: Specify number of RQ pairs for processing NVMET cmds
James Smartbcb24f62017-11-20 16:00:36 -08003756 * lpfc_nvmet_mrq = 0 driver will calcualte optimal number of RQ pairs
James Smart2d7dbc42017-02-12 13:52:35 -08003757 * lpfc_nvmet_mrq = 1 use a single RQ pair
3758 * lpfc_nvmet_mrq >= 2 use specified RQ pairs for MRQ
3759 *
3760 */
3761LPFC_ATTR_R(nvmet_mrq,
James Smartbcb24f62017-11-20 16:00:36 -08003762 LPFC_NVMET_MRQ_AUTO, LPFC_NVMET_MRQ_AUTO, LPFC_NVMET_MRQ_MAX,
James Smart2d7dbc42017-02-12 13:52:35 -08003763 "Specify number of RQ pairs for processing NVMET cmds");
3764
3765/*
James Smart2448e482018-04-09 14:24:24 -07003766 * lpfc_nvmet_mrq_post: Specify number of RQ buffer to initially post
3767 * to each NVMET RQ. Range 64 to 2048, default is 512.
3768 */
3769LPFC_ATTR_R(nvmet_mrq_post,
3770 LPFC_NVMET_RQE_DEF_POST, LPFC_NVMET_RQE_MIN_POST,
3771 LPFC_NVMET_RQE_DEF_COUNT,
3772 "Specify number of RQ buffers to initially post");
3773
3774/*
James Smart895427b2017-02-12 13:52:30 -08003775 * lpfc_enable_fc4_type: Defines what FC4 types are supported.
3776 * Supported Values: 1 - register just FCP
3777 * 3 - register both FCP and NVME
James Smartb1684a02019-01-28 11:14:36 -08003778 * Supported values are [1,3]. Default value is 3
James Smart895427b2017-02-12 13:52:30 -08003779 */
James Smartb1684a02019-01-28 11:14:36 -08003780LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_BOTH,
James Smart895427b2017-02-12 13:52:30 -08003781 LPFC_ENABLE_FCP, LPFC_ENABLE_BOTH,
Dick Kennedycf4c8c82017-09-29 17:34:38 -07003782 "Enable FC4 Protocol support - FCP / NVME");
James Smart895427b2017-02-12 13:52:30 -08003783
3784/*
dea31012005-04-17 16:05:31 -05003785# lpfc_log_verbose: Only turn this flag on if you are willing to risk being
3786# deluged with LOTS of information.
3787# You can set a bit mask to record specific types of verbose messages:
James Smartf4b4c682009-05-22 14:53:12 -04003788# See lpfc_logmsh.h for definitions.
dea31012005-04-17 16:05:31 -05003789*/
James Smartf4b4c682009-05-22 14:53:12 -04003790LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffffffff,
James Smarte8b62012007-08-02 11:10:09 -04003791 "Verbose logging bit-mask");
dea31012005-04-17 16:05:31 -05003792
3793/*
James Smart7ee5d432007-10-27 13:37:17 -04003794# lpfc_enable_da_id: This turns on the DA_ID CT command that deregisters
3795# objects that have been registered with the nameserver after login.
3796*/
James Smartcf971242012-03-01 22:37:32 -05003797LPFC_VPORT_ATTR_R(enable_da_id, 1, 0, 1,
James Smart7ee5d432007-10-27 13:37:17 -04003798 "Deregister nameserver objects before LOGO");
3799
3800/*
dea31012005-04-17 16:05:31 -05003801# lun_queue_depth: This parameter is used to limit the number of outstanding
Dick Kennedy763a18c2020-03-23 09:19:35 -07003802# commands per FCP LUN.
dea31012005-04-17 16:05:31 -05003803*/
Dick Kennedy763a18c2020-03-23 09:19:35 -07003804LPFC_VPORT_ATTR_R(lun_queue_depth, 64, 1, 512,
James Smart3de2a652007-08-02 11:09:59 -04003805 "Max number of FCP commands we can queue to a specific LUN");
dea31012005-04-17 16:05:31 -05003806
3807/*
James Smart7dc517d2010-07-14 15:32:10 -04003808# tgt_queue_depth: This parameter is used to limit the number of outstanding
3809# commands per target port. Value range is [10,65535]. Default value is 65535.
3810*/
James Smartf91bc592018-04-09 14:24:22 -07003811static uint lpfc_tgt_queue_depth = LPFC_MAX_TGT_QDEPTH;
3812module_param(lpfc_tgt_queue_depth, uint, 0444);
3813MODULE_PARM_DESC(lpfc_tgt_queue_depth, "Set max Target queue depth");
3814lpfc_vport_param_show(tgt_queue_depth);
3815lpfc_vport_param_init(tgt_queue_depth, LPFC_MAX_TGT_QDEPTH,
3816 LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH);
3817
3818/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00003819 * lpfc_tgt_queue_depth_set: Sets an attribute value.
Lee Jonesa738bd92020-11-02 14:23:45 +00003820 * @vport: lpfc vport structure pointer.
James Smartf91bc592018-04-09 14:24:22 -07003821 * @val: integer attribute value.
3822 *
3823 * Description: Sets the parameter to the new value.
3824 *
3825 * Returns:
3826 * zero on success
3827 * -EINVAL if val is invalid
3828 */
3829static int
3830lpfc_tgt_queue_depth_set(struct lpfc_vport *vport, uint val)
3831{
3832 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3833 struct lpfc_nodelist *ndlp;
3834
3835 if (!lpfc_rangecheck(val, LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH))
3836 return -EINVAL;
3837
3838 if (val == vport->cfg_tgt_queue_depth)
3839 return 0;
3840
3841 spin_lock_irq(shost->host_lock);
3842 vport->cfg_tgt_queue_depth = val;
3843
3844 /* Next loop thru nodelist and change cmd_qdepth */
3845 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp)
3846 ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
3847
3848 spin_unlock_irq(shost->host_lock);
3849 return 0;
3850}
3851
3852lpfc_vport_param_store(tgt_queue_depth);
3853static DEVICE_ATTR_RW(lpfc_tgt_queue_depth);
James Smart7dc517d2010-07-14 15:32:10 -04003854
3855/*
Jamie Wellnitzb28485a2006-02-28 19:25:21 -05003856# hba_queue_depth: This parameter is used to limit the number of outstanding
3857# commands per lpfc HBA. Value range is [32,8192]. If this parameter
3858# value is greater than the maximum number of exchanges supported by the HBA,
3859# then maximum number of exchanges supported by the HBA is used to determine
3860# the hba_queue_depth.
3861*/
3862LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192,
3863 "Max number of FCP commands we can queue to a lpfc HBA");
3864
3865/*
James Smart92d7f7b2007-06-17 19:56:38 -05003866# peer_port_login: This parameter allows/prevents logins
3867# between peer ports hosted on the same physical port.
3868# When this parameter is set 0 peer ports of same physical port
3869# are not allowed to login to each other.
3870# When this parameter is set 1 peer ports of same physical port
3871# are allowed to login to each other.
3872# Default value of this parameter is 0.
3873*/
James Smart3de2a652007-08-02 11:09:59 -04003874LPFC_VPORT_ATTR_R(peer_port_login, 0, 0, 1,
3875 "Allow peer ports on the same physical port to login to each "
3876 "other.");
James Smart92d7f7b2007-06-17 19:56:38 -05003877
3878/*
James Smart3de2a652007-08-02 11:09:59 -04003879# restrict_login: This parameter allows/prevents logins
James Smart92d7f7b2007-06-17 19:56:38 -05003880# between Virtual Ports and remote initiators.
3881# When this parameter is not set (0) Virtual Ports will accept PLOGIs from
3882# other initiators and will attempt to PLOGI all remote ports.
3883# When this parameter is set (1) Virtual Ports will reject PLOGIs from
3884# remote ports and will not attempt to PLOGI to other initiators.
3885# This parameter does not restrict to the physical port.
3886# This parameter does not restrict logins to Fabric resident remote ports.
3887# Default value of this parameter is 1.
3888*/
James Smart3de2a652007-08-02 11:09:59 -04003889static int lpfc_restrict_login = 1;
James Smartab56dc22011-02-16 12:39:57 -05003890module_param(lpfc_restrict_login, int, S_IRUGO);
James Smart3de2a652007-08-02 11:09:59 -04003891MODULE_PARM_DESC(lpfc_restrict_login,
3892 "Restrict virtual ports login to remote initiators.");
3893lpfc_vport_param_show(restrict_login);
3894
James Smarte59058c2008-08-24 21:49:00 -04003895/**
James Smart3621a712009-04-06 18:47:14 -04003896 * lpfc_restrict_login_init - Set the vport restrict login flag
James Smarte59058c2008-08-24 21:49:00 -04003897 * @vport: lpfc vport structure pointer.
3898 * @val: contains the restrict login value.
3899 *
3900 * Description:
3901 * If val is not in a valid range then log a kernel error message and set
3902 * the vport restrict login to one.
3903 * If the port type is physical clear the restrict login flag and return.
3904 * Else set the restrict login flag to val.
3905 *
3906 * Returns:
3907 * zero if val is in range
3908 * -EINVAL val out of range
3909 **/
James Smart3de2a652007-08-02 11:09:59 -04003910static int
3911lpfc_restrict_login_init(struct lpfc_vport *vport, int val)
3912{
3913 if (val < 0 || val > 1) {
James Smarte8b62012007-08-02 11:10:09 -04003914 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartd7c255b2008-08-24 21:50:00 -04003915 "0422 lpfc_restrict_login attribute cannot "
James Smarte8b62012007-08-02 11:10:09 -04003916 "be set to %d, allowed range is [0, 1]\n",
3917 val);
James Smart3de2a652007-08-02 11:09:59 -04003918 vport->cfg_restrict_login = 1;
3919 return -EINVAL;
3920 }
3921 if (vport->port_type == LPFC_PHYSICAL_PORT) {
3922 vport->cfg_restrict_login = 0;
3923 return 0;
3924 }
3925 vport->cfg_restrict_login = val;
3926 return 0;
3927}
3928
James Smarte59058c2008-08-24 21:49:00 -04003929/**
James Smart3621a712009-04-06 18:47:14 -04003930 * lpfc_restrict_login_set - Set the vport restrict login flag
James Smarte59058c2008-08-24 21:49:00 -04003931 * @vport: lpfc vport structure pointer.
3932 * @val: contains the restrict login value.
3933 *
3934 * Description:
3935 * If val is not in a valid range then log a kernel error message and set
3936 * the vport restrict login to one.
3937 * If the port type is physical and the val is not zero log a kernel
3938 * error message, clear the restrict login flag and return zero.
3939 * Else set the restrict login flag to val.
3940 *
3941 * Returns:
3942 * zero if val is in range
3943 * -EINVAL val out of range
3944 **/
James Smart3de2a652007-08-02 11:09:59 -04003945static int
3946lpfc_restrict_login_set(struct lpfc_vport *vport, int val)
3947{
3948 if (val < 0 || val > 1) {
James Smarte8b62012007-08-02 11:10:09 -04003949 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartd7c255b2008-08-24 21:50:00 -04003950 "0425 lpfc_restrict_login attribute cannot "
James Smarte8b62012007-08-02 11:10:09 -04003951 "be set to %d, allowed range is [0, 1]\n",
3952 val);
James Smart3de2a652007-08-02 11:09:59 -04003953 vport->cfg_restrict_login = 1;
3954 return -EINVAL;
3955 }
3956 if (vport->port_type == LPFC_PHYSICAL_PORT && val != 0) {
James Smarte8b62012007-08-02 11:10:09 -04003957 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3958 "0468 lpfc_restrict_login must be 0 for "
3959 "Physical ports.\n");
James Smart3de2a652007-08-02 11:09:59 -04003960 vport->cfg_restrict_login = 0;
3961 return 0;
3962 }
3963 vport->cfg_restrict_login = val;
3964 return 0;
3965}
3966lpfc_vport_param_store(restrict_login);
Joe Perchesb6b996b2017-12-19 10:15:07 -08003967static DEVICE_ATTR_RW(lpfc_restrict_login);
James Smart92d7f7b2007-06-17 19:56:38 -05003968
3969/*
dea31012005-04-17 16:05:31 -05003970# Some disk devices have a "select ID" or "select Target" capability.
3971# From a protocol standpoint "select ID" usually means select the
3972# Fibre channel "ALPA". In the FC-AL Profile there is an "informative
3973# annex" which contains a table that maps a "select ID" (a number
3974# between 0 and 7F) to an ALPA. By default, for compatibility with
3975# older drivers, the lpfc driver scans this table from low ALPA to high
3976# ALPA.
3977#
3978# Turning on the scan-down variable (on = 1, off = 0) will
3979# cause the lpfc driver to use an inverted table, effectively
3980# scanning ALPAs from high to low. Value range is [0,1]. Default value is 1.
3981#
3982# (Note: This "select ID" functionality is a LOOP ONLY characteristic
3983# and will not work across a fabric. Also this parameter will take
3984# effect only in the case when ALPA map is not available.)
3985*/
James Smart3de2a652007-08-02 11:09:59 -04003986LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1,
3987 "Start scanning for devices from highest ALPA to lowest");
dea31012005-04-17 16:05:31 -05003988
3989/*
dea31012005-04-17 16:05:31 -05003990# lpfc_topology: link topology for init link
3991# 0x0 = attempt loop mode then point-to-point
Jamie Wellnitz367c2712006-02-28 19:25:32 -05003992# 0x01 = internal loopback mode
dea31012005-04-17 16:05:31 -05003993# 0x02 = attempt point-to-point mode only
3994# 0x04 = attempt loop mode only
3995# 0x06 = attempt point-to-point mode then loop
3996# Set point-to-point mode if you want to run as an N_Port.
3997# Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
3998# Default value is 0.
3999*/
James Smart0a035432016-10-13 15:06:10 -07004000LPFC_ATTR(topology, 0, 0, 6,
4001 "Select Fibre Channel topology");
James Smarte59058c2008-08-24 21:49:00 -04004002
4003/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00004004 * lpfc_topology_store - Set the adapters topology field
Lee Jonesa738bd92020-11-02 14:23:45 +00004005 * @dev: class device that is converted into a scsi_host.
4006 * @attr:device attribute, not used.
4007 * @buf: buffer for passing information.
4008 * @count: size of the data buffer.
James Smarte59058c2008-08-24 21:49:00 -04004009 *
4010 * Description:
4011 * If val is in a valid range then set the adapter's topology field and
4012 * issue a lip; if the lip fails reset the topology to the old value.
4013 *
4014 * If the value is not in range log a kernel error message and return an error.
4015 *
4016 * Returns:
4017 * zero if val is in range and lip okay
4018 * non-zero return value from lpfc_issue_lip()
4019 * -EINVAL val out of range
4020 **/
James Smarta257bf92009-04-06 18:48:10 -04004021static ssize_t
4022lpfc_topology_store(struct device *dev, struct device_attribute *attr,
4023 const char *buf, size_t count)
James Smart83108bd2008-01-11 01:53:09 -05004024{
James Smarta257bf92009-04-06 18:48:10 -04004025 struct Scsi_Host *shost = class_to_shost(dev);
4026 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4027 struct lpfc_hba *phba = vport->phba;
4028 int val = 0;
4029 int nolip = 0;
4030 const char *val_buf = buf;
James Smart83108bd2008-01-11 01:53:09 -05004031 int err;
4032 uint32_t prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004033
4034 if (!strncmp(buf, "nolip ", strlen("nolip "))) {
4035 nolip = 1;
4036 val_buf = &buf[strlen("nolip ")];
4037 }
4038
4039 if (!isdigit(val_buf[0]))
4040 return -EINVAL;
4041 if (sscanf(val_buf, "%i", &val) != 1)
4042 return -EINVAL;
4043
James Smart83108bd2008-01-11 01:53:09 -05004044 if (val >= 0 && val <= 6) {
4045 prev_val = phba->cfg_topology;
James Smartff78d8f2011-12-13 13:21:35 -05004046 if (phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G &&
4047 val == 4) {
4048 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4049 "3113 Loop mode not supported at speed %d\n",
James Smartd38dd522015-08-31 16:48:17 -04004050 val);
James Smartff78d8f2011-12-13 13:21:35 -05004051 return -EINVAL;
4052 }
James Smart83c6cb12019-10-18 14:18:30 -07004053 /*
4054 * The 'topology' is not a configurable parameter if :
4055 * - persistent topology enabled
James Smarta052ce82019-12-18 15:58:04 -08004056 * - G7/G6 with no private loop support
James Smart83c6cb12019-10-18 14:18:30 -07004057 */
4058
James Smarta052ce82019-12-18 15:58:04 -08004059 if ((phba->hba_flag & HBA_PERSISTENT_TOPO ||
James Smart83c6cb12019-10-18 14:18:30 -07004060 (!phba->sli4_hba.pc_sli4_params.pls &&
James Smarta052ce82019-12-18 15:58:04 -08004061 (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC ||
4062 phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC))) &&
James Smartf6978f42019-05-21 17:48:57 -07004063 val == 4) {
James Smartd38dd522015-08-31 16:48:17 -04004064 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartf6978f42019-05-21 17:48:57 -07004065 "3114 Loop mode not supported\n");
James Smartd38dd522015-08-31 16:48:17 -04004066 return -EINVAL;
4067 }
4068 phba->cfg_topology = val;
James Smarta257bf92009-04-06 18:48:10 -04004069 if (nolip)
4070 return strlen(buf);
4071
James Smart88a2cfb2011-07-22 18:36:33 -04004072 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4073 "3054 lpfc_topology changed from %d to %d\n",
4074 prev_val, val);
James Smarte74c03c2013-04-17 20:15:19 -04004075 if (prev_val != val && phba->sli_rev == LPFC_SLI_REV4)
4076 phba->fc_topology_changed = 1;
James Smart83108bd2008-01-11 01:53:09 -05004077 err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
James Smarta257bf92009-04-06 18:48:10 -04004078 if (err) {
James Smart83108bd2008-01-11 01:53:09 -05004079 phba->cfg_topology = prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004080 return -EINVAL;
4081 } else
4082 return strlen(buf);
James Smart83108bd2008-01-11 01:53:09 -05004083 }
4084 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4085 "%d:0467 lpfc_topology attribute cannot be set to %d, "
4086 "allowed range is [0, 6]\n",
4087 phba->brd_no, val);
4088 return -EINVAL;
4089}
James Smart0a035432016-10-13 15:06:10 -07004090
James Smart83108bd2008-01-11 01:53:09 -05004091lpfc_param_show(topology)
Joe Perchesb6b996b2017-12-19 10:15:07 -08004092static DEVICE_ATTR_RW(lpfc_topology);
dea31012005-04-17 16:05:31 -05004093
James Smart21e9a0a2009-05-22 14:53:21 -04004094/**
4095 * lpfc_static_vport_show: Read callback function for
4096 * lpfc_static_vport sysfs file.
4097 * @dev: Pointer to class device object.
4098 * @attr: device attribute structure.
4099 * @buf: Data buffer.
4100 *
4101 * This function is the read call back function for
4102 * lpfc_static_vport sysfs file. The lpfc_static_vport
4103 * sysfs file report the mageability of the vport.
4104 **/
4105static ssize_t
4106lpfc_static_vport_show(struct device *dev, struct device_attribute *attr,
4107 char *buf)
4108{
4109 struct Scsi_Host *shost = class_to_shost(dev);
4110 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4111 if (vport->vport_flag & STATIC_VPORT)
4112 sprintf(buf, "1\n");
4113 else
4114 sprintf(buf, "0\n");
4115
4116 return strlen(buf);
4117}
4118
4119/*
4120 * Sysfs attribute to control the statistical data collection.
4121 */
Joe Perchesc828a892017-12-19 10:15:08 -08004122static DEVICE_ATTR_RO(lpfc_static_vport);
James Smartea2151b2008-09-07 11:52:10 -04004123
4124/**
James Smart3621a712009-04-06 18:47:14 -04004125 * lpfc_stat_data_ctrl_store - write call back for lpfc_stat_data_ctrl sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004126 * @dev: Pointer to class device.
Lee Jonesa738bd92020-11-02 14:23:45 +00004127 * @attr: Unused.
James Smartea2151b2008-09-07 11:52:10 -04004128 * @buf: Data buffer.
4129 * @count: Size of the data buffer.
4130 *
Masahiro Yamada9332ef92017-02-27 14:28:47 -08004131 * This function get called when a user write to the lpfc_stat_data_ctrl
James Smartea2151b2008-09-07 11:52:10 -04004132 * sysfs file. This function parse the command written to the sysfs file
4133 * and take appropriate action. These commands are used for controlling
4134 * driver statistical data collection.
4135 * Following are the command this function handles.
4136 *
4137 * setbucket <bucket_type> <base> <step>
4138 * = Set the latency buckets.
4139 * destroybucket = destroy all the buckets.
4140 * start = start data collection
4141 * stop = stop data collection
4142 * reset = reset the collected data
4143 **/
4144static ssize_t
4145lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
4146 const char *buf, size_t count)
4147{
4148 struct Scsi_Host *shost = class_to_shost(dev);
4149 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4150 struct lpfc_hba *phba = vport->phba;
4151#define LPFC_MAX_DATA_CTRL_LEN 1024
4152 static char bucket_data[LPFC_MAX_DATA_CTRL_LEN];
4153 unsigned long i;
4154 char *str_ptr, *token;
4155 struct lpfc_vport **vports;
4156 struct Scsi_Host *v_shost;
4157 char *bucket_type_str, *base_str, *step_str;
4158 unsigned long base, step, bucket_type;
4159
4160 if (!strncmp(buf, "setbucket", strlen("setbucket"))) {
James Smarta257bf92009-04-06 18:48:10 -04004161 if (strlen(buf) > (LPFC_MAX_DATA_CTRL_LEN - 1))
James Smartea2151b2008-09-07 11:52:10 -04004162 return -EINVAL;
4163
James Smarteb016562014-09-03 12:58:06 -04004164 strncpy(bucket_data, buf, LPFC_MAX_DATA_CTRL_LEN);
James Smartea2151b2008-09-07 11:52:10 -04004165 str_ptr = &bucket_data[0];
4166 /* Ignore this token - this is command token */
4167 token = strsep(&str_ptr, "\t ");
4168 if (!token)
4169 return -EINVAL;
4170
4171 bucket_type_str = strsep(&str_ptr, "\t ");
4172 if (!bucket_type_str)
4173 return -EINVAL;
4174
4175 if (!strncmp(bucket_type_str, "linear", strlen("linear")))
4176 bucket_type = LPFC_LINEAR_BUCKET;
4177 else if (!strncmp(bucket_type_str, "power2", strlen("power2")))
4178 bucket_type = LPFC_POWER2_BUCKET;
4179 else
4180 return -EINVAL;
4181
4182 base_str = strsep(&str_ptr, "\t ");
4183 if (!base_str)
4184 return -EINVAL;
4185 base = simple_strtoul(base_str, NULL, 0);
4186
4187 step_str = strsep(&str_ptr, "\t ");
4188 if (!step_str)
4189 return -EINVAL;
4190 step = simple_strtoul(step_str, NULL, 0);
4191 if (!step)
4192 return -EINVAL;
4193
4194 /* Block the data collection for every vport */
4195 vports = lpfc_create_vport_work_array(phba);
4196 if (vports == NULL)
4197 return -ENOMEM;
4198
James Smartf4b4c682009-05-22 14:53:12 -04004199 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004200 v_shost = lpfc_shost_from_vport(vports[i]);
4201 spin_lock_irq(v_shost->host_lock);
4202 /* Block and reset data collection */
4203 vports[i]->stat_data_blocked = 1;
4204 if (vports[i]->stat_data_enabled)
4205 lpfc_vport_reset_stat_data(vports[i]);
4206 spin_unlock_irq(v_shost->host_lock);
4207 }
4208
4209 /* Set the bucket attributes */
4210 phba->bucket_type = bucket_type;
4211 phba->bucket_base = base;
4212 phba->bucket_step = step;
4213
James Smartf4b4c682009-05-22 14:53:12 -04004214 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004215 v_shost = lpfc_shost_from_vport(vports[i]);
4216
4217 /* Unblock data collection */
4218 spin_lock_irq(v_shost->host_lock);
4219 vports[i]->stat_data_blocked = 0;
4220 spin_unlock_irq(v_shost->host_lock);
4221 }
4222 lpfc_destroy_vport_work_array(phba, vports);
4223 return strlen(buf);
4224 }
4225
4226 if (!strncmp(buf, "destroybucket", strlen("destroybucket"))) {
4227 vports = lpfc_create_vport_work_array(phba);
4228 if (vports == NULL)
4229 return -ENOMEM;
4230
James Smartf4b4c682009-05-22 14:53:12 -04004231 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004232 v_shost = lpfc_shost_from_vport(vports[i]);
4233 spin_lock_irq(shost->host_lock);
4234 vports[i]->stat_data_blocked = 1;
4235 lpfc_free_bucket(vport);
4236 vport->stat_data_enabled = 0;
4237 vports[i]->stat_data_blocked = 0;
4238 spin_unlock_irq(shost->host_lock);
4239 }
4240 lpfc_destroy_vport_work_array(phba, vports);
4241 phba->bucket_type = LPFC_NO_BUCKET;
4242 phba->bucket_base = 0;
4243 phba->bucket_step = 0;
4244 return strlen(buf);
4245 }
4246
4247 if (!strncmp(buf, "start", strlen("start"))) {
4248 /* If no buckets configured return error */
4249 if (phba->bucket_type == LPFC_NO_BUCKET)
4250 return -EINVAL;
4251 spin_lock_irq(shost->host_lock);
4252 if (vport->stat_data_enabled) {
4253 spin_unlock_irq(shost->host_lock);
4254 return strlen(buf);
4255 }
4256 lpfc_alloc_bucket(vport);
4257 vport->stat_data_enabled = 1;
4258 spin_unlock_irq(shost->host_lock);
4259 return strlen(buf);
4260 }
4261
4262 if (!strncmp(buf, "stop", strlen("stop"))) {
4263 spin_lock_irq(shost->host_lock);
4264 if (vport->stat_data_enabled == 0) {
4265 spin_unlock_irq(shost->host_lock);
4266 return strlen(buf);
4267 }
4268 lpfc_free_bucket(vport);
4269 vport->stat_data_enabled = 0;
4270 spin_unlock_irq(shost->host_lock);
4271 return strlen(buf);
4272 }
4273
4274 if (!strncmp(buf, "reset", strlen("reset"))) {
4275 if ((phba->bucket_type == LPFC_NO_BUCKET)
4276 || !vport->stat_data_enabled)
4277 return strlen(buf);
4278 spin_lock_irq(shost->host_lock);
4279 vport->stat_data_blocked = 1;
4280 lpfc_vport_reset_stat_data(vport);
4281 vport->stat_data_blocked = 0;
4282 spin_unlock_irq(shost->host_lock);
4283 return strlen(buf);
4284 }
4285 return -EINVAL;
4286}
4287
4288
4289/**
James Smart3621a712009-04-06 18:47:14 -04004290 * lpfc_stat_data_ctrl_show - Read function for lpfc_stat_data_ctrl sysfs file
Lee Jonesa738bd92020-11-02 14:23:45 +00004291 * @dev: Pointer to class device.
4292 * @attr: Unused.
James Smartea2151b2008-09-07 11:52:10 -04004293 * @buf: Data buffer.
4294 *
4295 * This function is the read call back function for
4296 * lpfc_stat_data_ctrl sysfs file. This function report the
4297 * current statistical data collection state.
4298 **/
4299static ssize_t
4300lpfc_stat_data_ctrl_show(struct device *dev, struct device_attribute *attr,
4301 char *buf)
4302{
4303 struct Scsi_Host *shost = class_to_shost(dev);
4304 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4305 struct lpfc_hba *phba = vport->phba;
4306 int index = 0;
4307 int i;
4308 char *bucket_type;
4309 unsigned long bucket_value;
4310
4311 switch (phba->bucket_type) {
4312 case LPFC_LINEAR_BUCKET:
4313 bucket_type = "linear";
4314 break;
4315 case LPFC_POWER2_BUCKET:
4316 bucket_type = "power2";
4317 break;
4318 default:
4319 bucket_type = "No Bucket";
4320 break;
4321 }
4322
4323 sprintf(&buf[index], "Statistical Data enabled :%d, "
4324 "blocked :%d, Bucket type :%s, Bucket base :%d,"
4325 " Bucket step :%d\nLatency Ranges :",
4326 vport->stat_data_enabled, vport->stat_data_blocked,
4327 bucket_type, phba->bucket_base, phba->bucket_step);
4328 index = strlen(buf);
4329 if (phba->bucket_type != LPFC_NO_BUCKET) {
4330 for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
4331 if (phba->bucket_type == LPFC_LINEAR_BUCKET)
4332 bucket_value = phba->bucket_base +
4333 phba->bucket_step * i;
4334 else
4335 bucket_value = phba->bucket_base +
4336 (1 << i) * phba->bucket_step;
4337
4338 if (index + 10 > PAGE_SIZE)
4339 break;
4340 sprintf(&buf[index], "%08ld ", bucket_value);
4341 index = strlen(buf);
4342 }
4343 }
4344 sprintf(&buf[index], "\n");
4345 return strlen(buf);
4346}
4347
4348/*
4349 * Sysfs attribute to control the statistical data collection.
4350 */
Joe Perchesb6b996b2017-12-19 10:15:07 -08004351static DEVICE_ATTR_RW(lpfc_stat_data_ctrl);
James Smartea2151b2008-09-07 11:52:10 -04004352
4353/*
4354 * lpfc_drvr_stat_data: sysfs attr to get driver statistical data.
4355 */
4356
4357/*
4358 * Each Bucket takes 11 characters and 1 new line + 17 bytes WWN
4359 * for each target.
4360 */
4361#define STAT_DATA_SIZE_PER_TARGET(NUM_BUCKETS) ((NUM_BUCKETS) * 11 + 18)
4362#define MAX_STAT_DATA_SIZE_PER_TARGET \
4363 STAT_DATA_SIZE_PER_TARGET(LPFC_MAX_BUCKET_COUNT)
4364
4365
4366/**
James Smart3621a712009-04-06 18:47:14 -04004367 * sysfs_drvr_stat_data_read - Read function for lpfc_drvr_stat_data attribute
Chris Wright2c3c8be2010-05-12 18:28:57 -07004368 * @filp: sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004369 * @kobj: Pointer to the kernel object
4370 * @bin_attr: Attribute object
Lee Jonesa738bd92020-11-02 14:23:45 +00004371 * @buf: Buffer pointer
James Smartea2151b2008-09-07 11:52:10 -04004372 * @off: File offset
4373 * @count: Buffer size
4374 *
4375 * This function is the read call back function for lpfc_drvr_stat_data
4376 * sysfs file. This function export the statistical data to user
4377 * applications.
4378 **/
4379static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07004380sysfs_drvr_stat_data_read(struct file *filp, struct kobject *kobj,
4381 struct bin_attribute *bin_attr,
James Smartea2151b2008-09-07 11:52:10 -04004382 char *buf, loff_t off, size_t count)
4383{
4384 struct device *dev = container_of(kobj, struct device,
4385 kobj);
4386 struct Scsi_Host *shost = class_to_shost(dev);
4387 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4388 struct lpfc_hba *phba = vport->phba;
4389 int i = 0, index = 0;
4390 unsigned long nport_index;
4391 struct lpfc_nodelist *ndlp = NULL;
4392 nport_index = (unsigned long)off /
4393 MAX_STAT_DATA_SIZE_PER_TARGET;
4394
4395 if (!vport->stat_data_enabled || vport->stat_data_blocked
4396 || (phba->bucket_type == LPFC_NO_BUCKET))
4397 return 0;
4398
4399 spin_lock_irq(shost->host_lock);
4400 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart307e3382020-11-15 11:26:30 -08004401 if (!ndlp->lat_data)
James Smartea2151b2008-09-07 11:52:10 -04004402 continue;
4403
4404 if (nport_index > 0) {
4405 nport_index--;
4406 continue;
4407 }
4408
4409 if ((index + MAX_STAT_DATA_SIZE_PER_TARGET)
4410 > count)
4411 break;
4412
4413 if (!ndlp->lat_data)
4414 continue;
4415
4416 /* Print the WWN */
4417 sprintf(&buf[index], "%02x%02x%02x%02x%02x%02x%02x%02x:",
4418 ndlp->nlp_portname.u.wwn[0],
4419 ndlp->nlp_portname.u.wwn[1],
4420 ndlp->nlp_portname.u.wwn[2],
4421 ndlp->nlp_portname.u.wwn[3],
4422 ndlp->nlp_portname.u.wwn[4],
4423 ndlp->nlp_portname.u.wwn[5],
4424 ndlp->nlp_portname.u.wwn[6],
4425 ndlp->nlp_portname.u.wwn[7]);
4426
4427 index = strlen(buf);
4428
4429 for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
4430 sprintf(&buf[index], "%010u,",
4431 ndlp->lat_data[i].cmd_count);
4432 index = strlen(buf);
4433 }
4434 sprintf(&buf[index], "\n");
4435 index = strlen(buf);
4436 }
4437 spin_unlock_irq(shost->host_lock);
4438 return index;
4439}
4440
4441static struct bin_attribute sysfs_drvr_stat_data_attr = {
4442 .attr = {
4443 .name = "lpfc_drvr_stat_data",
4444 .mode = S_IRUSR,
James Smartea2151b2008-09-07 11:52:10 -04004445 },
4446 .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET,
4447 .read = sysfs_drvr_stat_data_read,
4448 .write = NULL,
4449};
4450
dea31012005-04-17 16:05:31 -05004451/*
4452# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
4453# connection.
James Smart76a95d72010-11-20 23:11:48 -05004454# Value range is [0,16]. Default value is 0.
dea31012005-04-17 16:05:31 -05004455*/
James Smarte59058c2008-08-24 21:49:00 -04004456/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00004457 * lpfc_link_speed_store - Set the adapters link speed
Lee Jonesa738bd92020-11-02 14:23:45 +00004458 * @dev: Pointer to class device.
4459 * @attr: Unused.
4460 * @buf: Data buffer.
4461 * @count: Size of the data buffer.
James Smarte59058c2008-08-24 21:49:00 -04004462 *
4463 * Description:
4464 * If val is in a valid range then set the adapter's link speed field and
4465 * issue a lip; if the lip fails reset the link speed to the old value.
4466 *
4467 * Notes:
4468 * If the value is not in range log a kernel error message and return an error.
4469 *
4470 * Returns:
4471 * zero if val is in range and lip okay.
4472 * non-zero return value from lpfc_issue_lip()
4473 * -EINVAL val out of range
4474 **/
James Smarta257bf92009-04-06 18:48:10 -04004475static ssize_t
4476lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
4477 const char *buf, size_t count)
James Smart83108bd2008-01-11 01:53:09 -05004478{
James Smarta257bf92009-04-06 18:48:10 -04004479 struct Scsi_Host *shost = class_to_shost(dev);
4480 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4481 struct lpfc_hba *phba = vport->phba;
James Smart76a95d72010-11-20 23:11:48 -05004482 int val = LPFC_USER_LINK_SPEED_AUTO;
James Smarta257bf92009-04-06 18:48:10 -04004483 int nolip = 0;
4484 const char *val_buf = buf;
James Smart83108bd2008-01-11 01:53:09 -05004485 int err;
James Smartc6918162016-10-13 15:06:16 -07004486 uint32_t prev_val, if_type;
4487
4488 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
James Smart719162b2018-12-10 19:37:01 -08004489 if (if_type >= LPFC_SLI_INTF_IF_TYPE_2 &&
James Smartc6918162016-10-13 15:06:16 -07004490 phba->hba_flag & HBA_FORCED_LINK_SPEED)
4491 return -EPERM;
James Smart83108bd2008-01-11 01:53:09 -05004492
James Smarta257bf92009-04-06 18:48:10 -04004493 if (!strncmp(buf, "nolip ", strlen("nolip "))) {
4494 nolip = 1;
4495 val_buf = &buf[strlen("nolip ")];
4496 }
4497
4498 if (!isdigit(val_buf[0]))
4499 return -EINVAL;
4500 if (sscanf(val_buf, "%i", &val) != 1)
4501 return -EINVAL;
4502
James Smart88a2cfb2011-07-22 18:36:33 -04004503 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4504 "3055 lpfc_link_speed changed from %d to %d %s\n",
4505 phba->cfg_link_speed, val, nolip ? "(nolip)" : "(lip)");
4506
James Smart76a95d72010-11-20 23:11:48 -05004507 if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
4508 ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
4509 ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
4510 ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
4511 ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
James Smartd38dd522015-08-31 16:48:17 -04004512 ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
James Smartfbd8a6b2018-02-22 08:18:45 -08004513 ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
4514 ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
James Smart76a95d72010-11-20 23:11:48 -05004515 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4516 "2879 lpfc_link_speed attribute cannot be set "
4517 "to %d. Speed is not supported by this port.\n",
4518 val);
James Smart83108bd2008-01-11 01:53:09 -05004519 return -EINVAL;
James Smart76a95d72010-11-20 23:11:48 -05004520 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004521 if (val >= LPFC_USER_LINK_SPEED_16G &&
4522 phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smartff78d8f2011-12-13 13:21:35 -05004523 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4524 "3112 lpfc_link_speed attribute cannot be set "
4525 "to %d. Speed is not supported in loop mode.\n",
4526 val);
4527 return -EINVAL;
4528 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004529
4530 switch (val) {
4531 case LPFC_USER_LINK_SPEED_AUTO:
4532 case LPFC_USER_LINK_SPEED_1G:
4533 case LPFC_USER_LINK_SPEED_2G:
4534 case LPFC_USER_LINK_SPEED_4G:
4535 case LPFC_USER_LINK_SPEED_8G:
4536 case LPFC_USER_LINK_SPEED_16G:
4537 case LPFC_USER_LINK_SPEED_32G:
4538 case LPFC_USER_LINK_SPEED_64G:
James Smart83108bd2008-01-11 01:53:09 -05004539 prev_val = phba->cfg_link_speed;
4540 phba->cfg_link_speed = val;
James Smarta257bf92009-04-06 18:48:10 -04004541 if (nolip)
4542 return strlen(buf);
4543
James Smart83108bd2008-01-11 01:53:09 -05004544 err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
James Smarta257bf92009-04-06 18:48:10 -04004545 if (err) {
James Smart83108bd2008-01-11 01:53:09 -05004546 phba->cfg_link_speed = prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004547 return -EINVAL;
James Smartfbd8a6b2018-02-22 08:18:45 -08004548 }
4549 return strlen(buf);
4550 default:
4551 break;
James Smart83108bd2008-01-11 01:53:09 -05004552 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004553
James Smart83108bd2008-01-11 01:53:09 -05004554 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smartfbd8a6b2018-02-22 08:18:45 -08004555 "0469 lpfc_link_speed attribute cannot be set to %d, "
4556 "allowed values are [%s]\n",
4557 val, LPFC_LINK_SPEED_STRING);
James Smart83108bd2008-01-11 01:53:09 -05004558 return -EINVAL;
James Smartfbd8a6b2018-02-22 08:18:45 -08004559
James Smart83108bd2008-01-11 01:53:09 -05004560}
4561
4562static int lpfc_link_speed = 0;
James Smartab56dc22011-02-16 12:39:57 -05004563module_param(lpfc_link_speed, int, S_IRUGO);
James Smart83108bd2008-01-11 01:53:09 -05004564MODULE_PARM_DESC(lpfc_link_speed, "Select link speed");
4565lpfc_param_show(link_speed)
James Smarte59058c2008-08-24 21:49:00 -04004566
4567/**
James Smart3621a712009-04-06 18:47:14 -04004568 * lpfc_link_speed_init - Set the adapters link speed
James Smarte59058c2008-08-24 21:49:00 -04004569 * @phba: lpfc_hba pointer.
4570 * @val: link speed value.
4571 *
4572 * Description:
4573 * If val is in a valid range then set the adapter's link speed field.
4574 *
4575 * Notes:
4576 * If the value is not in range log a kernel error message, clear the link
4577 * speed and return an error.
4578 *
4579 * Returns:
4580 * zero if val saved.
4581 * -EINVAL val out of range
4582 **/
James Smart83108bd2008-01-11 01:53:09 -05004583static int
4584lpfc_link_speed_init(struct lpfc_hba *phba, int val)
4585{
James Smartfbd8a6b2018-02-22 08:18:45 -08004586 if (val >= LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) {
James Smartff78d8f2011-12-13 13:21:35 -05004587 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4588 "3111 lpfc_link_speed of %d cannot "
4589 "support loop mode, setting topology to default.\n",
4590 val);
4591 phba->cfg_topology = 0;
4592 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004593
4594 switch (val) {
4595 case LPFC_USER_LINK_SPEED_AUTO:
4596 case LPFC_USER_LINK_SPEED_1G:
4597 case LPFC_USER_LINK_SPEED_2G:
4598 case LPFC_USER_LINK_SPEED_4G:
4599 case LPFC_USER_LINK_SPEED_8G:
4600 case LPFC_USER_LINK_SPEED_16G:
4601 case LPFC_USER_LINK_SPEED_32G:
4602 case LPFC_USER_LINK_SPEED_64G:
James Smart83108bd2008-01-11 01:53:09 -05004603 phba->cfg_link_speed = val;
4604 return 0;
James Smartfbd8a6b2018-02-22 08:18:45 -08004605 default:
4606 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4607 "0405 lpfc_link_speed attribute cannot "
4608 "be set to %d, allowed values are "
4609 "["LPFC_LINK_SPEED_STRING"]\n", val);
4610 phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
4611 return -EINVAL;
James Smart83108bd2008-01-11 01:53:09 -05004612 }
James Smart83108bd2008-01-11 01:53:09 -05004613}
4614
Joe Perchesb6b996b2017-12-19 10:15:07 -08004615static DEVICE_ATTR_RW(lpfc_link_speed);
dea31012005-04-17 16:05:31 -05004616
4617/*
James Smart0d878412009-10-02 15:16:56 -04004618# lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
4619# 0 = aer disabled or not supported
4620# 1 = aer supported and enabled (default)
4621# Value range is [0,1]. Default value is 1.
4622*/
James Smart506139a2016-10-13 15:06:09 -07004623LPFC_ATTR(aer_support, 1, 0, 1,
4624 "Enable PCIe device AER support");
4625lpfc_param_show(aer_support)
James Smart0d878412009-10-02 15:16:56 -04004626
4627/**
4628 * lpfc_aer_support_store - Set the adapter for aer support
4629 *
4630 * @dev: class device that is converted into a Scsi_host.
4631 * @attr: device attribute, not used.
James Smart912e3ac2011-05-24 11:42:11 -04004632 * @buf: containing enable or disable aer flag.
James Smart0d878412009-10-02 15:16:56 -04004633 * @count: unused variable.
4634 *
4635 * Description:
4636 * If the val is 1 and currently the device's AER capability was not
4637 * enabled, invoke the kernel's enable AER helper routine, trying to
4638 * enable the device's AER capability. If the helper routine enabling
4639 * AER returns success, update the device's cfg_aer_support flag to
4640 * indicate AER is supported by the device; otherwise, if the device
4641 * AER capability is already enabled to support AER, then do nothing.
4642 *
4643 * If the val is 0 and currently the device's AER support was enabled,
4644 * invoke the kernel's disable AER helper routine. After that, update
4645 * the device's cfg_aer_support flag to indicate AER is not supported
4646 * by the device; otherwise, if the device AER capability is already
4647 * disabled from supporting AER, then do nothing.
4648 *
4649 * Returns:
4650 * length of the buf on success if val is in range the intended mode
4651 * is supported.
4652 * -EINVAL if val out of range or intended mode is not supported.
4653 **/
4654static ssize_t
4655lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
4656 const char *buf, size_t count)
4657{
4658 struct Scsi_Host *shost = class_to_shost(dev);
4659 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4660 struct lpfc_hba *phba = vport->phba;
4661 int val = 0, rc = -EINVAL;
4662
4663 if (!isdigit(buf[0]))
4664 return -EINVAL;
4665 if (sscanf(buf, "%i", &val) != 1)
4666 return -EINVAL;
4667
4668 switch (val) {
4669 case 0:
4670 if (phba->hba_flag & HBA_AER_ENABLED) {
4671 rc = pci_disable_pcie_error_reporting(phba->pcidev);
4672 if (!rc) {
4673 spin_lock_irq(&phba->hbalock);
4674 phba->hba_flag &= ~HBA_AER_ENABLED;
4675 spin_unlock_irq(&phba->hbalock);
4676 phba->cfg_aer_support = 0;
4677 rc = strlen(buf);
4678 } else
James Smart891478a2009-11-18 15:40:23 -05004679 rc = -EPERM;
4680 } else {
James Smart0d878412009-10-02 15:16:56 -04004681 phba->cfg_aer_support = 0;
James Smart891478a2009-11-18 15:40:23 -05004682 rc = strlen(buf);
4683 }
James Smart0d878412009-10-02 15:16:56 -04004684 break;
4685 case 1:
4686 if (!(phba->hba_flag & HBA_AER_ENABLED)) {
4687 rc = pci_enable_pcie_error_reporting(phba->pcidev);
4688 if (!rc) {
4689 spin_lock_irq(&phba->hbalock);
4690 phba->hba_flag |= HBA_AER_ENABLED;
4691 spin_unlock_irq(&phba->hbalock);
4692 phba->cfg_aer_support = 1;
4693 rc = strlen(buf);
4694 } else
James Smart891478a2009-11-18 15:40:23 -05004695 rc = -EPERM;
4696 } else {
James Smart0d878412009-10-02 15:16:56 -04004697 phba->cfg_aer_support = 1;
James Smart891478a2009-11-18 15:40:23 -05004698 rc = strlen(buf);
4699 }
James Smart0d878412009-10-02 15:16:56 -04004700 break;
4701 default:
4702 rc = -EINVAL;
4703 break;
4704 }
4705 return rc;
4706}
4707
Joe Perchesb6b996b2017-12-19 10:15:07 -08004708static DEVICE_ATTR_RW(lpfc_aer_support);
James Smart0d878412009-10-02 15:16:56 -04004709
4710/**
4711 * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device
4712 * @dev: class device that is converted into a Scsi_host.
4713 * @attr: device attribute, not used.
James Smart912e3ac2011-05-24 11:42:11 -04004714 * @buf: containing flag 1 for aer cleanup state.
James Smart0d878412009-10-02 15:16:56 -04004715 * @count: unused variable.
4716 *
4717 * Description:
4718 * If the @buf contains 1 and the device currently has the AER support
4719 * enabled, then invokes the kernel AER helper routine
Kuppuswamy Sathyanarayanan894020f2020-03-23 17:26:08 -07004720 * pci_aer_clear_nonfatal_status() to clean up the uncorrectable
James Smart0d878412009-10-02 15:16:56 -04004721 * error status register.
4722 *
4723 * Notes:
4724 *
4725 * Returns:
4726 * -EINVAL if the buf does not contain the 1 or the device is not currently
4727 * enabled with the AER support.
4728 **/
4729static ssize_t
4730lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr,
4731 const char *buf, size_t count)
4732{
4733 struct Scsi_Host *shost = class_to_shost(dev);
4734 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4735 struct lpfc_hba *phba = vport->phba;
4736 int val, rc = -1;
4737
4738 if (!isdigit(buf[0]))
4739 return -EINVAL;
4740 if (sscanf(buf, "%i", &val) != 1)
4741 return -EINVAL;
James Smart891478a2009-11-18 15:40:23 -05004742 if (val != 1)
4743 return -EINVAL;
James Smart0d878412009-10-02 15:16:56 -04004744
James Smart891478a2009-11-18 15:40:23 -05004745 if (phba->hba_flag & HBA_AER_ENABLED)
Kuppuswamy Sathyanarayanan894020f2020-03-23 17:26:08 -07004746 rc = pci_aer_clear_nonfatal_status(phba->pcidev);
James Smart0d878412009-10-02 15:16:56 -04004747
4748 if (rc == 0)
4749 return strlen(buf);
4750 else
James Smart891478a2009-11-18 15:40:23 -05004751 return -EPERM;
James Smart0d878412009-10-02 15:16:56 -04004752}
4753
4754static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
4755 lpfc_aer_cleanup_state);
4756
James Smart912e3ac2011-05-24 11:42:11 -04004757/**
4758 * lpfc_sriov_nr_virtfn_store - Enable the adapter for sr-iov virtual functions
4759 *
4760 * @dev: class device that is converted into a Scsi_host.
4761 * @attr: device attribute, not used.
4762 * @buf: containing the string the number of vfs to be enabled.
4763 * @count: unused variable.
4764 *
4765 * Description:
4766 * When this api is called either through user sysfs, the driver shall
4767 * try to enable or disable SR-IOV virtual functions according to the
4768 * following:
4769 *
4770 * If zero virtual function has been enabled to the physical function,
4771 * the driver shall invoke the pci enable virtual function api trying
4772 * to enable the virtual functions. If the nr_vfn provided is greater
4773 * than the maximum supported, the maximum virtual function number will
4774 * be used for invoking the api; otherwise, the nr_vfn provided shall
4775 * be used for invoking the api. If the api call returned success, the
4776 * actual number of virtual functions enabled will be set to the driver
4777 * cfg_sriov_nr_virtfn; otherwise, -EINVAL shall be returned and driver
4778 * cfg_sriov_nr_virtfn remains zero.
4779 *
4780 * If none-zero virtual functions have already been enabled to the
4781 * physical function, as reflected by the driver's cfg_sriov_nr_virtfn,
4782 * -EINVAL will be returned and the driver does nothing;
4783 *
4784 * If the nr_vfn provided is zero and none-zero virtual functions have
4785 * been enabled, as indicated by the driver's cfg_sriov_nr_virtfn, the
4786 * disabling virtual function api shall be invoded to disable all the
4787 * virtual functions and driver's cfg_sriov_nr_virtfn shall be set to
4788 * zero. Otherwise, if zero virtual function has been enabled, do
4789 * nothing.
4790 *
4791 * Returns:
4792 * length of the buf on success if val is in range the intended mode
4793 * is supported.
4794 * -EINVAL if val out of range or intended mode is not supported.
4795 **/
4796static ssize_t
4797lpfc_sriov_nr_virtfn_store(struct device *dev, struct device_attribute *attr,
4798 const char *buf, size_t count)
4799{
4800 struct Scsi_Host *shost = class_to_shost(dev);
4801 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4802 struct lpfc_hba *phba = vport->phba;
4803 struct pci_dev *pdev = phba->pcidev;
4804 int val = 0, rc = -EINVAL;
4805
4806 /* Sanity check on user data */
4807 if (!isdigit(buf[0]))
4808 return -EINVAL;
4809 if (sscanf(buf, "%i", &val) != 1)
4810 return -EINVAL;
4811 if (val < 0)
4812 return -EINVAL;
4813
4814 /* Request disabling virtual functions */
4815 if (val == 0) {
4816 if (phba->cfg_sriov_nr_virtfn > 0) {
4817 pci_disable_sriov(pdev);
4818 phba->cfg_sriov_nr_virtfn = 0;
4819 }
4820 return strlen(buf);
4821 }
4822
4823 /* Request enabling virtual functions */
4824 if (phba->cfg_sriov_nr_virtfn > 0) {
4825 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4826 "3018 There are %d virtual functions "
4827 "enabled on physical function.\n",
4828 phba->cfg_sriov_nr_virtfn);
4829 return -EEXIST;
4830 }
4831
4832 if (val <= LPFC_MAX_VFN_PER_PFN)
4833 phba->cfg_sriov_nr_virtfn = val;
4834 else {
4835 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4836 "3019 Enabling %d virtual functions is not "
4837 "allowed.\n", val);
4838 return -EINVAL;
4839 }
4840
4841 rc = lpfc_sli_probe_sriov_nr_virtfn(phba, phba->cfg_sriov_nr_virtfn);
4842 if (rc) {
4843 phba->cfg_sriov_nr_virtfn = 0;
4844 rc = -EPERM;
4845 } else
4846 rc = strlen(buf);
4847
4848 return rc;
4849}
4850
James Smart0cfbbf22016-10-13 15:06:12 -07004851LPFC_ATTR(sriov_nr_virtfn, LPFC_DEF_VFN_PER_PFN, 0, LPFC_MAX_VFN_PER_PFN,
4852 "Enable PCIe device SR-IOV virtual fn");
4853
James Smart912e3ac2011-05-24 11:42:11 -04004854lpfc_param_show(sriov_nr_virtfn)
Joe Perchesb6b996b2017-12-19 10:15:07 -08004855static DEVICE_ATTR_RW(lpfc_sriov_nr_virtfn);
James Smart912e3ac2011-05-24 11:42:11 -04004856
James Smart173edbb2012-06-12 13:54:50 -04004857/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00004858 * lpfc_request_firmware_upgrade_store - Request for Linux generic firmware upgrade
James Smartc71ab862012-10-31 14:44:33 -04004859 *
4860 * @dev: class device that is converted into a Scsi_host.
4861 * @attr: device attribute, not used.
4862 * @buf: containing the string the number of vfs to be enabled.
4863 * @count: unused variable.
4864 *
4865 * Description:
4866 *
4867 * Returns:
4868 * length of the buf on success if val is in range the intended mode
4869 * is supported.
4870 * -EINVAL if val out of range or intended mode is not supported.
4871 **/
4872static ssize_t
4873lpfc_request_firmware_upgrade_store(struct device *dev,
4874 struct device_attribute *attr,
4875 const char *buf, size_t count)
4876{
4877 struct Scsi_Host *shost = class_to_shost(dev);
4878 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4879 struct lpfc_hba *phba = vport->phba;
Colin Ian King6e27a862020-05-07 21:31:11 +01004880 int val = 0, rc;
James Smartc71ab862012-10-31 14:44:33 -04004881
4882 /* Sanity check on user data */
4883 if (!isdigit(buf[0]))
4884 return -EINVAL;
4885 if (sscanf(buf, "%i", &val) != 1)
4886 return -EINVAL;
4887 if (val != 1)
4888 return -EINVAL;
4889
4890 rc = lpfc_sli4_request_firmware_update(phba, RUN_FW_UPGRADE);
4891 if (rc)
4892 rc = -EPERM;
4893 else
4894 rc = strlen(buf);
4895 return rc;
4896}
4897
4898static int lpfc_req_fw_upgrade;
4899module_param(lpfc_req_fw_upgrade, int, S_IRUGO|S_IWUSR);
4900MODULE_PARM_DESC(lpfc_req_fw_upgrade, "Enable Linux generic firmware upgrade");
4901lpfc_param_show(request_firmware_upgrade)
4902
4903/**
4904 * lpfc_request_firmware_upgrade_init - Enable initial linux generic fw upgrade
4905 * @phba: lpfc_hba pointer.
4906 * @val: 0 or 1.
4907 *
4908 * Description:
4909 * Set the initial Linux generic firmware upgrade enable or disable flag.
4910 *
4911 * Returns:
4912 * zero if val saved.
4913 * -EINVAL val out of range
4914 **/
4915static int
4916lpfc_request_firmware_upgrade_init(struct lpfc_hba *phba, int val)
4917{
4918 if (val >= 0 && val <= 1) {
4919 phba->cfg_request_firmware_upgrade = val;
4920 return 0;
4921 }
4922 return -EINVAL;
4923}
4924static DEVICE_ATTR(lpfc_req_fw_upgrade, S_IRUGO | S_IWUSR,
4925 lpfc_request_firmware_upgrade_show,
4926 lpfc_request_firmware_upgrade_store);
4927
4928/**
James Smart41b194b2019-05-14 14:58:08 -07004929 * lpfc_force_rscn_store
4930 *
4931 * @dev: class device that is converted into a Scsi_host.
4932 * @attr: device attribute, not used.
4933 * @buf: unused string
4934 * @count: unused variable.
4935 *
4936 * Description:
4937 * Force the switch to send a RSCN to all other NPorts in our zone
4938 * If we are direct connect pt2pt, build the RSCN command ourself
4939 * and send to the other NPort. Not supported for private loop.
4940 *
4941 * Returns:
4942 * 0 - on success
4943 * -EIO - if command is not sent
4944 **/
4945static ssize_t
4946lpfc_force_rscn_store(struct device *dev, struct device_attribute *attr,
4947 const char *buf, size_t count)
4948{
4949 struct Scsi_Host *shost = class_to_shost(dev);
4950 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4951 int i;
4952
4953 i = lpfc_issue_els_rscn(vport, 0);
4954 if (i)
4955 return -EIO;
4956 return strlen(buf);
4957}
4958
4959/*
4960 * lpfc_force_rscn: Force an RSCN to be sent to all remote NPorts
4961 * connected to the HBA.
4962 *
4963 * Value range is any ascii value
4964 */
4965static int lpfc_force_rscn;
4966module_param(lpfc_force_rscn, int, 0644);
4967MODULE_PARM_DESC(lpfc_force_rscn,
4968 "Force an RSCN to be sent to all remote NPorts");
4969lpfc_param_show(force_rscn)
4970
4971/**
4972 * lpfc_force_rscn_init - Force an RSCN to be sent to all remote NPorts
4973 * @phba: lpfc_hba pointer.
4974 * @val: unused value.
4975 *
4976 * Returns:
4977 * zero if val saved.
4978 **/
4979static int
4980lpfc_force_rscn_init(struct lpfc_hba *phba, int val)
4981{
4982 return 0;
4983}
4984static DEVICE_ATTR_RW(lpfc_force_rscn);
4985
4986/**
James Smart173edbb2012-06-12 13:54:50 -04004987 * lpfc_fcp_imax_store
4988 *
4989 * @dev: class device that is converted into a Scsi_host.
4990 * @attr: device attribute, not used.
4991 * @buf: string with the number of fast-path FCP interrupts per second.
4992 * @count: unused variable.
4993 *
4994 * Description:
4995 * If val is in a valid range [636,651042], then set the adapter's
4996 * maximum number of fast-path FCP interrupts per second.
4997 *
4998 * Returns:
4999 * length of the buf on success if val is in range the intended mode
5000 * is supported.
5001 * -EINVAL if val out of range or intended mode is not supported.
5002 **/
5003static ssize_t
5004lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr,
5005 const char *buf, size_t count)
5006{
5007 struct Scsi_Host *shost = class_to_shost(dev);
5008 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5009 struct lpfc_hba *phba = vport->phba;
James Smart32517fc2019-01-28 11:14:33 -08005010 struct lpfc_eq_intr_info *eqi;
James Smartcb733e32019-01-28 11:14:32 -08005011 uint32_t usdelay;
James Smart173edbb2012-06-12 13:54:50 -04005012 int val = 0, i;
5013
James Smartbf8dae82012-08-03 12:36:24 -04005014 /* fcp_imax is only valid for SLI4 */
5015 if (phba->sli_rev != LPFC_SLI_REV4)
5016 return -EINVAL;
5017
James Smart173edbb2012-06-12 13:54:50 -04005018 /* Sanity check on user data */
5019 if (!isdigit(buf[0]))
5020 return -EINVAL;
5021 if (sscanf(buf, "%i", &val) != 1)
5022 return -EINVAL;
5023
James Smartbf8dae82012-08-03 12:36:24 -04005024 /*
5025 * Value range for the HBA is [5000,5000000]
5026 * The value for each EQ depends on how many EQs are configured.
James Smart895427b2017-02-12 13:52:30 -08005027 * Allow value == 0
James Smartbf8dae82012-08-03 12:36:24 -04005028 */
James Smart895427b2017-02-12 13:52:30 -08005029 if (val && (val < LPFC_MIN_IMAX || val > LPFC_MAX_IMAX))
James Smart173edbb2012-06-12 13:54:50 -04005030 return -EINVAL;
5031
James Smart32517fc2019-01-28 11:14:33 -08005032 phba->cfg_auto_imax = (val) ? 0 : 1;
5033 if (phba->cfg_fcp_imax && !val) {
5034 queue_delayed_work(phba->wq, &phba->eq_delay_work,
5035 msecs_to_jiffies(LPFC_EQ_DELAY_MSECS));
5036
5037 for_each_present_cpu(i) {
5038 eqi = per_cpu_ptr(phba->sli4_hba.eq_info, i);
5039 eqi->icnt = 0;
5040 }
5041 }
5042
James Smart173edbb2012-06-12 13:54:50 -04005043 phba->cfg_fcp_imax = (uint32_t)val;
James Smart43140ca2017-03-04 09:30:34 -08005044
James Smartcb733e32019-01-28 11:14:32 -08005045 if (phba->cfg_fcp_imax)
5046 usdelay = LPFC_SEC_TO_USEC / phba->cfg_fcp_imax;
5047 else
5048 usdelay = 0;
5049
James Smart6a828b02019-01-28 11:14:31 -08005050 for (i = 0; i < phba->cfg_irq_chann; i += LPFC_MAX_EQ_DELAY_EQID_CNT)
James Smart0cf07f842017-06-01 21:07:10 -07005051 lpfc_modify_hba_eq_delay(phba, i, LPFC_MAX_EQ_DELAY_EQID_CNT,
James Smartcb733e32019-01-28 11:14:32 -08005052 usdelay);
James Smart173edbb2012-06-12 13:54:50 -04005053
5054 return strlen(buf);
5055}
5056
5057/*
5058# lpfc_fcp_imax: The maximum number of fast-path FCP interrupts per second
James Smartbf8dae82012-08-03 12:36:24 -04005059# for the HBA.
James Smart173edbb2012-06-12 13:54:50 -04005060#
James Smartbf8dae82012-08-03 12:36:24 -04005061# Value range is [5,000 to 5,000,000]. Default value is 50,000.
James Smart173edbb2012-06-12 13:54:50 -04005062*/
James Smartbf8dae82012-08-03 12:36:24 -04005063static int lpfc_fcp_imax = LPFC_DEF_IMAX;
James Smart173edbb2012-06-12 13:54:50 -04005064module_param(lpfc_fcp_imax, int, S_IRUGO|S_IWUSR);
5065MODULE_PARM_DESC(lpfc_fcp_imax,
James Smartbf8dae82012-08-03 12:36:24 -04005066 "Set the maximum number of FCP interrupts per second per HBA");
James Smart173edbb2012-06-12 13:54:50 -04005067lpfc_param_show(fcp_imax)
5068
5069/**
5070 * lpfc_fcp_imax_init - Set the initial sr-iov virtual function enable
5071 * @phba: lpfc_hba pointer.
5072 * @val: link speed value.
5073 *
5074 * Description:
5075 * If val is in a valid range [636,651042], then initialize the adapter's
5076 * maximum number of fast-path FCP interrupts per second.
5077 *
5078 * Returns:
5079 * zero if val saved.
5080 * -EINVAL val out of range
5081 **/
5082static int
5083lpfc_fcp_imax_init(struct lpfc_hba *phba, int val)
5084{
James Smartbf8dae82012-08-03 12:36:24 -04005085 if (phba->sli_rev != LPFC_SLI_REV4) {
5086 phba->cfg_fcp_imax = 0;
5087 return 0;
5088 }
5089
James Smart895427b2017-02-12 13:52:30 -08005090 if ((val >= LPFC_MIN_IMAX && val <= LPFC_MAX_IMAX) ||
5091 (val == 0)) {
James Smart173edbb2012-06-12 13:54:50 -04005092 phba->cfg_fcp_imax = val;
5093 return 0;
5094 }
5095
5096 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07005097 "3016 lpfc_fcp_imax: %d out of range, using default\n",
5098 val);
James Smartbf8dae82012-08-03 12:36:24 -04005099 phba->cfg_fcp_imax = LPFC_DEF_IMAX;
James Smart173edbb2012-06-12 13:54:50 -04005100
5101 return 0;
5102}
5103
Joe Perchesb6b996b2017-12-19 10:15:07 -08005104static DEVICE_ATTR_RW(lpfc_fcp_imax);
James Smart173edbb2012-06-12 13:54:50 -04005105
James Smart32517fc2019-01-28 11:14:33 -08005106/**
5107 * lpfc_cq_max_proc_limit_store
5108 *
5109 * @dev: class device that is converted into a Scsi_host.
5110 * @attr: device attribute, not used.
5111 * @buf: string with the cq max processing limit of cqes
5112 * @count: unused variable.
5113 *
5114 * Description:
5115 * If val is in a valid range, then set value on each cq
5116 *
5117 * Returns:
5118 * The length of the buf: if successful
5119 * -ERANGE: if val is not in the valid range
5120 * -EINVAL: if bad value format or intended mode is not supported.
5121 **/
5122static ssize_t
5123lpfc_cq_max_proc_limit_store(struct device *dev, struct device_attribute *attr,
5124 const char *buf, size_t count)
5125{
5126 struct Scsi_Host *shost = class_to_shost(dev);
5127 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5128 struct lpfc_hba *phba = vport->phba;
5129 struct lpfc_queue *eq, *cq;
5130 unsigned long val;
5131 int i;
5132
5133 /* cq_max_proc_limit is only valid for SLI4 */
5134 if (phba->sli_rev != LPFC_SLI_REV4)
5135 return -EINVAL;
5136
5137 /* Sanity check on user data */
5138 if (!isdigit(buf[0]))
5139 return -EINVAL;
5140 if (kstrtoul(buf, 0, &val))
5141 return -EINVAL;
5142
5143 if (val < LPFC_CQ_MIN_PROC_LIMIT || val > LPFC_CQ_MAX_PROC_LIMIT)
5144 return -ERANGE;
5145
5146 phba->cfg_cq_max_proc_limit = (uint32_t)val;
5147
5148 /* set the values on the cq's */
5149 for (i = 0; i < phba->cfg_irq_chann; i++) {
James Smart657add42019-05-21 17:49:06 -07005150 /* Get the EQ corresponding to the IRQ vector */
5151 eq = phba->sli4_hba.hba_eq_hdl[i].eq;
James Smart32517fc2019-01-28 11:14:33 -08005152 if (!eq)
5153 continue;
5154
5155 list_for_each_entry(cq, &eq->child_list, list)
5156 cq->max_proc_limit = min(phba->cfg_cq_max_proc_limit,
5157 cq->entry_count);
5158 }
5159
5160 return strlen(buf);
5161}
5162
James Smart0cf07f842017-06-01 21:07:10 -07005163/*
James Smart32517fc2019-01-28 11:14:33 -08005164 * lpfc_cq_max_proc_limit: The maximum number CQE entries processed in an
5165 * itteration of CQ processing.
James Smart0cf07f842017-06-01 21:07:10 -07005166 */
James Smart32517fc2019-01-28 11:14:33 -08005167static int lpfc_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
5168module_param(lpfc_cq_max_proc_limit, int, 0644);
5169MODULE_PARM_DESC(lpfc_cq_max_proc_limit,
5170 "Set the maximum number CQEs processed in an iteration of "
5171 "CQ processing");
5172lpfc_param_show(cq_max_proc_limit)
5173
5174/*
5175 * lpfc_cq_poll_threshold: Set the threshold of CQE completions in a
5176 * single handler call which should request a polled completion rather
5177 * than re-enabling interrupts.
5178 */
5179LPFC_ATTR_RW(cq_poll_threshold, LPFC_CQ_DEF_THRESHOLD_TO_POLL,
5180 LPFC_CQ_MIN_THRESHOLD_TO_POLL,
5181 LPFC_CQ_MAX_THRESHOLD_TO_POLL,
5182 "CQE Processing Threshold to enable Polling");
5183
5184/**
5185 * lpfc_cq_max_proc_limit_init - Set the initial cq max_proc_limit
5186 * @phba: lpfc_hba pointer.
5187 * @val: entry limit
5188 *
5189 * Description:
5190 * If val is in a valid range, then initialize the adapter's maximum
5191 * value.
5192 *
5193 * Returns:
5194 * Always returns 0 for success, even if value not always set to
5195 * requested value. If value out of range or not supported, will fall
5196 * back to default.
5197 **/
5198static int
5199lpfc_cq_max_proc_limit_init(struct lpfc_hba *phba, int val)
5200{
5201 phba->cfg_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
5202
5203 if (phba->sli_rev != LPFC_SLI_REV4)
5204 return 0;
5205
5206 if (val >= LPFC_CQ_MIN_PROC_LIMIT && val <= LPFC_CQ_MAX_PROC_LIMIT) {
5207 phba->cfg_cq_max_proc_limit = val;
5208 return 0;
5209 }
5210
5211 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
5212 "0371 "LPFC_DRIVER_NAME"_cq_max_proc_limit: "
5213 "%d out of range, using default\n",
5214 phba->cfg_cq_max_proc_limit);
5215
5216 return 0;
5217}
5218
5219static DEVICE_ATTR_RW(lpfc_cq_max_proc_limit);
James Smart0cf07f842017-06-01 21:07:10 -07005220
James Smart7bb03bb2013-04-17 20:19:16 -04005221/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00005222 * lpfc_fcp_cpu_map_show - Display current driver CPU affinity
James Smart7bb03bb2013-04-17 20:19:16 -04005223 * @dev: class converted to a Scsi_host structure.
5224 * @attr: device attribute, not used.
5225 * @buf: on return contains text describing the state of the link.
5226 *
5227 * Returns: size of formatted string.
5228 **/
5229static ssize_t
5230lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr,
5231 char *buf)
5232{
5233 struct Scsi_Host *shost = class_to_shost(dev);
5234 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5235 struct lpfc_hba *phba = vport->phba;
5236 struct lpfc_vector_map_info *cpup;
James Smart76fd07a2014-02-20 09:57:18 -05005237 int len = 0;
James Smart7bb03bb2013-04-17 20:19:16 -04005238
5239 if ((phba->sli_rev != LPFC_SLI_REV4) ||
5240 (phba->intr_type != MSIX))
5241 return len;
5242
5243 switch (phba->cfg_fcp_cpu_map) {
5244 case 0:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005245 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart7bb03bb2013-04-17 20:19:16 -04005246 "fcp_cpu_map: No mapping (%d)\n",
5247 phba->cfg_fcp_cpu_map);
5248 return len;
5249 case 1:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005250 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart7bb03bb2013-04-17 20:19:16 -04005251 "fcp_cpu_map: HBA centric mapping (%d): "
James Smart222e9232019-01-28 11:14:35 -08005252 "%d of %d CPUs online from %d possible CPUs\n",
5253 phba->cfg_fcp_cpu_map, num_online_cpus(),
5254 num_present_cpus(),
5255 phba->sli4_hba.num_possible_cpu);
James Smart7bb03bb2013-04-17 20:19:16 -04005256 break;
James Smart7bb03bb2013-04-17 20:19:16 -04005257 }
5258
James Smart222e9232019-01-28 11:14:35 -08005259 while (phba->sli4_hba.curr_disp_cpu <
5260 phba->sli4_hba.num_possible_cpu) {
James Smart76fd07a2014-02-20 09:57:18 -05005261 cpup = &phba->sli4_hba.cpu_map[phba->sli4_hba.curr_disp_cpu];
5262
James Smart222e9232019-01-28 11:14:35 -08005263 if (!cpu_present(phba->sli4_hba.curr_disp_cpu))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005264 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart222e9232019-01-28 11:14:35 -08005265 "CPU %02d not present\n",
5266 phba->sli4_hba.curr_disp_cpu);
James Smartdcaa2132019-11-04 16:57:06 -08005267 else if (cpup->eq == LPFC_VECTOR_MAP_EMPTY) {
James Smartb3295c22019-01-28 11:14:30 -08005268 if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005269 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005270 buf + len, PAGE_SIZE - len,
5271 "CPU %02d hdwq None "
James Smartd9954a22019-05-21 17:49:05 -07005272 "physid %d coreid %d ht %d ua %d\n",
James Smart76fd07a2014-02-20 09:57:18 -05005273 phba->sli4_hba.curr_disp_cpu,
James Smartd9954a22019-05-21 17:49:05 -07005274 cpup->phys_id, cpup->core_id,
5275 (cpup->flag & LPFC_CPU_MAP_HYPER),
5276 (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
James Smartb3295c22019-01-28 11:14:30 -08005277 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005278 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005279 buf + len, PAGE_SIZE - len,
James Smartdcaa2132019-11-04 16:57:06 -08005280 "CPU %02d EQ None hdwq %04d "
James Smartd9954a22019-05-21 17:49:05 -07005281 "physid %d coreid %d ht %d ua %d\n",
James Smartb3295c22019-01-28 11:14:30 -08005282 phba->sli4_hba.curr_disp_cpu,
James Smartdcaa2132019-11-04 16:57:06 -08005283 cpup->hdwq, cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005284 cpup->core_id,
5285 (cpup->flag & LPFC_CPU_MAP_HYPER),
5286 (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
James Smartb3295c22019-01-28 11:14:30 -08005287 } else {
5288 if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005289 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005290 buf + len, PAGE_SIZE - len,
5291 "CPU %02d hdwq None "
James Smartd9954a22019-05-21 17:49:05 -07005292 "physid %d coreid %d ht %d ua %d IRQ %d\n",
James Smart76fd07a2014-02-20 09:57:18 -05005293 phba->sli4_hba.curr_disp_cpu,
James Smartb3295c22019-01-28 11:14:30 -08005294 cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005295 cpup->core_id,
5296 (cpup->flag & LPFC_CPU_MAP_HYPER),
5297 (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
James Smartdcaa2132019-11-04 16:57:06 -08005298 lpfc_get_irq(cpup->eq));
James Smartb3295c22019-01-28 11:14:30 -08005299 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005300 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005301 buf + len, PAGE_SIZE - len,
James Smart6a828b02019-01-28 11:14:31 -08005302 "CPU %02d EQ %04d hdwq %04d "
James Smartd9954a22019-05-21 17:49:05 -07005303 "physid %d coreid %d ht %d ua %d IRQ %d\n",
James Smartb3295c22019-01-28 11:14:30 -08005304 phba->sli4_hba.curr_disp_cpu,
James Smart6a828b02019-01-28 11:14:31 -08005305 cpup->eq, cpup->hdwq, cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005306 cpup->core_id,
5307 (cpup->flag & LPFC_CPU_MAP_HYPER),
5308 (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
James Smartdcaa2132019-11-04 16:57:06 -08005309 lpfc_get_irq(cpup->eq));
James Smartb3295c22019-01-28 11:14:30 -08005310 }
James Smart7bb03bb2013-04-17 20:19:16 -04005311
James Smart76fd07a2014-02-20 09:57:18 -05005312 phba->sli4_hba.curr_disp_cpu++;
5313
5314 /* display max number of CPUs keeping some margin */
5315 if (phba->sli4_hba.curr_disp_cpu <
James Smart222e9232019-01-28 11:14:35 -08005316 phba->sli4_hba.num_possible_cpu &&
James Smart76fd07a2014-02-20 09:57:18 -05005317 (len >= (PAGE_SIZE - 64))) {
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005318 len += scnprintf(buf + len,
James Smart222e9232019-01-28 11:14:35 -08005319 PAGE_SIZE - len, "more...\n");
James Smart76fd07a2014-02-20 09:57:18 -05005320 break;
5321 }
James Smart7bb03bb2013-04-17 20:19:16 -04005322 }
James Smart76fd07a2014-02-20 09:57:18 -05005323
James Smart222e9232019-01-28 11:14:35 -08005324 if (phba->sli4_hba.curr_disp_cpu == phba->sli4_hba.num_possible_cpu)
James Smart76fd07a2014-02-20 09:57:18 -05005325 phba->sli4_hba.curr_disp_cpu = 0;
5326
James Smart7bb03bb2013-04-17 20:19:16 -04005327 return len;
5328}
5329
5330/**
5331 * lpfc_fcp_cpu_map_store - Change CPU affinity of driver vectors
5332 * @dev: class device that is converted into a Scsi_host.
5333 * @attr: device attribute, not used.
5334 * @buf: one or more lpfc_polling_flags values.
5335 * @count: not used.
5336 *
5337 * Returns:
5338 * -EINVAL - Not implemented yet.
5339 **/
5340static ssize_t
5341lpfc_fcp_cpu_map_store(struct device *dev, struct device_attribute *attr,
5342 const char *buf, size_t count)
5343{
Ye Bin37fa4292020-09-16 10:28:59 +08005344 return -EINVAL;
James Smart7bb03bb2013-04-17 20:19:16 -04005345}
5346
5347/*
5348# lpfc_fcp_cpu_map: Defines how to map CPUs to IRQ vectors
5349# for the HBA.
5350#
James Smart6a828b02019-01-28 11:14:31 -08005351# Value range is [0 to 1]. Default value is LPFC_HBA_CPU_MAP (1).
James Smart7bb03bb2013-04-17 20:19:16 -04005352# 0 - Do not affinitze IRQ vectors
5353# 1 - Affintize HBA vectors with respect to each HBA
5354# (start with CPU0 for each HBA)
James Smart6a828b02019-01-28 11:14:31 -08005355# This also defines how Hardware Queues are mapped to specific CPUs.
James Smart7bb03bb2013-04-17 20:19:16 -04005356*/
James Smart6a828b02019-01-28 11:14:31 -08005357static int lpfc_fcp_cpu_map = LPFC_HBA_CPU_MAP;
James Smart7bb03bb2013-04-17 20:19:16 -04005358module_param(lpfc_fcp_cpu_map, int, S_IRUGO|S_IWUSR);
5359MODULE_PARM_DESC(lpfc_fcp_cpu_map,
5360 "Defines how to map CPUs to IRQ vectors per HBA");
5361
5362/**
5363 * lpfc_fcp_cpu_map_init - Set the initial sr-iov virtual function enable
5364 * @phba: lpfc_hba pointer.
5365 * @val: link speed value.
5366 *
5367 * Description:
5368 * If val is in a valid range [0-2], then affinitze the adapter's
5369 * MSIX vectors.
5370 *
5371 * Returns:
5372 * zero if val saved.
5373 * -EINVAL val out of range
5374 **/
5375static int
5376lpfc_fcp_cpu_map_init(struct lpfc_hba *phba, int val)
5377{
5378 if (phba->sli_rev != LPFC_SLI_REV4) {
5379 phba->cfg_fcp_cpu_map = 0;
5380 return 0;
5381 }
5382
5383 if (val >= LPFC_MIN_CPU_MAP && val <= LPFC_MAX_CPU_MAP) {
5384 phba->cfg_fcp_cpu_map = val;
5385 return 0;
5386 }
5387
5388 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07005389 "3326 lpfc_fcp_cpu_map: %d out of range, using "
5390 "default\n", val);
James Smart6a828b02019-01-28 11:14:31 -08005391 phba->cfg_fcp_cpu_map = LPFC_HBA_CPU_MAP;
James Smart7bb03bb2013-04-17 20:19:16 -04005392
5393 return 0;
5394}
5395
Joe Perchesb6b996b2017-12-19 10:15:07 -08005396static DEVICE_ATTR_RW(lpfc_fcp_cpu_map);
James Smart7bb03bb2013-04-17 20:19:16 -04005397
James Smart0d878412009-10-02 15:16:56 -04005398/*
dea31012005-04-17 16:05:31 -05005399# lpfc_fcp_class: Determines FC class to use for the FCP protocol.
5400# Value range is [2,3]. Default value is 3.
5401*/
James Smart3de2a652007-08-02 11:09:59 -04005402LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3,
5403 "Select Fibre Channel class of service for FCP sequences");
dea31012005-04-17 16:05:31 -05005404
5405/*
5406# lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
5407# is [0,1]. Default value is 0.
5408*/
James Smart3de2a652007-08-02 11:09:59 -04005409LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1,
5410 "Use ADISC on rediscovery to authenticate FCP devices");
dea31012005-04-17 16:05:31 -05005411
5412/*
James Smart3cb01c52013-07-15 18:35:04 -04005413# lpfc_first_burst_size: First burst size to use on the NPorts
5414# that support first burst.
5415# Value range is [0,65536]. Default value is 0.
5416*/
5417LPFC_VPORT_ATTR_RW(first_burst_size, 0, 0, 65536,
5418 "First burst size for Targets that support first burst");
5419
5420/*
James Smart2d7dbc42017-02-12 13:52:35 -08005421* lpfc_nvmet_fb_size: NVME Target mode supported first burst size.
5422* When the driver is configured as an NVME target, this value is
5423* communicated to the NVME initiator in the PRLI response. It is
5424* used only when the lpfc_nvme_enable_fb and lpfc_nvmet_support
5425* parameters are set and the target is sending the PRLI RSP.
James Smart895427b2017-02-12 13:52:30 -08005426* Parameter supported on physical port only - no NPIV support.
James Smart2d7dbc42017-02-12 13:52:35 -08005427* Value range is [0,65536]. Default value is 0.
James Smart895427b2017-02-12 13:52:30 -08005428*/
James Smart2d7dbc42017-02-12 13:52:35 -08005429LPFC_ATTR_RW(nvmet_fb_size, 0, 0, 65536,
5430 "NVME Target mode first burst size in 512B increments.");
5431
5432/*
5433 * lpfc_nvme_enable_fb: Enable NVME first burst on I and T functions.
5434 * For the Initiator (I), enabling this parameter means that an NVMET
5435 * PRLI response with FBA enabled and an FB_SIZE set to a nonzero value will be
James Smartdb197bc2019-08-14 16:57:03 -07005436 * processed by the initiator for subsequent NVME FCP IO.
5437 * Currently, this feature is not supported on the NVME target
James Smart2d7dbc42017-02-12 13:52:35 -08005438 * Value range is [0,1]. Default value is 0 (disabled).
5439 */
James Smart895427b2017-02-12 13:52:30 -08005440LPFC_ATTR_RW(nvme_enable_fb, 0, 0, 1,
James Smartdb197bc2019-08-14 16:57:03 -07005441 "Enable First Burst feature for NVME Initiator.");
James Smart895427b2017-02-12 13:52:30 -08005442
5443/*
James Smart977b5a02008-09-07 11:52:04 -04005444# lpfc_max_scsicmpl_time: Use scsi command completion time to control I/O queue
5445# depth. Default value is 0. When the value of this parameter is zero the
5446# SCSI command completion time is not used for controlling I/O queue depth. When
5447# the parameter is set to a non-zero value, the I/O queue depth is controlled
5448# to limit the I/O completion time to the parameter value.
5449# The value is set in milliseconds.
5450*/
James Smarted5b1522016-10-13 15:06:11 -07005451LPFC_VPORT_ATTR(max_scsicmpl_time, 0, 0, 60000,
James Smart977b5a02008-09-07 11:52:04 -04005452 "Use command completion time to control queue depth");
James Smarted5b1522016-10-13 15:06:11 -07005453
James Smart977b5a02008-09-07 11:52:04 -04005454lpfc_vport_param_show(max_scsicmpl_time);
James Smart977b5a02008-09-07 11:52:04 -04005455static int
5456lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val)
5457{
5458 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5459 struct lpfc_nodelist *ndlp, *next_ndlp;
5460
5461 if (val == vport->cfg_max_scsicmpl_time)
5462 return 0;
5463 if ((val < 0) || (val > 60000))
5464 return -EINVAL;
5465 vport->cfg_max_scsicmpl_time = val;
5466
5467 spin_lock_irq(shost->host_lock);
5468 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
James Smart977b5a02008-09-07 11:52:04 -04005469 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
5470 continue;
James Smart7dc517d2010-07-14 15:32:10 -04005471 ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
James Smart977b5a02008-09-07 11:52:04 -04005472 }
5473 spin_unlock_irq(shost->host_lock);
5474 return 0;
5475}
5476lpfc_vport_param_store(max_scsicmpl_time);
Joe Perchesb6b996b2017-12-19 10:15:07 -08005477static DEVICE_ATTR_RW(lpfc_max_scsicmpl_time);
James Smart977b5a02008-09-07 11:52:04 -04005478
5479/*
dea31012005-04-17 16:05:31 -05005480# lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
5481# range is [0,1]. Default value is 0.
5482*/
5483LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
5484
5485/*
James Smartc4908502019-01-28 11:14:28 -08005486# lpfc_xri_rebalancing: enable or disable XRI rebalancing feature
5487# range is [0,1]. Default value is 1.
5488*/
5489LPFC_ATTR_R(xri_rebalancing, 1, 0, 1, "Enable/Disable XRI rebalancing");
5490
5491/*
James Smart895427b2017-02-12 13:52:30 -08005492 * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds
5493 * range is [0,1]. Default value is 0.
James Smart45aa3122019-01-28 11:14:29 -08005494 * For [0], FCP commands are issued to Work Queues based on upper layer
5495 * hardware queue index.
James Smart895427b2017-02-12 13:52:30 -08005496 * For [1], FCP commands are issued to a Work Queue associated with the
5497 * current CPU.
5498 *
James Smart45aa3122019-01-28 11:14:29 -08005499 * LPFC_FCP_SCHED_BY_HDWQ == 0
James Smart895427b2017-02-12 13:52:30 -08005500 * LPFC_FCP_SCHED_BY_CPU == 1
5501 *
5502 * The driver dynamically sets this to 1 (BY_CPU) if it's able to set up cpu
5503 * affinity for FCP/NVME I/Os through Work Queues associated with the current
5504 * CPU. Otherwise, the default 0 (Round Robin) scheduling of FCP/NVME I/Os
5505 * through WQs will be used.
5506 */
James Smart6a828b02019-01-28 11:14:31 -08005507LPFC_ATTR_RW(fcp_io_sched, LPFC_FCP_SCHED_BY_CPU,
James Smart45aa3122019-01-28 11:14:29 -08005508 LPFC_FCP_SCHED_BY_HDWQ,
James Smart895427b2017-02-12 13:52:30 -08005509 LPFC_FCP_SCHED_BY_CPU,
5510 "Determine scheduling algorithm for "
James Smart45aa3122019-01-28 11:14:29 -08005511 "issuing commands [0] - Hardware Queue, [1] - Current CPU");
James Smart49aa1432012-08-03 12:36:42 -04005512
5513/*
James Smart7ea92eb2018-10-23 13:41:10 -07005514 * lpfc_ns_query: Determine algrithmn for NameServer queries after RSCN
5515 * range is [0,1]. Default value is 0.
5516 * For [0], GID_FT is used for NameServer queries after RSCN (default)
5517 * For [1], GID_PT is used for NameServer queries after RSCN
5518 *
5519 */
5520LPFC_ATTR_RW(ns_query, LPFC_NS_QUERY_GID_FT,
5521 LPFC_NS_QUERY_GID_FT, LPFC_NS_QUERY_GID_PT,
5522 "Determine algorithm NameServer queries after RSCN "
5523 "[0] - GID_FT, [1] - GID_PT");
5524
5525/*
James Smarta6571c62012-10-31 14:44:42 -04005526# lpfc_fcp2_no_tgt_reset: Determine bus reset behavior
5527# range is [0,1]. Default value is 0.
5528# For [0], bus reset issues target reset to ALL devices
5529# For [1], bus reset issues target reset to non-FCP2 devices
5530*/
5531LPFC_ATTR_RW(fcp2_no_tgt_reset, 0, 0, 1, "Determine bus reset behavior for "
5532 "FCP2 devices [0] - issue tgt reset, [1] - no tgt reset");
5533
5534
5535/*
dea31012005-04-17 16:05:31 -05005536# lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
5537# cr_delay (msec) or cr_count outstanding commands. cr_delay can take
James Smart7054a602007-04-25 09:52:34 -04005538# value [0,63]. cr_count can take value [1,255]. Default value of cr_delay
dea31012005-04-17 16:05:31 -05005539# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
5540# cr_delay is set to 0.
5541*/
Jamie Wellnitz8189fd12006-02-28 19:25:35 -05005542LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an "
dea31012005-04-17 16:05:31 -05005543 "interrupt response is generated");
5544
Jamie Wellnitz8189fd12006-02-28 19:25:35 -05005545LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "
dea31012005-04-17 16:05:31 -05005546 "interrupt response is generated");
5547
5548/*
Jamie Wellnitzcf5bf972006-02-28 22:33:08 -05005549# lpfc_multi_ring_support: Determines how many rings to spread available
5550# cmd/rsp IOCB entries across.
5551# Value range is [1,2]. Default value is 1.
5552*/
5553LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
5554 "SLI rings to spread IOCB entries across");
5555
5556/*
James Smarta4bc3372006-12-02 13:34:16 -05005557# lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this
5558# identifies what rctl value to configure the additional ring for.
5559# Value range is [1,0xff]. Default value is 4 (Unsolicated Data).
5560*/
James Smart6a9c52c2009-10-02 15:16:51 -04005561LPFC_ATTR_R(multi_ring_rctl, FC_RCTL_DD_UNSOL_DATA, 1,
James Smarta4bc3372006-12-02 13:34:16 -05005562 255, "Identifies RCTL for additional ring configuration");
5563
5564/*
5565# lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this
5566# identifies what type value to configure the additional ring for.
5567# Value range is [1,0xff]. Default value is 5 (LLC/SNAP).
5568*/
James Smart6a9c52c2009-10-02 15:16:51 -04005569LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP, 1,
James Smarta4bc3372006-12-02 13:34:16 -05005570 255, "Identifies TYPE for additional ring configuration");
5571
5572/*
James Smart4258e982015-12-16 18:11:58 -05005573# lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN
5574# 0 = SmartSAN functionality disabled (default)
5575# 1 = SmartSAN functionality enabled
5576# This parameter will override the value of lpfc_fdmi_on module parameter.
5577# Value range is [0,1]. Default value is 0.
dea31012005-04-17 16:05:31 -05005578*/
James Smart4258e982015-12-16 18:11:58 -05005579LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality");
5580
5581/*
5582# lpfc_fdmi_on: Controls FDMI support.
James Smart9abd9992018-08-14 12:55:05 -07005583# 0 No FDMI support
5584# 1 Traditional FDMI support (default)
James Smart8663cbb2016-03-31 14:12:33 -07005585# Traditional FDMI support means the driver will assume FDMI-2 support;
5586# however, if that fails, it will fallback to FDMI-1.
5587# If lpfc_enable_SmartSAN is set to 1, the driver ignores lpfc_fdmi_on.
5588# If lpfc_enable_SmartSAN is set 0, the driver uses the current value of
5589# lpfc_fdmi_on.
James Smart9abd9992018-08-14 12:55:05 -07005590# Value range [0,1]. Default value is 1.
James Smart4258e982015-12-16 18:11:58 -05005591*/
James Smart9abd9992018-08-14 12:55:05 -07005592LPFC_ATTR_R(fdmi_on, 1, 0, 1, "Enable FDMI support");
dea31012005-04-17 16:05:31 -05005593
5594/*
5595# Specifies the maximum number of ELS cmds we can have outstanding (for
5596# discovery). Value range is [1,64]. Default value = 32.
5597*/
James Smart3de2a652007-08-02 11:09:59 -04005598LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
dea31012005-04-17 16:05:31 -05005599 "during discovery");
5600
5601/*
James Smartc4a7c922013-05-31 17:04:59 -04005602# lpfc_max_luns: maximum allowed LUN ID. This is the highest LUN ID that
5603# will be scanned by the SCSI midlayer when sequential scanning is
5604# used; and is also the highest LUN ID allowed when the SCSI midlayer
5605# parses REPORT_LUN responses. The lpfc driver has no LUN count or
5606# LUN ID limit, but the SCSI midlayer requires this field for the uses
5607# above. The lpfc driver limits the default value to 255 for two reasons.
5608# As it bounds the sequential scan loop, scanning for thousands of luns
5609# on a target can take minutes of wall clock time. Additionally,
5610# there are FC targets, such as JBODs, that only recognize 8-bits of
5611# LUN ID. When they receive a value greater than 8 bits, they chop off
5612# the high order bits. In other words, they see LUN IDs 0, 256, 512,
5613# and so on all as LUN ID 0. This causes the linux kernel, which sees
5614# valid responses at each of the LUN IDs, to believe there are multiple
5615# devices present, when in fact, there is only 1.
5616# A customer that is aware of their target behaviors, and the results as
5617# indicated above, is welcome to increase the lpfc_max_luns value.
5618# As mentioned, this value is not used by the lpfc driver, only the
5619# SCSI midlayer.
James Smart65a29c12006-07-06 15:50:50 -04005620# Value range is [0,65535]. Default value is 255.
5621# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
dea31012005-04-17 16:05:31 -05005622*/
Hannes Reinecke1abf6352014-06-25 15:27:38 +02005623LPFC_VPORT_ULL_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN ID");
dea31012005-04-17 16:05:31 -05005624
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05005625/*
5626# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
5627# Value range is [1,255], default value is 10.
5628*/
5629LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
5630 "Milliseconds driver will wait between polling FCP ring");
5631
James Smart4ff43242006-12-02 13:34:56 -05005632/*
James Smart0c411222013-09-06 12:22:46 -04005633# lpfc_task_mgmt_tmo: Maximum time to wait for task management commands
5634# to complete in seconds. Value range is [5,180], default value is 60.
5635*/
5636LPFC_ATTR_RW(task_mgmt_tmo, 60, 5, 180,
5637 "Maximum time to wait for task management commands to complete");
5638/*
James Smart4ff43242006-12-02 13:34:56 -05005639# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
5640# support this feature
George Kadianakis8605c462010-01-17 21:19:31 +02005641# 0 = MSI disabled
James Smart4ff43242006-12-02 13:34:56 -05005642# 1 = MSI enabled
George Kadianakis8605c462010-01-17 21:19:31 +02005643# 2 = MSI-X enabled (default)
5644# Value range is [0,2]. Default value is 2.
James Smart4ff43242006-12-02 13:34:56 -05005645*/
George Kadianakis8605c462010-01-17 21:19:31 +02005646LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
James Smartdb2378e2008-02-08 18:49:51 -05005647 "MSI-X (2), if possible");
James Smart4ff43242006-12-02 13:34:56 -05005648
James Smart13815c82008-01-11 01:52:48 -05005649/*
James Smartf358dd02017-02-12 13:52:34 -08005650 * lpfc_nvme_oas: Use the oas bit when sending NVME/NVMET IOs
James Smart895427b2017-02-12 13:52:30 -08005651 *
5652 * 0 = NVME OAS disabled
5653 * 1 = NVME OAS enabled
5654 *
5655 * Value range is [0,1]. Default value is 0.
5656 */
5657LPFC_ATTR_RW(nvme_oas, 0, 0, 1,
5658 "Use OAS bit on NVME IOs");
5659
5660/*
James Smart4e565cf2018-02-22 08:18:50 -08005661 * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
5662 *
5663 * 0 = Put NVME Command in SGL
5664 * 1 = Embed NVME Command in WQE (unless G7)
5665 * 2 = Embed NVME Command in WQE (force)
5666 *
5667 * Value range is [0,2]. Default value is 1.
5668 */
5669LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
5670 "Embed NVME Command in WQE");
5671
5672/*
James Smart77ffd342019-08-15 19:36:49 -07005673 * lpfc_fcp_mq_threshold: Set the maximum number of Hardware Queues
5674 * the driver will advertise it supports to the SCSI layer.
5675 *
5676 * 0 = Set nr_hw_queues by the number of CPUs or HW queues.
James Smartdcaa2132019-11-04 16:57:06 -08005677 * 1,256 = Manually specify nr_hw_queue value to be advertised,
James Smart77ffd342019-08-15 19:36:49 -07005678 *
James Smart06228002019-08-27 14:28:23 -07005679 * Value range is [0,256]. Default value is 8.
James Smart77ffd342019-08-15 19:36:49 -07005680 */
5681LPFC_ATTR_R(fcp_mq_threshold, LPFC_FCP_MQ_THRESHOLD_DEF,
5682 LPFC_FCP_MQ_THRESHOLD_MIN, LPFC_FCP_MQ_THRESHOLD_MAX,
5683 "Set the number of SCSI Queues advertised");
5684
5685/*
James Smart6a828b02019-01-28 11:14:31 -08005686 * lpfc_hdw_queue: Set the number of Hardware Queues the driver
James Smartcdb42be2019-01-28 11:14:21 -08005687 * will advertise it supports to the NVME and SCSI layers. This also
James Smart6a828b02019-01-28 11:14:31 -08005688 * will map to the number of CQ/WQ pairs the driver will create.
James Smart895427b2017-02-12 13:52:30 -08005689 *
5690 * The NVME Layer will try to create this many, plus 1 administrative
5691 * hardware queue. The administrative queue will always map to WQ 0
James Smart6a828b02019-01-28 11:14:31 -08005692 * A hardware IO queue maps (qidx) to a specific driver CQ/WQ.
James Smart895427b2017-02-12 13:52:30 -08005693 *
James Smartcdb42be2019-01-28 11:14:21 -08005694 * 0 = Configure the number of hdw queues to the number of active CPUs.
James Smartdcaa2132019-11-04 16:57:06 -08005695 * 1,256 = Manually specify how many hdw queues to use.
James Smart895427b2017-02-12 13:52:30 -08005696 *
James Smartdcaa2132019-11-04 16:57:06 -08005697 * Value range is [0,256]. Default value is 0.
James Smart895427b2017-02-12 13:52:30 -08005698 */
James Smartcdb42be2019-01-28 11:14:21 -08005699LPFC_ATTR_R(hdw_queue,
5700 LPFC_HBA_HDWQ_DEF,
5701 LPFC_HBA_HDWQ_MIN, LPFC_HBA_HDWQ_MAX,
5702 "Set the number of I/O Hardware Queues");
James Smart895427b2017-02-12 13:52:30 -08005703
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005704#if IS_ENABLED(CONFIG_X86)
5705/**
5706 * lpfc_cpumask_irq_mode_init - initalizes cpumask of phba based on
5707 * irq_chann_mode
5708 * @phba: Pointer to HBA context object.
5709 **/
5710static void
5711lpfc_cpumask_irq_mode_init(struct lpfc_hba *phba)
5712{
5713 unsigned int cpu, first_cpu, numa_node = NUMA_NO_NODE;
5714 const struct cpumask *sibling_mask;
5715 struct cpumask *aff_mask = &phba->sli4_hba.irq_aff_mask;
5716
5717 cpumask_clear(aff_mask);
5718
5719 if (phba->irq_chann_mode == NUMA_MODE) {
5720 /* Check if we're a NUMA architecture */
5721 numa_node = dev_to_node(&phba->pcidev->dev);
5722 if (numa_node == NUMA_NO_NODE) {
5723 phba->irq_chann_mode = NORMAL_MODE;
5724 return;
5725 }
5726 }
5727
5728 for_each_possible_cpu(cpu) {
5729 switch (phba->irq_chann_mode) {
5730 case NUMA_MODE:
5731 if (cpu_to_node(cpu) == numa_node)
5732 cpumask_set_cpu(cpu, aff_mask);
5733 break;
5734 case NHT_MODE:
5735 sibling_mask = topology_sibling_cpumask(cpu);
5736 first_cpu = cpumask_first(sibling_mask);
5737 if (first_cpu < nr_cpu_ids)
5738 cpumask_set_cpu(first_cpu, aff_mask);
5739 break;
5740 default:
5741 break;
5742 }
5743 }
5744}
5745#endif
5746
5747static void
5748lpfc_assign_default_irq_chann(struct lpfc_hba *phba)
James Smartdcaa2132019-11-04 16:57:06 -08005749{
5750#if IS_ENABLED(CONFIG_X86)
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005751 switch (boot_cpu_data.x86_vendor) {
5752 case X86_VENDOR_AMD:
5753 /* If AMD architecture, then default is NUMA_MODE */
5754 phba->irq_chann_mode = NUMA_MODE;
5755 break;
5756 case X86_VENDOR_INTEL:
5757 /* If Intel architecture, then default is no hyperthread mode */
5758 phba->irq_chann_mode = NHT_MODE;
5759 break;
5760 default:
5761 phba->irq_chann_mode = NORMAL_MODE;
5762 break;
5763 }
5764 lpfc_cpumask_irq_mode_init(phba);
James Smartdcaa2132019-11-04 16:57:06 -08005765#else
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005766 phba->irq_chann_mode = NORMAL_MODE;
James Smartdcaa2132019-11-04 16:57:06 -08005767#endif
5768}
5769
James Smart895427b2017-02-12 13:52:30 -08005770/*
James Smart6a828b02019-01-28 11:14:31 -08005771 * lpfc_irq_chann: Set the number of IRQ vectors that are available
5772 * for Hardware Queues to utilize. This also will map to the number
5773 * of EQ / MSI-X vectors the driver will create. This should never be
5774 * more than the number of Hardware Queues
5775 *
James Smartdcaa2132019-11-04 16:57:06 -08005776 * 0 = Configure number of IRQ Channels to:
5777 * if AMD architecture, number of CPUs on HBA's NUMA node
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005778 * if Intel architecture, number of physical CPUs.
James Smartdcaa2132019-11-04 16:57:06 -08005779 * otherwise, number of active CPUs.
5780 * [1,256] = Manually specify how many IRQ Channels to use.
James Smart6a828b02019-01-28 11:14:31 -08005781 *
James Smartdcaa2132019-11-04 16:57:06 -08005782 * Value range is [0,256]. Default value is [0].
James Smart6a828b02019-01-28 11:14:31 -08005783 */
James Smartdcaa2132019-11-04 16:57:06 -08005784static uint lpfc_irq_chann = LPFC_IRQ_CHANN_DEF;
5785module_param(lpfc_irq_chann, uint, 0444);
5786MODULE_PARM_DESC(lpfc_irq_chann, "Set number of interrupt vectors to allocate");
5787
5788/* lpfc_irq_chann_init - Set the hba irq_chann initial value
5789 * @phba: lpfc_hba pointer.
5790 * @val: contains the initial value
5791 *
5792 * Description:
5793 * Validates the initial value is within range and assigns it to the
5794 * adapter. If not in range, an error message is posted and the
5795 * default value is assigned.
5796 *
5797 * Returns:
5798 * zero if value is in range and is set
5799 * -EINVAL if value was out of range
5800 **/
5801static int
5802lpfc_irq_chann_init(struct lpfc_hba *phba, uint32_t val)
5803{
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005804 const struct cpumask *aff_mask;
James Smartdcaa2132019-11-04 16:57:06 -08005805
5806 if (phba->cfg_use_msi != 2) {
5807 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5808 "8532 use_msi = %u ignoring cfg_irq_numa\n",
5809 phba->cfg_use_msi);
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005810 phba->irq_chann_mode = NORMAL_MODE;
5811 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005812 return 0;
5813 }
5814
5815 /* Check if default setting was passed */
5816 if (val == LPFC_IRQ_CHANN_DEF)
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005817 lpfc_assign_default_irq_chann(phba);
James Smartdcaa2132019-11-04 16:57:06 -08005818
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005819 if (phba->irq_chann_mode != NORMAL_MODE) {
5820 aff_mask = &phba->sli4_hba.irq_aff_mask;
James Smartdcaa2132019-11-04 16:57:06 -08005821
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005822 if (cpumask_empty(aff_mask)) {
James Smartdcaa2132019-11-04 16:57:06 -08005823 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005824 "8533 Could not identify CPUS for "
5825 "mode %d, ignoring\n",
5826 phba->irq_chann_mode);
5827 phba->irq_chann_mode = NORMAL_MODE;
5828 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005829 } else {
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005830 phba->cfg_irq_chann = cpumask_weight(aff_mask);
5831
5832 /* If no hyperthread mode, then set hdwq count to
5833 * aff_mask weight as well
5834 */
5835 if (phba->irq_chann_mode == NHT_MODE)
5836 phba->cfg_hdw_queue = phba->cfg_irq_chann;
5837
James Smartdcaa2132019-11-04 16:57:06 -08005838 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5839 "8543 lpfc_irq_chann set to %u "
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005840 "(mode: %d)\n", phba->cfg_irq_chann,
5841 phba->irq_chann_mode);
James Smartdcaa2132019-11-04 16:57:06 -08005842 }
5843 } else {
5844 if (val > LPFC_IRQ_CHANN_MAX) {
5845 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5846 "8545 lpfc_irq_chann attribute cannot "
5847 "be set to %u, allowed range is "
5848 "[%u,%u]\n",
5849 val,
5850 LPFC_IRQ_CHANN_MIN,
5851 LPFC_IRQ_CHANN_MAX);
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005852 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005853 return -EINVAL;
5854 }
5855 phba->cfg_irq_chann = val;
5856 }
5857
5858 return 0;
5859}
5860
5861/**
5862 * lpfc_irq_chann_show - Display value of irq_chann
5863 * @dev: class converted to a Scsi_host structure.
5864 * @attr: device attribute, not used.
5865 * @buf: on return contains a string with the list sizes
5866 *
5867 * Returns: size of formatted string.
5868 **/
5869static ssize_t
5870lpfc_irq_chann_show(struct device *dev, struct device_attribute *attr,
5871 char *buf)
5872{
5873 struct Scsi_Host *shost = class_to_shost(dev);
5874 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5875 struct lpfc_hba *phba = vport->phba;
5876
5877 return scnprintf(buf, PAGE_SIZE, "%u\n", phba->cfg_irq_chann);
5878}
5879
5880static DEVICE_ATTR_RO(lpfc_irq_chann);
James Smart6a828b02019-01-28 11:14:31 -08005881
5882/*
James Smart13815c82008-01-11 01:52:48 -05005883# lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware.
5884# 0 = HBA resets disabled
5885# 1 = HBA resets enabled (default)
James Smart50212672018-12-13 15:17:57 -08005886# 2 = HBA reset via PCI bus reset enabled
5887# Value range is [0,2]. Default value is 1.
James Smart13815c82008-01-11 01:52:48 -05005888*/
James Smart50212672018-12-13 15:17:57 -08005889LPFC_ATTR_RW(enable_hba_reset, 1, 0, 2, "Enable HBA resets from the driver.");
James Smartc3f28af2006-08-18 17:47:18 -04005890
James Smart13815c82008-01-11 01:52:48 -05005891/*
James Smarteb7a3392010-11-20 23:12:02 -05005892# lpfc_enable_hba_heartbeat: Disable HBA heartbeat timer..
James Smart13815c82008-01-11 01:52:48 -05005893# 0 = HBA Heartbeat disabled
5894# 1 = HBA Heartbeat enabled (default)
5895# Value range is [0,1]. Default value is 1.
5896*/
James Smarteb7a3392010-11-20 23:12:02 -05005897LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat.");
James Smart92d7f7b2007-06-17 19:56:38 -05005898
James Smart83108bd2008-01-11 01:53:09 -05005899/*
James Smart1ba981f2014-02-20 09:56:45 -05005900# lpfc_EnableXLane: Enable Express Lane Feature
5901# 0x0 Express Lane Feature disabled
5902# 0x1 Express Lane Feature enabled
5903# Value range is [0,1]. Default value is 0.
5904*/
5905LPFC_ATTR_R(EnableXLane, 0, 0, 1, "Enable Express Lane Feature.");
5906
5907/*
5908# lpfc_XLanePriority: Define CS_CTL priority for Express Lane Feature
5909# 0x0 - 0x7f = CS_CTL field in FC header (high 7 bits)
5910# Value range is [0x0,0x7f]. Default value is 0
5911*/
James Smart28d7f3d2014-05-21 08:05:28 -04005912LPFC_ATTR_RW(XLanePriority, 0, 0x0, 0x7f, "CS_CTL for Express Lane Feature.");
James Smart1ba981f2014-02-20 09:56:45 -05005913
5914/*
James Smart81301a92008-12-04 22:39:46 -05005915# lpfc_enable_bg: Enable BlockGuard (Emulex's Implementation of T10-DIF)
5916# 0 = BlockGuard disabled (default)
5917# 1 = BlockGuard enabled
5918# Value range is [0,1]. Default value is 0.
5919*/
5920LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
5921
James Smart6fb120a2009-05-22 14:52:59 -04005922/*
James Smart81301a92008-12-04 22:39:46 -05005923# lpfc_prot_mask: i
5924# - Bit mask of host protection capabilities used to register with the
5925# SCSI mid-layer
5926# - Only meaningful if BG is turned on (lpfc_enable_bg=1).
5927# - Allows you to ultimately specify which profiles to use
5928# - Default will result in registering capabilities for all profiles.
James Smart005ffa72012-09-29 11:29:17 -04005929# - SHOST_DIF_TYPE1_PROTECTION 1
5930# HBA supports T10 DIF Type 1: HBA to Target Type 1 Protection
5931# - SHOST_DIX_TYPE0_PROTECTION 8
5932# HBA supports DIX Type 0: Host to HBA protection only
5933# - SHOST_DIX_TYPE1_PROTECTION 16
5934# HBA supports DIX Type 1: Host to HBA Type 1 protection
James Smart81301a92008-12-04 22:39:46 -05005935#
5936*/
James Smartb3b98b72016-10-13 15:06:06 -07005937LPFC_ATTR(prot_mask,
5938 (SHOST_DIF_TYPE1_PROTECTION |
5939 SHOST_DIX_TYPE0_PROTECTION |
5940 SHOST_DIX_TYPE1_PROTECTION),
5941 0,
5942 (SHOST_DIF_TYPE1_PROTECTION |
5943 SHOST_DIX_TYPE0_PROTECTION |
5944 SHOST_DIX_TYPE1_PROTECTION),
5945 "T10-DIF host protection capabilities mask");
James Smart81301a92008-12-04 22:39:46 -05005946
5947/*
5948# lpfc_prot_guard: i
5949# - Bit mask of protection guard types to register with the SCSI mid-layer
James Smart005ffa72012-09-29 11:29:17 -04005950# - Guard types are currently either 1) T10-DIF CRC 2) IP checksum
James Smart81301a92008-12-04 22:39:46 -05005951# - Allows you to ultimately specify which profiles to use
5952# - Default will result in registering capabilities for all guard types
5953#
5954*/
James Smartb3b98b72016-10-13 15:06:06 -07005955LPFC_ATTR(prot_guard,
5956 SHOST_DIX_GUARD_IP, SHOST_DIX_GUARD_CRC, SHOST_DIX_GUARD_IP,
5957 "T10-DIF host protection guard type");
James Smart81301a92008-12-04 22:39:46 -05005958
James Smart92494142011-02-16 12:39:44 -05005959/*
5960 * Delay initial NPort discovery when Clean Address bit is cleared in
5961 * FLOGI/FDISC accept and FCID/Fabric name/Fabric portname is changed.
5962 * This parameter can have value 0 or 1.
5963 * When this parameter is set to 0, no delay is added to the initial
5964 * discovery.
5965 * When this parameter is set to non-zero value, initial Nport discovery is
5966 * delayed by ra_tov seconds when Clean Address bit is cleared in FLOGI/FDISC
5967 * accept and FCID/Fabric name/Fabric portname is changed.
5968 * Driver always delay Nport discovery for subsequent FLOGI/FDISC completion
5969 * when Clean Address bit is cleared in FLOGI/FDISC
5970 * accept and FCID/Fabric name/Fabric portname is changed.
5971 * Default value is 0.
5972 */
James Smart8eb8b962016-07-06 12:36:08 -07005973LPFC_ATTR(delay_discovery, 0, 0, 1,
5974 "Delay NPort discovery when Clean Address bit is cleared.");
James Smart81301a92008-12-04 22:39:46 -05005975
5976/*
James Smart3621a712009-04-06 18:47:14 -04005977 * lpfc_sg_seg_cnt - Initial Maximum DMA Segment Count
James Smart5b9e70b2018-09-10 10:30:42 -07005978 * This value can be set to values between 64 and 4096. The default value
5979 * is 64, but may be increased to allow for larger Max I/O sizes. The scsi
5980 * and nvme layers will allow I/O sizes up to (MAX_SEG_COUNT * SEG_SIZE).
James Smart96f70772013-04-17 20:16:15 -04005981 * Because of the additional overhead involved in setting up T10-DIF,
5982 * this parameter will be limited to 128 if BlockGuard is enabled under SLI4
5983 * and will be limited to 512 if BlockGuard is enabled under SLI3.
James Smart83108bd2008-01-11 01:53:09 -05005984 */
James Smart5b9e70b2018-09-10 10:30:42 -07005985static uint lpfc_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
5986module_param(lpfc_sg_seg_cnt, uint, 0444);
5987MODULE_PARM_DESC(lpfc_sg_seg_cnt, "Max Scatter Gather Segment Count");
5988
5989/**
5990 * lpfc_sg_seg_cnt_show - Display the scatter/gather list sizes
5991 * configured for the adapter
5992 * @dev: class converted to a Scsi_host structure.
5993 * @attr: device attribute, not used.
5994 * @buf: on return contains a string with the list sizes
5995 *
5996 * Returns: size of formatted string.
5997 **/
5998static ssize_t
5999lpfc_sg_seg_cnt_show(struct device *dev, struct device_attribute *attr,
6000 char *buf)
6001{
6002 struct Scsi_Host *shost = class_to_shost(dev);
6003 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
6004 struct lpfc_hba *phba = vport->phba;
6005 int len;
6006
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07006007 len = scnprintf(buf, PAGE_SIZE, "SGL sz: %d total SGEs: %d\n",
James Smart5b9e70b2018-09-10 10:30:42 -07006008 phba->cfg_sg_dma_buf_size, phba->cfg_total_seg_cnt);
6009
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07006010 len += scnprintf(buf + len, PAGE_SIZE, "Cfg: %d SCSI: %d NVME: %d\n",
James Smart5b9e70b2018-09-10 10:30:42 -07006011 phba->cfg_sg_seg_cnt, phba->cfg_scsi_seg_cnt,
6012 phba->cfg_nvme_seg_cnt);
6013 return len;
6014}
6015
6016static DEVICE_ATTR_RO(lpfc_sg_seg_cnt);
6017
6018/**
6019 * lpfc_sg_seg_cnt_init - Set the hba sg_seg_cnt initial value
6020 * @phba: lpfc_hba pointer.
6021 * @val: contains the initial value
6022 *
6023 * Description:
6024 * Validates the initial value is within range and assigns it to the
6025 * adapter. If not in range, an error message is posted and the
6026 * default value is assigned.
6027 *
6028 * Returns:
6029 * zero if value is in range and is set
6030 * -EINVAL if value was out of range
6031 **/
6032static int
6033lpfc_sg_seg_cnt_init(struct lpfc_hba *phba, int val)
6034{
6035 if (val >= LPFC_MIN_SG_SEG_CNT && val <= LPFC_MAX_SG_SEG_CNT) {
6036 phba->cfg_sg_seg_cnt = val;
6037 return 0;
6038 }
6039 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
6040 "0409 "LPFC_DRIVER_NAME"_sg_seg_cnt attribute cannot "
6041 "be set to %d, allowed range is [%d, %d]\n",
6042 val, LPFC_MIN_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT);
6043 phba->cfg_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
6044 return -EINVAL;
6045}
James Smart83108bd2008-01-11 01:53:09 -05006046
James Smart96f70772013-04-17 20:16:15 -04006047/*
James Smart7bdedb32016-07-06 12:36:00 -07006048 * lpfc_enable_mds_diags: Enable MDS Diagnostics
6049 * 0 = MDS Diagnostics disabled (default)
6050 * 1 = MDS Diagnostics enabled
6051 * Value range is [0,1]. Default value is 0.
6052 */
James Smarte62245d2019-08-14 16:57:08 -07006053LPFC_ATTR_RW(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");
James Smart7bdedb32016-07-06 12:36:00 -07006054
James Smart44fd7fe2017-08-23 16:55:47 -07006055/*
James Smartd2cc9bc2018-09-10 10:30:50 -07006056 * lpfc_ras_fwlog_buffsize: Firmware logging host buffer size
6057 * 0 = Disable firmware logging (default)
6058 * [1-4] = Multiple of 1/4th Mb of host memory for FW logging
6059 * Value range [0..4]. Default value is 0
6060 */
James Smart95bfc6d2019-10-18 14:18:27 -07006061LPFC_ATTR(ras_fwlog_buffsize, 0, 0, 4, "Host memory for FW logging");
6062lpfc_param_show(ras_fwlog_buffsize);
6063
6064static ssize_t
6065lpfc_ras_fwlog_buffsize_set(struct lpfc_hba *phba, uint val)
6066{
6067 int ret = 0;
6068 enum ras_state state;
6069
6070 if (!lpfc_rangecheck(val, 0, 4))
6071 return -EINVAL;
6072
6073 if (phba->cfg_ras_fwlog_buffsize == val)
6074 return 0;
6075
James Smartdda5bdf2019-11-04 16:57:02 -08006076 if (phba->cfg_ras_fwlog_func != PCI_FUNC(phba->pcidev->devfn))
James Smart95bfc6d2019-10-18 14:18:27 -07006077 return -EINVAL;
6078
6079 spin_lock_irq(&phba->hbalock);
6080 state = phba->ras_fwlog.state;
6081 spin_unlock_irq(&phba->hbalock);
6082
6083 if (state == REG_INPROGRESS) {
6084 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "6147 RAS Logging "
6085 "registration is in progress\n");
6086 return -EBUSY;
6087 }
6088
6089 /* For disable logging: stop the logs and free the DMA.
6090 * For ras_fwlog_buffsize size change we still need to free and
6091 * reallocate the DMA in lpfc_sli4_ras_fwlog_init.
6092 */
6093 phba->cfg_ras_fwlog_buffsize = val;
6094 if (state == ACTIVE) {
6095 lpfc_ras_stop_fwlog(phba);
6096 lpfc_sli4_ras_dma_free(phba);
6097 }
6098
6099 lpfc_sli4_ras_init(phba);
6100 if (phba->ras_fwlog.ras_enabled)
6101 ret = lpfc_sli4_ras_fwlog_init(phba, phba->cfg_ras_fwlog_level,
6102 LPFC_RAS_ENABLE_LOGGING);
6103 return ret;
6104}
6105
6106lpfc_param_store(ras_fwlog_buffsize);
6107static DEVICE_ATTR_RW(lpfc_ras_fwlog_buffsize);
James Smartd2cc9bc2018-09-10 10:30:50 -07006108
6109/*
6110 * lpfc_ras_fwlog_level: Firmware logging verbosity level
6111 * Valid only if firmware logging is enabled
6112 * 0(Least Verbosity) 4 (most verbosity)
6113 * Value range is [0..4]. Default value is 0
6114 */
6115LPFC_ATTR_RW(ras_fwlog_level, 0, 0, 4, "Firmware Logging Level");
6116
6117/*
6118 * lpfc_ras_fwlog_func: Firmware logging enabled on function number
6119 * Default function which has RAS support : 0
6120 * Value Range is [0..7].
6121 * FW logging is a global action and enablement is via a specific
6122 * port.
6123 */
6124LPFC_ATTR_RW(ras_fwlog_func, 0, 0, 7, "Firmware Logging Enabled on Function");
6125
6126/*
James Smart44fd7fe2017-08-23 16:55:47 -07006127 * lpfc_enable_bbcr: Enable BB Credit Recovery
6128 * 0 = BB Credit Recovery disabled
6129 * 1 = BB Credit Recovery enabled (default)
6130 * Value range is [0,1]. Default value is 1.
6131 */
6132LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
6133
James Smart1351e692018-02-22 08:18:43 -08006134/*
6135 * lpfc_enable_dpp: Enable DPP on G7
6136 * 0 = DPP on G7 disabled
6137 * 1 = DPP on G7 enabled (default)
6138 * Value range is [0,1]. Default value is 1.
6139 */
6140LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
6141
James Smart8aaa7bc2020-10-20 13:27:17 -07006142/*
6143 * lpfc_enable_mi: Enable FDMI MIB
6144 * 0 = disabled
6145 * 1 = enabled (default)
6146 * Value range is [0,1].
6147 */
6148LPFC_ATTR_R(enable_mi, 1, 0, 1, "Enable MI");
6149
Tony Jonesee959b02008-02-22 00:13:36 +01006150struct device_attribute *lpfc_hba_attrs[] = {
James Smart895427b2017-02-12 13:52:30 -08006151 &dev_attr_nvme_info,
James Smart4c47efc2019-01-28 11:14:25 -08006152 &dev_attr_scsi_stat,
James Smart81301a92008-12-04 22:39:46 -05006153 &dev_attr_bg_info,
6154 &dev_attr_bg_guard_err,
6155 &dev_attr_bg_apptag_err,
6156 &dev_attr_bg_reftag_err,
Tony Jonesee959b02008-02-22 00:13:36 +01006157 &dev_attr_info,
6158 &dev_attr_serialnum,
6159 &dev_attr_modeldesc,
6160 &dev_attr_modelname,
6161 &dev_attr_programtype,
6162 &dev_attr_portnum,
6163 &dev_attr_fwrev,
6164 &dev_attr_hdw,
6165 &dev_attr_option_rom_version,
Hannes Reineckebbd1ae42008-03-18 14:32:28 +01006166 &dev_attr_link_state,
Tony Jonesee959b02008-02-22 00:13:36 +01006167 &dev_attr_num_discovered_ports,
James Smart84774a42008-08-24 21:50:06 -04006168 &dev_attr_menlo_mgmt_mode,
Tony Jonesee959b02008-02-22 00:13:36 +01006169 &dev_attr_lpfc_drvr_version,
James Smart45ed1192009-10-02 15:17:02 -04006170 &dev_attr_lpfc_enable_fip,
Tony Jonesee959b02008-02-22 00:13:36 +01006171 &dev_attr_lpfc_temp_sensor,
6172 &dev_attr_lpfc_log_verbose,
6173 &dev_attr_lpfc_lun_queue_depth,
James Smart7dc517d2010-07-14 15:32:10 -04006174 &dev_attr_lpfc_tgt_queue_depth,
Tony Jonesee959b02008-02-22 00:13:36 +01006175 &dev_attr_lpfc_hba_queue_depth,
6176 &dev_attr_lpfc_peer_port_login,
6177 &dev_attr_lpfc_nodev_tmo,
6178 &dev_attr_lpfc_devloss_tmo,
James Smart895427b2017-02-12 13:52:30 -08006179 &dev_attr_lpfc_enable_fc4_type,
Tony Jonesee959b02008-02-22 00:13:36 +01006180 &dev_attr_lpfc_fcp_class,
6181 &dev_attr_lpfc_use_adisc,
James Smart3cb01c52013-07-15 18:35:04 -04006182 &dev_attr_lpfc_first_burst_size,
Tony Jonesee959b02008-02-22 00:13:36 +01006183 &dev_attr_lpfc_ack0,
James Smartc4908502019-01-28 11:14:28 -08006184 &dev_attr_lpfc_xri_rebalancing,
Tony Jonesee959b02008-02-22 00:13:36 +01006185 &dev_attr_lpfc_topology,
6186 &dev_attr_lpfc_scan_down,
6187 &dev_attr_lpfc_link_speed,
James Smart49aa1432012-08-03 12:36:42 -04006188 &dev_attr_lpfc_fcp_io_sched,
James Smart7ea92eb2018-10-23 13:41:10 -07006189 &dev_attr_lpfc_ns_query,
James Smarta6571c62012-10-31 14:44:42 -04006190 &dev_attr_lpfc_fcp2_no_tgt_reset,
Tony Jonesee959b02008-02-22 00:13:36 +01006191 &dev_attr_lpfc_cr_delay,
6192 &dev_attr_lpfc_cr_count,
6193 &dev_attr_lpfc_multi_ring_support,
6194 &dev_attr_lpfc_multi_ring_rctl,
6195 &dev_attr_lpfc_multi_ring_type,
6196 &dev_attr_lpfc_fdmi_on,
James Smart4258e982015-12-16 18:11:58 -05006197 &dev_attr_lpfc_enable_SmartSAN,
Tony Jonesee959b02008-02-22 00:13:36 +01006198 &dev_attr_lpfc_max_luns,
6199 &dev_attr_lpfc_enable_npiv,
James Smart7d791df2011-07-22 18:37:52 -04006200 &dev_attr_lpfc_fcf_failover_policy,
James Smart19ca7602010-11-20 23:11:55 -05006201 &dev_attr_lpfc_enable_rrq,
Tony Jonesee959b02008-02-22 00:13:36 +01006202 &dev_attr_nport_evt_cnt,
6203 &dev_attr_board_mode,
6204 &dev_attr_max_vpi,
6205 &dev_attr_used_vpi,
6206 &dev_attr_max_rpi,
6207 &dev_attr_used_rpi,
6208 &dev_attr_max_xri,
6209 &dev_attr_used_xri,
6210 &dev_attr_npiv_info,
6211 &dev_attr_issue_reset,
6212 &dev_attr_lpfc_poll,
6213 &dev_attr_lpfc_poll_tmo,
James Smart0c411222013-09-06 12:22:46 -04006214 &dev_attr_lpfc_task_mgmt_tmo,
Tony Jonesee959b02008-02-22 00:13:36 +01006215 &dev_attr_lpfc_use_msi,
James Smart895427b2017-02-12 13:52:30 -08006216 &dev_attr_lpfc_nvme_oas,
James Smart4e565cf2018-02-22 08:18:50 -08006217 &dev_attr_lpfc_nvme_embed_cmd,
James Smartda0436e2009-05-22 14:51:39 -04006218 &dev_attr_lpfc_fcp_imax,
James Smart41b194b2019-05-14 14:58:08 -07006219 &dev_attr_lpfc_force_rscn,
James Smart32517fc2019-01-28 11:14:33 -08006220 &dev_attr_lpfc_cq_poll_threshold,
6221 &dev_attr_lpfc_cq_max_proc_limit,
James Smart7bb03bb2013-04-17 20:19:16 -04006222 &dev_attr_lpfc_fcp_cpu_map,
James Smart77ffd342019-08-15 19:36:49 -07006223 &dev_attr_lpfc_fcp_mq_threshold,
James Smartcdb42be2019-01-28 11:14:21 -08006224 &dev_attr_lpfc_hdw_queue,
James Smart6a828b02019-01-28 11:14:31 -08006225 &dev_attr_lpfc_irq_chann,
James Smartf358dd02017-02-12 13:52:34 -08006226 &dev_attr_lpfc_suppress_rsp,
James Smart2d7dbc42017-02-12 13:52:35 -08006227 &dev_attr_lpfc_nvmet_mrq,
James Smart2448e482018-04-09 14:24:24 -07006228 &dev_attr_lpfc_nvmet_mrq_post,
James Smart895427b2017-02-12 13:52:30 -08006229 &dev_attr_lpfc_nvme_enable_fb,
James Smart2d7dbc42017-02-12 13:52:35 -08006230 &dev_attr_lpfc_nvmet_fb_size,
James Smart81301a92008-12-04 22:39:46 -05006231 &dev_attr_lpfc_enable_bg,
James Smart352e5fd2016-12-30 06:57:47 -08006232 &dev_attr_lpfc_soft_wwnn,
6233 &dev_attr_lpfc_soft_wwpn,
6234 &dev_attr_lpfc_soft_wwn_enable,
Tony Jonesee959b02008-02-22 00:13:36 +01006235 &dev_attr_lpfc_enable_hba_reset,
6236 &dev_attr_lpfc_enable_hba_heartbeat,
James Smart1ba981f2014-02-20 09:56:45 -05006237 &dev_attr_lpfc_EnableXLane,
6238 &dev_attr_lpfc_XLanePriority,
6239 &dev_attr_lpfc_xlane_lun,
6240 &dev_attr_lpfc_xlane_tgt,
6241 &dev_attr_lpfc_xlane_vpt,
6242 &dev_attr_lpfc_xlane_lun_state,
6243 &dev_attr_lpfc_xlane_lun_status,
James Smartc92c8412016-07-06 12:36:05 -07006244 &dev_attr_lpfc_xlane_priority,
Tony Jonesee959b02008-02-22 00:13:36 +01006245 &dev_attr_lpfc_sg_seg_cnt,
James Smart977b5a02008-09-07 11:52:04 -04006246 &dev_attr_lpfc_max_scsicmpl_time,
James Smartea2151b2008-09-07 11:52:10 -04006247 &dev_attr_lpfc_stat_data_ctrl,
James Smart0d878412009-10-02 15:16:56 -04006248 &dev_attr_lpfc_aer_support,
6249 &dev_attr_lpfc_aer_state_cleanup,
James Smart912e3ac2011-05-24 11:42:11 -04006250 &dev_attr_lpfc_sriov_nr_virtfn,
James Smartc71ab862012-10-31 14:44:33 -04006251 &dev_attr_lpfc_req_fw_upgrade,
James Smart84d1b002010-02-12 14:42:33 -05006252 &dev_attr_lpfc_suppress_link_up,
James Smart2a9bf3d2010-06-07 15:24:45 -04006253 &dev_attr_iocb_hw,
James Smart83c6cb12019-10-18 14:18:30 -07006254 &dev_attr_pls,
6255 &dev_attr_pt,
James Smart2a9bf3d2010-06-07 15:24:45 -04006256 &dev_attr_txq_hw,
6257 &dev_attr_txcmplq_hw,
James Smart912e3ac2011-05-24 11:42:11 -04006258 &dev_attr_lpfc_sriov_hw_max_virtfn,
James Smart026abb82011-12-13 13:20:45 -05006259 &dev_attr_protocol,
James Smart1ba981f2014-02-20 09:56:45 -05006260 &dev_attr_lpfc_xlane_supported,
James Smart7bdedb32016-07-06 12:36:00 -07006261 &dev_attr_lpfc_enable_mds_diags,
James Smartd2cc9bc2018-09-10 10:30:50 -07006262 &dev_attr_lpfc_ras_fwlog_buffsize,
6263 &dev_attr_lpfc_ras_fwlog_level,
6264 &dev_attr_lpfc_ras_fwlog_func,
James Smart44fd7fe2017-08-23 16:55:47 -07006265 &dev_attr_lpfc_enable_bbcr,
James Smart1351e692018-02-22 08:18:43 -08006266 &dev_attr_lpfc_enable_dpp,
James Smart8aaa7bc2020-10-20 13:27:17 -07006267 &dev_attr_lpfc_enable_mi,
dea31012005-04-17 16:05:31 -05006268 NULL,
6269};
6270
Tony Jonesee959b02008-02-22 00:13:36 +01006271struct device_attribute *lpfc_vport_attrs[] = {
6272 &dev_attr_info,
Hannes Reineckebbd1ae42008-03-18 14:32:28 +01006273 &dev_attr_link_state,
Tony Jonesee959b02008-02-22 00:13:36 +01006274 &dev_attr_num_discovered_ports,
6275 &dev_attr_lpfc_drvr_version,
6276 &dev_attr_lpfc_log_verbose,
6277 &dev_attr_lpfc_lun_queue_depth,
James Smart7dc517d2010-07-14 15:32:10 -04006278 &dev_attr_lpfc_tgt_queue_depth,
Tony Jonesee959b02008-02-22 00:13:36 +01006279 &dev_attr_lpfc_nodev_tmo,
6280 &dev_attr_lpfc_devloss_tmo,
6281 &dev_attr_lpfc_hba_queue_depth,
6282 &dev_attr_lpfc_peer_port_login,
6283 &dev_attr_lpfc_restrict_login,
6284 &dev_attr_lpfc_fcp_class,
6285 &dev_attr_lpfc_use_adisc,
James Smart3cb01c52013-07-15 18:35:04 -04006286 &dev_attr_lpfc_first_burst_size,
Tony Jonesee959b02008-02-22 00:13:36 +01006287 &dev_attr_lpfc_max_luns,
6288 &dev_attr_nport_evt_cnt,
6289 &dev_attr_npiv_info,
6290 &dev_attr_lpfc_enable_da_id,
James Smartea2151b2008-09-07 11:52:10 -04006291 &dev_attr_lpfc_max_scsicmpl_time,
6292 &dev_attr_lpfc_stat_data_ctrl,
James Smart21e9a0a2009-05-22 14:53:21 -04006293 &dev_attr_lpfc_static_vport,
James Smart3de2a652007-08-02 11:09:59 -04006294 NULL,
6295};
6296
James Smarte59058c2008-08-24 21:49:00 -04006297/**
James Smart3621a712009-04-06 18:47:14 -04006298 * sysfs_ctlreg_write - Write method for writing to ctlreg
Chris Wright2c3c8be2010-05-12 18:28:57 -07006299 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006300 * @kobj: kernel kobject that contains the kernel class device.
6301 * @bin_attr: kernel attributes passed to us.
6302 * @buf: contains the data to be written to the adapter IOREG space.
6303 * @off: offset into buffer to beginning of data.
6304 * @count: bytes to transfer.
6305 *
6306 * Description:
6307 * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
6308 * Uses the adapter io control registers to send buf contents to the adapter.
6309 *
6310 * Returns:
6311 * -ERANGE off and count combo out of range
6312 * -EINVAL off, count or buff address invalid
6313 * -EPERM adapter is offline
6314 * value of count, buf contents written
6315 **/
dea31012005-04-17 16:05:31 -05006316static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006317sysfs_ctlreg_write(struct file *filp, struct kobject *kobj,
6318 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006319 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006320{
6321 size_t buf_off;
Tony Jonesee959b02008-02-22 00:13:36 +01006322 struct device *dev = container_of(kobj, struct device, kobj);
6323 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05006324 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6325 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006326
James Smartf1126682009-06-10 17:22:44 -04006327 if (phba->sli_rev >= LPFC_SLI_REV4)
6328 return -EPERM;
6329
dea31012005-04-17 16:05:31 -05006330 if ((off + count) > FF_REG_AREA_SIZE)
6331 return -ERANGE;
6332
James Smartf7a919b2011-08-21 21:49:16 -04006333 if (count <= LPFC_REG_WRITE_KEY_SIZE)
6334 return 0;
dea31012005-04-17 16:05:31 -05006335
6336 if (off % 4 || count % 4 || (unsigned long)buf % 4)
6337 return -EINVAL;
6338
James Smartf7a919b2011-08-21 21:49:16 -04006339 /* This is to protect HBA registers from accidental writes. */
6340 if (memcmp(buf, LPFC_REG_WRITE_KEY, LPFC_REG_WRITE_KEY_SIZE))
6341 return -EINVAL;
6342
6343 if (!(vport->fc_flag & FC_OFFLINE_MODE))
dea31012005-04-17 16:05:31 -05006344 return -EPERM;
dea31012005-04-17 16:05:31 -05006345
James Smart2e0fef82007-06-17 19:56:36 -05006346 spin_lock_irq(&phba->hbalock);
James Smartf7a919b2011-08-21 21:49:16 -04006347 for (buf_off = 0; buf_off < count - LPFC_REG_WRITE_KEY_SIZE;
6348 buf_off += sizeof(uint32_t))
6349 writel(*((uint32_t *)(buf + buf_off + LPFC_REG_WRITE_KEY_SIZE)),
dea31012005-04-17 16:05:31 -05006350 phba->ctrl_regs_memmap_p + off + buf_off);
6351
James Smart2e0fef82007-06-17 19:56:36 -05006352 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006353
6354 return count;
6355}
6356
James Smarte59058c2008-08-24 21:49:00 -04006357/**
James Smart3621a712009-04-06 18:47:14 -04006358 * sysfs_ctlreg_read - Read method for reading from ctlreg
Chris Wright2c3c8be2010-05-12 18:28:57 -07006359 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006360 * @kobj: kernel kobject that contains the kernel class device.
6361 * @bin_attr: kernel attributes passed to us.
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02006362 * @buf: if successful contains the data from the adapter IOREG space.
James Smarte59058c2008-08-24 21:49:00 -04006363 * @off: offset into buffer to beginning of data.
6364 * @count: bytes to transfer.
6365 *
6366 * Description:
6367 * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
6368 * Uses the adapter io control registers to read data into buf.
6369 *
6370 * Returns:
6371 * -ERANGE off and count combo out of range
6372 * -EINVAL off, count or buff address invalid
6373 * value of count, buf contents read
6374 **/
dea31012005-04-17 16:05:31 -05006375static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006376sysfs_ctlreg_read(struct file *filp, struct kobject *kobj,
6377 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006378 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006379{
6380 size_t buf_off;
6381 uint32_t * tmp_ptr;
Tony Jonesee959b02008-02-22 00:13:36 +01006382 struct device *dev = container_of(kobj, struct device, kobj);
6383 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05006384 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6385 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006386
James Smartf1126682009-06-10 17:22:44 -04006387 if (phba->sli_rev >= LPFC_SLI_REV4)
6388 return -EPERM;
6389
dea31012005-04-17 16:05:31 -05006390 if (off > FF_REG_AREA_SIZE)
6391 return -ERANGE;
6392
6393 if ((off + count) > FF_REG_AREA_SIZE)
6394 count = FF_REG_AREA_SIZE - off;
6395
6396 if (count == 0) return 0;
6397
6398 if (off % 4 || count % 4 || (unsigned long)buf % 4)
6399 return -EINVAL;
6400
James Smart2e0fef82007-06-17 19:56:36 -05006401 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006402
6403 for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {
6404 tmp_ptr = (uint32_t *)(buf + buf_off);
6405 *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);
6406 }
6407
James Smart2e0fef82007-06-17 19:56:36 -05006408 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006409
6410 return count;
6411}
6412
6413static struct bin_attribute sysfs_ctlreg_attr = {
6414 .attr = {
6415 .name = "ctlreg",
6416 .mode = S_IRUSR | S_IWUSR,
dea31012005-04-17 16:05:31 -05006417 },
6418 .size = 256,
6419 .read = sysfs_ctlreg_read,
6420 .write = sysfs_ctlreg_write,
6421};
6422
James Smarte59058c2008-08-24 21:49:00 -04006423/**
James Smart3621a712009-04-06 18:47:14 -04006424 * sysfs_mbox_write - Write method for writing information via mbox
Chris Wright2c3c8be2010-05-12 18:28:57 -07006425 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006426 * @kobj: kernel kobject that contains the kernel class device.
6427 * @bin_attr: kernel attributes passed to us.
6428 * @buf: contains the data to be written to sysfs mbox.
6429 * @off: offset into buffer to beginning of data.
6430 * @count: bytes to transfer.
6431 *
6432 * Description:
James Smart026abb82011-12-13 13:20:45 -05006433 * Deprecated function. All mailbox access from user space is performed via the
6434 * bsg interface.
James Smarte59058c2008-08-24 21:49:00 -04006435 *
6436 * Returns:
James Smart026abb82011-12-13 13:20:45 -05006437 * -EPERM operation not permitted
James Smarte59058c2008-08-24 21:49:00 -04006438 **/
dea31012005-04-17 16:05:31 -05006439static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006440sysfs_mbox_write(struct file *filp, struct kobject *kobj,
6441 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006442 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006443{
James Smart026abb82011-12-13 13:20:45 -05006444 return -EPERM;
dea31012005-04-17 16:05:31 -05006445}
6446
James Smarte59058c2008-08-24 21:49:00 -04006447/**
James Smart3621a712009-04-06 18:47:14 -04006448 * sysfs_mbox_read - Read method for reading information via mbox
Chris Wright2c3c8be2010-05-12 18:28:57 -07006449 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006450 * @kobj: kernel kobject that contains the kernel class device.
6451 * @bin_attr: kernel attributes passed to us.
6452 * @buf: contains the data to be read from sysfs mbox.
6453 * @off: offset into buffer to beginning of data.
6454 * @count: bytes to transfer.
6455 *
6456 * Description:
James Smart026abb82011-12-13 13:20:45 -05006457 * Deprecated function. All mailbox access from user space is performed via the
6458 * bsg interface.
James Smarte59058c2008-08-24 21:49:00 -04006459 *
6460 * Returns:
James Smart026abb82011-12-13 13:20:45 -05006461 * -EPERM operation not permitted
James Smarte59058c2008-08-24 21:49:00 -04006462 **/
dea31012005-04-17 16:05:31 -05006463static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006464sysfs_mbox_read(struct file *filp, struct kobject *kobj,
6465 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006466 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006467{
James Smart026abb82011-12-13 13:20:45 -05006468 return -EPERM;
dea31012005-04-17 16:05:31 -05006469}
6470
6471static struct bin_attribute sysfs_mbox_attr = {
6472 .attr = {
6473 .name = "mbox",
6474 .mode = S_IRUSR | S_IWUSR,
dea31012005-04-17 16:05:31 -05006475 },
James Smartc0c11512011-05-24 11:41:34 -04006476 .size = MAILBOX_SYSFS_MAX,
dea31012005-04-17 16:05:31 -05006477 .read = sysfs_mbox_read,
6478 .write = sysfs_mbox_write,
6479};
6480
James Smarte59058c2008-08-24 21:49:00 -04006481/**
James Smart3621a712009-04-06 18:47:14 -04006482 * lpfc_alloc_sysfs_attr - Creates the ctlreg and mbox entries
James Smarte59058c2008-08-24 21:49:00 -04006483 * @vport: address of lpfc vport structure.
6484 *
6485 * Return codes:
6486 * zero on success
6487 * error return code from sysfs_create_bin_file()
6488 **/
dea31012005-04-17 16:05:31 -05006489int
James Smart2e0fef82007-06-17 19:56:36 -05006490lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05006491{
James Smart2e0fef82007-06-17 19:56:36 -05006492 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05006493 int error;
6494
Tony Jonesee959b02008-02-22 00:13:36 +01006495 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smarteada2722008-12-04 22:39:13 -05006496 &sysfs_drvr_stat_data_attr);
6497
6498 /* Virtual ports do not need ctrl_reg and mbox */
6499 if (error || vport->port_type == LPFC_NPIV_PORT)
6500 goto out;
6501
6502 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smart92d7f7b2007-06-17 19:56:38 -05006503 &sysfs_ctlreg_attr);
dea31012005-04-17 16:05:31 -05006504 if (error)
James Smarteada2722008-12-04 22:39:13 -05006505 goto out_remove_stat_attr;
dea31012005-04-17 16:05:31 -05006506
Tony Jonesee959b02008-02-22 00:13:36 +01006507 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smart92d7f7b2007-06-17 19:56:38 -05006508 &sysfs_mbox_attr);
dea31012005-04-17 16:05:31 -05006509 if (error)
6510 goto out_remove_ctlreg_attr;
6511
6512 return 0;
6513out_remove_ctlreg_attr:
Tony Jonesee959b02008-02-22 00:13:36 +01006514 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
James Smarteada2722008-12-04 22:39:13 -05006515out_remove_stat_attr:
6516 sysfs_remove_bin_file(&shost->shost_dev.kobj,
6517 &sysfs_drvr_stat_data_attr);
dea31012005-04-17 16:05:31 -05006518out:
6519 return error;
6520}
6521
James Smarte59058c2008-08-24 21:49:00 -04006522/**
James Smart3621a712009-04-06 18:47:14 -04006523 * lpfc_free_sysfs_attr - Removes the ctlreg and mbox entries
James Smarte59058c2008-08-24 21:49:00 -04006524 * @vport: address of lpfc vport structure.
6525 **/
dea31012005-04-17 16:05:31 -05006526void
James Smart2e0fef82007-06-17 19:56:36 -05006527lpfc_free_sysfs_attr(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05006528{
James Smart2e0fef82007-06-17 19:56:36 -05006529 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smartea2151b2008-09-07 11:52:10 -04006530 sysfs_remove_bin_file(&shost->shost_dev.kobj,
6531 &sysfs_drvr_stat_data_attr);
James Smarteada2722008-12-04 22:39:13 -05006532 /* Virtual ports do not need ctrl_reg and mbox */
6533 if (vport->port_type == LPFC_NPIV_PORT)
6534 return;
Tony Jonesee959b02008-02-22 00:13:36 +01006535 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
6536 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
dea31012005-04-17 16:05:31 -05006537}
6538
dea31012005-04-17 16:05:31 -05006539/*
6540 * Dynamic FC Host Attributes Support
6541 */
6542
James Smarte59058c2008-08-24 21:49:00 -04006543/**
James Smart6c9231f2016-12-19 15:07:24 -08006544 * lpfc_get_host_symbolic_name - Copy symbolic name into the scsi host
6545 * @shost: kernel scsi host pointer.
6546 **/
6547static void
6548lpfc_get_host_symbolic_name(struct Scsi_Host *shost)
6549{
6550 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
6551
6552 lpfc_vport_symbolic_node_name(vport, fc_host_symbolic_name(shost),
6553 sizeof fc_host_symbolic_name(shost));
6554}
6555
6556/**
James Smart3621a712009-04-06 18:47:14 -04006557 * lpfc_get_host_port_id - Copy the vport DID into the scsi host port id
James Smarte59058c2008-08-24 21:49:00 -04006558 * @shost: kernel scsi host pointer.
6559 **/
dea31012005-04-17 16:05:31 -05006560static void
6561lpfc_get_host_port_id(struct Scsi_Host *shost)
6562{
James Smart2e0fef82007-06-17 19:56:36 -05006563 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6564
dea31012005-04-17 16:05:31 -05006565 /* note: fc_myDID already in cpu endianness */
James Smart2e0fef82007-06-17 19:56:36 -05006566 fc_host_port_id(shost) = vport->fc_myDID;
dea31012005-04-17 16:05:31 -05006567}
6568
James Smarte59058c2008-08-24 21:49:00 -04006569/**
James Smart3621a712009-04-06 18:47:14 -04006570 * lpfc_get_host_port_type - Set the value of the scsi host port type
James Smarte59058c2008-08-24 21:49:00 -04006571 * @shost: kernel scsi host pointer.
6572 **/
dea31012005-04-17 16:05:31 -05006573static void
6574lpfc_get_host_port_type(struct Scsi_Host *shost)
6575{
James Smart2e0fef82007-06-17 19:56:36 -05006576 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6577 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006578
6579 spin_lock_irq(shost->host_lock);
6580
James Smart92d7f7b2007-06-17 19:56:38 -05006581 if (vport->port_type == LPFC_NPIV_PORT) {
6582 fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
6583 } else if (lpfc_is_link_up(phba)) {
James Smart76a95d72010-11-20 23:11:48 -05006584 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smart2e0fef82007-06-17 19:56:36 -05006585 if (vport->fc_flag & FC_PUBLIC_LOOP)
dea31012005-04-17 16:05:31 -05006586 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
6587 else
6588 fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
6589 } else {
James Smart2e0fef82007-06-17 19:56:36 -05006590 if (vport->fc_flag & FC_FABRIC)
dea31012005-04-17 16:05:31 -05006591 fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
6592 else
6593 fc_host_port_type(shost) = FC_PORTTYPE_PTP;
6594 }
6595 } else
6596 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
6597
6598 spin_unlock_irq(shost->host_lock);
6599}
6600
James Smarte59058c2008-08-24 21:49:00 -04006601/**
James Smart3621a712009-04-06 18:47:14 -04006602 * lpfc_get_host_port_state - Set the value of the scsi host port state
James Smarte59058c2008-08-24 21:49:00 -04006603 * @shost: kernel scsi host pointer.
6604 **/
dea31012005-04-17 16:05:31 -05006605static void
6606lpfc_get_host_port_state(struct Scsi_Host *shost)
6607{
James Smart2e0fef82007-06-17 19:56:36 -05006608 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6609 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006610
6611 spin_lock_irq(shost->host_lock);
6612
James Smart2e0fef82007-06-17 19:56:36 -05006613 if (vport->fc_flag & FC_OFFLINE_MODE)
dea31012005-04-17 16:05:31 -05006614 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
6615 else {
James Smart2e0fef82007-06-17 19:56:36 -05006616 switch (phba->link_state) {
6617 case LPFC_LINK_UNKNOWN:
dea31012005-04-17 16:05:31 -05006618 case LPFC_LINK_DOWN:
6619 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
6620 break;
6621 case LPFC_LINK_UP:
dea31012005-04-17 16:05:31 -05006622 case LPFC_CLEAR_LA:
6623 case LPFC_HBA_READY:
James Smart026abb82011-12-13 13:20:45 -05006624 /* Links up, reports port state accordingly */
6625 if (vport->port_state < LPFC_VPORT_READY)
6626 fc_host_port_state(shost) =
6627 FC_PORTSTATE_BYPASSED;
6628 else
6629 fc_host_port_state(shost) =
6630 FC_PORTSTATE_ONLINE;
dea31012005-04-17 16:05:31 -05006631 break;
6632 case LPFC_HBA_ERROR:
6633 fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
6634 break;
6635 default:
6636 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
6637 break;
6638 }
6639 }
6640
6641 spin_unlock_irq(shost->host_lock);
6642}
6643
James Smarte59058c2008-08-24 21:49:00 -04006644/**
James Smart3621a712009-04-06 18:47:14 -04006645 * lpfc_get_host_speed - Set the value of the scsi host speed
James Smarte59058c2008-08-24 21:49:00 -04006646 * @shost: kernel scsi host pointer.
6647 **/
dea31012005-04-17 16:05:31 -05006648static void
6649lpfc_get_host_speed(struct Scsi_Host *shost)
6650{
James Smart2e0fef82007-06-17 19:56:36 -05006651 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6652 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006653
6654 spin_lock_irq(shost->host_lock);
6655
James Smarta085e872015-12-16 18:12:02 -05006656 if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) {
dea31012005-04-17 16:05:31 -05006657 switch(phba->fc_linkspeed) {
James Smart76a95d72010-11-20 23:11:48 -05006658 case LPFC_LINK_SPEED_1GHZ:
6659 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
dea31012005-04-17 16:05:31 -05006660 break;
James Smart76a95d72010-11-20 23:11:48 -05006661 case LPFC_LINK_SPEED_2GHZ:
6662 fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
dea31012005-04-17 16:05:31 -05006663 break;
James Smart76a95d72010-11-20 23:11:48 -05006664 case LPFC_LINK_SPEED_4GHZ:
6665 fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
dea31012005-04-17 16:05:31 -05006666 break;
James Smart76a95d72010-11-20 23:11:48 -05006667 case LPFC_LINK_SPEED_8GHZ:
6668 fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
James Smartb87eab32007-04-25 09:53:28 -04006669 break;
James Smart76a95d72010-11-20 23:11:48 -05006670 case LPFC_LINK_SPEED_10GHZ:
6671 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
James Smartf4b4c682009-05-22 14:53:12 -04006672 break;
James Smart76a95d72010-11-20 23:11:48 -05006673 case LPFC_LINK_SPEED_16GHZ:
6674 fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
6675 break;
James Smartd38dd522015-08-31 16:48:17 -04006676 case LPFC_LINK_SPEED_32GHZ:
6677 fc_host_speed(shost) = FC_PORTSPEED_32GBIT;
6678 break;
James Smartfbd8a6b2018-02-22 08:18:45 -08006679 case LPFC_LINK_SPEED_64GHZ:
6680 fc_host_speed(shost) = FC_PORTSPEED_64GBIT;
6681 break;
James Smart1dc5ec22018-10-23 13:41:11 -07006682 case LPFC_LINK_SPEED_128GHZ:
6683 fc_host_speed(shost) = FC_PORTSPEED_128GBIT;
6684 break;
James Smart76a95d72010-11-20 23:11:48 -05006685 default:
6686 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
dea31012005-04-17 16:05:31 -05006687 break;
6688 }
James Smartb615a202018-07-31 17:23:19 -07006689 } else if (lpfc_is_link_up(phba) && (phba->hba_flag & HBA_FCOE_MODE)) {
6690 switch (phba->fc_linkspeed) {
Dick Kennedya1e4d3d2020-08-03 14:02:22 -07006691 case LPFC_ASYNC_LINK_SPEED_1GBPS:
6692 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
6693 break;
James Smartb615a202018-07-31 17:23:19 -07006694 case LPFC_ASYNC_LINK_SPEED_10GBPS:
6695 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
6696 break;
Dick Kennedya1e4d3d2020-08-03 14:02:22 -07006697 case LPFC_ASYNC_LINK_SPEED_20GBPS:
6698 fc_host_speed(shost) = FC_PORTSPEED_20GBIT;
6699 break;
James Smartb615a202018-07-31 17:23:19 -07006700 case LPFC_ASYNC_LINK_SPEED_25GBPS:
6701 fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
6702 break;
6703 case LPFC_ASYNC_LINK_SPEED_40GBPS:
6704 fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
6705 break;
6706 case LPFC_ASYNC_LINK_SPEED_100GBPS:
6707 fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
6708 break;
6709 default:
6710 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
6711 break;
6712 }
James Smart09372822008-01-11 01:52:54 -05006713 } else
6714 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
dea31012005-04-17 16:05:31 -05006715
6716 spin_unlock_irq(shost->host_lock);
6717}
6718
James Smarte59058c2008-08-24 21:49:00 -04006719/**
James Smart3621a712009-04-06 18:47:14 -04006720 * lpfc_get_host_fabric_name - Set the value of the scsi host fabric name
James Smarte59058c2008-08-24 21:49:00 -04006721 * @shost: kernel scsi host pointer.
6722 **/
dea31012005-04-17 16:05:31 -05006723static void
6724lpfc_get_host_fabric_name (struct Scsi_Host *shost)
6725{
James Smart2e0fef82007-06-17 19:56:36 -05006726 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6727 struct lpfc_hba *phba = vport->phba;
Andrew Vasquezf631b4b2005-08-31 15:23:12 -07006728 u64 node_name;
dea31012005-04-17 16:05:31 -05006729
6730 spin_lock_irq(shost->host_lock);
6731
James Smart73d91e52011-10-10 21:32:10 -04006732 if ((vport->port_state > LPFC_FLOGI) &&
6733 ((vport->fc_flag & FC_FABRIC) ||
6734 ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
6735 (vport->fc_flag & FC_PUBLIC_LOOP))))
Andrew Morton68ce1eb2005-09-21 09:46:54 -07006736 node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
dea31012005-04-17 16:05:31 -05006737 else
6738 /* fabric is local port if there is no F/FL_Port */
James Smart09372822008-01-11 01:52:54 -05006739 node_name = 0;
dea31012005-04-17 16:05:31 -05006740
6741 spin_unlock_irq(shost->host_lock);
6742
Andrew Vasquezf631b4b2005-08-31 15:23:12 -07006743 fc_host_fabric_name(shost) = node_name;
dea31012005-04-17 16:05:31 -05006744}
6745
James Smarte59058c2008-08-24 21:49:00 -04006746/**
James Smart3621a712009-04-06 18:47:14 -04006747 * lpfc_get_stats - Return statistical information about the adapter
James Smarte59058c2008-08-24 21:49:00 -04006748 * @shost: kernel scsi host pointer.
6749 *
6750 * Notes:
6751 * NULL on error for link down, no mbox pool, sli2 active,
6752 * management not allowed, memory allocation error, or mbox error.
6753 *
6754 * Returns:
6755 * NULL for error
6756 * address of the adapter host statistics
6757 **/
dea31012005-04-17 16:05:31 -05006758static struct fc_host_statistics *
6759lpfc_get_stats(struct Scsi_Host *shost)
6760{
James Smart2e0fef82007-06-17 19:56:36 -05006761 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6762 struct lpfc_hba *phba = vport->phba;
6763 struct lpfc_sli *psli = &phba->sli;
James.Smart@Emulex.Comf888ba32005-08-10 15:03:01 -04006764 struct fc_host_statistics *hs = &phba->link_stats;
James Smart64ba8812006-08-02 15:24:34 -04006765 struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
dea31012005-04-17 16:05:31 -05006766 LPFC_MBOXQ_t *pmboxq;
6767 MAILBOX_t *pmb;
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006768 int rc = 0;
dea31012005-04-17 16:05:31 -05006769
James Smart92d7f7b2007-06-17 19:56:38 -05006770 /*
6771 * prevent udev from issuing mailbox commands until the port is
6772 * configured.
6773 */
James Smart2e0fef82007-06-17 19:56:36 -05006774 if (phba->link_state < LPFC_LINK_DOWN ||
6775 !phba->mbox_mem_pool ||
James Smartf4b4c682009-05-22 14:53:12 -04006776 (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
James Smart92d7f7b2007-06-17 19:56:38 -05006777 return NULL;
James Smart2e0fef82007-06-17 19:56:36 -05006778
6779 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
James Smart46fa3112007-04-25 09:51:45 -04006780 return NULL;
6781
dea31012005-04-17 16:05:31 -05006782 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
6783 if (!pmboxq)
6784 return NULL;
6785 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
6786
James Smart04c68492009-05-22 14:52:52 -04006787 pmb = &pmboxq->u.mb;
dea31012005-04-17 16:05:31 -05006788 pmb->mbxCommand = MBX_READ_STATUS;
6789 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006790 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006791 pmboxq->vport = vport;
dea31012005-04-17 16:05:31 -05006792
James Smart304ee432021-04-11 18:31:17 -07006793 if (vport->fc_flag & FC_OFFLINE_MODE) {
dea31012005-04-17 16:05:31 -05006794 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006795 if (rc != MBX_SUCCESS) {
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006796 mempool_free(pmboxq, phba->mbox_mem_pool);
James Smart304ee432021-04-11 18:31:17 -07006797 return NULL;
6798 }
6799 } else {
6800 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6801 if (rc != MBX_SUCCESS) {
6802 if (rc != MBX_TIMEOUT)
6803 mempool_free(pmboxq, phba->mbox_mem_pool);
6804 return NULL;
6805 }
dea31012005-04-17 16:05:31 -05006806 }
6807
James.Smart@Emulex.Comf888ba32005-08-10 15:03:01 -04006808 memset(hs, 0, sizeof (struct fc_host_statistics));
6809
dea31012005-04-17 16:05:31 -05006810 hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
James Smart73d91e52011-10-10 21:32:10 -04006811 /*
6812 * The MBX_READ_STATUS returns tx_k_bytes which has to
6813 * converted to words
6814 */
6815 hs->tx_words = (uint64_t)
6816 ((uint64_t)pmb->un.varRdStatus.xmitByteCnt
6817 * (uint64_t)256);
dea31012005-04-17 16:05:31 -05006818 hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
James Smart73d91e52011-10-10 21:32:10 -04006819 hs->rx_words = (uint64_t)
6820 ((uint64_t)pmb->un.varRdStatus.rcvByteCnt
6821 * (uint64_t)256);
dea31012005-04-17 16:05:31 -05006822
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006823 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
dea31012005-04-17 16:05:31 -05006824 pmb->mbxCommand = MBX_READ_LNK_STAT;
6825 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006826 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006827 pmboxq->vport = vport;
dea31012005-04-17 16:05:31 -05006828
James Smart304ee432021-04-11 18:31:17 -07006829 if (vport->fc_flag & FC_OFFLINE_MODE) {
dea31012005-04-17 16:05:31 -05006830 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006831 if (rc != MBX_SUCCESS) {
James Smart92d7f7b2007-06-17 19:56:38 -05006832 mempool_free(pmboxq, phba->mbox_mem_pool);
James Smart304ee432021-04-11 18:31:17 -07006833 return NULL;
6834 }
6835 } else {
6836 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6837 if (rc != MBX_SUCCESS) {
6838 if (rc != MBX_TIMEOUT)
6839 mempool_free(pmboxq, phba->mbox_mem_pool);
6840 return NULL;
6841 }
dea31012005-04-17 16:05:31 -05006842 }
6843
6844 hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
6845 hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
6846 hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
6847 hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
6848 hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
6849 hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
6850 hs->error_frames = pmb->un.varRdLnk.crcCnt;
6851
James Smart64ba8812006-08-02 15:24:34 -04006852 hs->link_failure_count -= lso->link_failure_count;
6853 hs->loss_of_sync_count -= lso->loss_of_sync_count;
6854 hs->loss_of_signal_count -= lso->loss_of_signal_count;
6855 hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count;
6856 hs->invalid_tx_word_count -= lso->invalid_tx_word_count;
6857 hs->invalid_crc_count -= lso->invalid_crc_count;
6858 hs->error_frames -= lso->error_frames;
6859
James Smart76a95d72010-11-20 23:11:48 -05006860 if (phba->hba_flag & HBA_FCOE_MODE) {
James Smart4d9ab992009-10-02 15:16:39 -04006861 hs->lip_count = -1;
6862 hs->nos_count = (phba->link_events >> 1);
6863 hs->nos_count -= lso->link_events;
James Smart76a95d72010-11-20 23:11:48 -05006864 } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
dea31012005-04-17 16:05:31 -05006865 hs->lip_count = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006866 hs->lip_count -= lso->link_events;
dea31012005-04-17 16:05:31 -05006867 hs->nos_count = -1;
6868 } else {
6869 hs->lip_count = -1;
6870 hs->nos_count = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006871 hs->nos_count -= lso->link_events;
dea31012005-04-17 16:05:31 -05006872 }
6873
6874 hs->dumped_frames = -1;
6875
Arnd Bergmannc4d6204d2018-06-18 17:28:23 +02006876 hs->seconds_since_last_reset = ktime_get_seconds() - psli->stats_start;
dea31012005-04-17 16:05:31 -05006877
James Smart1dcb58e2007-04-25 09:51:30 -04006878 mempool_free(pmboxq, phba->mbox_mem_pool);
6879
dea31012005-04-17 16:05:31 -05006880 return hs;
6881}
6882
James Smarte59058c2008-08-24 21:49:00 -04006883/**
James Smart3621a712009-04-06 18:47:14 -04006884 * lpfc_reset_stats - Copy the adapter link stats information
James Smarte59058c2008-08-24 21:49:00 -04006885 * @shost: kernel scsi host pointer.
6886 **/
James Smart64ba8812006-08-02 15:24:34 -04006887static void
6888lpfc_reset_stats(struct Scsi_Host *shost)
6889{
James Smart2e0fef82007-06-17 19:56:36 -05006890 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6891 struct lpfc_hba *phba = vport->phba;
6892 struct lpfc_sli *psli = &phba->sli;
6893 struct lpfc_lnk_stat *lso = &psli->lnk_stat_offsets;
James Smart64ba8812006-08-02 15:24:34 -04006894 LPFC_MBOXQ_t *pmboxq;
6895 MAILBOX_t *pmb;
6896 int rc = 0;
6897
James Smart2e0fef82007-06-17 19:56:36 -05006898 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
James Smart46fa3112007-04-25 09:51:45 -04006899 return;
6900
James Smart64ba8812006-08-02 15:24:34 -04006901 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
6902 if (!pmboxq)
6903 return;
6904 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
6905
James Smart04c68492009-05-22 14:52:52 -04006906 pmb = &pmboxq->u.mb;
James Smart64ba8812006-08-02 15:24:34 -04006907 pmb->mbxCommand = MBX_READ_STATUS;
6908 pmb->mbxOwner = OWN_HOST;
6909 pmb->un.varWords[0] = 0x1; /* reset request */
James Smart3e1f0712018-11-29 16:09:29 -08006910 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006911 pmboxq->vport = vport;
James Smart64ba8812006-08-02 15:24:34 -04006912
James Smart2e0fef82007-06-17 19:56:36 -05006913 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smart304ee432021-04-11 18:31:17 -07006914 (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
James Smart64ba8812006-08-02 15:24:34 -04006915 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006916 if (rc != MBX_SUCCESS) {
James Smart64ba8812006-08-02 15:24:34 -04006917 mempool_free(pmboxq, phba->mbox_mem_pool);
James Smart304ee432021-04-11 18:31:17 -07006918 return;
6919 }
6920 } else {
6921 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6922 if (rc != MBX_SUCCESS) {
6923 if (rc != MBX_TIMEOUT)
6924 mempool_free(pmboxq, phba->mbox_mem_pool);
6925 return;
6926 }
James Smart64ba8812006-08-02 15:24:34 -04006927 }
6928
6929 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
6930 pmb->mbxCommand = MBX_READ_LNK_STAT;
6931 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006932 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006933 pmboxq->vport = vport;
James Smart64ba8812006-08-02 15:24:34 -04006934
James Smart2e0fef82007-06-17 19:56:36 -05006935 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smart304ee432021-04-11 18:31:17 -07006936 (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
James Smart64ba8812006-08-02 15:24:34 -04006937 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006938 if (rc != MBX_SUCCESS) {
6939 mempool_free(pmboxq, phba->mbox_mem_pool);
6940 return;
6941 }
6942 } else {
James Smart64ba8812006-08-02 15:24:34 -04006943 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
James Smart304ee432021-04-11 18:31:17 -07006944 if (rc != MBX_SUCCESS) {
6945 if (rc != MBX_TIMEOUT)
6946 mempool_free(pmboxq, phba->mbox_mem_pool);
6947 return;
6948 }
James Smart64ba8812006-08-02 15:24:34 -04006949 }
6950
6951 lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
6952 lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
6953 lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
6954 lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
6955 lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
6956 lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
6957 lso->error_frames = pmb->un.varRdLnk.crcCnt;
James Smart76a95d72010-11-20 23:11:48 -05006958 if (phba->hba_flag & HBA_FCOE_MODE)
James Smart4d9ab992009-10-02 15:16:39 -04006959 lso->link_events = (phba->link_events >> 1);
6960 else
6961 lso->link_events = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006962
Arnd Bergmannc4d6204d2018-06-18 17:28:23 +02006963 psli->stats_start = ktime_get_seconds();
James Smart64ba8812006-08-02 15:24:34 -04006964
James Smart1dcb58e2007-04-25 09:51:30 -04006965 mempool_free(pmboxq, phba->mbox_mem_pool);
6966
James Smart64ba8812006-08-02 15:24:34 -04006967 return;
6968}
dea31012005-04-17 16:05:31 -05006969
6970/*
6971 * The LPFC driver treats linkdown handling as target loss events so there
6972 * are no sysfs handlers for link_down_tmo.
6973 */
James Smart685f0bf2007-04-25 09:53:08 -04006974
James Smarte59058c2008-08-24 21:49:00 -04006975/**
James Smart3621a712009-04-06 18:47:14 -04006976 * lpfc_get_node_by_target - Return the nodelist for a target
James Smarte59058c2008-08-24 21:49:00 -04006977 * @starget: kernel scsi target pointer.
6978 *
6979 * Returns:
6980 * address of the node list if found
6981 * NULL target not found
6982 **/
James Smart685f0bf2007-04-25 09:53:08 -04006983static struct lpfc_nodelist *
6984lpfc_get_node_by_target(struct scsi_target *starget)
dea31012005-04-17 16:05:31 -05006985{
James Smart2e0fef82007-06-17 19:56:36 -05006986 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
6987 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
James Smart685f0bf2007-04-25 09:53:08 -04006988 struct lpfc_nodelist *ndlp;
dea31012005-04-17 16:05:31 -05006989
6990 spin_lock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04006991 /* Search for this, mapped, target ID */
James Smart2e0fef82007-06-17 19:56:36 -05006992 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart307e3382020-11-15 11:26:30 -08006993 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
James Smart685f0bf2007-04-25 09:53:08 -04006994 starget->id == ndlp->nlp_sid) {
6995 spin_unlock_irq(shost->host_lock);
6996 return ndlp;
dea31012005-04-17 16:05:31 -05006997 }
6998 }
6999 spin_unlock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04007000 return NULL;
7001}
dea31012005-04-17 16:05:31 -05007002
James Smarte59058c2008-08-24 21:49:00 -04007003/**
James Smart3621a712009-04-06 18:47:14 -04007004 * lpfc_get_starget_port_id - Set the target port id to the ndlp DID or -1
James Smarte59058c2008-08-24 21:49:00 -04007005 * @starget: kernel scsi target pointer.
7006 **/
James Smart685f0bf2007-04-25 09:53:08 -04007007static void
7008lpfc_get_starget_port_id(struct scsi_target *starget)
7009{
7010 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
7011
7012 fc_starget_port_id(starget) = ndlp ? ndlp->nlp_DID : -1;
dea31012005-04-17 16:05:31 -05007013}
7014
James Smarte59058c2008-08-24 21:49:00 -04007015/**
James Smart3621a712009-04-06 18:47:14 -04007016 * lpfc_get_starget_node_name - Set the target node name
James Smarte59058c2008-08-24 21:49:00 -04007017 * @starget: kernel scsi target pointer.
7018 *
7019 * Description: Set the target node name to the ndlp node name wwn or zero.
7020 **/
dea31012005-04-17 16:05:31 -05007021static void
7022lpfc_get_starget_node_name(struct scsi_target *starget)
7023{
James Smart685f0bf2007-04-25 09:53:08 -04007024 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
dea31012005-04-17 16:05:31 -05007025
James Smart685f0bf2007-04-25 09:53:08 -04007026 fc_starget_node_name(starget) =
7027 ndlp ? wwn_to_u64(ndlp->nlp_nodename.u.wwn) : 0;
dea31012005-04-17 16:05:31 -05007028}
7029
James Smarte59058c2008-08-24 21:49:00 -04007030/**
James Smart3621a712009-04-06 18:47:14 -04007031 * lpfc_get_starget_port_name - Set the target port name
James Smarte59058c2008-08-24 21:49:00 -04007032 * @starget: kernel scsi target pointer.
7033 *
7034 * Description: set the target port name to the ndlp port name wwn or zero.
7035 **/
dea31012005-04-17 16:05:31 -05007036static void
7037lpfc_get_starget_port_name(struct scsi_target *starget)
7038{
James Smart685f0bf2007-04-25 09:53:08 -04007039 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
dea31012005-04-17 16:05:31 -05007040
James Smart685f0bf2007-04-25 09:53:08 -04007041 fc_starget_port_name(starget) =
7042 ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0;
dea31012005-04-17 16:05:31 -05007043}
7044
James Smarte59058c2008-08-24 21:49:00 -04007045/**
James Smart3621a712009-04-06 18:47:14 -04007046 * lpfc_set_rport_loss_tmo - Set the rport dev loss tmo
James Smarte59058c2008-08-24 21:49:00 -04007047 * @rport: fc rport address.
7048 * @timeout: new value for dev loss tmo.
7049 *
7050 * Description:
7051 * If timeout is non zero set the dev_loss_tmo to timeout, else set
7052 * dev_loss_tmo to one.
7053 **/
dea31012005-04-17 16:05:31 -05007054static void
dea31012005-04-17 16:05:31 -05007055lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
7056{
James Smarta643c6d2019-08-14 16:56:48 -07007057 struct lpfc_rport_data *rdata = rport->dd_data;
7058 struct lpfc_nodelist *ndlp = rdata->pnode;
7059#if (IS_ENABLED(CONFIG_NVME_FC))
7060 struct lpfc_nvme_rport *nrport = NULL;
7061#endif
7062
dea31012005-04-17 16:05:31 -05007063 if (timeout)
James Smartc01f3202006-08-18 17:47:08 -04007064 rport->dev_loss_tmo = timeout;
dea31012005-04-17 16:05:31 -05007065 else
James Smartc01f3202006-08-18 17:47:08 -04007066 rport->dev_loss_tmo = 1;
James Smarta643c6d2019-08-14 16:56:48 -07007067
James Smart307e3382020-11-15 11:26:30 -08007068 if (!ndlp) {
James Smarta643c6d2019-08-14 16:56:48 -07007069 dev_info(&rport->dev, "Cannot find remote node to "
7070 "set rport dev loss tmo, port_id x%x\n",
7071 rport->port_id);
7072 return;
7073 }
7074
7075#if (IS_ENABLED(CONFIG_NVME_FC))
7076 nrport = lpfc_ndlp_get_nrport(ndlp);
7077
7078 if (nrport && nrport->remoteport)
7079 nvme_fc_set_remoteport_devloss(nrport->remoteport,
7080 rport->dev_loss_tmo);
7081#endif
dea31012005-04-17 16:05:31 -05007082}
7083
Lee Jones9176ad22020-11-02 14:23:44 +00007084/*
James Smart3621a712009-04-06 18:47:14 -04007085 * lpfc_rport_show_function - Return rport target information
James Smarte59058c2008-08-24 21:49:00 -04007086 *
7087 * Description:
7088 * Macro that uses field to generate a function with the name lpfc_show_rport_
7089 *
7090 * lpfc_show_rport_##field: returns the bytes formatted in buf
7091 * @cdev: class converted to an fc_rport.
7092 * @buf: on return contains the target_field or zero.
7093 *
7094 * Returns: size of formatted string.
7095 **/
dea31012005-04-17 16:05:31 -05007096#define lpfc_rport_show_function(field, format_string, sz, cast) \
7097static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01007098lpfc_show_rport_##field (struct device *dev, \
7099 struct device_attribute *attr, \
7100 char *buf) \
dea31012005-04-17 16:05:31 -05007101{ \
Tony Jonesee959b02008-02-22 00:13:36 +01007102 struct fc_rport *rport = transport_class_to_rport(dev); \
dea31012005-04-17 16:05:31 -05007103 struct lpfc_rport_data *rdata = rport->hostdata; \
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07007104 return scnprintf(buf, sz, format_string, \
dea31012005-04-17 16:05:31 -05007105 (rdata->target) ? cast rdata->target->field : 0); \
7106}
7107
7108#define lpfc_rport_rd_attr(field, format_string, sz) \
7109 lpfc_rport_show_function(field, format_string, sz, ) \
7110static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
7111
James Smarteada2722008-12-04 22:39:13 -05007112/**
James Smart3621a712009-04-06 18:47:14 -04007113 * lpfc_set_vport_symbolic_name - Set the vport's symbolic name
James Smarteada2722008-12-04 22:39:13 -05007114 * @fc_vport: The fc_vport who's symbolic name has been changed.
7115 *
7116 * Description:
7117 * This function is called by the transport after the @fc_vport's symbolic name
7118 * has been changed. This function re-registers the symbolic name with the
Lucas De Marchi25985ed2011-03-30 22:57:33 -03007119 * switch to propagate the change into the fabric if the vport is active.
James Smarteada2722008-12-04 22:39:13 -05007120 **/
7121static void
7122lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport)
7123{
7124 struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
7125
7126 if (vport->port_state == LPFC_VPORT_READY)
7127 lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
7128}
dea31012005-04-17 16:05:31 -05007129
James Smartf4b4c682009-05-22 14:53:12 -04007130/**
7131 * lpfc_hba_log_verbose_init - Set hba's log verbose level
7132 * @phba: Pointer to lpfc_hba struct.
Lee Jonesa738bd92020-11-02 14:23:45 +00007133 * @verbose: Verbose level to set.
James Smartf4b4c682009-05-22 14:53:12 -04007134 *
7135 * This function is called by the lpfc_get_cfgparam() routine to set the
7136 * module lpfc_log_verbose into the @phba cfg_log_verbose for use with
Justin P. Mattock70f23fd2011-05-10 10:16:21 +02007137 * log message according to the module's lpfc_log_verbose parameter setting
James Smartf4b4c682009-05-22 14:53:12 -04007138 * before hba port or vport created.
7139 **/
7140static void
7141lpfc_hba_log_verbose_init(struct lpfc_hba *phba, uint32_t verbose)
7142{
7143 phba->cfg_log_verbose = verbose;
7144}
7145
dea31012005-04-17 16:05:31 -05007146struct fc_function_template lpfc_transport_functions = {
7147 /* fixed attributes the driver supports */
7148 .show_host_node_name = 1,
7149 .show_host_port_name = 1,
7150 .show_host_supported_classes = 1,
7151 .show_host_supported_fc4s = 1,
dea31012005-04-17 16:05:31 -05007152 .show_host_supported_speeds = 1,
7153 .show_host_maxframe_size = 1,
James Smart6c9231f2016-12-19 15:07:24 -08007154
7155 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
James Smarteada2722008-12-04 22:39:13 -05007156 .show_host_symbolic_name = 1,
dea31012005-04-17 16:05:31 -05007157
7158 /* dynamic attributes the driver supports */
7159 .get_host_port_id = lpfc_get_host_port_id,
7160 .show_host_port_id = 1,
7161
7162 .get_host_port_type = lpfc_get_host_port_type,
7163 .show_host_port_type = 1,
7164
7165 .get_host_port_state = lpfc_get_host_port_state,
7166 .show_host_port_state = 1,
7167
7168 /* active_fc4s is shown but doesn't change (thus no get function) */
7169 .show_host_active_fc4s = 1,
7170
7171 .get_host_speed = lpfc_get_host_speed,
7172 .show_host_speed = 1,
7173
7174 .get_host_fabric_name = lpfc_get_host_fabric_name,
7175 .show_host_fabric_name = 1,
7176
7177 /*
7178 * The LPFC driver treats linkdown handling as target loss events
7179 * so there are no sysfs handlers for link_down_tmo.
7180 */
7181
7182 .get_fc_host_stats = lpfc_get_stats,
James Smart64ba8812006-08-02 15:24:34 -04007183 .reset_fc_host_stats = lpfc_reset_stats,
dea31012005-04-17 16:05:31 -05007184
7185 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
7186 .show_rport_maxframe_size = 1,
7187 .show_rport_supported_classes = 1,
7188
dea31012005-04-17 16:05:31 -05007189 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
7190 .show_rport_dev_loss_tmo = 1,
7191
7192 .get_starget_port_id = lpfc_get_starget_port_id,
7193 .show_starget_port_id = 1,
7194
7195 .get_starget_node_name = lpfc_get_starget_node_name,
7196 .show_starget_node_name = 1,
7197
7198 .get_starget_port_name = lpfc_get_starget_port_name,
7199 .show_starget_port_name = 1,
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07007200
7201 .issue_fc_host_lip = lpfc_issue_lip,
James Smartc01f3202006-08-18 17:47:08 -04007202 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
7203 .terminate_rport_io = lpfc_terminate_rport_io,
James Smart92d7f7b2007-06-17 19:56:38 -05007204
James Smart92d7f7b2007-06-17 19:56:38 -05007205 .dd_fcvport_size = sizeof(struct lpfc_vport *),
James Smarteada2722008-12-04 22:39:13 -05007206
7207 .vport_disable = lpfc_vport_disable,
7208
7209 .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
James Smartf1c3b0f2009-07-19 10:01:32 -04007210
7211 .bsg_request = lpfc_bsg_request,
7212 .bsg_timeout = lpfc_bsg_timeout,
James Smart92d7f7b2007-06-17 19:56:38 -05007213};
7214
James Smart98c9ea52007-10-27 13:37:33 -04007215struct fc_function_template lpfc_vport_transport_functions = {
7216 /* fixed attributes the driver supports */
7217 .show_host_node_name = 1,
7218 .show_host_port_name = 1,
7219 .show_host_supported_classes = 1,
7220 .show_host_supported_fc4s = 1,
7221 .show_host_supported_speeds = 1,
7222 .show_host_maxframe_size = 1,
James Smart6c9231f2016-12-19 15:07:24 -08007223
7224 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
James Smarteada2722008-12-04 22:39:13 -05007225 .show_host_symbolic_name = 1,
James Smart98c9ea52007-10-27 13:37:33 -04007226
7227 /* dynamic attributes the driver supports */
7228 .get_host_port_id = lpfc_get_host_port_id,
7229 .show_host_port_id = 1,
7230
7231 .get_host_port_type = lpfc_get_host_port_type,
7232 .show_host_port_type = 1,
7233
7234 .get_host_port_state = lpfc_get_host_port_state,
7235 .show_host_port_state = 1,
7236
7237 /* active_fc4s is shown but doesn't change (thus no get function) */
7238 .show_host_active_fc4s = 1,
7239
7240 .get_host_speed = lpfc_get_host_speed,
7241 .show_host_speed = 1,
7242
7243 .get_host_fabric_name = lpfc_get_host_fabric_name,
7244 .show_host_fabric_name = 1,
7245
7246 /*
7247 * The LPFC driver treats linkdown handling as target loss events
7248 * so there are no sysfs handlers for link_down_tmo.
7249 */
7250
7251 .get_fc_host_stats = lpfc_get_stats,
7252 .reset_fc_host_stats = lpfc_reset_stats,
7253
7254 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
7255 .show_rport_maxframe_size = 1,
7256 .show_rport_supported_classes = 1,
7257
7258 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
7259 .show_rport_dev_loss_tmo = 1,
7260
7261 .get_starget_port_id = lpfc_get_starget_port_id,
7262 .show_starget_port_id = 1,
7263
7264 .get_starget_node_name = lpfc_get_starget_node_name,
7265 .show_starget_node_name = 1,
7266
7267 .get_starget_port_name = lpfc_get_starget_port_name,
7268 .show_starget_port_name = 1,
7269
7270 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
7271 .terminate_rport_io = lpfc_terminate_rport_io,
7272
7273 .vport_disable = lpfc_vport_disable,
James Smarteada2722008-12-04 22:39:13 -05007274
7275 .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
James Smart98c9ea52007-10-27 13:37:33 -04007276};
7277
James Smarte59058c2008-08-24 21:49:00 -04007278/**
James Smart4945c0f2019-08-14 16:57:02 -07007279 * lpfc_get_hba_function_mode - Used to determine the HBA function in FCoE
7280 * Mode
7281 * @phba: lpfc_hba pointer.
7282 **/
7283static void
7284lpfc_get_hba_function_mode(struct lpfc_hba *phba)
7285{
James Smart412e7372019-09-21 20:59:04 -07007286 /* If the adapter supports FCoE mode */
7287 switch (phba->pcidev->device) {
7288 case PCI_DEVICE_ID_SKYHAWK:
7289 case PCI_DEVICE_ID_SKYHAWK_VF:
7290 case PCI_DEVICE_ID_LANCER_FCOE:
7291 case PCI_DEVICE_ID_LANCER_FCOE_VF:
7292 case PCI_DEVICE_ID_ZEPHYR_DCSP:
7293 case PCI_DEVICE_ID_HORNET:
7294 case PCI_DEVICE_ID_TIGERSHARK:
7295 case PCI_DEVICE_ID_TOMCAT:
James Smart4945c0f2019-08-14 16:57:02 -07007296 phba->hba_flag |= HBA_FCOE_MODE;
James Smart412e7372019-09-21 20:59:04 -07007297 break;
7298 default:
7299 /* for others, clear the flag */
James Smart4945c0f2019-08-14 16:57:02 -07007300 phba->hba_flag &= ~HBA_FCOE_MODE;
James Smart412e7372019-09-21 20:59:04 -07007301 }
James Smart4945c0f2019-08-14 16:57:02 -07007302}
7303
7304/**
James Smart3621a712009-04-06 18:47:14 -04007305 * lpfc_get_cfgparam - Used during probe_one to init the adapter structure
James Smarte59058c2008-08-24 21:49:00 -04007306 * @phba: lpfc_hba pointer.
7307 **/
dea31012005-04-17 16:05:31 -05007308void
7309lpfc_get_cfgparam(struct lpfc_hba *phba)
7310{
James Smartdcaa2132019-11-04 16:57:06 -08007311 lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
James Smart49aa1432012-08-03 12:36:42 -04007312 lpfc_fcp_io_sched_init(phba, lpfc_fcp_io_sched);
James Smart7ea92eb2018-10-23 13:41:10 -07007313 lpfc_ns_query_init(phba, lpfc_ns_query);
James Smarta6571c62012-10-31 14:44:42 -04007314 lpfc_fcp2_no_tgt_reset_init(phba, lpfc_fcp2_no_tgt_reset);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007315 lpfc_cr_delay_init(phba, lpfc_cr_delay);
7316 lpfc_cr_count_init(phba, lpfc_cr_count);
Jamie Wellnitzcf5bf972006-02-28 22:33:08 -05007317 lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
James Smarta4bc3372006-12-02 13:34:16 -05007318 lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
7319 lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007320 lpfc_ack0_init(phba, lpfc_ack0);
James Smartc4908502019-01-28 11:14:28 -08007321 lpfc_xri_rebalancing_init(phba, lpfc_xri_rebalancing);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007322 lpfc_topology_init(phba, lpfc_topology);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007323 lpfc_link_speed_init(phba, lpfc_link_speed);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05007324 lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
James Smart0c411222013-09-06 12:22:46 -04007325 lpfc_task_mgmt_tmo_init(phba, lpfc_task_mgmt_tmo);
James Smart78b2d852007-08-02 11:10:21 -04007326 lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
James Smart7d791df2011-07-22 18:37:52 -04007327 lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy);
James Smart19ca7602010-11-20 23:11:55 -05007328 lpfc_enable_rrq_init(phba, lpfc_enable_rrq);
James Smart4258e982015-12-16 18:11:58 -05007329 lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
7330 lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
James Smart4ff43242006-12-02 13:34:56 -05007331 lpfc_use_msi_init(phba, lpfc_use_msi);
James Smart895427b2017-02-12 13:52:30 -08007332 lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
James Smart4e565cf2018-02-22 08:18:50 -08007333 lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
James Smartda0436e2009-05-22 14:51:39 -04007334 lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
James Smart41b194b2019-05-14 14:58:08 -07007335 lpfc_force_rscn_init(phba, lpfc_force_rscn);
James Smart32517fc2019-01-28 11:14:33 -08007336 lpfc_cq_poll_threshold_init(phba, lpfc_cq_poll_threshold);
7337 lpfc_cq_max_proc_limit_init(phba, lpfc_cq_max_proc_limit);
James Smart7bb03bb2013-04-17 20:19:16 -04007338 lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
James Smart13815c82008-01-11 01:52:48 -05007339 lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
7340 lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
James Smart2ea259e2017-02-12 13:52:27 -08007341
James Smart1ba981f2014-02-20 09:56:45 -05007342 lpfc_EnableXLane_init(phba, lpfc_EnableXLane);
7343 if (phba->sli_rev != LPFC_SLI_REV4)
7344 phba->cfg_EnableXLane = 0;
7345 lpfc_XLanePriority_init(phba, lpfc_XLanePriority);
James Smart2ea259e2017-02-12 13:52:27 -08007346
James Smart1ba981f2014-02-20 09:56:45 -05007347 memset(phba->cfg_oas_tgt_wwpn, 0, (8 * sizeof(uint8_t)));
7348 memset(phba->cfg_oas_vpt_wwpn, 0, (8 * sizeof(uint8_t)));
7349 phba->cfg_oas_lun_state = 0;
7350 phba->cfg_oas_lun_status = 0;
7351 phba->cfg_oas_flags = 0;
James Smartc92c8412016-07-06 12:36:05 -07007352 phba->cfg_oas_priority = 0;
James Smart81301a92008-12-04 22:39:46 -05007353 lpfc_enable_bg_init(phba, lpfc_enable_bg);
James Smartb3b98b72016-10-13 15:06:06 -07007354 lpfc_prot_mask_init(phba, lpfc_prot_mask);
7355 lpfc_prot_guard_init(phba, lpfc_prot_guard);
James Smart45ed1192009-10-02 15:17:02 -04007356 if (phba->sli_rev == LPFC_SLI_REV4)
7357 phba->cfg_poll = 0;
7358 else
James Smart1ba981f2014-02-20 09:56:45 -05007359 phba->cfg_poll = lpfc_poll;
James Smartf44ac122018-03-05 12:04:08 -08007360
James Smart4945c0f2019-08-14 16:57:02 -07007361 /* Get the function mode */
7362 lpfc_get_hba_function_mode(phba);
7363
7364 /* BlockGuard allowed for FC only. */
7365 if (phba->cfg_enable_bg && phba->hba_flag & HBA_FCOE_MODE) {
7366 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
7367 "0581 BlockGuard feature not supported\n");
7368 /* If set, clear the BlockGuard support param */
7369 phba->cfg_enable_bg = 0;
7370 } else if (phba->cfg_enable_bg) {
James Smartf44ac122018-03-05 12:04:08 -08007371 phba->sli3_options |= LPFC_SLI3_BG_ENABLED;
James Smart4945c0f2019-08-14 16:57:02 -07007372 }
James Smartf44ac122018-03-05 12:04:08 -08007373
James Smartf358dd02017-02-12 13:52:34 -08007374 lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp);
James Smart4258e982015-12-16 18:11:58 -05007375
James Smart895427b2017-02-12 13:52:30 -08007376 lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type);
James Smart2d7dbc42017-02-12 13:52:35 -08007377 lpfc_nvmet_mrq_init(phba, lpfc_nvmet_mrq);
James Smart2448e482018-04-09 14:24:24 -07007378 lpfc_nvmet_mrq_post_init(phba, lpfc_nvmet_mrq_post);
James Smart895427b2017-02-12 13:52:30 -08007379
7380 /* Initialize first burst. Target vs Initiator are different. */
7381 lpfc_nvme_enable_fb_init(phba, lpfc_nvme_enable_fb);
James Smart2d7dbc42017-02-12 13:52:35 -08007382 lpfc_nvmet_fb_size_init(phba, lpfc_nvmet_fb_size);
James Smart77ffd342019-08-15 19:36:49 -07007383 lpfc_fcp_mq_threshold_init(phba, lpfc_fcp_mq_threshold);
James Smartcdb42be2019-01-28 11:14:21 -08007384 lpfc_hdw_queue_init(phba, lpfc_hdw_queue);
James Smart6a828b02019-01-28 11:14:31 -08007385 lpfc_irq_chann_init(phba, lpfc_irq_chann);
James Smart44fd7fe2017-08-23 16:55:47 -07007386 lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
James Smart1351e692018-02-22 08:18:43 -08007387 lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
James Smart8aaa7bc2020-10-20 13:27:17 -07007388 lpfc_enable_mi_init(phba, lpfc_enable_mi);
James Smart895427b2017-02-12 13:52:30 -08007389
7390 if (phba->sli_rev != LPFC_SLI_REV4) {
7391 /* NVME only supported on SLI4 */
7392 phba->nvmet_support = 0;
James Smart982ab122019-03-12 16:30:10 -07007393 phba->cfg_nvmet_mrq = 0;
James Smart895427b2017-02-12 13:52:30 -08007394 phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
James Smart44fd7fe2017-08-23 16:55:47 -07007395 phba->cfg_enable_bbcr = 0;
James Smartc4908502019-01-28 11:14:28 -08007396 phba->cfg_xri_rebalancing = 0;
James Smart895427b2017-02-12 13:52:30 -08007397 } else {
7398 /* We MUST have FCP support */
7399 if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
7400 phba->cfg_enable_fc4_type |= LPFC_ENABLE_FCP;
7401 }
7402
James Smart32517fc2019-01-28 11:14:33 -08007403 phba->cfg_auto_imax = (phba->cfg_fcp_imax) ? 0 : 1;
James Smart0cf07f842017-06-01 21:07:10 -07007404
James Smart06b6fa382018-07-31 17:23:24 -07007405 phba->cfg_enable_pbde = 0;
7406
James Smart895427b2017-02-12 13:52:30 -08007407 /* A value of 0 means use the number of CPUs found in the system */
James Smartcdb42be2019-01-28 11:14:21 -08007408 if (phba->cfg_hdw_queue == 0)
7409 phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
James Smart6a828b02019-01-28 11:14:31 -08007410 if (phba->cfg_irq_chann == 0)
7411 phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
7412 if (phba->cfg_irq_chann > phba->cfg_hdw_queue)
7413 phba->cfg_irq_chann = phba->cfg_hdw_queue;
James Smart4258e982015-12-16 18:11:58 -05007414
James Smart352e5fd2016-12-30 06:57:47 -08007415 phba->cfg_soft_wwnn = 0L;
7416 phba->cfg_soft_wwpn = 0L;
James Smart83108bd2008-01-11 01:53:09 -05007417 lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
James Smart7054a602007-04-25 09:52:34 -04007418 lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
James Smart0d878412009-10-02 15:16:56 -04007419 lpfc_aer_support_init(phba, lpfc_aer_support);
James Smart912e3ac2011-05-24 11:42:11 -04007420 lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn);
James Smartc71ab862012-10-31 14:44:33 -04007421 lpfc_request_firmware_upgrade_init(phba, lpfc_req_fw_upgrade);
James Smart84d1b002010-02-12 14:42:33 -05007422 lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up);
James Smart8eb8b962016-07-06 12:36:08 -07007423 lpfc_delay_discovery_init(phba, lpfc_delay_discovery);
James Smart12247e82016-07-06 12:36:09 -07007424 lpfc_sli_mode_init(phba, lpfc_sli_mode);
James Smart7bdedb32016-07-06 12:36:00 -07007425 lpfc_enable_mds_diags_init(phba, lpfc_enable_mds_diags);
James Smartd2cc9bc2018-09-10 10:30:50 -07007426 lpfc_ras_fwlog_buffsize_init(phba, lpfc_ras_fwlog_buffsize);
7427 lpfc_ras_fwlog_level_init(phba, lpfc_ras_fwlog_level);
7428 lpfc_ras_fwlog_func_init(phba, lpfc_ras_fwlog_func);
7429
James Smart3de2a652007-08-02 11:09:59 -04007430 return;
7431}
Jamie Wellnitzb28485a2006-02-28 19:25:21 -05007432
James Smarte59058c2008-08-24 21:49:00 -04007433/**
James Smart895427b2017-02-12 13:52:30 -08007434 * lpfc_nvme_mod_param_dep - Adjust module parameter value based on
7435 * dependencies between protocols and roles.
7436 * @phba: lpfc_hba pointer.
7437 **/
7438void
7439lpfc_nvme_mod_param_dep(struct lpfc_hba *phba)
7440{
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007441 int logit = 0;
7442
7443 if (phba->cfg_hdw_queue > phba->sli4_hba.num_present_cpu) {
James Smartcdb42be2019-01-28 11:14:21 -08007444 phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007445 logit = 1;
7446 }
7447 if (phba->cfg_irq_chann > phba->sli4_hba.num_present_cpu) {
James Smart6a828b02019-01-28 11:14:31 -08007448 phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007449 logit = 1;
7450 }
7451 if (phba->cfg_irq_chann > phba->cfg_hdw_queue) {
James Smart6a828b02019-01-28 11:14:31 -08007452 phba->cfg_irq_chann = phba->cfg_hdw_queue;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007453 logit = 1;
7454 }
7455 if (logit)
7456 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
7457 "2006 Reducing Queues - CPU limitation: "
7458 "IRQ %d HDWQ %d\n",
7459 phba->cfg_irq_chann,
7460 phba->cfg_hdw_queue);
James Smart895427b2017-02-12 13:52:30 -08007461
James Smartf358dd02017-02-12 13:52:34 -08007462 if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME &&
7463 phba->nvmet_support) {
7464 phba->cfg_enable_fc4_type &= ~LPFC_ENABLE_FCP;
James Smart2d7dbc42017-02-12 13:52:35 -08007465
7466 lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
7467 "6013 %s x%x fb_size x%x, fb_max x%x\n",
7468 "NVME Target PRLI ACC enable_fb ",
7469 phba->cfg_nvme_enable_fb,
7470 phba->cfg_nvmet_fb_size,
7471 LPFC_NVMET_FB_SZ_MAX);
7472
7473 if (phba->cfg_nvme_enable_fb == 0)
7474 phba->cfg_nvmet_fb_size = 0;
7475 else {
7476 if (phba->cfg_nvmet_fb_size > LPFC_NVMET_FB_SZ_MAX)
7477 phba->cfg_nvmet_fb_size = LPFC_NVMET_FB_SZ_MAX;
7478 }
7479
James Smartbcb24f62017-11-20 16:00:36 -08007480 if (!phba->cfg_nvmet_mrq)
James Smart97a9ed32019-10-18 14:18:17 -07007481 phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
James Smartbcb24f62017-11-20 16:00:36 -08007482
James Smart2d7dbc42017-02-12 13:52:35 -08007483 /* Adjust lpfc_nvmet_mrq to avoid running out of WQE slots */
James Smart97a9ed32019-10-18 14:18:17 -07007484 if (phba->cfg_nvmet_mrq > phba->cfg_hdw_queue) {
7485 phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
James Smart2d7dbc42017-02-12 13:52:35 -08007486 lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC,
7487 "6018 Adjust lpfc_nvmet_mrq to %d\n",
7488 phba->cfg_nvmet_mrq);
7489 }
James Smartbcb24f62017-11-20 16:00:36 -08007490 if (phba->cfg_nvmet_mrq > LPFC_NVMET_MRQ_MAX)
7491 phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_MAX;
7492
James Smart2d7dbc42017-02-12 13:52:35 -08007493 } else {
James Smartf358dd02017-02-12 13:52:34 -08007494 /* Not NVME Target mode. Turn off Target parameters. */
7495 phba->nvmet_support = 0;
James Smart982ab122019-03-12 16:30:10 -07007496 phba->cfg_nvmet_mrq = 0;
James Smart2d7dbc42017-02-12 13:52:35 -08007497 phba->cfg_nvmet_fb_size = 0;
7498 }
James Smart895427b2017-02-12 13:52:30 -08007499}
7500
7501/**
James Smart3621a712009-04-06 18:47:14 -04007502 * lpfc_get_vport_cfgparam - Used during port create, init the vport structure
James Smarte59058c2008-08-24 21:49:00 -04007503 * @vport: lpfc_vport pointer.
7504 **/
James Smart3de2a652007-08-02 11:09:59 -04007505void
7506lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
7507{
James Smarte8b62012007-08-02 11:10:09 -04007508 lpfc_log_verbose_init(vport, lpfc_log_verbose);
James Smart3de2a652007-08-02 11:09:59 -04007509 lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth);
James Smart7dc517d2010-07-14 15:32:10 -04007510 lpfc_tgt_queue_depth_init(vport, lpfc_tgt_queue_depth);
James Smart3de2a652007-08-02 11:09:59 -04007511 lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo);
7512 lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo);
7513 lpfc_peer_port_login_init(vport, lpfc_peer_port_login);
7514 lpfc_restrict_login_init(vport, lpfc_restrict_login);
7515 lpfc_fcp_class_init(vport, lpfc_fcp_class);
7516 lpfc_use_adisc_init(vport, lpfc_use_adisc);
James Smart3cb01c52013-07-15 18:35:04 -04007517 lpfc_first_burst_size_init(vport, lpfc_first_burst_size);
James Smart977b5a02008-09-07 11:52:04 -04007518 lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time);
James Smart3de2a652007-08-02 11:09:59 -04007519 lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
7520 lpfc_max_luns_init(vport, lpfc_max_luns);
7521 lpfc_scan_down_init(vport, lpfc_scan_down);
James Smart7ee5d432007-10-27 13:37:17 -04007522 lpfc_enable_da_id_init(vport, lpfc_enable_da_id);
dea31012005-04-17 16:05:31 -05007523 return;
7524}