blob: eb88aaaf36eb328031ddb1c81a78c544d52a8a84 [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),
James Smart3bfab8a2021-04-11 18:31:23 -0700490 atomic_read(&lport->xmt_fcp_wqerr),
491 atomic_read(&lport->xmt_fcp_err));
James Smartafff0d22018-06-26 08:24:22 -0700492 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,
James Smart3bfab8a2021-04-11 18:31:23 -07001177 "0466 Outstanding IO when "
James Smart895427b2017-02-12 13:52:30 -08001178 "bringing Adapter offline\n");
1179 return 0;
1180 }
1181 spin_lock_irq(lock);
1182 }
1183 spin_unlock_irq(lock);
1184 return 1;
1185}
1186
James Smarte59058c2008-08-24 21:49:00 -04001187/**
James Smart3621a712009-04-06 18:47:14 -04001188 * lpfc_do_offline - Issues a mailbox command to bring the link down
James Smarte59058c2008-08-24 21:49:00 -04001189 * @phba: lpfc_hba pointer.
1190 * @type: LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL.
1191 *
1192 * Notes:
1193 * Assumes any error from lpfc_do_offline() will be negative.
1194 * Can wait up to 5 seconds for the port ring buffers count
1195 * to reach zero, prints a warning if it is not zero and continues.
James Smart3621a712009-04-06 18:47:14 -04001196 * lpfc_workq_post_event() returns a non-zero return code if call fails.
James Smarte59058c2008-08-24 21:49:00 -04001197 *
1198 * Returns:
1199 * -EIO error posting the event
1200 * zero for success
1201 **/
James Smart40496f02006-07-06 15:50:22 -04001202static int
James Smart46fa3112007-04-25 09:51:45 -04001203lpfc_do_offline(struct lpfc_hba *phba, uint32_t type)
1204{
1205 struct completion online_compl;
James Smart895427b2017-02-12 13:52:30 -08001206 struct lpfc_queue *qp = NULL;
James Smart46fa3112007-04-25 09:51:45 -04001207 struct lpfc_sli_ring *pring;
1208 struct lpfc_sli *psli;
1209 int status = 0;
James Smart46fa3112007-04-25 09:51:45 -04001210 int i;
James Smartfedd3b72011-02-16 12:39:24 -05001211 int rc;
James Smart46fa3112007-04-25 09:51:45 -04001212
1213 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001214 rc = lpfc_workq_post_event(phba, &status, &online_compl,
James Smart46fa3112007-04-25 09:51:45 -04001215 LPFC_EVT_OFFLINE_PREP);
James Smartfedd3b72011-02-16 12:39:24 -05001216 if (rc == 0)
1217 return -ENOMEM;
1218
James Smart46fa3112007-04-25 09:51:45 -04001219 wait_for_completion(&online_compl);
1220
1221 if (status != 0)
1222 return -EIO;
1223
1224 psli = &phba->sli;
1225
James Smart4645f7b2019-03-12 16:30:14 -07001226 /*
1227 * If freeing the queues have already started, don't access them.
1228 * Otherwise set FREE_WAIT to indicate that queues are being used
1229 * to hold the freeing process until we finish.
1230 */
1231 spin_lock_irq(&phba->hbalock);
1232 if (!(psli->sli_flag & LPFC_QUEUE_FREE_INIT)) {
1233 psli->sli_flag |= LPFC_QUEUE_FREE_WAIT;
1234 } else {
1235 spin_unlock_irq(&phba->hbalock);
1236 goto skip_wait;
1237 }
1238 spin_unlock_irq(&phba->hbalock);
1239
James Smart09372822008-01-11 01:52:54 -05001240 /* Wait a little for things to settle down, but not
1241 * long enough for dev loss timeout to expire.
1242 */
James Smart895427b2017-02-12 13:52:30 -08001243 if (phba->sli_rev != LPFC_SLI_REV4) {
1244 for (i = 0; i < psli->num_rings; i++) {
1245 pring = &psli->sli3_ring[i];
1246 if (!lpfc_emptyq_wait(phba, &pring->txcmplq,
1247 &phba->hbalock))
1248 goto out;
1249 }
1250 } else {
1251 list_for_each_entry(qp, &phba->sli4_hba.lpfc_wq_list, wq_list) {
1252 pring = qp->pring;
1253 if (!pring)
1254 continue;
1255 if (!lpfc_emptyq_wait(phba, &pring->txcmplq,
1256 &pring->ring_lock))
1257 goto out;
James Smart46fa3112007-04-25 09:51:45 -04001258 }
1259 }
James Smart895427b2017-02-12 13:52:30 -08001260out:
James Smart4645f7b2019-03-12 16:30:14 -07001261 spin_lock_irq(&phba->hbalock);
1262 psli->sli_flag &= ~LPFC_QUEUE_FREE_WAIT;
1263 spin_unlock_irq(&phba->hbalock);
1264
1265skip_wait:
James Smart46fa3112007-04-25 09:51:45 -04001266 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001267 rc = lpfc_workq_post_event(phba, &status, &online_compl, type);
1268 if (rc == 0)
1269 return -ENOMEM;
1270
James Smart46fa3112007-04-25 09:51:45 -04001271 wait_for_completion(&online_compl);
1272
1273 if (status != 0)
1274 return -EIO;
1275
1276 return 0;
1277}
1278
James Smarte59058c2008-08-24 21:49:00 -04001279/**
James Smart50212672018-12-13 15:17:57 -08001280 * lpfc_reset_pci_bus - resets PCI bridge controller's secondary bus of an HBA
1281 * @phba: lpfc_hba pointer.
1282 *
1283 * Description:
1284 * Issues a PCI secondary bus reset for the phba->pcidev.
1285 *
1286 * Notes:
1287 * First walks the bus_list to ensure only PCI devices with Emulex
1288 * vendor id, device ids that support hot reset, only one occurrence
1289 * of function 0, and all ports on the bus are in offline mode to ensure the
1290 * hot reset only affects one valid HBA.
1291 *
1292 * Returns:
1293 * -ENOTSUPP, cfg_enable_hba_reset must be of value 2
1294 * -ENODEV, NULL ptr to pcidev
1295 * -EBADSLT, detected invalid device
1296 * -EBUSY, port is not in offline state
1297 * 0, successful
1298 */
Bart Van Assche3999df72019-03-28 11:06:16 -07001299static int
James Smart50212672018-12-13 15:17:57 -08001300lpfc_reset_pci_bus(struct lpfc_hba *phba)
1301{
1302 struct pci_dev *pdev = phba->pcidev;
1303 struct Scsi_Host *shost = NULL;
1304 struct lpfc_hba *phba_other = NULL;
1305 struct pci_dev *ptr = NULL;
1306 int res;
1307
1308 if (phba->cfg_enable_hba_reset != 2)
1309 return -ENOTSUPP;
1310
1311 if (!pdev) {
1312 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "8345 pdev NULL!\n");
1313 return -ENODEV;
1314 }
1315
1316 res = lpfc_check_pci_resettable(phba);
1317 if (res)
1318 return res;
1319
1320 /* Walk the list of devices on the pci_dev's bus */
1321 list_for_each_entry(ptr, &pdev->bus->devices, bus_list) {
1322 /* Check port is offline */
1323 shost = pci_get_drvdata(ptr);
1324 if (shost) {
1325 phba_other =
1326 ((struct lpfc_vport *)shost->hostdata)->phba;
1327 if (!(phba_other->pport->fc_flag & FC_OFFLINE_MODE)) {
1328 lpfc_printf_log(phba_other, KERN_INFO, LOG_INIT,
1329 "8349 WWPN = 0x%02x%02x%02x%02x"
1330 "%02x%02x%02x%02x is not "
1331 "offline!\n",
1332 phba_other->wwpn[0],
1333 phba_other->wwpn[1],
1334 phba_other->wwpn[2],
1335 phba_other->wwpn[3],
1336 phba_other->wwpn[4],
1337 phba_other->wwpn[5],
1338 phba_other->wwpn[6],
1339 phba_other->wwpn[7]);
1340 return -EBUSY;
1341 }
1342 }
1343 }
1344
1345 /* Issue PCI bus reset */
1346 res = pci_reset_bus(pdev);
1347 if (res) {
1348 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1349 "8350 PCI reset bus failed: %d\n", res);
1350 }
1351
1352 return res;
1353}
1354
1355/**
James Smart3621a712009-04-06 18:47:14 -04001356 * lpfc_selective_reset - Offline then onlines the port
James Smarte59058c2008-08-24 21:49:00 -04001357 * @phba: lpfc_hba pointer.
1358 *
1359 * Description:
1360 * If the port is configured to allow a reset then the hba is brought
1361 * offline then online.
1362 *
1363 * Notes:
1364 * Assumes any error from lpfc_do_offline() will be negative.
James Smartab56dc22011-02-16 12:39:57 -05001365 * Do not make this function static.
James Smarte59058c2008-08-24 21:49:00 -04001366 *
1367 * Returns:
1368 * lpfc_do_offline() return code if not zero
1369 * -EIO reset not configured or error posting the event
1370 * zero for success
1371 **/
James Smart7f860592011-03-11 16:05:52 -05001372int
James Smart40496f02006-07-06 15:50:22 -04001373lpfc_selective_reset(struct lpfc_hba *phba)
1374{
1375 struct completion online_compl;
1376 int status = 0;
James Smartfedd3b72011-02-16 12:39:24 -05001377 int rc;
James Smart40496f02006-07-06 15:50:22 -04001378
James Smart71157c92013-07-15 18:34:36 -04001379 if (!phba->cfg_enable_hba_reset)
James Smartf7a919b2011-08-21 21:49:16 -04001380 return -EACCES;
James Smart13815c82008-01-11 01:52:48 -05001381
James Smart71157c92013-07-15 18:34:36 -04001382 if (!(phba->pport->fc_flag & FC_OFFLINE_MODE)) {
1383 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
James Smart40496f02006-07-06 15:50:22 -04001384
James Smart71157c92013-07-15 18:34:36 -04001385 if (status != 0)
1386 return status;
1387 }
James Smart40496f02006-07-06 15:50:22 -04001388
1389 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001390 rc = lpfc_workq_post_event(phba, &status, &online_compl,
James Smart40496f02006-07-06 15:50:22 -04001391 LPFC_EVT_ONLINE);
James Smartfedd3b72011-02-16 12:39:24 -05001392 if (rc == 0)
1393 return -ENOMEM;
1394
James Smart40496f02006-07-06 15:50:22 -04001395 wait_for_completion(&online_compl);
1396
1397 if (status != 0)
1398 return -EIO;
1399
1400 return 0;
1401}
1402
James Smarte59058c2008-08-24 21:49:00 -04001403/**
James Smart3621a712009-04-06 18:47:14 -04001404 * lpfc_issue_reset - Selectively resets an adapter
James Smarte59058c2008-08-24 21:49:00 -04001405 * @dev: class device that is converted into a Scsi_host.
1406 * @attr: device attribute, not used.
1407 * @buf: containing the string "selective".
1408 * @count: unused variable.
1409 *
1410 * Description:
1411 * If the buf contains the string "selective" then lpfc_selective_reset()
1412 * is called to perform the reset.
1413 *
1414 * Notes:
1415 * Assumes any error from lpfc_selective_reset() will be negative.
1416 * If lpfc_selective_reset() returns zero then the length of the buffer
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02001417 * is returned which indicates success
James Smarte59058c2008-08-24 21:49:00 -04001418 *
1419 * Returns:
1420 * -EINVAL if the buffer does not contain the string "selective"
1421 * length of buf if lpfc-selective_reset() if the call succeeds
1422 * return value of lpfc_selective_reset() if the call fails
1423**/
James Smart40496f02006-07-06 15:50:22 -04001424static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001425lpfc_issue_reset(struct device *dev, struct device_attribute *attr,
1426 const char *buf, size_t count)
James Smart40496f02006-07-06 15:50:22 -04001427{
Tony Jonesee959b02008-02-22 00:13:36 +01001428 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001429 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1430 struct lpfc_hba *phba = vport->phba;
James Smart40496f02006-07-06 15:50:22 -04001431 int status = -EINVAL;
1432
James Smart73d91e52011-10-10 21:32:10 -04001433 if (!phba->cfg_enable_hba_reset)
1434 return -EACCES;
1435
James Smart40496f02006-07-06 15:50:22 -04001436 if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
James Smart7f860592011-03-11 16:05:52 -05001437 status = phba->lpfc_selective_reset(phba);
James Smart40496f02006-07-06 15:50:22 -04001438
1439 if (status == 0)
1440 return strlen(buf);
1441 else
1442 return status;
1443}
1444
James Smarte59058c2008-08-24 21:49:00 -04001445/**
James Smart88a2cfb2011-07-22 18:36:33 -04001446 * lpfc_sli4_pdev_status_reg_wait - Wait for pdev status register for readyness
1447 * @phba: lpfc_hba pointer.
1448 *
1449 * Description:
1450 * SLI4 interface type-2 device to wait on the sliport status register for
1451 * the readyness after performing a firmware reset.
1452 *
1453 * Returns:
Masanari Iida0b1587b2013-07-17 04:37:44 +09001454 * zero for success, -EPERM when port does not have privilege to perform the
James Smart026abb82011-12-13 13:20:45 -05001455 * reset, -EIO when port timeout from recovering from the reset.
1456 *
1457 * Note:
1458 * As the caller will interpret the return code by value, be careful in making
1459 * change or addition to return codes.
James Smart88a2cfb2011-07-22 18:36:33 -04001460 **/
James Smart73d91e52011-10-10 21:32:10 -04001461int
James Smart88a2cfb2011-07-22 18:36:33 -04001462lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba)
1463{
James Smartf7a919b2011-08-21 21:49:16 -04001464 struct lpfc_register portstat_reg = {0};
James Smart88a2cfb2011-07-22 18:36:33 -04001465 int i;
1466
James Smartf7a919b2011-08-21 21:49:16 -04001467 msleep(100);
James Smartb7b95fb2019-09-21 20:58:49 -07001468 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
1469 &portstat_reg.word0))
1470 return -EIO;
James Smart88a2cfb2011-07-22 18:36:33 -04001471
Masanari Iida0b1587b2013-07-17 04:37:44 +09001472 /* verify if privileged for the request operation */
James Smartf7a919b2011-08-21 21:49:16 -04001473 if (!bf_get(lpfc_sliport_status_rn, &portstat_reg) &&
1474 !bf_get(lpfc_sliport_status_err, &portstat_reg))
1475 return -EPERM;
1476
James Smart88a2cfb2011-07-22 18:36:33 -04001477 /* wait for the SLI port firmware ready after firmware reset */
1478 for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) {
1479 msleep(10);
James Smartb7b95fb2019-09-21 20:58:49 -07001480 if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
1481 &portstat_reg.word0))
1482 continue;
James Smart88a2cfb2011-07-22 18:36:33 -04001483 if (!bf_get(lpfc_sliport_status_err, &portstat_reg))
1484 continue;
1485 if (!bf_get(lpfc_sliport_status_rn, &portstat_reg))
1486 continue;
1487 if (!bf_get(lpfc_sliport_status_rdy, &portstat_reg))
1488 continue;
1489 break;
1490 }
1491
1492 if (i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT)
1493 return 0;
1494 else
1495 return -EIO;
1496}
1497
1498/**
James Smart52d52442011-05-24 11:42:45 -04001499 * lpfc_sli4_pdev_reg_request - Request physical dev to perform a register acc
James Smartc0c11512011-05-24 11:41:34 -04001500 * @phba: lpfc_hba pointer.
Lee Jones9176ad22020-11-02 14:23:44 +00001501 * @opcode: The sli4 config command opcode.
James Smartc0c11512011-05-24 11:41:34 -04001502 *
1503 * Description:
James Smart52d52442011-05-24 11:42:45 -04001504 * Request SLI4 interface type-2 device to perform a physical register set
1505 * access.
James Smartc0c11512011-05-24 11:41:34 -04001506 *
1507 * Returns:
1508 * zero for success
1509 **/
1510static ssize_t
James Smart52d52442011-05-24 11:42:45 -04001511lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
James Smartc0c11512011-05-24 11:41:34 -04001512{
1513 struct completion online_compl;
James Smartb76f2dc2011-07-22 18:37:42 -04001514 struct pci_dev *pdev = phba->pcidev;
James Smart026abb82011-12-13 13:20:45 -05001515 uint32_t before_fc_flag;
1516 uint32_t sriov_nr_virtfn;
James Smartc0c11512011-05-24 11:41:34 -04001517 uint32_t reg_val;
James Smart026abb82011-12-13 13:20:45 -05001518 int status = 0, rc = 0;
1519 int job_posted = 1, sriov_err;
James Smartc0c11512011-05-24 11:41:34 -04001520
1521 if (!phba->cfg_enable_hba_reset)
James Smartf7a919b2011-08-21 21:49:16 -04001522 return -EACCES;
James Smartc0c11512011-05-24 11:41:34 -04001523
James Smart52d52442011-05-24 11:42:45 -04001524 if ((phba->sli_rev < LPFC_SLI_REV4) ||
James Smart719162b2018-12-10 19:37:01 -08001525 (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
James Smart52d52442011-05-24 11:42:45 -04001526 LPFC_SLI_INTF_IF_TYPE_2))
1527 return -EPERM;
1528
James Smart026abb82011-12-13 13:20:45 -05001529 /* Keep state if we need to restore back */
1530 before_fc_flag = phba->pport->fc_flag;
1531 sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn;
1532
James Smartb76f2dc2011-07-22 18:37:42 -04001533 /* Disable SR-IOV virtual functions if enabled */
1534 if (phba->cfg_sriov_nr_virtfn) {
1535 pci_disable_sriov(pdev);
1536 phba->cfg_sriov_nr_virtfn = 0;
1537 }
James Smart229adb02013-04-17 20:16:51 -04001538
James Smart02936352014-04-04 13:52:12 -04001539 if (opcode == LPFC_FW_DUMP)
1540 phba->hba_flag |= HBA_FW_DUMP_OP;
1541
James Smartc0c11512011-05-24 11:41:34 -04001542 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
1543
James Smart02936352014-04-04 13:52:12 -04001544 if (status != 0) {
1545 phba->hba_flag &= ~HBA_FW_DUMP_OP;
James Smartc0c11512011-05-24 11:41:34 -04001546 return status;
James Smart02936352014-04-04 13:52:12 -04001547 }
James Smartc0c11512011-05-24 11:41:34 -04001548
1549 /* wait for the device to be quiesced before firmware reset */
1550 msleep(100);
1551
1552 reg_val = readl(phba->sli4_hba.conf_regs_memmap_p +
1553 LPFC_CTL_PDEV_CTL_OFFSET);
James Smart52d52442011-05-24 11:42:45 -04001554
1555 if (opcode == LPFC_FW_DUMP)
1556 reg_val |= LPFC_FW_DUMP_REQUEST;
1557 else if (opcode == LPFC_FW_RESET)
1558 reg_val |= LPFC_CTL_PDEV_CTL_FRST;
1559 else if (opcode == LPFC_DV_RESET)
1560 reg_val |= LPFC_CTL_PDEV_CTL_DRST;
1561
James Smartc0c11512011-05-24 11:41:34 -04001562 writel(reg_val, phba->sli4_hba.conf_regs_memmap_p +
1563 LPFC_CTL_PDEV_CTL_OFFSET);
1564 /* flush */
1565 readl(phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET);
1566
1567 /* delay driver action following IF_TYPE_2 reset */
James Smart88a2cfb2011-07-22 18:36:33 -04001568 rc = lpfc_sli4_pdev_status_reg_wait(phba);
1569
James Smart026abb82011-12-13 13:20:45 -05001570 if (rc == -EPERM) {
Masanari Iida0b1587b2013-07-17 04:37:44 +09001571 /* no privilege for reset */
James Smart6b5151f2012-01-18 16:24:06 -05001572 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
Masanari Iida0b1587b2013-07-17 04:37:44 +09001573 "3150 No privilege to perform the requested "
James Smart6b5151f2012-01-18 16:24:06 -05001574 "access: x%x\n", reg_val);
James Smart026abb82011-12-13 13:20:45 -05001575 } else if (rc == -EIO) {
1576 /* reset failed, there is nothing more we can do */
James Smart6b5151f2012-01-18 16:24:06 -05001577 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
1578 "3153 Fail to perform the requested "
1579 "access: x%x\n", reg_val);
James Smartf7a919b2011-08-21 21:49:16 -04001580 return rc;
James Smart026abb82011-12-13 13:20:45 -05001581 }
1582
1583 /* keep the original port state */
1584 if (before_fc_flag & FC_OFFLINE_MODE)
1585 goto out;
James Smartc0c11512011-05-24 11:41:34 -04001586
1587 init_completion(&online_compl);
James Smart026abb82011-12-13 13:20:45 -05001588 job_posted = lpfc_workq_post_event(phba, &status, &online_compl,
1589 LPFC_EVT_ONLINE);
1590 if (!job_posted)
1591 goto out;
James Smartc0c11512011-05-24 11:41:34 -04001592
1593 wait_for_completion(&online_compl);
1594
James Smart026abb82011-12-13 13:20:45 -05001595out:
1596 /* in any case, restore the virtual functions enabled as before */
1597 if (sriov_nr_virtfn) {
1598 sriov_err =
1599 lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn);
1600 if (!sriov_err)
1601 phba->cfg_sriov_nr_virtfn = sriov_nr_virtfn;
1602 }
James Smartc0c11512011-05-24 11:41:34 -04001603
James Smart026abb82011-12-13 13:20:45 -05001604 /* return proper error code */
1605 if (!rc) {
1606 if (!job_posted)
1607 rc = -ENOMEM;
1608 else if (status)
1609 rc = -EIO;
1610 }
1611 return rc;
James Smartc0c11512011-05-24 11:41:34 -04001612}
1613
1614/**
James Smart3621a712009-04-06 18:47:14 -04001615 * lpfc_nport_evt_cnt_show - Return the number of nport events
James Smarte59058c2008-08-24 21:49:00 -04001616 * @dev: class device that is converted into a Scsi_host.
1617 * @attr: device attribute, not used.
1618 * @buf: on return contains the ascii number of nport events.
1619 *
1620 * Returns: size of formatted string.
1621 **/
dea31012005-04-17 16:05:31 -05001622static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001623lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr,
1624 char *buf)
dea31012005-04-17 16:05:31 -05001625{
Tony Jonesee959b02008-02-22 00:13:36 +01001626 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001627 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1628 struct lpfc_hba *phba = vport->phba;
1629
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001630 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
dea31012005-04-17 16:05:31 -05001631}
1632
Bart Van Assche3999df72019-03-28 11:06:16 -07001633static int
James Smart1dc5ec22018-10-23 13:41:11 -07001634lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out)
1635{
1636 LPFC_MBOXQ_t *mbox = NULL;
1637 unsigned long val = 0;
Saurav Girepunje2c7fb462019-10-24 08:27:29 +05301638 char *pval = NULL;
James Smart1dc5ec22018-10-23 13:41:11 -07001639 int rc = 0;
1640
1641 if (!strncmp("enable", buff_out,
1642 strlen("enable"))) {
1643 pval = buff_out + strlen("enable") + 1;
1644 rc = kstrtoul(pval, 0, &val);
1645 if (rc)
1646 return rc; /* Invalid number */
1647 } else if (!strncmp("disable", buff_out,
1648 strlen("disable"))) {
1649 val = 0;
1650 } else {
1651 return -EINVAL; /* Invalid command */
1652 }
1653
1654 switch (val) {
1655 case 0:
1656 val = 0x0; /* Disable */
1657 break;
1658 case 2:
1659 val = 0x1; /* Enable two port trunk */
1660 break;
1661 case 4:
1662 val = 0x2; /* Enable four port trunk */
1663 break;
1664 default:
1665 return -EINVAL;
1666 }
1667
1668 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1669 "0070 Set trunk mode with val %ld ", val);
1670
1671 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1672 if (!mbox)
1673 return -ENOMEM;
1674
1675 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
1676 LPFC_MBOX_OPCODE_FCOE_FC_SET_TRUNK_MODE,
1677 12, LPFC_SLI4_MBX_EMBED);
1678
1679 bf_set(lpfc_mbx_set_trunk_mode,
1680 &mbox->u.mqe.un.set_trunk_mode,
1681 val);
1682 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
1683 if (rc)
1684 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1685 "0071 Set trunk mode failed with status: %d",
1686 rc);
James Smart304ee432021-04-11 18:31:17 -07001687 mempool_free(mbox, phba->mbox_mem_pool);
James Smart1dc5ec22018-10-23 13:41:11 -07001688
1689 return 0;
1690}
1691
James Smarte59058c2008-08-24 21:49:00 -04001692/**
James Smart3621a712009-04-06 18:47:14 -04001693 * lpfc_board_mode_show - Return the state of the board
James Smarte59058c2008-08-24 21:49:00 -04001694 * @dev: class device that is converted into a Scsi_host.
1695 * @attr: device attribute, not used.
1696 * @buf: on return contains the state of the adapter.
1697 *
1698 * Returns: size of formatted string.
1699 **/
dea31012005-04-17 16:05:31 -05001700static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001701lpfc_board_mode_show(struct device *dev, struct device_attribute *attr,
1702 char *buf)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001703{
Tony Jonesee959b02008-02-22 00:13:36 +01001704 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001705 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1706 struct lpfc_hba *phba = vport->phba;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001707 char * state;
1708
James Smart2e0fef82007-06-17 19:56:36 -05001709 if (phba->link_state == LPFC_HBA_ERROR)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001710 state = "error";
James Smart2e0fef82007-06-17 19:56:36 -05001711 else if (phba->link_state == LPFC_WARM_START)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001712 state = "warm start";
James Smart2e0fef82007-06-17 19:56:36 -05001713 else if (phba->link_state == LPFC_INIT_START)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001714 state = "offline";
1715 else
1716 state = "online";
1717
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001718 return scnprintf(buf, PAGE_SIZE, "%s\n", state);
Jamie Wellnitz41415862006-02-28 19:25:27 -05001719}
1720
James Smarte59058c2008-08-24 21:49:00 -04001721/**
James Smart3621a712009-04-06 18:47:14 -04001722 * lpfc_board_mode_store - Puts the hba in online, offline, warm or error state
James Smarte59058c2008-08-24 21:49:00 -04001723 * @dev: class device that is converted into a Scsi_host.
1724 * @attr: device attribute, not used.
1725 * @buf: containing one of the strings "online", "offline", "warm" or "error".
1726 * @count: unused variable.
1727 *
1728 * Returns:
1729 * -EACCES if enable hba reset not enabled
1730 * -EINVAL if the buffer does not contain a valid string (see above)
1731 * -EIO if lpfc_workq_post_event() or lpfc_do_offline() fails
1732 * buf length greater than zero indicates success
1733 **/
Jamie Wellnitz41415862006-02-28 19:25:27 -05001734static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001735lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
1736 const char *buf, size_t count)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001737{
Tony Jonesee959b02008-02-22 00:13:36 +01001738 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001739 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1740 struct lpfc_hba *phba = vport->phba;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001741 struct completion online_compl;
James Smart026abb82011-12-13 13:20:45 -05001742 char *board_mode_str = NULL;
1743 int status = 0;
James Smartfedd3b72011-02-16 12:39:24 -05001744 int rc;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001745
James Smart026abb82011-12-13 13:20:45 -05001746 if (!phba->cfg_enable_hba_reset) {
1747 status = -EACCES;
1748 goto board_mode_out;
1749 }
James Smart88a2cfb2011-07-22 18:36:33 -04001750
1751 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart026abb82011-12-13 13:20:45 -05001752 "3050 lpfc_board_mode set to %s\n", buf);
James Smart88a2cfb2011-07-22 18:36:33 -04001753
Jamie Wellnitz41415862006-02-28 19:25:27 -05001754 init_completion(&online_compl);
1755
James Smart46fa3112007-04-25 09:51:45 -04001756 if(strncmp(buf, "online", sizeof("online") - 1) == 0) {
James Smartfedd3b72011-02-16 12:39:24 -05001757 rc = lpfc_workq_post_event(phba, &status, &online_compl,
Jamie Wellnitz41415862006-02-28 19:25:27 -05001758 LPFC_EVT_ONLINE);
James Smart026abb82011-12-13 13:20:45 -05001759 if (rc == 0) {
1760 status = -ENOMEM;
1761 goto board_mode_out;
1762 }
James Smart46fa3112007-04-25 09:51:45 -04001763 wait_for_completion(&online_compl);
James Smart522dcee2017-06-01 21:07:03 -07001764 if (status)
1765 status = -EIO;
James Smart46fa3112007-04-25 09:51:45 -04001766 } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
1767 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
Jamie Wellnitz41415862006-02-28 19:25:27 -05001768 else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0)
James Smart6a9c52c2009-10-02 15:16:51 -04001769 if (phba->sli_rev == LPFC_SLI_REV4)
James Smart026abb82011-12-13 13:20:45 -05001770 status = -EINVAL;
James Smart6a9c52c2009-10-02 15:16:51 -04001771 else
1772 status = lpfc_do_offline(phba, LPFC_EVT_WARM_START);
James Smart46fa3112007-04-25 09:51:45 -04001773 else if (strncmp(buf, "error", sizeof("error") - 1) == 0)
James Smart6a9c52c2009-10-02 15:16:51 -04001774 if (phba->sli_rev == LPFC_SLI_REV4)
James Smart026abb82011-12-13 13:20:45 -05001775 status = -EINVAL;
James Smart6a9c52c2009-10-02 15:16:51 -04001776 else
1777 status = lpfc_do_offline(phba, LPFC_EVT_KILL);
James Smartc0c11512011-05-24 11:41:34 -04001778 else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0)
James Smart52d52442011-05-24 11:42:45 -04001779 status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_DUMP);
1780 else if (strncmp(buf, "fw_reset", sizeof("fw_reset") - 1) == 0)
1781 status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_RESET);
1782 else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0)
1783 status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET);
James Smart50212672018-12-13 15:17:57 -08001784 else if (strncmp(buf, "pci_bus_reset", sizeof("pci_bus_reset") - 1)
1785 == 0)
1786 status = lpfc_reset_pci_bus(phba);
James Smarta22d73b2021-01-04 10:02:38 -08001787 else if (strncmp(buf, "heartbeat", sizeof("heartbeat") - 1) == 0)
1788 lpfc_issue_hb_tmo(phba);
James Smart1dc5ec22018-10-23 13:41:11 -07001789 else if (strncmp(buf, "trunk", sizeof("trunk") - 1) == 0)
1790 status = lpfc_set_trunking(phba, (char *)buf + sizeof("trunk"));
Jamie Wellnitz41415862006-02-28 19:25:27 -05001791 else
James Smart026abb82011-12-13 13:20:45 -05001792 status = -EINVAL;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001793
James Smart026abb82011-12-13 13:20:45 -05001794board_mode_out:
Jamie Wellnitz41415862006-02-28 19:25:27 -05001795 if (!status)
1796 return strlen(buf);
James Smart026abb82011-12-13 13:20:45 -05001797 else {
1798 board_mode_str = strchr(buf, '\n');
1799 if (board_mode_str)
1800 *board_mode_str = '\0';
1801 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1802 "3097 Failed \"%s\", status(%d), "
1803 "fc_flag(x%x)\n",
1804 buf, status, phba->pport->fc_flag);
James Smartf7a919b2011-08-21 21:49:16 -04001805 return status;
James Smart026abb82011-12-13 13:20:45 -05001806 }
Jamie Wellnitz41415862006-02-28 19:25:27 -05001807}
1808
James Smarte59058c2008-08-24 21:49:00 -04001809/**
James Smart3621a712009-04-06 18:47:14 -04001810 * lpfc_get_hba_info - Return various bits of informaton about the adapter
James Smarte59058c2008-08-24 21:49:00 -04001811 * @phba: pointer to the adapter structure.
James Smart3621a712009-04-06 18:47:14 -04001812 * @mxri: max xri count.
1813 * @axri: available xri count.
1814 * @mrpi: max rpi count.
1815 * @arpi: available rpi count.
1816 * @mvpi: max vpi count.
1817 * @avpi: available vpi count.
James Smarte59058c2008-08-24 21:49:00 -04001818 *
1819 * Description:
1820 * If an integer pointer for an count is not null then the value for the
1821 * count is returned.
1822 *
1823 * Returns:
1824 * zero on error
1825 * one for success
1826 **/
James Smart311464e2007-08-02 11:10:37 -04001827static int
James Smart858c9f62007-06-17 19:56:39 -05001828lpfc_get_hba_info(struct lpfc_hba *phba,
1829 uint32_t *mxri, uint32_t *axri,
1830 uint32_t *mrpi, uint32_t *arpi,
1831 uint32_t *mvpi, uint32_t *avpi)
James Smart92d7f7b2007-06-17 19:56:38 -05001832{
James Smart04c68492009-05-22 14:52:52 -04001833 struct lpfc_mbx_read_config *rd_config;
James Smart92d7f7b2007-06-17 19:56:38 -05001834 LPFC_MBOXQ_t *pmboxq;
1835 MAILBOX_t *pmb;
1836 int rc = 0;
James Smart15672312010-04-06 14:49:03 -04001837 uint32_t max_vpi;
James Smart92d7f7b2007-06-17 19:56:38 -05001838
1839 /*
1840 * prevent udev from issuing mailbox commands until the port is
1841 * configured.
1842 */
1843 if (phba->link_state < LPFC_LINK_DOWN ||
1844 !phba->mbox_mem_pool ||
James Smartf4b4c682009-05-22 14:53:12 -04001845 (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
James Smart92d7f7b2007-06-17 19:56:38 -05001846 return 0;
1847
1848 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
1849 return 0;
1850
1851 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1852 if (!pmboxq)
1853 return 0;
1854 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
1855
James Smart04c68492009-05-22 14:52:52 -04001856 pmb = &pmboxq->u.mb;
James Smart92d7f7b2007-06-17 19:56:38 -05001857 pmb->mbxCommand = MBX_READ_CONFIG;
1858 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08001859 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05001860
James Smart75baf692010-06-08 18:31:21 -04001861 if (phba->pport->fc_flag & FC_OFFLINE_MODE)
James Smart92d7f7b2007-06-17 19:56:38 -05001862 rc = MBX_NOT_FINISHED;
1863 else
1864 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1865
1866 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05001867 if (rc != MBX_TIMEOUT)
James Smart92d7f7b2007-06-17 19:56:38 -05001868 mempool_free(pmboxq, phba->mbox_mem_pool);
1869 return 0;
1870 }
1871
James Smartda0436e2009-05-22 14:51:39 -04001872 if (phba->sli_rev == LPFC_SLI_REV4) {
1873 rd_config = &pmboxq->u.mqe.un.rd_config;
1874 if (mrpi)
1875 *mrpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config);
1876 if (arpi)
1877 *arpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config) -
1878 phba->sli4_hba.max_cfg_param.rpi_used;
1879 if (mxri)
1880 *mxri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
1881 if (axri)
1882 *axri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config) -
1883 phba->sli4_hba.max_cfg_param.xri_used;
James Smart15672312010-04-06 14:49:03 -04001884
1885 /* Account for differences with SLI-3. Get vpi count from
1886 * mailbox data and subtract one for max vpi value.
1887 */
1888 max_vpi = (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) > 0) ?
1889 (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) - 1) : 0;
1890
James Smart8b47ae62018-11-29 16:09:33 -08001891 /* Limit the max we support */
1892 if (max_vpi > LPFC_MAX_VPI)
1893 max_vpi = LPFC_MAX_VPI;
James Smartda0436e2009-05-22 14:51:39 -04001894 if (mvpi)
James Smart15672312010-04-06 14:49:03 -04001895 *mvpi = max_vpi;
James Smartda0436e2009-05-22 14:51:39 -04001896 if (avpi)
James Smart15672312010-04-06 14:49:03 -04001897 *avpi = max_vpi - phba->sli4_hba.max_cfg_param.vpi_used;
James Smartda0436e2009-05-22 14:51:39 -04001898 } else {
1899 if (mrpi)
1900 *mrpi = pmb->un.varRdConfig.max_rpi;
1901 if (arpi)
1902 *arpi = pmb->un.varRdConfig.avail_rpi;
1903 if (mxri)
1904 *mxri = pmb->un.varRdConfig.max_xri;
1905 if (axri)
1906 *axri = pmb->un.varRdConfig.avail_xri;
1907 if (mvpi)
1908 *mvpi = pmb->un.varRdConfig.max_vpi;
James Smart8b47ae62018-11-29 16:09:33 -08001909 if (avpi) {
1910 /* avail_vpi is only valid if link is up and ready */
1911 if (phba->link_state == LPFC_HBA_READY)
1912 *avpi = pmb->un.varRdConfig.avail_vpi;
1913 else
1914 *avpi = pmb->un.varRdConfig.max_vpi;
1915 }
James Smartda0436e2009-05-22 14:51:39 -04001916 }
James Smart92d7f7b2007-06-17 19:56:38 -05001917
1918 mempool_free(pmboxq, phba->mbox_mem_pool);
1919 return 1;
1920}
1921
James Smarte59058c2008-08-24 21:49:00 -04001922/**
James Smart3621a712009-04-06 18:47:14 -04001923 * lpfc_max_rpi_show - Return maximum rpi
James Smarte59058c2008-08-24 21:49:00 -04001924 * @dev: class device that is converted into a Scsi_host.
1925 * @attr: device attribute, not used.
1926 * @buf: on return contains the maximum rpi count in decimal or "Unknown".
1927 *
1928 * Description:
1929 * Calls lpfc_get_hba_info() asking for just the mrpi count.
1930 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1931 * to "Unknown" and the buffer length is returned, therefore the caller
1932 * must check for "Unknown" in the buffer to detect a failure.
1933 *
1934 * Returns: size of formatted string.
1935 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001936static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001937lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr,
1938 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001939{
Tony Jonesee959b02008-02-22 00:13:36 +01001940 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05001941 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1942 struct lpfc_hba *phba = vport->phba;
1943 uint32_t cnt;
1944
James Smart858c9f62007-06-17 19:56:39 -05001945 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001946 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
1947 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001948}
1949
James Smarte59058c2008-08-24 21:49:00 -04001950/**
James Smart3621a712009-04-06 18:47:14 -04001951 * lpfc_used_rpi_show - Return maximum rpi minus available rpi
James Smarte59058c2008-08-24 21:49:00 -04001952 * @dev: class device that is converted into a Scsi_host.
1953 * @attr: device attribute, not used.
1954 * @buf: containing the used rpi count in decimal or "Unknown".
1955 *
1956 * Description:
1957 * Calls lpfc_get_hba_info() asking for just the mrpi and arpi counts.
1958 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1959 * to "Unknown" and the buffer length is returned, therefore the caller
1960 * must check for "Unknown" in the buffer to detect a failure.
1961 *
1962 * Returns: size of formatted string.
1963 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001964static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001965lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr,
1966 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001967{
Tony Jonesee959b02008-02-22 00:13:36 +01001968 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05001969 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1970 struct lpfc_hba *phba = vport->phba;
1971 uint32_t cnt, acnt;
1972
James Smart858c9f62007-06-17 19:56:39 -05001973 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001974 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
1975 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001976}
1977
James Smarte59058c2008-08-24 21:49:00 -04001978/**
James Smart3621a712009-04-06 18:47:14 -04001979 * lpfc_max_xri_show - Return maximum xri
James Smarte59058c2008-08-24 21:49:00 -04001980 * @dev: class device that is converted into a Scsi_host.
1981 * @attr: device attribute, not used.
1982 * @buf: on return contains the maximum xri count in decimal or "Unknown".
1983 *
1984 * Description:
1985 * Calls lpfc_get_hba_info() asking for just the mrpi count.
1986 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1987 * to "Unknown" and the buffer length is returned, therefore the caller
1988 * must check for "Unknown" in the buffer to detect a failure.
1989 *
1990 * Returns: size of formatted string.
1991 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001992static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001993lpfc_max_xri_show(struct device *dev, struct device_attribute *attr,
1994 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001995{
Tony Jonesee959b02008-02-22 00:13:36 +01001996 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05001997 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1998 struct lpfc_hba *phba = vport->phba;
1999 uint32_t cnt;
2000
James Smart858c9f62007-06-17 19:56:39 -05002001 if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002002 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
2003 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002004}
2005
James Smarte59058c2008-08-24 21:49:00 -04002006/**
James Smart3621a712009-04-06 18:47:14 -04002007 * lpfc_used_xri_show - Return maximum xpi minus the available xpi
James Smarte59058c2008-08-24 21:49:00 -04002008 * @dev: class device that is converted into a Scsi_host.
2009 * @attr: device attribute, not used.
2010 * @buf: on return contains the used xri count in decimal or "Unknown".
2011 *
2012 * Description:
2013 * Calls lpfc_get_hba_info() asking for just the mxri and axri counts.
2014 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2015 * to "Unknown" and the buffer length is returned, therefore the caller
2016 * must check for "Unknown" in the buffer to detect a failure.
2017 *
2018 * Returns: size of formatted string.
2019 **/
James Smart92d7f7b2007-06-17 19:56:38 -05002020static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002021lpfc_used_xri_show(struct device *dev, struct device_attribute *attr,
2022 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05002023{
Tony Jonesee959b02008-02-22 00:13:36 +01002024 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05002025 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2026 struct lpfc_hba *phba = vport->phba;
2027 uint32_t cnt, acnt;
2028
James Smart858c9f62007-06-17 19:56:39 -05002029 if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002030 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
2031 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart858c9f62007-06-17 19:56:39 -05002032}
2033
James Smarte59058c2008-08-24 21:49:00 -04002034/**
James Smart3621a712009-04-06 18:47:14 -04002035 * lpfc_max_vpi_show - Return maximum vpi
James Smarte59058c2008-08-24 21:49:00 -04002036 * @dev: class device that is converted into a Scsi_host.
2037 * @attr: device attribute, not used.
2038 * @buf: on return contains the maximum vpi count in decimal or "Unknown".
2039 *
2040 * Description:
2041 * Calls lpfc_get_hba_info() asking for just the mvpi count.
2042 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2043 * to "Unknown" and the buffer length is returned, therefore the caller
2044 * must check for "Unknown" in the buffer to detect a failure.
2045 *
2046 * Returns: size of formatted string.
2047 **/
James Smart858c9f62007-06-17 19:56:39 -05002048static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002049lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr,
2050 char *buf)
James Smart858c9f62007-06-17 19:56:39 -05002051{
Tony Jonesee959b02008-02-22 00:13:36 +01002052 struct Scsi_Host *shost = class_to_shost(dev);
James Smart858c9f62007-06-17 19:56:39 -05002053 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2054 struct lpfc_hba *phba = vport->phba;
2055 uint32_t cnt;
2056
2057 if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002058 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
2059 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart858c9f62007-06-17 19:56:39 -05002060}
2061
James Smarte59058c2008-08-24 21:49:00 -04002062/**
James Smart3621a712009-04-06 18:47:14 -04002063 * lpfc_used_vpi_show - Return maximum vpi minus the available vpi
James Smarte59058c2008-08-24 21:49:00 -04002064 * @dev: class device that is converted into a Scsi_host.
2065 * @attr: device attribute, not used.
2066 * @buf: on return contains the used vpi count in decimal or "Unknown".
2067 *
2068 * Description:
2069 * Calls lpfc_get_hba_info() asking for just the mvpi and avpi counts.
2070 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2071 * to "Unknown" and the buffer length is returned, therefore the caller
2072 * must check for "Unknown" in the buffer to detect a failure.
2073 *
2074 * Returns: size of formatted string.
2075 **/
James Smart858c9f62007-06-17 19:56:39 -05002076static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002077lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr,
2078 char *buf)
James Smart858c9f62007-06-17 19:56:39 -05002079{
Tony Jonesee959b02008-02-22 00:13:36 +01002080 struct Scsi_Host *shost = class_to_shost(dev);
James Smart858c9f62007-06-17 19:56:39 -05002081 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2082 struct lpfc_hba *phba = vport->phba;
2083 uint32_t cnt, acnt;
2084
2085 if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, &acnt))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002086 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
2087 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002088}
2089
James Smarte59058c2008-08-24 21:49:00 -04002090/**
James Smart3621a712009-04-06 18:47:14 -04002091 * lpfc_npiv_info_show - Return text about NPIV support for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002092 * @dev: class device that is converted into a Scsi_host.
2093 * @attr: device attribute, not used.
2094 * @buf: text that must be interpreted to determine if npiv is supported.
2095 *
2096 * Description:
2097 * Buffer will contain text indicating npiv is not suppoerted on the port,
2098 * the port is an NPIV physical port, or it is an npiv virtual port with
2099 * the id of the vport.
2100 *
2101 * Returns: size of formatted string.
2102 **/
James Smart92d7f7b2007-06-17 19:56:38 -05002103static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002104lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr,
2105 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05002106{
Tony Jonesee959b02008-02-22 00:13:36 +01002107 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05002108 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2109 struct lpfc_hba *phba = vport->phba;
2110
2111 if (!(phba->max_vpi))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002112 return scnprintf(buf, PAGE_SIZE, "NPIV Not Supported\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002113 if (vport->port_type == LPFC_PHYSICAL_PORT)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002114 return scnprintf(buf, PAGE_SIZE, "NPIV Physical\n");
2115 return scnprintf(buf, PAGE_SIZE, "NPIV Virtual (VPI %d)\n", vport->vpi);
James Smart92d7f7b2007-06-17 19:56:38 -05002116}
2117
James Smarte59058c2008-08-24 21:49:00 -04002118/**
James Smart3621a712009-04-06 18:47:14 -04002119 * lpfc_poll_show - Return text about poll support for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002120 * @dev: class device that is converted into a Scsi_host.
2121 * @attr: device attribute, not used.
2122 * @buf: on return contains the cfg_poll in hex.
2123 *
2124 * Notes:
2125 * cfg_poll should be a lpfc_polling_flags type.
2126 *
2127 * Returns: size of formatted string.
2128 **/
Jamie Wellnitz41415862006-02-28 19:25:27 -05002129static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002130lpfc_poll_show(struct device *dev, struct device_attribute *attr,
2131 char *buf)
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002132{
Tony Jonesee959b02008-02-22 00:13:36 +01002133 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05002134 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2135 struct lpfc_hba *phba = vport->phba;
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002136
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002137 return scnprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002138}
2139
James Smarte59058c2008-08-24 21:49:00 -04002140/**
James Smart3621a712009-04-06 18:47:14 -04002141 * lpfc_poll_store - Set the value of cfg_poll for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002142 * @dev: class device that is converted into a Scsi_host.
2143 * @attr: device attribute, not used.
2144 * @buf: one or more lpfc_polling_flags values.
2145 * @count: not used.
2146 *
2147 * Notes:
2148 * buf contents converted to integer and checked for a valid value.
2149 *
2150 * Returns:
2151 * -EINVAL if the buffer connot be converted or is out of range
2152 * length of the buf on success
2153 **/
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002154static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002155lpfc_poll_store(struct device *dev, struct device_attribute *attr,
2156 const char *buf, size_t count)
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002157{
Tony Jonesee959b02008-02-22 00:13:36 +01002158 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05002159 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2160 struct lpfc_hba *phba = vport->phba;
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002161 uint32_t creg_val;
2162 uint32_t old_val;
2163 int val=0;
2164
2165 if (!isdigit(buf[0]))
2166 return -EINVAL;
2167
2168 if (sscanf(buf, "%i", &val) != 1)
2169 return -EINVAL;
2170
2171 if ((val & 0x3) != val)
2172 return -EINVAL;
2173
James Smart45ed1192009-10-02 15:17:02 -04002174 if (phba->sli_rev == LPFC_SLI_REV4)
2175 val = 0;
2176
James Smart88a2cfb2011-07-22 18:36:33 -04002177 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
2178 "3051 lpfc_poll changed from %d to %d\n",
2179 phba->cfg_poll, val);
2180
James Smart2e0fef82007-06-17 19:56:36 -05002181 spin_lock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002182
2183 old_val = phba->cfg_poll;
2184
2185 if (val & ENABLE_FCP_RING_POLLING) {
2186 if ((val & DISABLE_FCP_RING_INT) &&
2187 !(old_val & DISABLE_FCP_RING_INT)) {
James Smart9940b972011-03-11 16:06:12 -05002188 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
2189 spin_unlock_irq(&phba->hbalock);
2190 return -EINVAL;
2191 }
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002192 creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
2193 writel(creg_val, phba->HCregaddr);
2194 readl(phba->HCregaddr); /* flush */
2195
2196 lpfc_poll_start_timer(phba);
2197 }
2198 } else if (val != 0x0) {
James Smart2e0fef82007-06-17 19:56:36 -05002199 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002200 return -EINVAL;
2201 }
2202
2203 if (!(val & DISABLE_FCP_RING_INT) &&
2204 (old_val & DISABLE_FCP_RING_INT))
2205 {
James Smart2e0fef82007-06-17 19:56:36 -05002206 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002207 del_timer(&phba->fcp_poll_timer);
James Smart2e0fef82007-06-17 19:56:36 -05002208 spin_lock_irq(&phba->hbalock);
James Smart9940b972011-03-11 16:06:12 -05002209 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
2210 spin_unlock_irq(&phba->hbalock);
2211 return -EINVAL;
2212 }
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002213 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
2214 writel(creg_val, phba->HCregaddr);
2215 readl(phba->HCregaddr); /* flush */
2216 }
2217
2218 phba->cfg_poll = val;
2219
James Smart2e0fef82007-06-17 19:56:36 -05002220 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002221
2222 return strlen(buf);
2223}
dea31012005-04-17 16:05:31 -05002224
James Smarte59058c2008-08-24 21:49:00 -04002225/**
James Smart912e3ac2011-05-24 11:42:11 -04002226 * lpfc_sriov_hw_max_virtfn_show - Return maximum number of virtual functions
2227 * @dev: class converted to a Scsi_host structure.
2228 * @attr: device attribute, not used.
2229 * @buf: on return contains the formatted support level.
2230 *
2231 * Description:
2232 * Returns the maximum number of virtual functions a physical function can
2233 * support, 0 will be returned if called on virtual function.
2234 *
2235 * Returns: size of formatted string.
2236 **/
2237static ssize_t
2238lpfc_sriov_hw_max_virtfn_show(struct device *dev,
2239 struct device_attribute *attr,
2240 char *buf)
2241{
2242 struct Scsi_Host *shost = class_to_shost(dev);
2243 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2244 struct lpfc_hba *phba = vport->phba;
James Smart0a96e972011-07-22 18:37:28 -04002245 uint16_t max_nr_virtfn;
James Smart912e3ac2011-05-24 11:42:11 -04002246
James Smart0a96e972011-07-22 18:37:28 -04002247 max_nr_virtfn = lpfc_sli_sriov_nr_virtfn_get(phba);
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002248 return scnprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn);
James Smart912e3ac2011-05-24 11:42:11 -04002249}
2250
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002251static inline bool lpfc_rangecheck(uint val, uint min, uint max)
2252{
2253 return val >= min && val <= max;
2254}
2255
James Smart912e3ac2011-05-24 11:42:11 -04002256/**
James Smart44fd7fe2017-08-23 16:55:47 -07002257 * lpfc_enable_bbcr_set: Sets an attribute value.
2258 * @phba: pointer the the adapter structure.
2259 * @val: integer attribute value.
2260 *
2261 * Description:
2262 * Validates the min and max values then sets the
2263 * adapter config field if in the valid range. prints error message
2264 * and does not set the parameter if invalid.
2265 *
2266 * Returns:
2267 * zero on success
2268 * -EINVAL if val is invalid
2269 */
2270static ssize_t
2271lpfc_enable_bbcr_set(struct lpfc_hba *phba, uint val)
2272{
2273 if (lpfc_rangecheck(val, 0, 1) && phba->sli_rev == LPFC_SLI_REV4) {
2274 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart5b1f5082021-04-11 18:31:25 -07002275 "3068 lpfc_enable_bbcr changed from %d to "
2276 "%d\n", phba->cfg_enable_bbcr, val);
James Smart44fd7fe2017-08-23 16:55:47 -07002277 phba->cfg_enable_bbcr = val;
2278 return 0;
2279 }
2280 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart5b1f5082021-04-11 18:31:25 -07002281 "0451 lpfc_enable_bbcr cannot set to %d, range is 0, "
2282 "1\n", val);
James Smart44fd7fe2017-08-23 16:55:47 -07002283 return -EINVAL;
2284}
2285
Lee Jones9176ad22020-11-02 14:23:44 +00002286/*
James Smart3621a712009-04-06 18:47:14 -04002287 * lpfc_param_show - Return a cfg attribute value in decimal
James Smarte59058c2008-08-24 21:49:00 -04002288 *
2289 * Description:
2290 * Macro that given an attr e.g. hba_queue_depth expands
2291 * into a function with the name lpfc_hba_queue_depth_show.
2292 *
2293 * lpfc_##attr##_show: Return the decimal value of an adapters cfg_xxx field.
2294 * @dev: class device that is converted into a Scsi_host.
2295 * @attr: device attribute, not used.
2296 * @buf: on return contains the attribute value in decimal.
2297 *
2298 * Returns: size of formatted string.
2299 **/
dea31012005-04-17 16:05:31 -05002300#define lpfc_param_show(attr) \
2301static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002302lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2303 char *buf) \
dea31012005-04-17 16:05:31 -05002304{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002305 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002306 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2307 struct lpfc_hba *phba = vport->phba;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002308 return scnprintf(buf, PAGE_SIZE, "%d\n",\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002309 phba->cfg_##attr);\
dea31012005-04-17 16:05:31 -05002310}
2311
Lee Jones9176ad22020-11-02 14:23:44 +00002312/*
James Smart3621a712009-04-06 18:47:14 -04002313 * lpfc_param_hex_show - Return a cfg attribute value in hex
James Smarte59058c2008-08-24 21:49:00 -04002314 *
2315 * Description:
2316 * Macro that given an attr e.g. hba_queue_depth expands
2317 * into a function with the name lpfc_hba_queue_depth_show
2318 *
2319 * lpfc_##attr##_show: Return the hex value of an adapters cfg_xxx field.
2320 * @dev: class device that is converted into a Scsi_host.
2321 * @attr: device attribute, not used.
James Smart3621a712009-04-06 18:47:14 -04002322 * @buf: on return contains the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002323 *
2324 * Returns: size of formatted string.
2325 **/
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002326#define lpfc_param_hex_show(attr) \
2327static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002328lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2329 char *buf) \
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002330{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002331 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002332 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2333 struct lpfc_hba *phba = vport->phba;\
James Smart84d1b002010-02-12 14:42:33 -05002334 uint val = 0;\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002335 val = phba->cfg_##attr;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002336 return scnprintf(buf, PAGE_SIZE, "%#x\n",\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002337 phba->cfg_##attr);\
2338}
2339
Lee Jones9176ad22020-11-02 14:23:44 +00002340/*
Uwe Kleine-Königb5950762010-11-01 15:38:34 -04002341 * lpfc_param_init - Initializes a cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002342 *
2343 * Description:
2344 * Macro that given an attr e.g. hba_queue_depth expands
2345 * into a function with the name lpfc_hba_queue_depth_init. The macro also
2346 * takes a default argument, a minimum and maximum argument.
2347 *
2348 * lpfc_##attr##_init: Initializes an attribute.
2349 * @phba: pointer the the adapter structure.
2350 * @val: integer attribute value.
2351 *
2352 * Validates the min and max values then sets the adapter config field
2353 * accordingly, or uses the default if out of range and prints an error message.
2354 *
2355 * Returns:
2356 * zero on success
2357 * -EINVAL if default used
2358 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002359#define lpfc_param_init(attr, default, minval, maxval) \
2360static int \
James Smart84d1b002010-02-12 14:42:33 -05002361lpfc_##attr##_init(struct lpfc_hba *phba, uint val) \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002362{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002363 if (lpfc_rangecheck(val, minval, maxval)) {\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002364 phba->cfg_##attr = val;\
2365 return 0;\
2366 }\
2367 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
James Smarte8b62012007-08-02 11:10:09 -04002368 "0449 lpfc_"#attr" attribute cannot be set to %d, "\
2369 "allowed range is ["#minval", "#maxval"]\n", val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002370 phba->cfg_##attr = default;\
2371 return -EINVAL;\
2372}
2373
Lee Jones9176ad22020-11-02 14:23:44 +00002374/*
James Smart3621a712009-04-06 18:47:14 -04002375 * lpfc_param_set - Set a cfg attribute value
James Smarte59058c2008-08-24 21:49:00 -04002376 *
2377 * Description:
2378 * Macro that given an attr e.g. hba_queue_depth expands
2379 * into a function with the name lpfc_hba_queue_depth_set
2380 *
2381 * lpfc_##attr##_set: Sets an attribute value.
2382 * @phba: pointer the the adapter structure.
2383 * @val: integer attribute value.
2384 *
2385 * Description:
2386 * Validates the min and max values then sets the
2387 * adapter config field if in the valid range. prints error message
2388 * and does not set the parameter if invalid.
2389 *
2390 * Returns:
2391 * zero on success
2392 * -EINVAL if val is invalid
2393 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002394#define lpfc_param_set(attr, default, minval, maxval) \
2395static int \
James Smart84d1b002010-02-12 14:42:33 -05002396lpfc_##attr##_set(struct lpfc_hba *phba, uint val) \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002397{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002398 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart88a2cfb2011-07-22 18:36:33 -04002399 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
2400 "3052 lpfc_" #attr " changed from %d to %d\n", \
2401 phba->cfg_##attr, val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002402 phba->cfg_##attr = val;\
2403 return 0;\
2404 }\
2405 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
James Smarte8b62012007-08-02 11:10:09 -04002406 "0450 lpfc_"#attr" attribute cannot be set to %d, "\
2407 "allowed range is ["#minval", "#maxval"]\n", val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002408 return -EINVAL;\
2409}
2410
Lee Jones9176ad22020-11-02 14:23:44 +00002411/*
James Smart3621a712009-04-06 18:47:14 -04002412 * lpfc_param_store - Set a vport attribute value
James Smarte59058c2008-08-24 21:49:00 -04002413 *
2414 * Description:
2415 * Macro that given an attr e.g. hba_queue_depth expands
2416 * into a function with the name lpfc_hba_queue_depth_store.
2417 *
2418 * lpfc_##attr##_store: Set an sttribute value.
2419 * @dev: class device that is converted into a Scsi_host.
2420 * @attr: device attribute, not used.
2421 * @buf: contains the attribute value in ascii.
2422 * @count: not used.
2423 *
2424 * Description:
2425 * Convert the ascii text number to an integer, then
2426 * use the lpfc_##attr##_set function to set the value.
2427 *
2428 * Returns:
2429 * -EINVAL if val is invalid or lpfc_##attr##_set() fails
2430 * length of buffer upon success.
2431 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002432#define lpfc_param_store(attr) \
dea31012005-04-17 16:05:31 -05002433static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002434lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
2435 const char *buf, size_t count) \
dea31012005-04-17 16:05:31 -05002436{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002437 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002438 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2439 struct lpfc_hba *phba = vport->phba;\
James Smart84d1b002010-02-12 14:42:33 -05002440 uint val = 0;\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002441 if (!isdigit(buf[0]))\
2442 return -EINVAL;\
2443 if (sscanf(buf, "%i", &val) != 1)\
2444 return -EINVAL;\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002445 if (lpfc_##attr##_set(phba, val) == 0) \
James.Smart@Emulex.Com755c0d02005-10-28 20:29:06 -04002446 return strlen(buf);\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002447 else \
2448 return -EINVAL;\
dea31012005-04-17 16:05:31 -05002449}
2450
Lee Jones9176ad22020-11-02 14:23:44 +00002451/*
James Smart3621a712009-04-06 18:47:14 -04002452 * lpfc_vport_param_show - Return decimal formatted cfg attribute value
James Smarte59058c2008-08-24 21:49:00 -04002453 *
2454 * Description:
2455 * Macro that given an attr e.g. hba_queue_depth expands
2456 * into a function with the name lpfc_hba_queue_depth_show
2457 *
2458 * lpfc_##attr##_show: prints the attribute value in decimal.
2459 * @dev: class device that is converted into a Scsi_host.
2460 * @attr: device attribute, not used.
2461 * @buf: on return contains the attribute value in decimal.
2462 *
2463 * Returns: length of formatted string.
2464 **/
James Smart3de2a652007-08-02 11:09:59 -04002465#define lpfc_vport_param_show(attr) \
2466static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002467lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2468 char *buf) \
James Smart3de2a652007-08-02 11:09:59 -04002469{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002470 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002471 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002472 return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\
James Smart3de2a652007-08-02 11:09:59 -04002473}
2474
Lee Jones9176ad22020-11-02 14:23:44 +00002475/*
James Smart3621a712009-04-06 18:47:14 -04002476 * lpfc_vport_param_hex_show - Return hex formatted attribute value
James Smarte59058c2008-08-24 21:49:00 -04002477 *
2478 * Description:
2479 * Macro that given an attr e.g.
2480 * hba_queue_depth expands into a function with the name
2481 * lpfc_hba_queue_depth_show
2482 *
James Smart3621a712009-04-06 18:47:14 -04002483 * lpfc_##attr##_show: prints the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002484 * @dev: class device that is converted into a Scsi_host.
2485 * @attr: device attribute, not used.
James Smart3621a712009-04-06 18:47:14 -04002486 * @buf: on return contains the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002487 *
2488 * Returns: length of formatted string.
2489 **/
James Smart3de2a652007-08-02 11:09:59 -04002490#define lpfc_vport_param_hex_show(attr) \
2491static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002492lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2493 char *buf) \
James Smart3de2a652007-08-02 11:09:59 -04002494{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002495 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002496 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002497 return scnprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\
James Smart3de2a652007-08-02 11:09:59 -04002498}
2499
Lee Jones9176ad22020-11-02 14:23:44 +00002500/*
James Smart3621a712009-04-06 18:47:14 -04002501 * lpfc_vport_param_init - Initialize a vport cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002502 *
2503 * Description:
2504 * Macro that given an attr e.g. hba_queue_depth expands
2505 * into a function with the name lpfc_hba_queue_depth_init. The macro also
2506 * takes a default argument, a minimum and maximum argument.
2507 *
2508 * lpfc_##attr##_init: validates the min and max values then sets the
2509 * adapter config field accordingly, or uses the default if out of range
2510 * and prints an error message.
2511 * @phba: pointer the the adapter structure.
2512 * @val: integer attribute value.
2513 *
2514 * Returns:
2515 * zero on success
2516 * -EINVAL if default used
2517 **/
James Smart3de2a652007-08-02 11:09:59 -04002518#define lpfc_vport_param_init(attr, default, minval, maxval) \
2519static int \
James Smart84d1b002010-02-12 14:42:33 -05002520lpfc_##attr##_init(struct lpfc_vport *vport, uint val) \
James Smart3de2a652007-08-02 11:09:59 -04002521{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002522 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart3de2a652007-08-02 11:09:59 -04002523 vport->cfg_##attr = val;\
2524 return 0;\
2525 }\
James Smarte8b62012007-08-02 11:10:09 -04002526 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smartd7c255b2008-08-24 21:50:00 -04002527 "0423 lpfc_"#attr" attribute cannot be set to %d, "\
James Smarte8b62012007-08-02 11:10:09 -04002528 "allowed range is ["#minval", "#maxval"]\n", val); \
James Smart3de2a652007-08-02 11:09:59 -04002529 vport->cfg_##attr = default;\
2530 return -EINVAL;\
2531}
2532
Lee Jones9176ad22020-11-02 14:23:44 +00002533/*
James Smart3621a712009-04-06 18:47:14 -04002534 * lpfc_vport_param_set - Set a vport cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002535 *
2536 * Description:
2537 * Macro that given an attr e.g. hba_queue_depth expands
2538 * into a function with the name lpfc_hba_queue_depth_set
2539 *
2540 * lpfc_##attr##_set: validates the min and max values then sets the
2541 * adapter config field if in the valid range. prints error message
2542 * and does not set the parameter if invalid.
2543 * @phba: pointer the the adapter structure.
2544 * @val: integer attribute value.
2545 *
2546 * Returns:
2547 * zero on success
2548 * -EINVAL if val is invalid
2549 **/
James Smart3de2a652007-08-02 11:09:59 -04002550#define lpfc_vport_param_set(attr, default, minval, maxval) \
2551static int \
James Smart84d1b002010-02-12 14:42:33 -05002552lpfc_##attr##_set(struct lpfc_vport *vport, uint val) \
James Smart3de2a652007-08-02 11:09:59 -04002553{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002554 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart88a2cfb2011-07-22 18:36:33 -04002555 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smart14660f42013-09-06 12:20:20 -04002556 "3053 lpfc_" #attr \
2557 " changed from %d (x%x) to %d (x%x)\n", \
2558 vport->cfg_##attr, vport->cfg_##attr, \
2559 val, val); \
James Smart3de2a652007-08-02 11:09:59 -04002560 vport->cfg_##attr = val;\
2561 return 0;\
2562 }\
James Smarte8b62012007-08-02 11:10:09 -04002563 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smartd7c255b2008-08-24 21:50:00 -04002564 "0424 lpfc_"#attr" attribute cannot be set to %d, "\
James Smarte8b62012007-08-02 11:10:09 -04002565 "allowed range is ["#minval", "#maxval"]\n", val); \
James Smart3de2a652007-08-02 11:09:59 -04002566 return -EINVAL;\
2567}
2568
Lee Jones9176ad22020-11-02 14:23:44 +00002569/*
James Smart3621a712009-04-06 18:47:14 -04002570 * lpfc_vport_param_store - Set a vport attribute
James Smarte59058c2008-08-24 21:49:00 -04002571 *
2572 * Description:
2573 * Macro that given an attr e.g. hba_queue_depth
2574 * expands into a function with the name lpfc_hba_queue_depth_store
2575 *
2576 * lpfc_##attr##_store: convert the ascii text number to an integer, then
2577 * use the lpfc_##attr##_set function to set the value.
2578 * @cdev: class device that is converted into a Scsi_host.
2579 * @buf: contains the attribute value in decimal.
2580 * @count: not used.
2581 *
2582 * Returns:
2583 * -EINVAL if val is invalid or lpfc_##attr##_set() fails
2584 * length of buffer upon success.
2585 **/
James Smart3de2a652007-08-02 11:09:59 -04002586#define lpfc_vport_param_store(attr) \
2587static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002588lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
2589 const char *buf, size_t count) \
James Smart3de2a652007-08-02 11:09:59 -04002590{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002591 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002592 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
James Smart84d1b002010-02-12 14:42:33 -05002593 uint val = 0;\
James Smart3de2a652007-08-02 11:09:59 -04002594 if (!isdigit(buf[0]))\
2595 return -EINVAL;\
2596 if (sscanf(buf, "%i", &val) != 1)\
2597 return -EINVAL;\
2598 if (lpfc_##attr##_set(vport, val) == 0) \
2599 return strlen(buf);\
2600 else \
2601 return -EINVAL;\
2602}
2603
2604
James Smart895427b2017-02-12 13:52:30 -08002605static DEVICE_ATTR(nvme_info, 0444, lpfc_nvme_info_show, NULL);
James Smart4c47efc2019-01-28 11:14:25 -08002606static DEVICE_ATTR(scsi_stat, 0444, lpfc_scsi_stat_show, NULL);
James Smart81301a92008-12-04 22:39:46 -05002607static DEVICE_ATTR(bg_info, S_IRUGO, lpfc_bg_info_show, NULL);
2608static DEVICE_ATTR(bg_guard_err, S_IRUGO, lpfc_bg_guard_err_show, NULL);
2609static DEVICE_ATTR(bg_apptag_err, S_IRUGO, lpfc_bg_apptag_err_show, NULL);
2610static DEVICE_ATTR(bg_reftag_err, S_IRUGO, lpfc_bg_reftag_err_show, NULL);
Tony Jonesee959b02008-02-22 00:13:36 +01002611static DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
2612static DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
2613static DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
2614static DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL);
2615static DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);
2616static DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL);
2617static DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);
2618static DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);
James Smart84d1b002010-02-12 14:42:33 -05002619static DEVICE_ATTR(link_state, S_IRUGO | S_IWUSR, lpfc_link_state_show,
2620 lpfc_link_state_store);
Tony Jonesee959b02008-02-22 00:13:36 +01002621static DEVICE_ATTR(option_rom_version, S_IRUGO,
2622 lpfc_option_rom_version_show, NULL);
2623static DEVICE_ATTR(num_discovered_ports, S_IRUGO,
2624 lpfc_num_discovered_ports_show, NULL);
James Smart84774a42008-08-24 21:50:06 -04002625static DEVICE_ATTR(menlo_mgmt_mode, S_IRUGO, lpfc_mlomgmt_show, NULL);
Tony Jonesee959b02008-02-22 00:13:36 +01002626static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
Joe Perchesc828a892017-12-19 10:15:08 -08002627static DEVICE_ATTR_RO(lpfc_drvr_version);
2628static DEVICE_ATTR_RO(lpfc_enable_fip);
Tony Jonesee959b02008-02-22 00:13:36 +01002629static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
2630 lpfc_board_mode_show, lpfc_board_mode_store);
2631static DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
2632static DEVICE_ATTR(max_vpi, S_IRUGO, lpfc_max_vpi_show, NULL);
2633static DEVICE_ATTR(used_vpi, S_IRUGO, lpfc_used_vpi_show, NULL);
2634static DEVICE_ATTR(max_rpi, S_IRUGO, lpfc_max_rpi_show, NULL);
2635static DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL);
2636static DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL);
2637static DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL);
2638static DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL);
Joe Perchesc828a892017-12-19 10:15:08 -08002639static DEVICE_ATTR_RO(lpfc_temp_sensor);
Joe Perchesc828a892017-12-19 10:15:08 -08002640static DEVICE_ATTR_RO(lpfc_sriov_hw_max_virtfn);
James Smart026abb82011-12-13 13:20:45 -05002641static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL);
James Smart1ba981f2014-02-20 09:56:45 -05002642static DEVICE_ATTR(lpfc_xlane_supported, S_IRUGO, lpfc_oas_supported_show,
2643 NULL);
James Smartc3f28af2006-08-18 17:47:18 -04002644
James Smart352e5fd2016-12-30 06:57:47 -08002645static char *lpfc_soft_wwn_key = "C99G71SL8032A";
James Smart1ba981f2014-02-20 09:56:45 -05002646#define WWN_SZ 8
2647/**
2648 * lpfc_wwn_set - Convert string to the 8 byte WWN value.
2649 * @buf: WWN string.
2650 * @cnt: Length of string.
2651 * @wwn: Array to receive converted wwn value.
2652 *
2653 * Returns:
2654 * -EINVAL if the buffer does not contain a valid wwn
2655 * 0 success
2656 **/
2657static size_t
2658lpfc_wwn_set(const char *buf, size_t cnt, char wwn[])
2659{
2660 unsigned int i, j;
James Smartc3f28af2006-08-18 17:47:18 -04002661
James Smart1ba981f2014-02-20 09:56:45 -05002662 /* Count may include a LF at end of string */
2663 if (buf[cnt-1] == '\n')
2664 cnt--;
2665
2666 if ((cnt < 16) || (cnt > 18) || ((cnt == 17) && (*buf++ != 'x')) ||
2667 ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
2668 return -EINVAL;
2669
2670 memset(wwn, 0, WWN_SZ);
2671
2672 /* Validate and store the new name */
2673 for (i = 0, j = 0; i < 16; i++) {
2674 if ((*buf >= 'a') && (*buf <= 'f'))
2675 j = ((j << 4) | ((*buf++ - 'a') + 10));
2676 else if ((*buf >= 'A') && (*buf <= 'F'))
2677 j = ((j << 4) | ((*buf++ - 'A') + 10));
2678 else if ((*buf >= '0') && (*buf <= '9'))
2679 j = ((j << 4) | (*buf++ - '0'));
2680 else
2681 return -EINVAL;
2682 if (i % 2) {
2683 wwn[i/2] = j & 0xff;
2684 j = 0;
2685 }
2686 }
2687 return 0;
2688}
James Smart352e5fd2016-12-30 06:57:47 -08002689/**
2690 * lpfc_soft_wwn_enable_store - Allows setting of the wwn if the key is valid
2691 * @dev: class device that is converted into a Scsi_host.
2692 * @attr: device attribute, not used.
2693 * @buf: containing the string lpfc_soft_wwn_key.
2694 * @count: must be size of lpfc_soft_wwn_key.
2695 *
2696 * Returns:
2697 * -EINVAL if the buffer does not contain lpfc_soft_wwn_key
2698 * length of buf indicates success
2699 **/
2700static ssize_t
2701lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr,
2702 const char *buf, size_t count)
2703{
2704 struct Scsi_Host *shost = class_to_shost(dev);
2705 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2706 struct lpfc_hba *phba = vport->phba;
2707 unsigned int cnt = count;
James Smartaeb3c812017-04-21 16:05:02 -07002708 uint8_t vvvl = vport->fc_sparam.cmn.valid_vendor_ver_level;
2709 u32 *fawwpn_key = (uint32_t *)&vport->fc_sparam.un.vendorVersion[0];
James Smart352e5fd2016-12-30 06:57:47 -08002710
2711 /*
2712 * We're doing a simple sanity check for soft_wwpn setting.
2713 * We require that the user write a specific key to enable
2714 * the soft_wwpn attribute to be settable. Once the attribute
2715 * is written, the enable key resets. If further updates are
2716 * desired, the key must be written again to re-enable the
2717 * attribute.
2718 *
2719 * The "key" is not secret - it is a hardcoded string shown
2720 * here. The intent is to protect against the random user or
2721 * application that is just writing attributes.
2722 */
James Smartaeb3c812017-04-21 16:05:02 -07002723 if (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR) {
2724 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart5b1f5082021-04-11 18:31:25 -07002725 "0051 lpfc soft wwpn can not be enabled: "
2726 "fawwpn is enabled\n");
James Smartaeb3c812017-04-21 16:05:02 -07002727 return -EINVAL;
2728 }
James Smart352e5fd2016-12-30 06:57:47 -08002729
2730 /* count may include a LF at end of string */
2731 if (buf[cnt-1] == '\n')
2732 cnt--;
2733
2734 if ((cnt != strlen(lpfc_soft_wwn_key)) ||
2735 (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0))
2736 return -EINVAL;
2737
2738 phba->soft_wwn_enable = 1;
2739
2740 dev_printk(KERN_WARNING, &phba->pcidev->dev,
2741 "lpfc%d: soft_wwpn assignment has been enabled.\n",
2742 phba->brd_no);
2743 dev_printk(KERN_WARNING, &phba->pcidev->dev,
2744 " The soft_wwpn feature is not supported by Broadcom.");
2745
2746 return count;
2747}
Joe Perches6cbaefb2017-12-19 10:15:09 -08002748static DEVICE_ATTR_WO(lpfc_soft_wwn_enable);
James Smart352e5fd2016-12-30 06:57:47 -08002749
2750/**
2751 * lpfc_soft_wwpn_show - Return the cfg soft ww port name of the adapter
2752 * @dev: class device that is converted into a Scsi_host.
2753 * @attr: device attribute, not used.
2754 * @buf: on return contains the wwpn in hexadecimal.
2755 *
2756 * Returns: size of formatted string.
2757 **/
2758static ssize_t
2759lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr,
2760 char *buf)
2761{
2762 struct Scsi_Host *shost = class_to_shost(dev);
2763 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2764 struct lpfc_hba *phba = vport->phba;
2765
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002766 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart352e5fd2016-12-30 06:57:47 -08002767 (unsigned long long)phba->cfg_soft_wwpn);
2768}
2769
2770/**
2771 * lpfc_soft_wwpn_store - Set the ww port name of the adapter
Lee Jonesa738bd92020-11-02 14:23:45 +00002772 * @dev: class device that is converted into a Scsi_host.
James Smart352e5fd2016-12-30 06:57:47 -08002773 * @attr: device attribute, not used.
2774 * @buf: contains the wwpn in hexadecimal.
2775 * @count: number of wwpn bytes in buf
2776 *
2777 * Returns:
2778 * -EACCES hba reset not enabled, adapter over temp
2779 * -EINVAL soft wwn not enabled, count is invalid, invalid wwpn byte invalid
2780 * -EIO error taking adapter offline or online
2781 * value of count on success
2782 **/
2783static ssize_t
2784lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr,
2785 const char *buf, size_t count)
2786{
2787 struct Scsi_Host *shost = class_to_shost(dev);
2788 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2789 struct lpfc_hba *phba = vport->phba;
2790 struct completion online_compl;
2791 int stat1 = 0, stat2 = 0;
2792 unsigned int cnt = count;
2793 u8 wwpn[WWN_SZ];
2794 int rc;
2795
2796 if (!phba->cfg_enable_hba_reset)
2797 return -EACCES;
2798 spin_lock_irq(&phba->hbalock);
2799 if (phba->over_temp_state == HBA_OVER_TEMP) {
2800 spin_unlock_irq(&phba->hbalock);
2801 return -EACCES;
2802 }
2803 spin_unlock_irq(&phba->hbalock);
2804 /* count may include a LF at end of string */
2805 if (buf[cnt-1] == '\n')
2806 cnt--;
2807
2808 if (!phba->soft_wwn_enable)
2809 return -EINVAL;
2810
2811 /* lock setting wwpn, wwnn down */
2812 phba->soft_wwn_enable = 0;
2813
2814 rc = lpfc_wwn_set(buf, cnt, wwpn);
James Smarte2934ed2017-01-17 12:31:56 -08002815 if (rc) {
James Smart352e5fd2016-12-30 06:57:47 -08002816 /* not able to set wwpn, unlock it */
2817 phba->soft_wwn_enable = 1;
2818 return rc;
2819 }
2820
2821 phba->cfg_soft_wwpn = wwn_to_u64(wwpn);
2822 fc_host_port_name(shost) = phba->cfg_soft_wwpn;
2823 if (phba->cfg_soft_wwnn)
2824 fc_host_node_name(shost) = phba->cfg_soft_wwnn;
2825
2826 dev_printk(KERN_NOTICE, &phba->pcidev->dev,
2827 "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no);
2828
2829 stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
2830 if (stat1)
2831 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2832 "0463 lpfc_soft_wwpn attribute set failed to "
2833 "reinit adapter - %d\n", stat1);
2834 init_completion(&online_compl);
2835 rc = lpfc_workq_post_event(phba, &stat2, &online_compl,
2836 LPFC_EVT_ONLINE);
2837 if (rc == 0)
2838 return -ENOMEM;
2839
2840 wait_for_completion(&online_compl);
2841 if (stat2)
2842 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2843 "0464 lpfc_soft_wwpn attribute set failed to "
2844 "reinit adapter - %d\n", stat2);
2845 return (stat1 || stat2) ? -EIO : count;
2846}
Joe Perchesb6b996b2017-12-19 10:15:07 -08002847static DEVICE_ATTR_RW(lpfc_soft_wwpn);
James Smart352e5fd2016-12-30 06:57:47 -08002848
2849/**
2850 * lpfc_soft_wwnn_show - Return the cfg soft ww node name for the adapter
2851 * @dev: class device that is converted into a Scsi_host.
2852 * @attr: device attribute, not used.
2853 * @buf: on return contains the wwnn in hexadecimal.
2854 *
2855 * Returns: size of formatted string.
2856 **/
2857static ssize_t
2858lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr,
2859 char *buf)
2860{
2861 struct Scsi_Host *shost = class_to_shost(dev);
2862 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002863 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart352e5fd2016-12-30 06:57:47 -08002864 (unsigned long long)phba->cfg_soft_wwnn);
2865}
2866
2867/**
2868 * lpfc_soft_wwnn_store - sets the ww node name of the adapter
Lee Jonesa738bd92020-11-02 14:23:45 +00002869 * @dev: class device that is converted into a Scsi_host.
2870 * @attr: device attribute, not used.
James Smart352e5fd2016-12-30 06:57:47 -08002871 * @buf: contains the ww node name in hexadecimal.
2872 * @count: number of wwnn bytes in buf.
2873 *
2874 * Returns:
2875 * -EINVAL soft wwn not enabled, count is invalid, invalid wwnn byte invalid
2876 * value of count on success
2877 **/
2878static ssize_t
2879lpfc_soft_wwnn_store(struct device *dev, struct device_attribute *attr,
2880 const char *buf, size_t count)
2881{
2882 struct Scsi_Host *shost = class_to_shost(dev);
2883 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2884 unsigned int cnt = count;
2885 u8 wwnn[WWN_SZ];
2886 int rc;
2887
2888 /* count may include a LF at end of string */
2889 if (buf[cnt-1] == '\n')
2890 cnt--;
2891
2892 if (!phba->soft_wwn_enable)
2893 return -EINVAL;
2894
2895 rc = lpfc_wwn_set(buf, cnt, wwnn);
James Smarte2934ed2017-01-17 12:31:56 -08002896 if (rc) {
James Smart352e5fd2016-12-30 06:57:47 -08002897 /* Allow wwnn to be set many times, as long as the enable
2898 * is set. However, once the wwpn is set, everything locks.
2899 */
2900 return rc;
2901 }
2902
2903 phba->cfg_soft_wwnn = wwn_to_u64(wwnn);
2904
2905 dev_printk(KERN_NOTICE, &phba->pcidev->dev,
2906 "lpfc%d: soft_wwnn set. Value will take effect upon "
2907 "setting of the soft_wwpn\n", phba->brd_no);
2908
2909 return count;
2910}
Joe Perchesb6b996b2017-12-19 10:15:07 -08002911static DEVICE_ATTR_RW(lpfc_soft_wwnn);
James Smarta12e07b2006-12-02 13:35:30 -05002912
James Smart1ba981f2014-02-20 09:56:45 -05002913/**
2914 * lpfc_oas_tgt_show - Return wwpn of target whose luns maybe enabled for
2915 * Optimized Access Storage (OAS) operations.
2916 * @dev: class device that is converted into a Scsi_host.
2917 * @attr: device attribute, not used.
2918 * @buf: buffer for passing information.
2919 *
2920 * Returns:
2921 * value of count
2922 **/
2923static ssize_t
2924lpfc_oas_tgt_show(struct device *dev, struct device_attribute *attr,
2925 char *buf)
2926{
2927 struct Scsi_Host *shost = class_to_shost(dev);
2928 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2929
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002930 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart1ba981f2014-02-20 09:56:45 -05002931 wwn_to_u64(phba->cfg_oas_tgt_wwpn));
2932}
2933
2934/**
2935 * lpfc_oas_tgt_store - Store wwpn of target whose luns maybe enabled for
2936 * Optimized Access Storage (OAS) operations.
2937 * @dev: class device that is converted into a Scsi_host.
2938 * @attr: device attribute, not used.
2939 * @buf: buffer for passing information.
2940 * @count: Size of the data buffer.
2941 *
2942 * Returns:
2943 * -EINVAL count is invalid, invalid wwpn byte invalid
2944 * -EPERM oas is not supported by hba
2945 * value of count on success
2946 **/
2947static ssize_t
2948lpfc_oas_tgt_store(struct device *dev, struct device_attribute *attr,
2949 const char *buf, size_t count)
2950{
2951 struct Scsi_Host *shost = class_to_shost(dev);
2952 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2953 unsigned int cnt = count;
2954 uint8_t wwpn[WWN_SZ];
2955 int rc;
2956
James Smartf38fa0b2014-04-04 13:52:21 -04002957 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05002958 return -EPERM;
2959
2960 /* count may include a LF at end of string */
2961 if (buf[cnt-1] == '\n')
2962 cnt--;
2963
2964 rc = lpfc_wwn_set(buf, cnt, wwpn);
2965 if (rc)
2966 return rc;
2967
2968 memcpy(phba->cfg_oas_tgt_wwpn, wwpn, (8 * sizeof(uint8_t)));
2969 memcpy(phba->sli4_hba.oas_next_tgt_wwpn, wwpn, (8 * sizeof(uint8_t)));
2970 if (wwn_to_u64(wwpn) == 0)
2971 phba->cfg_oas_flags |= OAS_FIND_ANY_TARGET;
2972 else
2973 phba->cfg_oas_flags &= ~OAS_FIND_ANY_TARGET;
2974 phba->cfg_oas_flags &= ~OAS_LUN_VALID;
2975 phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
2976 return count;
2977}
2978static DEVICE_ATTR(lpfc_xlane_tgt, S_IRUGO | S_IWUSR,
2979 lpfc_oas_tgt_show, lpfc_oas_tgt_store);
2980
2981/**
James Smartc92c8412016-07-06 12:36:05 -07002982 * lpfc_oas_priority_show - Return wwpn of target whose luns maybe enabled for
2983 * Optimized Access Storage (OAS) operations.
2984 * @dev: class device that is converted into a Scsi_host.
2985 * @attr: device attribute, not used.
2986 * @buf: buffer for passing information.
2987 *
2988 * Returns:
2989 * value of count
2990 **/
2991static ssize_t
2992lpfc_oas_priority_show(struct device *dev, struct device_attribute *attr,
2993 char *buf)
2994{
2995 struct Scsi_Host *shost = class_to_shost(dev);
2996 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2997
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002998 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_priority);
James Smartc92c8412016-07-06 12:36:05 -07002999}
3000
3001/**
3002 * lpfc_oas_priority_store - Store wwpn of target whose luns maybe enabled for
3003 * Optimized Access Storage (OAS) operations.
3004 * @dev: class device that is converted into a Scsi_host.
3005 * @attr: device attribute, not used.
3006 * @buf: buffer for passing information.
3007 * @count: Size of the data buffer.
3008 *
3009 * Returns:
3010 * -EINVAL count is invalid, invalid wwpn byte invalid
3011 * -EPERM oas is not supported by hba
3012 * value of count on success
3013 **/
3014static ssize_t
3015lpfc_oas_priority_store(struct device *dev, struct device_attribute *attr,
3016 const char *buf, size_t count)
3017{
3018 struct Scsi_Host *shost = class_to_shost(dev);
3019 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3020 unsigned int cnt = count;
3021 unsigned long val;
3022 int ret;
3023
3024 if (!phba->cfg_fof)
3025 return -EPERM;
3026
3027 /* count may include a LF at end of string */
3028 if (buf[cnt-1] == '\n')
3029 cnt--;
3030
3031 ret = kstrtoul(buf, 0, &val);
3032 if (ret || (val > 0x7f))
3033 return -EINVAL;
3034
3035 if (val)
3036 phba->cfg_oas_priority = (uint8_t)val;
3037 else
3038 phba->cfg_oas_priority = phba->cfg_XLanePriority;
3039 return count;
3040}
3041static DEVICE_ATTR(lpfc_xlane_priority, S_IRUGO | S_IWUSR,
3042 lpfc_oas_priority_show, lpfc_oas_priority_store);
3043
3044/**
James Smart1ba981f2014-02-20 09:56:45 -05003045 * lpfc_oas_vpt_show - Return wwpn of vport whose targets maybe enabled
3046 * for Optimized Access Storage (OAS) operations.
3047 * @dev: class device that is converted into a Scsi_host.
3048 * @attr: device attribute, not used.
3049 * @buf: buffer for passing information.
3050 *
3051 * Returns:
3052 * value of count on success
3053 **/
3054static ssize_t
3055lpfc_oas_vpt_show(struct device *dev, struct device_attribute *attr,
3056 char *buf)
3057{
3058 struct Scsi_Host *shost = class_to_shost(dev);
3059 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3060
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003061 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart1ba981f2014-02-20 09:56:45 -05003062 wwn_to_u64(phba->cfg_oas_vpt_wwpn));
3063}
3064
3065/**
3066 * lpfc_oas_vpt_store - Store wwpn of vport whose targets maybe enabled
3067 * for Optimized Access Storage (OAS) operations.
3068 * @dev: class device that is converted into a Scsi_host.
3069 * @attr: device attribute, not used.
3070 * @buf: buffer for passing information.
3071 * @count: Size of the data buffer.
3072 *
3073 * Returns:
3074 * -EINVAL count is invalid, invalid wwpn byte invalid
3075 * -EPERM oas is not supported by hba
3076 * value of count on success
3077 **/
3078static ssize_t
3079lpfc_oas_vpt_store(struct device *dev, struct device_attribute *attr,
3080 const char *buf, size_t count)
3081{
3082 struct Scsi_Host *shost = class_to_shost(dev);
3083 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3084 unsigned int cnt = count;
3085 uint8_t wwpn[WWN_SZ];
3086 int rc;
3087
James Smartf38fa0b2014-04-04 13:52:21 -04003088 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003089 return -EPERM;
3090
3091 /* count may include a LF at end of string */
3092 if (buf[cnt-1] == '\n')
3093 cnt--;
3094
3095 rc = lpfc_wwn_set(buf, cnt, wwpn);
3096 if (rc)
3097 return rc;
3098
3099 memcpy(phba->cfg_oas_vpt_wwpn, wwpn, (8 * sizeof(uint8_t)));
3100 memcpy(phba->sli4_hba.oas_next_vpt_wwpn, wwpn, (8 * sizeof(uint8_t)));
3101 if (wwn_to_u64(wwpn) == 0)
3102 phba->cfg_oas_flags |= OAS_FIND_ANY_VPORT;
3103 else
3104 phba->cfg_oas_flags &= ~OAS_FIND_ANY_VPORT;
3105 phba->cfg_oas_flags &= ~OAS_LUN_VALID;
James Smartb5749fe2016-12-19 15:07:26 -08003106 if (phba->cfg_oas_priority == 0)
3107 phba->cfg_oas_priority = phba->cfg_XLanePriority;
James Smart1ba981f2014-02-20 09:56:45 -05003108 phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
3109 return count;
3110}
3111static DEVICE_ATTR(lpfc_xlane_vpt, S_IRUGO | S_IWUSR,
3112 lpfc_oas_vpt_show, lpfc_oas_vpt_store);
3113
3114/**
3115 * lpfc_oas_lun_state_show - Return the current state (enabled or disabled)
3116 * of whether luns will be enabled or disabled
3117 * for Optimized Access Storage (OAS) operations.
3118 * @dev: class device that is converted into a Scsi_host.
3119 * @attr: device attribute, not used.
3120 * @buf: buffer for passing information.
3121 *
3122 * Returns:
3123 * size of formatted string.
3124 **/
3125static ssize_t
3126lpfc_oas_lun_state_show(struct device *dev, struct device_attribute *attr,
3127 char *buf)
3128{
3129 struct Scsi_Host *shost = class_to_shost(dev);
3130 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3131
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003132 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_state);
James Smart1ba981f2014-02-20 09:56:45 -05003133}
3134
3135/**
3136 * lpfc_oas_lun_state_store - Store the state (enabled or disabled)
3137 * of whether luns will be enabled or disabled
3138 * for Optimized Access Storage (OAS) operations.
3139 * @dev: class device that is converted into a Scsi_host.
3140 * @attr: device attribute, not used.
3141 * @buf: buffer for passing information.
3142 * @count: Size of the data buffer.
3143 *
3144 * Returns:
3145 * -EINVAL count is invalid, invalid wwpn byte invalid
3146 * -EPERM oas is not supported by hba
3147 * value of count on success
3148 **/
3149static ssize_t
3150lpfc_oas_lun_state_store(struct device *dev, struct device_attribute *attr,
3151 const char *buf, size_t count)
3152{
3153 struct Scsi_Host *shost = class_to_shost(dev);
3154 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3155 int val = 0;
3156
James Smartf38fa0b2014-04-04 13:52:21 -04003157 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003158 return -EPERM;
3159
3160 if (!isdigit(buf[0]))
3161 return -EINVAL;
3162
3163 if (sscanf(buf, "%i", &val) != 1)
3164 return -EINVAL;
3165
3166 if ((val != 0) && (val != 1))
3167 return -EINVAL;
3168
3169 phba->cfg_oas_lun_state = val;
James Smart1ba981f2014-02-20 09:56:45 -05003170 return strlen(buf);
3171}
3172static DEVICE_ATTR(lpfc_xlane_lun_state, S_IRUGO | S_IWUSR,
3173 lpfc_oas_lun_state_show, lpfc_oas_lun_state_store);
3174
3175/**
3176 * lpfc_oas_lun_status_show - Return the status of the Optimized Access
3177 * Storage (OAS) lun returned by the
3178 * lpfc_oas_lun_show function.
3179 * @dev: class device that is converted into a Scsi_host.
3180 * @attr: device attribute, not used.
3181 * @buf: buffer for passing information.
3182 *
3183 * Returns:
3184 * size of formatted string.
3185 **/
3186static ssize_t
3187lpfc_oas_lun_status_show(struct device *dev, struct device_attribute *attr,
3188 char *buf)
3189{
3190 struct Scsi_Host *shost = class_to_shost(dev);
3191 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3192
3193 if (!(phba->cfg_oas_flags & OAS_LUN_VALID))
3194 return -EFAULT;
3195
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003196 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_status);
James Smart1ba981f2014-02-20 09:56:45 -05003197}
3198static DEVICE_ATTR(lpfc_xlane_lun_status, S_IRUGO,
3199 lpfc_oas_lun_status_show, NULL);
3200
3201
3202/**
3203 * lpfc_oas_lun_state_set - enable or disable a lun for Optimized Access Storage
3204 * (OAS) operations.
3205 * @phba: lpfc_hba pointer.
Lee Jonesa738bd92020-11-02 14:23:45 +00003206 * @vpt_wwpn: wwpn of the vport associated with the returned lun
3207 * @tgt_wwpn: wwpn of the target associated with the returned lun
James Smart1ba981f2014-02-20 09:56:45 -05003208 * @lun: the fc lun for setting oas state.
3209 * @oas_state: the oas state to be set to the lun.
Lee Jonesa738bd92020-11-02 14:23:45 +00003210 * @pri: priority
James Smart1ba981f2014-02-20 09:56:45 -05003211 *
3212 * Returns:
3213 * SUCCESS : 0
3214 * -EPERM OAS is not enabled or not supported by this port.
3215 *
3216 */
3217static size_t
3218lpfc_oas_lun_state_set(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
James Smartc92c8412016-07-06 12:36:05 -07003219 uint8_t tgt_wwpn[], uint64_t lun,
3220 uint32_t oas_state, uint8_t pri)
James Smart1ba981f2014-02-20 09:56:45 -05003221{
3222
3223 int rc = 0;
3224
James Smartf38fa0b2014-04-04 13:52:21 -04003225 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003226 return -EPERM;
3227
3228 if (oas_state) {
3229 if (!lpfc_enable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
James Smartc92c8412016-07-06 12:36:05 -07003230 (struct lpfc_name *)tgt_wwpn,
3231 lun, pri))
James Smart1ba981f2014-02-20 09:56:45 -05003232 rc = -ENOMEM;
3233 } else {
3234 lpfc_disable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003235 (struct lpfc_name *)tgt_wwpn, lun, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003236 }
3237 return rc;
3238
3239}
3240
3241/**
3242 * lpfc_oas_lun_get_next - get the next lun that has been enabled for Optimized
3243 * Access Storage (OAS) operations.
3244 * @phba: lpfc_hba pointer.
3245 * @vpt_wwpn: wwpn of the vport associated with the returned lun
3246 * @tgt_wwpn: wwpn of the target associated with the returned lun
3247 * @lun_status: status of the lun returned lun
Lee Jonesa738bd92020-11-02 14:23:45 +00003248 * @lun_pri: priority of the lun returned lun
James Smart1ba981f2014-02-20 09:56:45 -05003249 *
3250 * Returns the first or next lun enabled for OAS operations for the vport/target
3251 * specified. If a lun is found, its vport wwpn, target wwpn and status is
3252 * returned. If the lun is not found, NOT_OAS_ENABLED_LUN is returned.
3253 *
3254 * Return:
3255 * lun that is OAS enabled for the vport/target
3256 * NOT_OAS_ENABLED_LUN when no oas enabled lun found.
3257 */
3258static uint64_t
3259lpfc_oas_lun_get_next(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
James Smartb5749fe2016-12-19 15:07:26 -08003260 uint8_t tgt_wwpn[], uint32_t *lun_status,
3261 uint32_t *lun_pri)
James Smart1ba981f2014-02-20 09:56:45 -05003262{
3263 uint64_t found_lun;
3264
3265 if (unlikely(!phba) || !vpt_wwpn || !tgt_wwpn)
3266 return NOT_OAS_ENABLED_LUN;
3267 if (lpfc_find_next_oas_lun(phba, (struct lpfc_name *)
3268 phba->sli4_hba.oas_next_vpt_wwpn,
3269 (struct lpfc_name *)
3270 phba->sli4_hba.oas_next_tgt_wwpn,
3271 &phba->sli4_hba.oas_next_lun,
3272 (struct lpfc_name *)vpt_wwpn,
3273 (struct lpfc_name *)tgt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003274 &found_lun, lun_status, lun_pri))
James Smart1ba981f2014-02-20 09:56:45 -05003275 return found_lun;
3276 else
3277 return NOT_OAS_ENABLED_LUN;
3278}
3279
3280/**
3281 * lpfc_oas_lun_state_change - enable/disable a lun for OAS operations
3282 * @phba: lpfc_hba pointer.
3283 * @vpt_wwpn: vport wwpn by reference.
3284 * @tgt_wwpn: target wwpn by reference.
3285 * @lun: the fc lun for setting oas state.
3286 * @oas_state: the oas state to be set to the oas_lun.
Lee Jonesa738bd92020-11-02 14:23:45 +00003287 * @pri: priority
James Smart1ba981f2014-02-20 09:56:45 -05003288 *
3289 * This routine enables (OAS_LUN_ENABLE) or disables (OAS_LUN_DISABLE)
3290 * a lun for OAS operations.
3291 *
3292 * Return:
3293 * SUCCESS: 0
3294 * -ENOMEM: failed to enable an lun for OAS operations
3295 * -EPERM: OAS is not enabled
3296 */
3297static ssize_t
3298lpfc_oas_lun_state_change(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
3299 uint8_t tgt_wwpn[], uint64_t lun,
James Smartc92c8412016-07-06 12:36:05 -07003300 uint32_t oas_state, uint8_t pri)
James Smart1ba981f2014-02-20 09:56:45 -05003301{
3302
3303 int rc;
3304
3305 rc = lpfc_oas_lun_state_set(phba, vpt_wwpn, tgt_wwpn, lun,
James Smartc92c8412016-07-06 12:36:05 -07003306 oas_state, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003307 return rc;
3308}
3309
3310/**
3311 * lpfc_oas_lun_show - Return oas enabled luns from a chosen target
3312 * @dev: class device that is converted into a Scsi_host.
3313 * @attr: device attribute, not used.
3314 * @buf: buffer for passing information.
3315 *
3316 * This routine returns a lun enabled for OAS each time the function
3317 * is called.
3318 *
3319 * Returns:
3320 * SUCCESS: size of formatted string.
3321 * -EFAULT: target or vport wwpn was not set properly.
3322 * -EPERM: oas is not enabled.
3323 **/
3324static ssize_t
3325lpfc_oas_lun_show(struct device *dev, struct device_attribute *attr,
3326 char *buf)
3327{
3328 struct Scsi_Host *shost = class_to_shost(dev);
3329 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3330
3331 uint64_t oas_lun;
3332 int len = 0;
3333
James Smartf38fa0b2014-04-04 13:52:21 -04003334 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003335 return -EPERM;
3336
3337 if (wwn_to_u64(phba->cfg_oas_vpt_wwpn) == 0)
3338 if (!(phba->cfg_oas_flags & OAS_FIND_ANY_VPORT))
3339 return -EFAULT;
3340
3341 if (wwn_to_u64(phba->cfg_oas_tgt_wwpn) == 0)
3342 if (!(phba->cfg_oas_flags & OAS_FIND_ANY_TARGET))
3343 return -EFAULT;
3344
3345 oas_lun = lpfc_oas_lun_get_next(phba, phba->cfg_oas_vpt_wwpn,
3346 phba->cfg_oas_tgt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003347 &phba->cfg_oas_lun_status,
3348 &phba->cfg_oas_priority);
James Smart1ba981f2014-02-20 09:56:45 -05003349 if (oas_lun != NOT_OAS_ENABLED_LUN)
3350 phba->cfg_oas_flags |= OAS_LUN_VALID;
3351
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003352 len += scnprintf(buf + len, PAGE_SIZE-len, "0x%llx", oas_lun);
James Smart1ba981f2014-02-20 09:56:45 -05003353
3354 return len;
3355}
3356
3357/**
3358 * lpfc_oas_lun_store - Sets the OAS state for lun
3359 * @dev: class device that is converted into a Scsi_host.
3360 * @attr: device attribute, not used.
3361 * @buf: buffer for passing information.
Lee Jonesa738bd92020-11-02 14:23:45 +00003362 * @count: size of the formatting string
James Smart1ba981f2014-02-20 09:56:45 -05003363 *
3364 * This function sets the OAS state for lun. Before this function is called,
3365 * the vport wwpn, target wwpn, and oas state need to be set.
3366 *
3367 * Returns:
3368 * SUCCESS: size of formatted string.
3369 * -EFAULT: target or vport wwpn was not set properly.
3370 * -EPERM: oas is not enabled.
3371 * size of formatted string.
3372 **/
3373static ssize_t
3374lpfc_oas_lun_store(struct device *dev, struct device_attribute *attr,
3375 const char *buf, size_t count)
3376{
3377 struct Scsi_Host *shost = class_to_shost(dev);
3378 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3379 uint64_t scsi_lun;
James Smartb5749fe2016-12-19 15:07:26 -08003380 uint32_t pri;
James Smart1ba981f2014-02-20 09:56:45 -05003381 ssize_t rc;
3382
James Smartf38fa0b2014-04-04 13:52:21 -04003383 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003384 return -EPERM;
3385
3386 if (wwn_to_u64(phba->cfg_oas_vpt_wwpn) == 0)
3387 return -EFAULT;
3388
3389 if (wwn_to_u64(phba->cfg_oas_tgt_wwpn) == 0)
3390 return -EFAULT;
3391
3392 if (!isdigit(buf[0]))
3393 return -EINVAL;
3394
3395 if (sscanf(buf, "0x%llx", &scsi_lun) != 1)
3396 return -EINVAL;
3397
James Smartb5749fe2016-12-19 15:07:26 -08003398 pri = phba->cfg_oas_priority;
3399 if (pri == 0)
3400 pri = phba->cfg_XLanePriority;
3401
James Smart1ba981f2014-02-20 09:56:45 -05003402 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
James Smartc92c8412016-07-06 12:36:05 -07003403 "3372 Try to set vport 0x%llx target 0x%llx lun:0x%llx "
3404 "priority 0x%x with oas state %d\n",
James Smart1ba981f2014-02-20 09:56:45 -05003405 wwn_to_u64(phba->cfg_oas_vpt_wwpn),
3406 wwn_to_u64(phba->cfg_oas_tgt_wwpn), scsi_lun,
James Smartb5749fe2016-12-19 15:07:26 -08003407 pri, phba->cfg_oas_lun_state);
James Smart1ba981f2014-02-20 09:56:45 -05003408
3409 rc = lpfc_oas_lun_state_change(phba, phba->cfg_oas_vpt_wwpn,
James Smartc92c8412016-07-06 12:36:05 -07003410 phba->cfg_oas_tgt_wwpn, scsi_lun,
James Smartb5749fe2016-12-19 15:07:26 -08003411 phba->cfg_oas_lun_state, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003412 if (rc)
3413 return rc;
3414
3415 return count;
3416}
3417static DEVICE_ATTR(lpfc_xlane_lun, S_IRUGO | S_IWUSR,
3418 lpfc_oas_lun_show, lpfc_oas_lun_store);
James Smartc3f28af2006-08-18 17:47:18 -04003419
James Smartf358dd02017-02-12 13:52:34 -08003420int lpfc_enable_nvmet_cnt;
3421unsigned long long lpfc_enable_nvmet[LPFC_NVMET_MAX_PORTS] = {
3422 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3423 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
3424module_param_array(lpfc_enable_nvmet, ullong, &lpfc_enable_nvmet_cnt, 0444);
3425MODULE_PARM_DESC(lpfc_enable_nvmet, "Enable HBA port(s) WWPN as a NVME Target");
3426
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05003427static int lpfc_poll = 0;
James Smartab56dc22011-02-16 12:39:57 -05003428module_param(lpfc_poll, int, S_IRUGO);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05003429MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
3430 " 0 - none,"
3431 " 1 - poll with interrupts enabled"
3432 " 3 - poll and disable FCP ring interrupts");
3433
Joe Perchesb6b996b2017-12-19 10:15:07 -08003434static DEVICE_ATTR_RW(lpfc_poll);
dea31012005-04-17 16:05:31 -05003435
James Smart96418b52017-03-04 09:30:31 -08003436int lpfc_no_hba_reset_cnt;
3437unsigned long lpfc_no_hba_reset[MAX_HBAS_NO_RESET] = {
3438 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
3439module_param_array(lpfc_no_hba_reset, ulong, &lpfc_no_hba_reset_cnt, 0444);
3440MODULE_PARM_DESC(lpfc_no_hba_reset, "WWPN of HBAs that should not be reset");
3441
James Smartd2f25472021-01-04 10:02:27 -08003442LPFC_ATTR(sli_mode, 3, 3, 3,
3443 "SLI mode selector: 3 - select SLI-3");
James Smart92d7f7b2007-06-17 19:56:38 -05003444
James Smart458c0832016-07-06 12:36:07 -07003445LPFC_ATTR_R(enable_npiv, 1, 0, 1,
3446 "Enable NPIV functionality");
James Smart92d7f7b2007-06-17 19:56:38 -05003447
James Smart7d791df2011-07-22 18:37:52 -04003448LPFC_ATTR_R(fcf_failover_policy, 1, 1, 2,
3449 "FCF Fast failover=1 Priority failover=2");
3450
James Smarte5771b42013-03-01 16:37:14 -05003451/*
James Smart3e49af92021-05-14 12:55:57 -07003452 * lpfc_fcp_wait_abts_rsp: Modifies criteria for reporting completion of
3453 * aborted IO.
3454 * The range is [0,1]. Default value is 0
3455 * 0, IO completes after ABTS issued (default).
3456 * 1, IO completes after receipt of ABTS response or timeout.
3457 */
3458LPFC_ATTR_R(fcp_wait_abts_rsp, 0, 0, 1, "Wait for FCP ABTS completion");
3459
3460/*
James Smarte5771b42013-03-01 16:37:14 -05003461# lpfc_enable_rrq: Track XRI/OXID reuse after IO failures
3462# 0x0 = disabled, XRI/OXID use not tracked.
3463# 0x1 = XRI/OXID reuse is timed with ratov, RRQ sent.
3464# 0x2 = XRI/OXID reuse is timed with ratov, No RRQ sent.
3465*/
James Smart31202b02016-10-13 15:06:08 -07003466LPFC_ATTR_R(enable_rrq, 2, 0, 2,
3467 "Enable RRQ functionality");
James Smart19ca7602010-11-20 23:11:55 -05003468
dea31012005-04-17 16:05:31 -05003469/*
James Smart84d1b002010-02-12 14:42:33 -05003470# lpfc_suppress_link_up: Bring link up at initialization
3471# 0x0 = bring link up (issue MBX_INIT_LINK)
3472# 0x1 = do NOT bring link up at initialization(MBX_INIT_LINK)
3473# 0x2 = never bring up link
3474# Default value is 0.
3475*/
James Smarte40a02c2010-02-26 14:13:54 -05003476LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK,
3477 LPFC_DELAY_INIT_LINK_INDEFINITELY,
3478 "Suppress Link Up at initialization");
James Smart83c6cb12019-10-18 14:18:30 -07003479
3480static ssize_t
3481lpfc_pls_show(struct device *dev, struct device_attribute *attr, char *buf)
3482{
3483 struct Scsi_Host *shost = class_to_shost(dev);
3484 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3485
3486 return scnprintf(buf, PAGE_SIZE, "%d\n",
3487 phba->sli4_hba.pc_sli4_params.pls);
3488}
3489static DEVICE_ATTR(pls, 0444,
3490 lpfc_pls_show, NULL);
3491
3492static ssize_t
3493lpfc_pt_show(struct device *dev, struct device_attribute *attr, char *buf)
3494{
3495 struct Scsi_Host *shost = class_to_shost(dev);
3496 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3497
3498 return scnprintf(buf, PAGE_SIZE, "%d\n",
3499 (phba->hba_flag & HBA_PERSISTENT_TOPO) ? 1 : 0);
3500}
3501static DEVICE_ATTR(pt, 0444,
3502 lpfc_pt_show, NULL);
3503
James Smart2a9bf3d2010-06-07 15:24:45 -04003504/*
3505# lpfc_cnt: Number of IOCBs allocated for ELS, CT, and ABTS
3506# 1 - (1024)
3507# 2 - (2048)
3508# 3 - (3072)
3509# 4 - (4096)
3510# 5 - (5120)
3511*/
3512static ssize_t
3513lpfc_iocb_hw_show(struct device *dev, struct device_attribute *attr, char *buf)
3514{
3515 struct Scsi_Host *shost = class_to_shost(dev);
3516 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
3517
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003518 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->iocb_max);
James Smart2a9bf3d2010-06-07 15:24:45 -04003519}
3520
3521static DEVICE_ATTR(iocb_hw, S_IRUGO,
3522 lpfc_iocb_hw_show, NULL);
3523static ssize_t
3524lpfc_txq_hw_show(struct device *dev, struct device_attribute *attr, char *buf)
3525{
3526 struct Scsi_Host *shost = class_to_shost(dev);
3527 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
James Smart895427b2017-02-12 13:52:30 -08003528 struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
James Smart2a9bf3d2010-06-07 15:24:45 -04003529
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003530 return scnprintf(buf, PAGE_SIZE, "%d\n",
Dick Kennedy1234a6d2017-09-29 17:34:29 -07003531 pring ? pring->txq_max : 0);
James Smart2a9bf3d2010-06-07 15:24:45 -04003532}
3533
3534static DEVICE_ATTR(txq_hw, S_IRUGO,
3535 lpfc_txq_hw_show, NULL);
3536static ssize_t
3537lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr,
3538 char *buf)
3539{
3540 struct Scsi_Host *shost = class_to_shost(dev);
3541 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
James Smart895427b2017-02-12 13:52:30 -08003542 struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
James Smart2a9bf3d2010-06-07 15:24:45 -04003543
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003544 return scnprintf(buf, PAGE_SIZE, "%d\n",
Dick Kennedy1234a6d2017-09-29 17:34:29 -07003545 pring ? pring->txcmplq_max : 0);
James Smart2a9bf3d2010-06-07 15:24:45 -04003546}
3547
3548static DEVICE_ATTR(txcmplq_hw, S_IRUGO,
3549 lpfc_txcmplq_hw_show, NULL);
3550
James Smart84d1b002010-02-12 14:42:33 -05003551/*
James Smartc01f3202006-08-18 17:47:08 -04003552# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
3553# until the timer expires. Value range is [0,255]. Default value is 30.
3554*/
3555static int lpfc_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
3556static int lpfc_devloss_tmo = LPFC_DEF_DEVLOSS_TMO;
3557module_param(lpfc_nodev_tmo, int, 0);
3558MODULE_PARM_DESC(lpfc_nodev_tmo,
3559 "Seconds driver will hold I/O waiting "
3560 "for a device to come back");
James Smarte59058c2008-08-24 21:49:00 -04003561
3562/**
James Smart3621a712009-04-06 18:47:14 -04003563 * lpfc_nodev_tmo_show - Return the hba dev loss timeout value
James Smarte59058c2008-08-24 21:49:00 -04003564 * @dev: class converted to a Scsi_host structure.
3565 * @attr: device attribute, not used.
3566 * @buf: on return contains the dev loss timeout in decimal.
3567 *
3568 * Returns: size of formatted string.
3569 **/
James Smartc01f3202006-08-18 17:47:08 -04003570static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01003571lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr,
3572 char *buf)
James Smartc01f3202006-08-18 17:47:08 -04003573{
Tony Jonesee959b02008-02-22 00:13:36 +01003574 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05003575 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
James Smarte40a02c2010-02-26 14:13:54 -05003576
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003577 return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003578}
3579
James Smarte59058c2008-08-24 21:49:00 -04003580/**
James Smart3621a712009-04-06 18:47:14 -04003581 * lpfc_nodev_tmo_init - Set the hba nodev timeout value
James Smarte59058c2008-08-24 21:49:00 -04003582 * @vport: lpfc vport structure pointer.
3583 * @val: contains the nodev timeout value.
3584 *
3585 * Description:
3586 * If the devloss tmo is already set then nodev tmo is set to devloss tmo,
3587 * a kernel error message is printed and zero is returned.
3588 * Else if val is in range then nodev tmo and devloss tmo are set to val.
3589 * Otherwise nodev tmo is set to the default value.
3590 *
3591 * Returns:
3592 * zero if already set or if val is in range
3593 * -EINVAL val out of range
3594 **/
James Smartc01f3202006-08-18 17:47:08 -04003595static int
James Smart3de2a652007-08-02 11:09:59 -04003596lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003597{
James Smart3de2a652007-08-02 11:09:59 -04003598 if (vport->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) {
3599 vport->cfg_nodev_tmo = vport->cfg_devloss_tmo;
3600 if (val != LPFC_DEF_DEVLOSS_TMO)
James Smarte8b62012007-08-02 11:10:09 -04003601 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003602 "0407 Ignoring lpfc_nodev_tmo module "
3603 "parameter because lpfc_devloss_tmo "
3604 "is set.\n");
James Smartc01f3202006-08-18 17:47:08 -04003605 return 0;
3606 }
3607
3608 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003609 vport->cfg_nodev_tmo = val;
3610 vport->cfg_devloss_tmo = val;
James Smartc01f3202006-08-18 17:47:08 -04003611 return 0;
3612 }
James Smarte8b62012007-08-02 11:10:09 -04003613 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3614 "0400 lpfc_nodev_tmo attribute cannot be set to"
3615 " %d, allowed range is [%d, %d]\n",
3616 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smart3de2a652007-08-02 11:09:59 -04003617 vport->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
James Smartc01f3202006-08-18 17:47:08 -04003618 return -EINVAL;
3619}
3620
James Smarte59058c2008-08-24 21:49:00 -04003621/**
James Smart3621a712009-04-06 18:47:14 -04003622 * lpfc_update_rport_devloss_tmo - Update dev loss tmo value
James Smarte59058c2008-08-24 21:49:00 -04003623 * @vport: lpfc vport structure pointer.
3624 *
3625 * Description:
3626 * Update all the ndlp's dev loss tmo with the vport devloss tmo value.
3627 **/
James Smart7054a602007-04-25 09:52:34 -04003628static void
James Smart3de2a652007-08-02 11:09:59 -04003629lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
James Smart7054a602007-04-25 09:52:34 -04003630{
James Smart858c9f62007-06-17 19:56:39 -05003631 struct Scsi_Host *shost;
James Smart7054a602007-04-25 09:52:34 -04003632 struct lpfc_nodelist *ndlp;
James Smart01466022018-04-09 14:24:27 -07003633#if (IS_ENABLED(CONFIG_NVME_FC))
3634 struct lpfc_nvme_rport *rport;
James Smart9e210172018-09-13 15:41:10 -07003635 struct nvme_fc_remote_port *remoteport = NULL;
James Smart01466022018-04-09 14:24:27 -07003636#endif
James Smart7054a602007-04-25 09:52:34 -04003637
James Smart51ef4c22007-08-02 11:10:31 -04003638 shost = lpfc_shost_from_vport(vport);
3639 spin_lock_irq(shost->host_lock);
James Smart7a06dcd2017-06-01 21:06:55 -07003640 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart7a06dcd2017-06-01 21:06:55 -07003641 if (ndlp->rport)
James Smart51ef4c22007-08-02 11:10:31 -04003642 ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
James Smart6ddcf0a2017-11-03 09:33:30 -07003643#if (IS_ENABLED(CONFIG_NVME_FC))
James Smartc6adba12020-11-15 11:26:34 -08003644 spin_lock(&ndlp->lock);
James Smart01466022018-04-09 14:24:27 -07003645 rport = lpfc_ndlp_get_nrport(ndlp);
3646 if (rport)
James Smart9e210172018-09-13 15:41:10 -07003647 remoteport = rport->remoteport;
James Smartc6adba12020-11-15 11:26:34 -08003648 spin_unlock(&ndlp->lock);
James Smart07f50992019-08-14 16:56:45 -07003649 if (rport && remoteport)
3650 nvme_fc_set_remoteport_devloss(remoteport,
James Smart6ddcf0a2017-11-03 09:33:30 -07003651 vport->cfg_devloss_tmo);
3652#endif
James Smart7a06dcd2017-06-01 21:06:55 -07003653 }
James Smart51ef4c22007-08-02 11:10:31 -04003654 spin_unlock_irq(shost->host_lock);
James Smart7054a602007-04-25 09:52:34 -04003655}
3656
James Smarte59058c2008-08-24 21:49:00 -04003657/**
James Smart3621a712009-04-06 18:47:14 -04003658 * lpfc_nodev_tmo_set - Set the vport nodev tmo and devloss tmo values
James Smarte59058c2008-08-24 21:49:00 -04003659 * @vport: lpfc vport structure pointer.
3660 * @val: contains the tmo value.
3661 *
3662 * Description:
3663 * If the devloss tmo is already set or the vport dev loss tmo has changed
3664 * then a kernel error message is printed and zero is returned.
3665 * Else if val is in range then nodev tmo and devloss tmo are set to val.
3666 * Otherwise nodev tmo is set to the default value.
3667 *
3668 * Returns:
3669 * zero if already set or if val is in range
3670 * -EINVAL val out of range
3671 **/
James Smartc01f3202006-08-18 17:47:08 -04003672static int
James Smart3de2a652007-08-02 11:09:59 -04003673lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003674{
James Smart3de2a652007-08-02 11:09:59 -04003675 if (vport->dev_loss_tmo_changed ||
3676 (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
James Smarte8b62012007-08-02 11:10:09 -04003677 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003678 "0401 Ignoring change to lpfc_nodev_tmo "
3679 "because lpfc_devloss_tmo is set.\n");
James Smartc01f3202006-08-18 17:47:08 -04003680 return 0;
3681 }
James Smartc01f3202006-08-18 17:47:08 -04003682 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003683 vport->cfg_nodev_tmo = val;
3684 vport->cfg_devloss_tmo = val;
Mike Christie0af5d702010-09-15 16:52:31 -05003685 /*
3686 * For compat: set the fc_host dev loss so new rports
3687 * will get the value.
3688 */
3689 fc_host_dev_loss_tmo(lpfc_shost_from_vport(vport)) = val;
James Smart3de2a652007-08-02 11:09:59 -04003690 lpfc_update_rport_devloss_tmo(vport);
James Smartc01f3202006-08-18 17:47:08 -04003691 return 0;
3692 }
James Smarte8b62012007-08-02 11:10:09 -04003693 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003694 "0403 lpfc_nodev_tmo attribute cannot be set to "
James Smarte8b62012007-08-02 11:10:09 -04003695 "%d, allowed range is [%d, %d]\n",
3696 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smartc01f3202006-08-18 17:47:08 -04003697 return -EINVAL;
3698}
3699
James Smart3de2a652007-08-02 11:09:59 -04003700lpfc_vport_param_store(nodev_tmo)
James Smartc01f3202006-08-18 17:47:08 -04003701
Joe Perchesb6b996b2017-12-19 10:15:07 -08003702static DEVICE_ATTR_RW(lpfc_nodev_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003703
3704/*
3705# lpfc_devloss_tmo: If set, it will hold all I/O errors on devices that
3706# disappear until the timer expires. Value range is [0,255]. Default
3707# value is 30.
3708*/
James Smartab56dc22011-02-16 12:39:57 -05003709module_param(lpfc_devloss_tmo, int, S_IRUGO);
James Smartc01f3202006-08-18 17:47:08 -04003710MODULE_PARM_DESC(lpfc_devloss_tmo,
3711 "Seconds driver will hold I/O waiting "
3712 "for a device to come back");
James Smart3de2a652007-08-02 11:09:59 -04003713lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
3714 LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
3715lpfc_vport_param_show(devloss_tmo)
James Smarte59058c2008-08-24 21:49:00 -04003716
3717/**
James Smart3621a712009-04-06 18:47:14 -04003718 * lpfc_devloss_tmo_set - Sets vport nodev tmo, devloss tmo values, changed bit
James Smarte59058c2008-08-24 21:49:00 -04003719 * @vport: lpfc vport structure pointer.
3720 * @val: contains the tmo value.
3721 *
3722 * Description:
3723 * If val is in a valid range then set the vport nodev tmo,
3724 * devloss tmo, also set the vport dev loss tmo changed flag.
3725 * Else a kernel error message is printed.
3726 *
3727 * Returns:
3728 * zero if val is in range
3729 * -EINVAL val out of range
3730 **/
James Smartc01f3202006-08-18 17:47:08 -04003731static int
James Smart3de2a652007-08-02 11:09:59 -04003732lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003733{
3734 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003735 vport->cfg_nodev_tmo = val;
3736 vport->cfg_devloss_tmo = val;
3737 vport->dev_loss_tmo_changed = 1;
Mike Christie0af5d702010-09-15 16:52:31 -05003738 fc_host_dev_loss_tmo(lpfc_shost_from_vport(vport)) = val;
James Smart3de2a652007-08-02 11:09:59 -04003739 lpfc_update_rport_devloss_tmo(vport);
James Smartc01f3202006-08-18 17:47:08 -04003740 return 0;
3741 }
3742
James Smarte8b62012007-08-02 11:10:09 -04003743 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003744 "0404 lpfc_devloss_tmo attribute cannot be set to "
3745 "%d, allowed range is [%d, %d]\n",
James Smarte8b62012007-08-02 11:10:09 -04003746 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smartc01f3202006-08-18 17:47:08 -04003747 return -EINVAL;
3748}
3749
James Smart3de2a652007-08-02 11:09:59 -04003750lpfc_vport_param_store(devloss_tmo)
Joe Perchesb6b996b2017-12-19 10:15:07 -08003751static DEVICE_ATTR_RW(lpfc_devloss_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003752
3753/*
James Smartf358dd02017-02-12 13:52:34 -08003754 * lpfc_suppress_rsp: Enable suppress rsp feature is firmware supports it
3755 * lpfc_suppress_rsp = 0 Disable
3756 * lpfc_suppress_rsp = 1 Enable (default)
3757 *
3758 */
3759LPFC_ATTR_R(suppress_rsp, 1, 0, 1,
3760 "Enable suppress rsp feature is firmware supports it");
3761
3762/*
James Smart2d7dbc42017-02-12 13:52:35 -08003763 * lpfc_nvmet_mrq: Specify number of RQ pairs for processing NVMET cmds
James Smartbcb24f62017-11-20 16:00:36 -08003764 * lpfc_nvmet_mrq = 0 driver will calcualte optimal number of RQ pairs
James Smart2d7dbc42017-02-12 13:52:35 -08003765 * lpfc_nvmet_mrq = 1 use a single RQ pair
3766 * lpfc_nvmet_mrq >= 2 use specified RQ pairs for MRQ
3767 *
3768 */
3769LPFC_ATTR_R(nvmet_mrq,
James Smartbcb24f62017-11-20 16:00:36 -08003770 LPFC_NVMET_MRQ_AUTO, LPFC_NVMET_MRQ_AUTO, LPFC_NVMET_MRQ_MAX,
James Smart2d7dbc42017-02-12 13:52:35 -08003771 "Specify number of RQ pairs for processing NVMET cmds");
3772
3773/*
James Smart2448e482018-04-09 14:24:24 -07003774 * lpfc_nvmet_mrq_post: Specify number of RQ buffer to initially post
3775 * to each NVMET RQ. Range 64 to 2048, default is 512.
3776 */
3777LPFC_ATTR_R(nvmet_mrq_post,
3778 LPFC_NVMET_RQE_DEF_POST, LPFC_NVMET_RQE_MIN_POST,
3779 LPFC_NVMET_RQE_DEF_COUNT,
3780 "Specify number of RQ buffers to initially post");
3781
3782/*
James Smart895427b2017-02-12 13:52:30 -08003783 * lpfc_enable_fc4_type: Defines what FC4 types are supported.
3784 * Supported Values: 1 - register just FCP
3785 * 3 - register both FCP and NVME
James Smartb1684a02019-01-28 11:14:36 -08003786 * Supported values are [1,3]. Default value is 3
James Smart895427b2017-02-12 13:52:30 -08003787 */
James Smartb1684a02019-01-28 11:14:36 -08003788LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_BOTH,
James Smart895427b2017-02-12 13:52:30 -08003789 LPFC_ENABLE_FCP, LPFC_ENABLE_BOTH,
Dick Kennedycf4c8c82017-09-29 17:34:38 -07003790 "Enable FC4 Protocol support - FCP / NVME");
James Smart895427b2017-02-12 13:52:30 -08003791
3792/*
dea31012005-04-17 16:05:31 -05003793# lpfc_log_verbose: Only turn this flag on if you are willing to risk being
3794# deluged with LOTS of information.
3795# You can set a bit mask to record specific types of verbose messages:
James Smartf4b4c682009-05-22 14:53:12 -04003796# See lpfc_logmsh.h for definitions.
dea31012005-04-17 16:05:31 -05003797*/
James Smartf4b4c682009-05-22 14:53:12 -04003798LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffffffff,
James Smarte8b62012007-08-02 11:10:09 -04003799 "Verbose logging bit-mask");
dea31012005-04-17 16:05:31 -05003800
3801/*
James Smart7ee5d432007-10-27 13:37:17 -04003802# lpfc_enable_da_id: This turns on the DA_ID CT command that deregisters
3803# objects that have been registered with the nameserver after login.
3804*/
James Smartcf971242012-03-01 22:37:32 -05003805LPFC_VPORT_ATTR_R(enable_da_id, 1, 0, 1,
James Smart7ee5d432007-10-27 13:37:17 -04003806 "Deregister nameserver objects before LOGO");
3807
3808/*
dea31012005-04-17 16:05:31 -05003809# lun_queue_depth: This parameter is used to limit the number of outstanding
Dick Kennedy763a18c2020-03-23 09:19:35 -07003810# commands per FCP LUN.
dea31012005-04-17 16:05:31 -05003811*/
Dick Kennedy763a18c2020-03-23 09:19:35 -07003812LPFC_VPORT_ATTR_R(lun_queue_depth, 64, 1, 512,
James Smart3de2a652007-08-02 11:09:59 -04003813 "Max number of FCP commands we can queue to a specific LUN");
dea31012005-04-17 16:05:31 -05003814
3815/*
James Smart7dc517d2010-07-14 15:32:10 -04003816# tgt_queue_depth: This parameter is used to limit the number of outstanding
3817# commands per target port. Value range is [10,65535]. Default value is 65535.
3818*/
James Smartf91bc592018-04-09 14:24:22 -07003819static uint lpfc_tgt_queue_depth = LPFC_MAX_TGT_QDEPTH;
3820module_param(lpfc_tgt_queue_depth, uint, 0444);
3821MODULE_PARM_DESC(lpfc_tgt_queue_depth, "Set max Target queue depth");
3822lpfc_vport_param_show(tgt_queue_depth);
3823lpfc_vport_param_init(tgt_queue_depth, LPFC_MAX_TGT_QDEPTH,
3824 LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH);
3825
3826/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00003827 * lpfc_tgt_queue_depth_set: Sets an attribute value.
Lee Jonesa738bd92020-11-02 14:23:45 +00003828 * @vport: lpfc vport structure pointer.
James Smartf91bc592018-04-09 14:24:22 -07003829 * @val: integer attribute value.
3830 *
3831 * Description: Sets the parameter to the new value.
3832 *
3833 * Returns:
3834 * zero on success
3835 * -EINVAL if val is invalid
3836 */
3837static int
3838lpfc_tgt_queue_depth_set(struct lpfc_vport *vport, uint val)
3839{
3840 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3841 struct lpfc_nodelist *ndlp;
3842
3843 if (!lpfc_rangecheck(val, LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH))
3844 return -EINVAL;
3845
3846 if (val == vport->cfg_tgt_queue_depth)
3847 return 0;
3848
3849 spin_lock_irq(shost->host_lock);
3850 vport->cfg_tgt_queue_depth = val;
3851
3852 /* Next loop thru nodelist and change cmd_qdepth */
3853 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp)
3854 ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
3855
3856 spin_unlock_irq(shost->host_lock);
3857 return 0;
3858}
3859
3860lpfc_vport_param_store(tgt_queue_depth);
3861static DEVICE_ATTR_RW(lpfc_tgt_queue_depth);
James Smart7dc517d2010-07-14 15:32:10 -04003862
3863/*
Jamie Wellnitzb28485a2006-02-28 19:25:21 -05003864# hba_queue_depth: This parameter is used to limit the number of outstanding
3865# commands per lpfc HBA. Value range is [32,8192]. If this parameter
3866# value is greater than the maximum number of exchanges supported by the HBA,
3867# then maximum number of exchanges supported by the HBA is used to determine
3868# the hba_queue_depth.
3869*/
3870LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192,
3871 "Max number of FCP commands we can queue to a lpfc HBA");
3872
3873/*
James Smart92d7f7b2007-06-17 19:56:38 -05003874# peer_port_login: This parameter allows/prevents logins
3875# between peer ports hosted on the same physical port.
3876# When this parameter is set 0 peer ports of same physical port
3877# are not allowed to login to each other.
3878# When this parameter is set 1 peer ports of same physical port
3879# are allowed to login to each other.
3880# Default value of this parameter is 0.
3881*/
James Smart3de2a652007-08-02 11:09:59 -04003882LPFC_VPORT_ATTR_R(peer_port_login, 0, 0, 1,
3883 "Allow peer ports on the same physical port to login to each "
3884 "other.");
James Smart92d7f7b2007-06-17 19:56:38 -05003885
3886/*
James Smart3de2a652007-08-02 11:09:59 -04003887# restrict_login: This parameter allows/prevents logins
James Smart92d7f7b2007-06-17 19:56:38 -05003888# between Virtual Ports and remote initiators.
3889# When this parameter is not set (0) Virtual Ports will accept PLOGIs from
3890# other initiators and will attempt to PLOGI all remote ports.
3891# When this parameter is set (1) Virtual Ports will reject PLOGIs from
3892# remote ports and will not attempt to PLOGI to other initiators.
3893# This parameter does not restrict to the physical port.
3894# This parameter does not restrict logins to Fabric resident remote ports.
3895# Default value of this parameter is 1.
3896*/
James Smart3de2a652007-08-02 11:09:59 -04003897static int lpfc_restrict_login = 1;
James Smartab56dc22011-02-16 12:39:57 -05003898module_param(lpfc_restrict_login, int, S_IRUGO);
James Smart3de2a652007-08-02 11:09:59 -04003899MODULE_PARM_DESC(lpfc_restrict_login,
3900 "Restrict virtual ports login to remote initiators.");
3901lpfc_vport_param_show(restrict_login);
3902
James Smarte59058c2008-08-24 21:49:00 -04003903/**
James Smart3621a712009-04-06 18:47:14 -04003904 * lpfc_restrict_login_init - Set the vport restrict login flag
James Smarte59058c2008-08-24 21:49:00 -04003905 * @vport: lpfc vport structure pointer.
3906 * @val: contains the restrict login value.
3907 *
3908 * Description:
3909 * If val is not in a valid range then log a kernel error message and set
3910 * the vport restrict login to one.
3911 * If the port type is physical clear the restrict login flag and return.
3912 * Else set the restrict login flag to val.
3913 *
3914 * Returns:
3915 * zero if val is in range
3916 * -EINVAL val out of range
3917 **/
James Smart3de2a652007-08-02 11:09:59 -04003918static int
3919lpfc_restrict_login_init(struct lpfc_vport *vport, int val)
3920{
3921 if (val < 0 || val > 1) {
James Smarte8b62012007-08-02 11:10:09 -04003922 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartd7c255b2008-08-24 21:50:00 -04003923 "0422 lpfc_restrict_login attribute cannot "
James Smarte8b62012007-08-02 11:10:09 -04003924 "be set to %d, allowed range is [0, 1]\n",
3925 val);
James Smart3de2a652007-08-02 11:09:59 -04003926 vport->cfg_restrict_login = 1;
3927 return -EINVAL;
3928 }
3929 if (vport->port_type == LPFC_PHYSICAL_PORT) {
3930 vport->cfg_restrict_login = 0;
3931 return 0;
3932 }
3933 vport->cfg_restrict_login = val;
3934 return 0;
3935}
3936
James Smarte59058c2008-08-24 21:49:00 -04003937/**
James Smart3621a712009-04-06 18:47:14 -04003938 * lpfc_restrict_login_set - Set the vport restrict login flag
James Smarte59058c2008-08-24 21:49:00 -04003939 * @vport: lpfc vport structure pointer.
3940 * @val: contains the restrict login value.
3941 *
3942 * Description:
3943 * If val is not in a valid range then log a kernel error message and set
3944 * the vport restrict login to one.
3945 * If the port type is physical and the val is not zero log a kernel
3946 * error message, clear the restrict login flag and return zero.
3947 * Else set the restrict login flag to val.
3948 *
3949 * Returns:
3950 * zero if val is in range
3951 * -EINVAL val out of range
3952 **/
James Smart3de2a652007-08-02 11:09:59 -04003953static int
3954lpfc_restrict_login_set(struct lpfc_vport *vport, int val)
3955{
3956 if (val < 0 || val > 1) {
James Smarte8b62012007-08-02 11:10:09 -04003957 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartd7c255b2008-08-24 21:50:00 -04003958 "0425 lpfc_restrict_login attribute cannot "
James Smarte8b62012007-08-02 11:10:09 -04003959 "be set to %d, allowed range is [0, 1]\n",
3960 val);
James Smart3de2a652007-08-02 11:09:59 -04003961 vport->cfg_restrict_login = 1;
3962 return -EINVAL;
3963 }
3964 if (vport->port_type == LPFC_PHYSICAL_PORT && val != 0) {
James Smarte8b62012007-08-02 11:10:09 -04003965 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3966 "0468 lpfc_restrict_login must be 0 for "
3967 "Physical ports.\n");
James Smart3de2a652007-08-02 11:09:59 -04003968 vport->cfg_restrict_login = 0;
3969 return 0;
3970 }
3971 vport->cfg_restrict_login = val;
3972 return 0;
3973}
3974lpfc_vport_param_store(restrict_login);
Joe Perchesb6b996b2017-12-19 10:15:07 -08003975static DEVICE_ATTR_RW(lpfc_restrict_login);
James Smart92d7f7b2007-06-17 19:56:38 -05003976
3977/*
dea31012005-04-17 16:05:31 -05003978# Some disk devices have a "select ID" or "select Target" capability.
3979# From a protocol standpoint "select ID" usually means select the
3980# Fibre channel "ALPA". In the FC-AL Profile there is an "informative
3981# annex" which contains a table that maps a "select ID" (a number
3982# between 0 and 7F) to an ALPA. By default, for compatibility with
3983# older drivers, the lpfc driver scans this table from low ALPA to high
3984# ALPA.
3985#
3986# Turning on the scan-down variable (on = 1, off = 0) will
3987# cause the lpfc driver to use an inverted table, effectively
3988# scanning ALPAs from high to low. Value range is [0,1]. Default value is 1.
3989#
3990# (Note: This "select ID" functionality is a LOOP ONLY characteristic
3991# and will not work across a fabric. Also this parameter will take
3992# effect only in the case when ALPA map is not available.)
3993*/
James Smart3de2a652007-08-02 11:09:59 -04003994LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1,
3995 "Start scanning for devices from highest ALPA to lowest");
dea31012005-04-17 16:05:31 -05003996
3997/*
dea31012005-04-17 16:05:31 -05003998# lpfc_topology: link topology for init link
3999# 0x0 = attempt loop mode then point-to-point
Jamie Wellnitz367c2712006-02-28 19:25:32 -05004000# 0x01 = internal loopback mode
dea31012005-04-17 16:05:31 -05004001# 0x02 = attempt point-to-point mode only
4002# 0x04 = attempt loop mode only
4003# 0x06 = attempt point-to-point mode then loop
4004# Set point-to-point mode if you want to run as an N_Port.
4005# Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
4006# Default value is 0.
4007*/
James Smart0a035432016-10-13 15:06:10 -07004008LPFC_ATTR(topology, 0, 0, 6,
4009 "Select Fibre Channel topology");
James Smarte59058c2008-08-24 21:49:00 -04004010
4011/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00004012 * lpfc_topology_store - Set the adapters topology field
Lee Jonesa738bd92020-11-02 14:23:45 +00004013 * @dev: class device that is converted into a scsi_host.
4014 * @attr:device attribute, not used.
4015 * @buf: buffer for passing information.
4016 * @count: size of the data buffer.
James Smarte59058c2008-08-24 21:49:00 -04004017 *
4018 * Description:
4019 * If val is in a valid range then set the adapter's topology field and
4020 * issue a lip; if the lip fails reset the topology to the old value.
4021 *
4022 * If the value is not in range log a kernel error message and return an error.
4023 *
4024 * Returns:
4025 * zero if val is in range and lip okay
4026 * non-zero return value from lpfc_issue_lip()
4027 * -EINVAL val out of range
4028 **/
James Smarta257bf92009-04-06 18:48:10 -04004029static ssize_t
4030lpfc_topology_store(struct device *dev, struct device_attribute *attr,
4031 const char *buf, size_t count)
James Smart83108bd2008-01-11 01:53:09 -05004032{
James Smarta257bf92009-04-06 18:48:10 -04004033 struct Scsi_Host *shost = class_to_shost(dev);
4034 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4035 struct lpfc_hba *phba = vport->phba;
4036 int val = 0;
4037 int nolip = 0;
4038 const char *val_buf = buf;
James Smart83108bd2008-01-11 01:53:09 -05004039 int err;
4040 uint32_t prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004041
4042 if (!strncmp(buf, "nolip ", strlen("nolip "))) {
4043 nolip = 1;
4044 val_buf = &buf[strlen("nolip ")];
4045 }
4046
4047 if (!isdigit(val_buf[0]))
4048 return -EINVAL;
4049 if (sscanf(val_buf, "%i", &val) != 1)
4050 return -EINVAL;
4051
James Smart83108bd2008-01-11 01:53:09 -05004052 if (val >= 0 && val <= 6) {
4053 prev_val = phba->cfg_topology;
James Smartff78d8f2011-12-13 13:21:35 -05004054 if (phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G &&
4055 val == 4) {
4056 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4057 "3113 Loop mode not supported at speed %d\n",
James Smartd38dd522015-08-31 16:48:17 -04004058 val);
James Smartff78d8f2011-12-13 13:21:35 -05004059 return -EINVAL;
4060 }
James Smart83c6cb12019-10-18 14:18:30 -07004061 /*
4062 * The 'topology' is not a configurable parameter if :
4063 * - persistent topology enabled
James Smarta052ce82019-12-18 15:58:04 -08004064 * - G7/G6 with no private loop support
James Smart83c6cb12019-10-18 14:18:30 -07004065 */
4066
James Smarta052ce82019-12-18 15:58:04 -08004067 if ((phba->hba_flag & HBA_PERSISTENT_TOPO ||
James Smart83c6cb12019-10-18 14:18:30 -07004068 (!phba->sli4_hba.pc_sli4_params.pls &&
James Smarta052ce82019-12-18 15:58:04 -08004069 (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC ||
4070 phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC))) &&
James Smartf6978f42019-05-21 17:48:57 -07004071 val == 4) {
James Smartd38dd522015-08-31 16:48:17 -04004072 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartf6978f42019-05-21 17:48:57 -07004073 "3114 Loop mode not supported\n");
James Smartd38dd522015-08-31 16:48:17 -04004074 return -EINVAL;
4075 }
4076 phba->cfg_topology = val;
James Smarta257bf92009-04-06 18:48:10 -04004077 if (nolip)
4078 return strlen(buf);
4079
James Smart88a2cfb2011-07-22 18:36:33 -04004080 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4081 "3054 lpfc_topology changed from %d to %d\n",
4082 prev_val, val);
James Smarte74c03c2013-04-17 20:15:19 -04004083 if (prev_val != val && phba->sli_rev == LPFC_SLI_REV4)
4084 phba->fc_topology_changed = 1;
James Smart83108bd2008-01-11 01:53:09 -05004085 err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
James Smarta257bf92009-04-06 18:48:10 -04004086 if (err) {
James Smart83108bd2008-01-11 01:53:09 -05004087 phba->cfg_topology = prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004088 return -EINVAL;
4089 } else
4090 return strlen(buf);
James Smart83108bd2008-01-11 01:53:09 -05004091 }
4092 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4093 "%d:0467 lpfc_topology attribute cannot be set to %d, "
4094 "allowed range is [0, 6]\n",
4095 phba->brd_no, val);
4096 return -EINVAL;
4097}
James Smart0a035432016-10-13 15:06:10 -07004098
James Smart83108bd2008-01-11 01:53:09 -05004099lpfc_param_show(topology)
Joe Perchesb6b996b2017-12-19 10:15:07 -08004100static DEVICE_ATTR_RW(lpfc_topology);
dea31012005-04-17 16:05:31 -05004101
James Smart21e9a0a2009-05-22 14:53:21 -04004102/**
4103 * lpfc_static_vport_show: Read callback function for
4104 * lpfc_static_vport sysfs file.
4105 * @dev: Pointer to class device object.
4106 * @attr: device attribute structure.
4107 * @buf: Data buffer.
4108 *
4109 * This function is the read call back function for
4110 * lpfc_static_vport sysfs file. The lpfc_static_vport
4111 * sysfs file report the mageability of the vport.
4112 **/
4113static ssize_t
4114lpfc_static_vport_show(struct device *dev, struct device_attribute *attr,
4115 char *buf)
4116{
4117 struct Scsi_Host *shost = class_to_shost(dev);
4118 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4119 if (vport->vport_flag & STATIC_VPORT)
4120 sprintf(buf, "1\n");
4121 else
4122 sprintf(buf, "0\n");
4123
4124 return strlen(buf);
4125}
4126
4127/*
4128 * Sysfs attribute to control the statistical data collection.
4129 */
Joe Perchesc828a892017-12-19 10:15:08 -08004130static DEVICE_ATTR_RO(lpfc_static_vport);
James Smartea2151b2008-09-07 11:52:10 -04004131
4132/**
James Smart3621a712009-04-06 18:47:14 -04004133 * lpfc_stat_data_ctrl_store - write call back for lpfc_stat_data_ctrl sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004134 * @dev: Pointer to class device.
Lee Jonesa738bd92020-11-02 14:23:45 +00004135 * @attr: Unused.
James Smartea2151b2008-09-07 11:52:10 -04004136 * @buf: Data buffer.
4137 * @count: Size of the data buffer.
4138 *
Masahiro Yamada9332ef92017-02-27 14:28:47 -08004139 * This function get called when a user write to the lpfc_stat_data_ctrl
James Smartea2151b2008-09-07 11:52:10 -04004140 * sysfs file. This function parse the command written to the sysfs file
4141 * and take appropriate action. These commands are used for controlling
4142 * driver statistical data collection.
4143 * Following are the command this function handles.
4144 *
4145 * setbucket <bucket_type> <base> <step>
4146 * = Set the latency buckets.
4147 * destroybucket = destroy all the buckets.
4148 * start = start data collection
4149 * stop = stop data collection
4150 * reset = reset the collected data
4151 **/
4152static ssize_t
4153lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
4154 const char *buf, size_t count)
4155{
4156 struct Scsi_Host *shost = class_to_shost(dev);
4157 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4158 struct lpfc_hba *phba = vport->phba;
4159#define LPFC_MAX_DATA_CTRL_LEN 1024
4160 static char bucket_data[LPFC_MAX_DATA_CTRL_LEN];
4161 unsigned long i;
4162 char *str_ptr, *token;
4163 struct lpfc_vport **vports;
4164 struct Scsi_Host *v_shost;
4165 char *bucket_type_str, *base_str, *step_str;
4166 unsigned long base, step, bucket_type;
4167
4168 if (!strncmp(buf, "setbucket", strlen("setbucket"))) {
James Smarta257bf92009-04-06 18:48:10 -04004169 if (strlen(buf) > (LPFC_MAX_DATA_CTRL_LEN - 1))
James Smartea2151b2008-09-07 11:52:10 -04004170 return -EINVAL;
4171
James Smarteb016562014-09-03 12:58:06 -04004172 strncpy(bucket_data, buf, LPFC_MAX_DATA_CTRL_LEN);
James Smartea2151b2008-09-07 11:52:10 -04004173 str_ptr = &bucket_data[0];
4174 /* Ignore this token - this is command token */
4175 token = strsep(&str_ptr, "\t ");
4176 if (!token)
4177 return -EINVAL;
4178
4179 bucket_type_str = strsep(&str_ptr, "\t ");
4180 if (!bucket_type_str)
4181 return -EINVAL;
4182
4183 if (!strncmp(bucket_type_str, "linear", strlen("linear")))
4184 bucket_type = LPFC_LINEAR_BUCKET;
4185 else if (!strncmp(bucket_type_str, "power2", strlen("power2")))
4186 bucket_type = LPFC_POWER2_BUCKET;
4187 else
4188 return -EINVAL;
4189
4190 base_str = strsep(&str_ptr, "\t ");
4191 if (!base_str)
4192 return -EINVAL;
4193 base = simple_strtoul(base_str, NULL, 0);
4194
4195 step_str = strsep(&str_ptr, "\t ");
4196 if (!step_str)
4197 return -EINVAL;
4198 step = simple_strtoul(step_str, NULL, 0);
4199 if (!step)
4200 return -EINVAL;
4201
4202 /* Block the data collection for every vport */
4203 vports = lpfc_create_vport_work_array(phba);
4204 if (vports == NULL)
4205 return -ENOMEM;
4206
James Smartf4b4c682009-05-22 14:53:12 -04004207 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004208 v_shost = lpfc_shost_from_vport(vports[i]);
4209 spin_lock_irq(v_shost->host_lock);
4210 /* Block and reset data collection */
4211 vports[i]->stat_data_blocked = 1;
4212 if (vports[i]->stat_data_enabled)
4213 lpfc_vport_reset_stat_data(vports[i]);
4214 spin_unlock_irq(v_shost->host_lock);
4215 }
4216
4217 /* Set the bucket attributes */
4218 phba->bucket_type = bucket_type;
4219 phba->bucket_base = base;
4220 phba->bucket_step = step;
4221
James Smartf4b4c682009-05-22 14:53:12 -04004222 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004223 v_shost = lpfc_shost_from_vport(vports[i]);
4224
4225 /* Unblock data collection */
4226 spin_lock_irq(v_shost->host_lock);
4227 vports[i]->stat_data_blocked = 0;
4228 spin_unlock_irq(v_shost->host_lock);
4229 }
4230 lpfc_destroy_vport_work_array(phba, vports);
4231 return strlen(buf);
4232 }
4233
4234 if (!strncmp(buf, "destroybucket", strlen("destroybucket"))) {
4235 vports = lpfc_create_vport_work_array(phba);
4236 if (vports == NULL)
4237 return -ENOMEM;
4238
James Smartf4b4c682009-05-22 14:53:12 -04004239 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004240 v_shost = lpfc_shost_from_vport(vports[i]);
4241 spin_lock_irq(shost->host_lock);
4242 vports[i]->stat_data_blocked = 1;
4243 lpfc_free_bucket(vport);
4244 vport->stat_data_enabled = 0;
4245 vports[i]->stat_data_blocked = 0;
4246 spin_unlock_irq(shost->host_lock);
4247 }
4248 lpfc_destroy_vport_work_array(phba, vports);
4249 phba->bucket_type = LPFC_NO_BUCKET;
4250 phba->bucket_base = 0;
4251 phba->bucket_step = 0;
4252 return strlen(buf);
4253 }
4254
4255 if (!strncmp(buf, "start", strlen("start"))) {
4256 /* If no buckets configured return error */
4257 if (phba->bucket_type == LPFC_NO_BUCKET)
4258 return -EINVAL;
4259 spin_lock_irq(shost->host_lock);
4260 if (vport->stat_data_enabled) {
4261 spin_unlock_irq(shost->host_lock);
4262 return strlen(buf);
4263 }
4264 lpfc_alloc_bucket(vport);
4265 vport->stat_data_enabled = 1;
4266 spin_unlock_irq(shost->host_lock);
4267 return strlen(buf);
4268 }
4269
4270 if (!strncmp(buf, "stop", strlen("stop"))) {
4271 spin_lock_irq(shost->host_lock);
4272 if (vport->stat_data_enabled == 0) {
4273 spin_unlock_irq(shost->host_lock);
4274 return strlen(buf);
4275 }
4276 lpfc_free_bucket(vport);
4277 vport->stat_data_enabled = 0;
4278 spin_unlock_irq(shost->host_lock);
4279 return strlen(buf);
4280 }
4281
4282 if (!strncmp(buf, "reset", strlen("reset"))) {
4283 if ((phba->bucket_type == LPFC_NO_BUCKET)
4284 || !vport->stat_data_enabled)
4285 return strlen(buf);
4286 spin_lock_irq(shost->host_lock);
4287 vport->stat_data_blocked = 1;
4288 lpfc_vport_reset_stat_data(vport);
4289 vport->stat_data_blocked = 0;
4290 spin_unlock_irq(shost->host_lock);
4291 return strlen(buf);
4292 }
4293 return -EINVAL;
4294}
4295
4296
4297/**
James Smart3621a712009-04-06 18:47:14 -04004298 * lpfc_stat_data_ctrl_show - Read function for lpfc_stat_data_ctrl sysfs file
Lee Jonesa738bd92020-11-02 14:23:45 +00004299 * @dev: Pointer to class device.
4300 * @attr: Unused.
James Smartea2151b2008-09-07 11:52:10 -04004301 * @buf: Data buffer.
4302 *
4303 * This function is the read call back function for
4304 * lpfc_stat_data_ctrl sysfs file. This function report the
4305 * current statistical data collection state.
4306 **/
4307static ssize_t
4308lpfc_stat_data_ctrl_show(struct device *dev, struct device_attribute *attr,
4309 char *buf)
4310{
4311 struct Scsi_Host *shost = class_to_shost(dev);
4312 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4313 struct lpfc_hba *phba = vport->phba;
4314 int index = 0;
4315 int i;
4316 char *bucket_type;
4317 unsigned long bucket_value;
4318
4319 switch (phba->bucket_type) {
4320 case LPFC_LINEAR_BUCKET:
4321 bucket_type = "linear";
4322 break;
4323 case LPFC_POWER2_BUCKET:
4324 bucket_type = "power2";
4325 break;
4326 default:
4327 bucket_type = "No Bucket";
4328 break;
4329 }
4330
4331 sprintf(&buf[index], "Statistical Data enabled :%d, "
4332 "blocked :%d, Bucket type :%s, Bucket base :%d,"
4333 " Bucket step :%d\nLatency Ranges :",
4334 vport->stat_data_enabled, vport->stat_data_blocked,
4335 bucket_type, phba->bucket_base, phba->bucket_step);
4336 index = strlen(buf);
4337 if (phba->bucket_type != LPFC_NO_BUCKET) {
4338 for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
4339 if (phba->bucket_type == LPFC_LINEAR_BUCKET)
4340 bucket_value = phba->bucket_base +
4341 phba->bucket_step * i;
4342 else
4343 bucket_value = phba->bucket_base +
4344 (1 << i) * phba->bucket_step;
4345
4346 if (index + 10 > PAGE_SIZE)
4347 break;
4348 sprintf(&buf[index], "%08ld ", bucket_value);
4349 index = strlen(buf);
4350 }
4351 }
4352 sprintf(&buf[index], "\n");
4353 return strlen(buf);
4354}
4355
4356/*
4357 * Sysfs attribute to control the statistical data collection.
4358 */
Joe Perchesb6b996b2017-12-19 10:15:07 -08004359static DEVICE_ATTR_RW(lpfc_stat_data_ctrl);
James Smartea2151b2008-09-07 11:52:10 -04004360
4361/*
4362 * lpfc_drvr_stat_data: sysfs attr to get driver statistical data.
4363 */
4364
4365/*
4366 * Each Bucket takes 11 characters and 1 new line + 17 bytes WWN
4367 * for each target.
4368 */
4369#define STAT_DATA_SIZE_PER_TARGET(NUM_BUCKETS) ((NUM_BUCKETS) * 11 + 18)
4370#define MAX_STAT_DATA_SIZE_PER_TARGET \
4371 STAT_DATA_SIZE_PER_TARGET(LPFC_MAX_BUCKET_COUNT)
4372
4373
4374/**
James Smart3621a712009-04-06 18:47:14 -04004375 * sysfs_drvr_stat_data_read - Read function for lpfc_drvr_stat_data attribute
Chris Wright2c3c8be2010-05-12 18:28:57 -07004376 * @filp: sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004377 * @kobj: Pointer to the kernel object
4378 * @bin_attr: Attribute object
Lee Jonesa738bd92020-11-02 14:23:45 +00004379 * @buf: Buffer pointer
James Smartea2151b2008-09-07 11:52:10 -04004380 * @off: File offset
4381 * @count: Buffer size
4382 *
4383 * This function is the read call back function for lpfc_drvr_stat_data
4384 * sysfs file. This function export the statistical data to user
4385 * applications.
4386 **/
4387static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07004388sysfs_drvr_stat_data_read(struct file *filp, struct kobject *kobj,
4389 struct bin_attribute *bin_attr,
James Smartea2151b2008-09-07 11:52:10 -04004390 char *buf, loff_t off, size_t count)
4391{
4392 struct device *dev = container_of(kobj, struct device,
4393 kobj);
4394 struct Scsi_Host *shost = class_to_shost(dev);
4395 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4396 struct lpfc_hba *phba = vport->phba;
4397 int i = 0, index = 0;
4398 unsigned long nport_index;
4399 struct lpfc_nodelist *ndlp = NULL;
4400 nport_index = (unsigned long)off /
4401 MAX_STAT_DATA_SIZE_PER_TARGET;
4402
4403 if (!vport->stat_data_enabled || vport->stat_data_blocked
4404 || (phba->bucket_type == LPFC_NO_BUCKET))
4405 return 0;
4406
4407 spin_lock_irq(shost->host_lock);
4408 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart307e3382020-11-15 11:26:30 -08004409 if (!ndlp->lat_data)
James Smartea2151b2008-09-07 11:52:10 -04004410 continue;
4411
4412 if (nport_index > 0) {
4413 nport_index--;
4414 continue;
4415 }
4416
4417 if ((index + MAX_STAT_DATA_SIZE_PER_TARGET)
4418 > count)
4419 break;
4420
4421 if (!ndlp->lat_data)
4422 continue;
4423
4424 /* Print the WWN */
4425 sprintf(&buf[index], "%02x%02x%02x%02x%02x%02x%02x%02x:",
4426 ndlp->nlp_portname.u.wwn[0],
4427 ndlp->nlp_portname.u.wwn[1],
4428 ndlp->nlp_portname.u.wwn[2],
4429 ndlp->nlp_portname.u.wwn[3],
4430 ndlp->nlp_portname.u.wwn[4],
4431 ndlp->nlp_portname.u.wwn[5],
4432 ndlp->nlp_portname.u.wwn[6],
4433 ndlp->nlp_portname.u.wwn[7]);
4434
4435 index = strlen(buf);
4436
4437 for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
4438 sprintf(&buf[index], "%010u,",
4439 ndlp->lat_data[i].cmd_count);
4440 index = strlen(buf);
4441 }
4442 sprintf(&buf[index], "\n");
4443 index = strlen(buf);
4444 }
4445 spin_unlock_irq(shost->host_lock);
4446 return index;
4447}
4448
4449static struct bin_attribute sysfs_drvr_stat_data_attr = {
4450 .attr = {
4451 .name = "lpfc_drvr_stat_data",
4452 .mode = S_IRUSR,
James Smartea2151b2008-09-07 11:52:10 -04004453 },
4454 .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET,
4455 .read = sysfs_drvr_stat_data_read,
4456 .write = NULL,
4457};
4458
dea31012005-04-17 16:05:31 -05004459/*
4460# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
4461# connection.
James Smart76a95d72010-11-20 23:11:48 -05004462# Value range is [0,16]. Default value is 0.
dea31012005-04-17 16:05:31 -05004463*/
James Smarte59058c2008-08-24 21:49:00 -04004464/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00004465 * lpfc_link_speed_store - Set the adapters link speed
Lee Jonesa738bd92020-11-02 14:23:45 +00004466 * @dev: Pointer to class device.
4467 * @attr: Unused.
4468 * @buf: Data buffer.
4469 * @count: Size of the data buffer.
James Smarte59058c2008-08-24 21:49:00 -04004470 *
4471 * Description:
4472 * If val is in a valid range then set the adapter's link speed field and
4473 * issue a lip; if the lip fails reset the link speed to the old value.
4474 *
4475 * Notes:
4476 * If the value is not in range log a kernel error message and return an error.
4477 *
4478 * Returns:
4479 * zero if val is in range and lip okay.
4480 * non-zero return value from lpfc_issue_lip()
4481 * -EINVAL val out of range
4482 **/
James Smarta257bf92009-04-06 18:48:10 -04004483static ssize_t
4484lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
4485 const char *buf, size_t count)
James Smart83108bd2008-01-11 01:53:09 -05004486{
James Smarta257bf92009-04-06 18:48:10 -04004487 struct Scsi_Host *shost = class_to_shost(dev);
4488 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4489 struct lpfc_hba *phba = vport->phba;
James Smart76a95d72010-11-20 23:11:48 -05004490 int val = LPFC_USER_LINK_SPEED_AUTO;
James Smarta257bf92009-04-06 18:48:10 -04004491 int nolip = 0;
4492 const char *val_buf = buf;
James Smart83108bd2008-01-11 01:53:09 -05004493 int err;
James Smartc6918162016-10-13 15:06:16 -07004494 uint32_t prev_val, if_type;
4495
4496 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
James Smart719162b2018-12-10 19:37:01 -08004497 if (if_type >= LPFC_SLI_INTF_IF_TYPE_2 &&
James Smartc6918162016-10-13 15:06:16 -07004498 phba->hba_flag & HBA_FORCED_LINK_SPEED)
4499 return -EPERM;
James Smart83108bd2008-01-11 01:53:09 -05004500
James Smarta257bf92009-04-06 18:48:10 -04004501 if (!strncmp(buf, "nolip ", strlen("nolip "))) {
4502 nolip = 1;
4503 val_buf = &buf[strlen("nolip ")];
4504 }
4505
4506 if (!isdigit(val_buf[0]))
4507 return -EINVAL;
4508 if (sscanf(val_buf, "%i", &val) != 1)
4509 return -EINVAL;
4510
James Smart88a2cfb2011-07-22 18:36:33 -04004511 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4512 "3055 lpfc_link_speed changed from %d to %d %s\n",
4513 phba->cfg_link_speed, val, nolip ? "(nolip)" : "(lip)");
4514
James Smart76a95d72010-11-20 23:11:48 -05004515 if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
4516 ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
4517 ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
4518 ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
4519 ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
James Smartd38dd522015-08-31 16:48:17 -04004520 ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
James Smartfbd8a6b2018-02-22 08:18:45 -08004521 ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
4522 ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
James Smart76a95d72010-11-20 23:11:48 -05004523 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4524 "2879 lpfc_link_speed attribute cannot be set "
4525 "to %d. Speed is not supported by this port.\n",
4526 val);
James Smart83108bd2008-01-11 01:53:09 -05004527 return -EINVAL;
James Smart76a95d72010-11-20 23:11:48 -05004528 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004529 if (val >= LPFC_USER_LINK_SPEED_16G &&
4530 phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smartff78d8f2011-12-13 13:21:35 -05004531 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4532 "3112 lpfc_link_speed attribute cannot be set "
4533 "to %d. Speed is not supported in loop mode.\n",
4534 val);
4535 return -EINVAL;
4536 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004537
4538 switch (val) {
4539 case LPFC_USER_LINK_SPEED_AUTO:
4540 case LPFC_USER_LINK_SPEED_1G:
4541 case LPFC_USER_LINK_SPEED_2G:
4542 case LPFC_USER_LINK_SPEED_4G:
4543 case LPFC_USER_LINK_SPEED_8G:
4544 case LPFC_USER_LINK_SPEED_16G:
4545 case LPFC_USER_LINK_SPEED_32G:
4546 case LPFC_USER_LINK_SPEED_64G:
James Smart83108bd2008-01-11 01:53:09 -05004547 prev_val = phba->cfg_link_speed;
4548 phba->cfg_link_speed = val;
James Smarta257bf92009-04-06 18:48:10 -04004549 if (nolip)
4550 return strlen(buf);
4551
James Smart83108bd2008-01-11 01:53:09 -05004552 err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
James Smarta257bf92009-04-06 18:48:10 -04004553 if (err) {
James Smart83108bd2008-01-11 01:53:09 -05004554 phba->cfg_link_speed = prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004555 return -EINVAL;
James Smartfbd8a6b2018-02-22 08:18:45 -08004556 }
4557 return strlen(buf);
4558 default:
4559 break;
James Smart83108bd2008-01-11 01:53:09 -05004560 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004561
James Smart83108bd2008-01-11 01:53:09 -05004562 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smartfbd8a6b2018-02-22 08:18:45 -08004563 "0469 lpfc_link_speed attribute cannot be set to %d, "
4564 "allowed values are [%s]\n",
4565 val, LPFC_LINK_SPEED_STRING);
James Smart83108bd2008-01-11 01:53:09 -05004566 return -EINVAL;
James Smartfbd8a6b2018-02-22 08:18:45 -08004567
James Smart83108bd2008-01-11 01:53:09 -05004568}
4569
4570static int lpfc_link_speed = 0;
James Smartab56dc22011-02-16 12:39:57 -05004571module_param(lpfc_link_speed, int, S_IRUGO);
James Smart83108bd2008-01-11 01:53:09 -05004572MODULE_PARM_DESC(lpfc_link_speed, "Select link speed");
4573lpfc_param_show(link_speed)
James Smarte59058c2008-08-24 21:49:00 -04004574
4575/**
James Smart3621a712009-04-06 18:47:14 -04004576 * lpfc_link_speed_init - Set the adapters link speed
James Smarte59058c2008-08-24 21:49:00 -04004577 * @phba: lpfc_hba pointer.
4578 * @val: link speed value.
4579 *
4580 * Description:
4581 * If val is in a valid range then set the adapter's link speed field.
4582 *
4583 * Notes:
4584 * If the value is not in range log a kernel error message, clear the link
4585 * speed and return an error.
4586 *
4587 * Returns:
4588 * zero if val saved.
4589 * -EINVAL val out of range
4590 **/
James Smart83108bd2008-01-11 01:53:09 -05004591static int
4592lpfc_link_speed_init(struct lpfc_hba *phba, int val)
4593{
James Smartfbd8a6b2018-02-22 08:18:45 -08004594 if (val >= LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) {
James Smartff78d8f2011-12-13 13:21:35 -05004595 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4596 "3111 lpfc_link_speed of %d cannot "
4597 "support loop mode, setting topology to default.\n",
4598 val);
4599 phba->cfg_topology = 0;
4600 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004601
4602 switch (val) {
4603 case LPFC_USER_LINK_SPEED_AUTO:
4604 case LPFC_USER_LINK_SPEED_1G:
4605 case LPFC_USER_LINK_SPEED_2G:
4606 case LPFC_USER_LINK_SPEED_4G:
4607 case LPFC_USER_LINK_SPEED_8G:
4608 case LPFC_USER_LINK_SPEED_16G:
4609 case LPFC_USER_LINK_SPEED_32G:
4610 case LPFC_USER_LINK_SPEED_64G:
James Smart83108bd2008-01-11 01:53:09 -05004611 phba->cfg_link_speed = val;
4612 return 0;
James Smartfbd8a6b2018-02-22 08:18:45 -08004613 default:
4614 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4615 "0405 lpfc_link_speed attribute cannot "
4616 "be set to %d, allowed values are "
4617 "["LPFC_LINK_SPEED_STRING"]\n", val);
4618 phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
4619 return -EINVAL;
James Smart83108bd2008-01-11 01:53:09 -05004620 }
James Smart83108bd2008-01-11 01:53:09 -05004621}
4622
Joe Perchesb6b996b2017-12-19 10:15:07 -08004623static DEVICE_ATTR_RW(lpfc_link_speed);
dea31012005-04-17 16:05:31 -05004624
4625/*
James Smart0d878412009-10-02 15:16:56 -04004626# lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
4627# 0 = aer disabled or not supported
4628# 1 = aer supported and enabled (default)
4629# Value range is [0,1]. Default value is 1.
4630*/
James Smart506139a2016-10-13 15:06:09 -07004631LPFC_ATTR(aer_support, 1, 0, 1,
4632 "Enable PCIe device AER support");
4633lpfc_param_show(aer_support)
James Smart0d878412009-10-02 15:16:56 -04004634
4635/**
4636 * lpfc_aer_support_store - Set the adapter for aer support
4637 *
4638 * @dev: class device that is converted into a Scsi_host.
4639 * @attr: device attribute, not used.
James Smart912e3ac2011-05-24 11:42:11 -04004640 * @buf: containing enable or disable aer flag.
James Smart0d878412009-10-02 15:16:56 -04004641 * @count: unused variable.
4642 *
4643 * Description:
4644 * If the val is 1 and currently the device's AER capability was not
4645 * enabled, invoke the kernel's enable AER helper routine, trying to
4646 * enable the device's AER capability. If the helper routine enabling
4647 * AER returns success, update the device's cfg_aer_support flag to
4648 * indicate AER is supported by the device; otherwise, if the device
4649 * AER capability is already enabled to support AER, then do nothing.
4650 *
4651 * If the val is 0 and currently the device's AER support was enabled,
4652 * invoke the kernel's disable AER helper routine. After that, update
4653 * the device's cfg_aer_support flag to indicate AER is not supported
4654 * by the device; otherwise, if the device AER capability is already
4655 * disabled from supporting AER, then do nothing.
4656 *
4657 * Returns:
4658 * length of the buf on success if val is in range the intended mode
4659 * is supported.
4660 * -EINVAL if val out of range or intended mode is not supported.
4661 **/
4662static ssize_t
4663lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
4664 const char *buf, size_t count)
4665{
4666 struct Scsi_Host *shost = class_to_shost(dev);
4667 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4668 struct lpfc_hba *phba = vport->phba;
4669 int val = 0, rc = -EINVAL;
4670
4671 if (!isdigit(buf[0]))
4672 return -EINVAL;
4673 if (sscanf(buf, "%i", &val) != 1)
4674 return -EINVAL;
4675
4676 switch (val) {
4677 case 0:
4678 if (phba->hba_flag & HBA_AER_ENABLED) {
4679 rc = pci_disable_pcie_error_reporting(phba->pcidev);
4680 if (!rc) {
4681 spin_lock_irq(&phba->hbalock);
4682 phba->hba_flag &= ~HBA_AER_ENABLED;
4683 spin_unlock_irq(&phba->hbalock);
4684 phba->cfg_aer_support = 0;
4685 rc = strlen(buf);
4686 } else
James Smart891478a2009-11-18 15:40:23 -05004687 rc = -EPERM;
4688 } else {
James Smart0d878412009-10-02 15:16:56 -04004689 phba->cfg_aer_support = 0;
James Smart891478a2009-11-18 15:40:23 -05004690 rc = strlen(buf);
4691 }
James Smart0d878412009-10-02 15:16:56 -04004692 break;
4693 case 1:
4694 if (!(phba->hba_flag & HBA_AER_ENABLED)) {
4695 rc = pci_enable_pcie_error_reporting(phba->pcidev);
4696 if (!rc) {
4697 spin_lock_irq(&phba->hbalock);
4698 phba->hba_flag |= HBA_AER_ENABLED;
4699 spin_unlock_irq(&phba->hbalock);
4700 phba->cfg_aer_support = 1;
4701 rc = strlen(buf);
4702 } else
James Smart891478a2009-11-18 15:40:23 -05004703 rc = -EPERM;
4704 } else {
James Smart0d878412009-10-02 15:16:56 -04004705 phba->cfg_aer_support = 1;
James Smart891478a2009-11-18 15:40:23 -05004706 rc = strlen(buf);
4707 }
James Smart0d878412009-10-02 15:16:56 -04004708 break;
4709 default:
4710 rc = -EINVAL;
4711 break;
4712 }
4713 return rc;
4714}
4715
Joe Perchesb6b996b2017-12-19 10:15:07 -08004716static DEVICE_ATTR_RW(lpfc_aer_support);
James Smart0d878412009-10-02 15:16:56 -04004717
4718/**
4719 * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device
4720 * @dev: class device that is converted into a Scsi_host.
4721 * @attr: device attribute, not used.
James Smart912e3ac2011-05-24 11:42:11 -04004722 * @buf: containing flag 1 for aer cleanup state.
James Smart0d878412009-10-02 15:16:56 -04004723 * @count: unused variable.
4724 *
4725 * Description:
4726 * If the @buf contains 1 and the device currently has the AER support
4727 * enabled, then invokes the kernel AER helper routine
Kuppuswamy Sathyanarayanan894020f2020-03-23 17:26:08 -07004728 * pci_aer_clear_nonfatal_status() to clean up the uncorrectable
James Smart0d878412009-10-02 15:16:56 -04004729 * error status register.
4730 *
4731 * Notes:
4732 *
4733 * Returns:
4734 * -EINVAL if the buf does not contain the 1 or the device is not currently
4735 * enabled with the AER support.
4736 **/
4737static ssize_t
4738lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr,
4739 const char *buf, size_t count)
4740{
4741 struct Scsi_Host *shost = class_to_shost(dev);
4742 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4743 struct lpfc_hba *phba = vport->phba;
4744 int val, rc = -1;
4745
4746 if (!isdigit(buf[0]))
4747 return -EINVAL;
4748 if (sscanf(buf, "%i", &val) != 1)
4749 return -EINVAL;
James Smart891478a2009-11-18 15:40:23 -05004750 if (val != 1)
4751 return -EINVAL;
James Smart0d878412009-10-02 15:16:56 -04004752
James Smart891478a2009-11-18 15:40:23 -05004753 if (phba->hba_flag & HBA_AER_ENABLED)
Kuppuswamy Sathyanarayanan894020f2020-03-23 17:26:08 -07004754 rc = pci_aer_clear_nonfatal_status(phba->pcidev);
James Smart0d878412009-10-02 15:16:56 -04004755
4756 if (rc == 0)
4757 return strlen(buf);
4758 else
James Smart891478a2009-11-18 15:40:23 -05004759 return -EPERM;
James Smart0d878412009-10-02 15:16:56 -04004760}
4761
4762static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
4763 lpfc_aer_cleanup_state);
4764
James Smart912e3ac2011-05-24 11:42:11 -04004765/**
4766 * lpfc_sriov_nr_virtfn_store - Enable the adapter for sr-iov virtual functions
4767 *
4768 * @dev: class device that is converted into a Scsi_host.
4769 * @attr: device attribute, not used.
4770 * @buf: containing the string the number of vfs to be enabled.
4771 * @count: unused variable.
4772 *
4773 * Description:
4774 * When this api is called either through user sysfs, the driver shall
4775 * try to enable or disable SR-IOV virtual functions according to the
4776 * following:
4777 *
4778 * If zero virtual function has been enabled to the physical function,
4779 * the driver shall invoke the pci enable virtual function api trying
4780 * to enable the virtual functions. If the nr_vfn provided is greater
4781 * than the maximum supported, the maximum virtual function number will
4782 * be used for invoking the api; otherwise, the nr_vfn provided shall
4783 * be used for invoking the api. If the api call returned success, the
4784 * actual number of virtual functions enabled will be set to the driver
4785 * cfg_sriov_nr_virtfn; otherwise, -EINVAL shall be returned and driver
4786 * cfg_sriov_nr_virtfn remains zero.
4787 *
4788 * If none-zero virtual functions have already been enabled to the
4789 * physical function, as reflected by the driver's cfg_sriov_nr_virtfn,
4790 * -EINVAL will be returned and the driver does nothing;
4791 *
4792 * If the nr_vfn provided is zero and none-zero virtual functions have
4793 * been enabled, as indicated by the driver's cfg_sriov_nr_virtfn, the
4794 * disabling virtual function api shall be invoded to disable all the
4795 * virtual functions and driver's cfg_sriov_nr_virtfn shall be set to
4796 * zero. Otherwise, if zero virtual function has been enabled, do
4797 * nothing.
4798 *
4799 * Returns:
4800 * length of the buf on success if val is in range the intended mode
4801 * is supported.
4802 * -EINVAL if val out of range or intended mode is not supported.
4803 **/
4804static ssize_t
4805lpfc_sriov_nr_virtfn_store(struct device *dev, struct device_attribute *attr,
4806 const char *buf, size_t count)
4807{
4808 struct Scsi_Host *shost = class_to_shost(dev);
4809 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4810 struct lpfc_hba *phba = vport->phba;
4811 struct pci_dev *pdev = phba->pcidev;
4812 int val = 0, rc = -EINVAL;
4813
4814 /* Sanity check on user data */
4815 if (!isdigit(buf[0]))
4816 return -EINVAL;
4817 if (sscanf(buf, "%i", &val) != 1)
4818 return -EINVAL;
4819 if (val < 0)
4820 return -EINVAL;
4821
4822 /* Request disabling virtual functions */
4823 if (val == 0) {
4824 if (phba->cfg_sriov_nr_virtfn > 0) {
4825 pci_disable_sriov(pdev);
4826 phba->cfg_sriov_nr_virtfn = 0;
4827 }
4828 return strlen(buf);
4829 }
4830
4831 /* Request enabling virtual functions */
4832 if (phba->cfg_sriov_nr_virtfn > 0) {
4833 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4834 "3018 There are %d virtual functions "
4835 "enabled on physical function.\n",
4836 phba->cfg_sriov_nr_virtfn);
4837 return -EEXIST;
4838 }
4839
4840 if (val <= LPFC_MAX_VFN_PER_PFN)
4841 phba->cfg_sriov_nr_virtfn = val;
4842 else {
4843 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4844 "3019 Enabling %d virtual functions is not "
4845 "allowed.\n", val);
4846 return -EINVAL;
4847 }
4848
4849 rc = lpfc_sli_probe_sriov_nr_virtfn(phba, phba->cfg_sriov_nr_virtfn);
4850 if (rc) {
4851 phba->cfg_sriov_nr_virtfn = 0;
4852 rc = -EPERM;
4853 } else
4854 rc = strlen(buf);
4855
4856 return rc;
4857}
4858
James Smart0cfbbf22016-10-13 15:06:12 -07004859LPFC_ATTR(sriov_nr_virtfn, LPFC_DEF_VFN_PER_PFN, 0, LPFC_MAX_VFN_PER_PFN,
4860 "Enable PCIe device SR-IOV virtual fn");
4861
James Smart912e3ac2011-05-24 11:42:11 -04004862lpfc_param_show(sriov_nr_virtfn)
Joe Perchesb6b996b2017-12-19 10:15:07 -08004863static DEVICE_ATTR_RW(lpfc_sriov_nr_virtfn);
James Smart912e3ac2011-05-24 11:42:11 -04004864
James Smart173edbb2012-06-12 13:54:50 -04004865/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00004866 * lpfc_request_firmware_upgrade_store - Request for Linux generic firmware upgrade
James Smartc71ab862012-10-31 14:44:33 -04004867 *
4868 * @dev: class device that is converted into a Scsi_host.
4869 * @attr: device attribute, not used.
4870 * @buf: containing the string the number of vfs to be enabled.
4871 * @count: unused variable.
4872 *
4873 * Description:
4874 *
4875 * Returns:
4876 * length of the buf on success if val is in range the intended mode
4877 * is supported.
4878 * -EINVAL if val out of range or intended mode is not supported.
4879 **/
4880static ssize_t
4881lpfc_request_firmware_upgrade_store(struct device *dev,
4882 struct device_attribute *attr,
4883 const char *buf, size_t count)
4884{
4885 struct Scsi_Host *shost = class_to_shost(dev);
4886 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4887 struct lpfc_hba *phba = vport->phba;
Colin Ian King6e27a862020-05-07 21:31:11 +01004888 int val = 0, rc;
James Smartc71ab862012-10-31 14:44:33 -04004889
4890 /* Sanity check on user data */
4891 if (!isdigit(buf[0]))
4892 return -EINVAL;
4893 if (sscanf(buf, "%i", &val) != 1)
4894 return -EINVAL;
4895 if (val != 1)
4896 return -EINVAL;
4897
4898 rc = lpfc_sli4_request_firmware_update(phba, RUN_FW_UPGRADE);
4899 if (rc)
4900 rc = -EPERM;
4901 else
4902 rc = strlen(buf);
4903 return rc;
4904}
4905
4906static int lpfc_req_fw_upgrade;
4907module_param(lpfc_req_fw_upgrade, int, S_IRUGO|S_IWUSR);
4908MODULE_PARM_DESC(lpfc_req_fw_upgrade, "Enable Linux generic firmware upgrade");
4909lpfc_param_show(request_firmware_upgrade)
4910
4911/**
4912 * lpfc_request_firmware_upgrade_init - Enable initial linux generic fw upgrade
4913 * @phba: lpfc_hba pointer.
4914 * @val: 0 or 1.
4915 *
4916 * Description:
4917 * Set the initial Linux generic firmware upgrade enable or disable flag.
4918 *
4919 * Returns:
4920 * zero if val saved.
4921 * -EINVAL val out of range
4922 **/
4923static int
4924lpfc_request_firmware_upgrade_init(struct lpfc_hba *phba, int val)
4925{
4926 if (val >= 0 && val <= 1) {
4927 phba->cfg_request_firmware_upgrade = val;
4928 return 0;
4929 }
4930 return -EINVAL;
4931}
4932static DEVICE_ATTR(lpfc_req_fw_upgrade, S_IRUGO | S_IWUSR,
4933 lpfc_request_firmware_upgrade_show,
4934 lpfc_request_firmware_upgrade_store);
4935
4936/**
James Smart41b194b2019-05-14 14:58:08 -07004937 * lpfc_force_rscn_store
4938 *
4939 * @dev: class device that is converted into a Scsi_host.
4940 * @attr: device attribute, not used.
4941 * @buf: unused string
4942 * @count: unused variable.
4943 *
4944 * Description:
4945 * Force the switch to send a RSCN to all other NPorts in our zone
4946 * If we are direct connect pt2pt, build the RSCN command ourself
4947 * and send to the other NPort. Not supported for private loop.
4948 *
4949 * Returns:
4950 * 0 - on success
4951 * -EIO - if command is not sent
4952 **/
4953static ssize_t
4954lpfc_force_rscn_store(struct device *dev, struct device_attribute *attr,
4955 const char *buf, size_t count)
4956{
4957 struct Scsi_Host *shost = class_to_shost(dev);
4958 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4959 int i;
4960
4961 i = lpfc_issue_els_rscn(vport, 0);
4962 if (i)
4963 return -EIO;
4964 return strlen(buf);
4965}
4966
4967/*
4968 * lpfc_force_rscn: Force an RSCN to be sent to all remote NPorts
4969 * connected to the HBA.
4970 *
4971 * Value range is any ascii value
4972 */
4973static int lpfc_force_rscn;
4974module_param(lpfc_force_rscn, int, 0644);
4975MODULE_PARM_DESC(lpfc_force_rscn,
4976 "Force an RSCN to be sent to all remote NPorts");
4977lpfc_param_show(force_rscn)
4978
4979/**
4980 * lpfc_force_rscn_init - Force an RSCN to be sent to all remote NPorts
4981 * @phba: lpfc_hba pointer.
4982 * @val: unused value.
4983 *
4984 * Returns:
4985 * zero if val saved.
4986 **/
4987static int
4988lpfc_force_rscn_init(struct lpfc_hba *phba, int val)
4989{
4990 return 0;
4991}
4992static DEVICE_ATTR_RW(lpfc_force_rscn);
4993
4994/**
James Smart173edbb2012-06-12 13:54:50 -04004995 * lpfc_fcp_imax_store
4996 *
4997 * @dev: class device that is converted into a Scsi_host.
4998 * @attr: device attribute, not used.
4999 * @buf: string with the number of fast-path FCP interrupts per second.
5000 * @count: unused variable.
5001 *
5002 * Description:
5003 * If val is in a valid range [636,651042], then set the adapter's
5004 * maximum number of fast-path FCP interrupts per second.
5005 *
5006 * Returns:
5007 * length of the buf on success if val is in range the intended mode
5008 * is supported.
5009 * -EINVAL if val out of range or intended mode is not supported.
5010 **/
5011static ssize_t
5012lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr,
5013 const char *buf, size_t count)
5014{
5015 struct Scsi_Host *shost = class_to_shost(dev);
5016 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5017 struct lpfc_hba *phba = vport->phba;
James Smart32517fc2019-01-28 11:14:33 -08005018 struct lpfc_eq_intr_info *eqi;
James Smartcb733e32019-01-28 11:14:32 -08005019 uint32_t usdelay;
James Smart173edbb2012-06-12 13:54:50 -04005020 int val = 0, i;
5021
James Smartbf8dae82012-08-03 12:36:24 -04005022 /* fcp_imax is only valid for SLI4 */
5023 if (phba->sli_rev != LPFC_SLI_REV4)
5024 return -EINVAL;
5025
James Smart173edbb2012-06-12 13:54:50 -04005026 /* Sanity check on user data */
5027 if (!isdigit(buf[0]))
5028 return -EINVAL;
5029 if (sscanf(buf, "%i", &val) != 1)
5030 return -EINVAL;
5031
James Smartbf8dae82012-08-03 12:36:24 -04005032 /*
5033 * Value range for the HBA is [5000,5000000]
5034 * The value for each EQ depends on how many EQs are configured.
James Smart895427b2017-02-12 13:52:30 -08005035 * Allow value == 0
James Smartbf8dae82012-08-03 12:36:24 -04005036 */
James Smart895427b2017-02-12 13:52:30 -08005037 if (val && (val < LPFC_MIN_IMAX || val > LPFC_MAX_IMAX))
James Smart173edbb2012-06-12 13:54:50 -04005038 return -EINVAL;
5039
James Smart32517fc2019-01-28 11:14:33 -08005040 phba->cfg_auto_imax = (val) ? 0 : 1;
5041 if (phba->cfg_fcp_imax && !val) {
5042 queue_delayed_work(phba->wq, &phba->eq_delay_work,
5043 msecs_to_jiffies(LPFC_EQ_DELAY_MSECS));
5044
5045 for_each_present_cpu(i) {
5046 eqi = per_cpu_ptr(phba->sli4_hba.eq_info, i);
5047 eqi->icnt = 0;
5048 }
5049 }
5050
James Smart173edbb2012-06-12 13:54:50 -04005051 phba->cfg_fcp_imax = (uint32_t)val;
James Smart43140ca2017-03-04 09:30:34 -08005052
James Smartcb733e32019-01-28 11:14:32 -08005053 if (phba->cfg_fcp_imax)
5054 usdelay = LPFC_SEC_TO_USEC / phba->cfg_fcp_imax;
5055 else
5056 usdelay = 0;
5057
James Smart6a828b02019-01-28 11:14:31 -08005058 for (i = 0; i < phba->cfg_irq_chann; i += LPFC_MAX_EQ_DELAY_EQID_CNT)
James Smart0cf07f842017-06-01 21:07:10 -07005059 lpfc_modify_hba_eq_delay(phba, i, LPFC_MAX_EQ_DELAY_EQID_CNT,
James Smartcb733e32019-01-28 11:14:32 -08005060 usdelay);
James Smart173edbb2012-06-12 13:54:50 -04005061
5062 return strlen(buf);
5063}
5064
5065/*
5066# lpfc_fcp_imax: The maximum number of fast-path FCP interrupts per second
James Smartbf8dae82012-08-03 12:36:24 -04005067# for the HBA.
James Smart173edbb2012-06-12 13:54:50 -04005068#
James Smartbf8dae82012-08-03 12:36:24 -04005069# Value range is [5,000 to 5,000,000]. Default value is 50,000.
James Smart173edbb2012-06-12 13:54:50 -04005070*/
James Smartbf8dae82012-08-03 12:36:24 -04005071static int lpfc_fcp_imax = LPFC_DEF_IMAX;
James Smart173edbb2012-06-12 13:54:50 -04005072module_param(lpfc_fcp_imax, int, S_IRUGO|S_IWUSR);
5073MODULE_PARM_DESC(lpfc_fcp_imax,
James Smartbf8dae82012-08-03 12:36:24 -04005074 "Set the maximum number of FCP interrupts per second per HBA");
James Smart173edbb2012-06-12 13:54:50 -04005075lpfc_param_show(fcp_imax)
5076
5077/**
5078 * lpfc_fcp_imax_init - Set the initial sr-iov virtual function enable
5079 * @phba: lpfc_hba pointer.
5080 * @val: link speed value.
5081 *
5082 * Description:
5083 * If val is in a valid range [636,651042], then initialize the adapter's
5084 * maximum number of fast-path FCP interrupts per second.
5085 *
5086 * Returns:
5087 * zero if val saved.
5088 * -EINVAL val out of range
5089 **/
5090static int
5091lpfc_fcp_imax_init(struct lpfc_hba *phba, int val)
5092{
James Smartbf8dae82012-08-03 12:36:24 -04005093 if (phba->sli_rev != LPFC_SLI_REV4) {
5094 phba->cfg_fcp_imax = 0;
5095 return 0;
5096 }
5097
James Smart895427b2017-02-12 13:52:30 -08005098 if ((val >= LPFC_MIN_IMAX && val <= LPFC_MAX_IMAX) ||
5099 (val == 0)) {
James Smart173edbb2012-06-12 13:54:50 -04005100 phba->cfg_fcp_imax = val;
5101 return 0;
5102 }
5103
5104 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07005105 "3016 lpfc_fcp_imax: %d out of range, using default\n",
5106 val);
James Smartbf8dae82012-08-03 12:36:24 -04005107 phba->cfg_fcp_imax = LPFC_DEF_IMAX;
James Smart173edbb2012-06-12 13:54:50 -04005108
5109 return 0;
5110}
5111
Joe Perchesb6b996b2017-12-19 10:15:07 -08005112static DEVICE_ATTR_RW(lpfc_fcp_imax);
James Smart173edbb2012-06-12 13:54:50 -04005113
James Smart32517fc2019-01-28 11:14:33 -08005114/**
5115 * lpfc_cq_max_proc_limit_store
5116 *
5117 * @dev: class device that is converted into a Scsi_host.
5118 * @attr: device attribute, not used.
5119 * @buf: string with the cq max processing limit of cqes
5120 * @count: unused variable.
5121 *
5122 * Description:
5123 * If val is in a valid range, then set value on each cq
5124 *
5125 * Returns:
5126 * The length of the buf: if successful
5127 * -ERANGE: if val is not in the valid range
5128 * -EINVAL: if bad value format or intended mode is not supported.
5129 **/
5130static ssize_t
5131lpfc_cq_max_proc_limit_store(struct device *dev, struct device_attribute *attr,
5132 const char *buf, size_t count)
5133{
5134 struct Scsi_Host *shost = class_to_shost(dev);
5135 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5136 struct lpfc_hba *phba = vport->phba;
5137 struct lpfc_queue *eq, *cq;
5138 unsigned long val;
5139 int i;
5140
5141 /* cq_max_proc_limit is only valid for SLI4 */
5142 if (phba->sli_rev != LPFC_SLI_REV4)
5143 return -EINVAL;
5144
5145 /* Sanity check on user data */
5146 if (!isdigit(buf[0]))
5147 return -EINVAL;
5148 if (kstrtoul(buf, 0, &val))
5149 return -EINVAL;
5150
5151 if (val < LPFC_CQ_MIN_PROC_LIMIT || val > LPFC_CQ_MAX_PROC_LIMIT)
5152 return -ERANGE;
5153
5154 phba->cfg_cq_max_proc_limit = (uint32_t)val;
5155
5156 /* set the values on the cq's */
5157 for (i = 0; i < phba->cfg_irq_chann; i++) {
James Smart657add42019-05-21 17:49:06 -07005158 /* Get the EQ corresponding to the IRQ vector */
5159 eq = phba->sli4_hba.hba_eq_hdl[i].eq;
James Smart32517fc2019-01-28 11:14:33 -08005160 if (!eq)
5161 continue;
5162
5163 list_for_each_entry(cq, &eq->child_list, list)
5164 cq->max_proc_limit = min(phba->cfg_cq_max_proc_limit,
5165 cq->entry_count);
5166 }
5167
5168 return strlen(buf);
5169}
5170
James Smart0cf07f842017-06-01 21:07:10 -07005171/*
James Smart32517fc2019-01-28 11:14:33 -08005172 * lpfc_cq_max_proc_limit: The maximum number CQE entries processed in an
5173 * itteration of CQ processing.
James Smart0cf07f842017-06-01 21:07:10 -07005174 */
James Smart32517fc2019-01-28 11:14:33 -08005175static int lpfc_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
5176module_param(lpfc_cq_max_proc_limit, int, 0644);
5177MODULE_PARM_DESC(lpfc_cq_max_proc_limit,
5178 "Set the maximum number CQEs processed in an iteration of "
5179 "CQ processing");
5180lpfc_param_show(cq_max_proc_limit)
5181
5182/*
5183 * lpfc_cq_poll_threshold: Set the threshold of CQE completions in a
5184 * single handler call which should request a polled completion rather
5185 * than re-enabling interrupts.
5186 */
5187LPFC_ATTR_RW(cq_poll_threshold, LPFC_CQ_DEF_THRESHOLD_TO_POLL,
5188 LPFC_CQ_MIN_THRESHOLD_TO_POLL,
5189 LPFC_CQ_MAX_THRESHOLD_TO_POLL,
5190 "CQE Processing Threshold to enable Polling");
5191
5192/**
5193 * lpfc_cq_max_proc_limit_init - Set the initial cq max_proc_limit
5194 * @phba: lpfc_hba pointer.
5195 * @val: entry limit
5196 *
5197 * Description:
5198 * If val is in a valid range, then initialize the adapter's maximum
5199 * value.
5200 *
5201 * Returns:
5202 * Always returns 0 for success, even if value not always set to
5203 * requested value. If value out of range or not supported, will fall
5204 * back to default.
5205 **/
5206static int
5207lpfc_cq_max_proc_limit_init(struct lpfc_hba *phba, int val)
5208{
5209 phba->cfg_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
5210
5211 if (phba->sli_rev != LPFC_SLI_REV4)
5212 return 0;
5213
5214 if (val >= LPFC_CQ_MIN_PROC_LIMIT && val <= LPFC_CQ_MAX_PROC_LIMIT) {
5215 phba->cfg_cq_max_proc_limit = val;
5216 return 0;
5217 }
5218
5219 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart5b1f5082021-04-11 18:31:25 -07005220 "0371 lpfc_cq_max_proc_limit: %d out of range, using "
5221 "default\n",
James Smart32517fc2019-01-28 11:14:33 -08005222 phba->cfg_cq_max_proc_limit);
5223
5224 return 0;
5225}
5226
5227static DEVICE_ATTR_RW(lpfc_cq_max_proc_limit);
James Smart0cf07f842017-06-01 21:07:10 -07005228
James Smart7bb03bb2013-04-17 20:19:16 -04005229/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00005230 * lpfc_fcp_cpu_map_show - Display current driver CPU affinity
James Smart7bb03bb2013-04-17 20:19:16 -04005231 * @dev: class converted to a Scsi_host structure.
5232 * @attr: device attribute, not used.
5233 * @buf: on return contains text describing the state of the link.
5234 *
5235 * Returns: size of formatted string.
5236 **/
5237static ssize_t
5238lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr,
5239 char *buf)
5240{
5241 struct Scsi_Host *shost = class_to_shost(dev);
5242 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5243 struct lpfc_hba *phba = vport->phba;
5244 struct lpfc_vector_map_info *cpup;
James Smart76fd07a2014-02-20 09:57:18 -05005245 int len = 0;
James Smart7bb03bb2013-04-17 20:19:16 -04005246
5247 if ((phba->sli_rev != LPFC_SLI_REV4) ||
5248 (phba->intr_type != MSIX))
5249 return len;
5250
5251 switch (phba->cfg_fcp_cpu_map) {
5252 case 0:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005253 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart7bb03bb2013-04-17 20:19:16 -04005254 "fcp_cpu_map: No mapping (%d)\n",
5255 phba->cfg_fcp_cpu_map);
5256 return len;
5257 case 1:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005258 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart7bb03bb2013-04-17 20:19:16 -04005259 "fcp_cpu_map: HBA centric mapping (%d): "
James Smart222e9232019-01-28 11:14:35 -08005260 "%d of %d CPUs online from %d possible CPUs\n",
5261 phba->cfg_fcp_cpu_map, num_online_cpus(),
5262 num_present_cpus(),
5263 phba->sli4_hba.num_possible_cpu);
James Smart7bb03bb2013-04-17 20:19:16 -04005264 break;
James Smart7bb03bb2013-04-17 20:19:16 -04005265 }
5266
James Smart222e9232019-01-28 11:14:35 -08005267 while (phba->sli4_hba.curr_disp_cpu <
5268 phba->sli4_hba.num_possible_cpu) {
James Smart76fd07a2014-02-20 09:57:18 -05005269 cpup = &phba->sli4_hba.cpu_map[phba->sli4_hba.curr_disp_cpu];
5270
James Smart222e9232019-01-28 11:14:35 -08005271 if (!cpu_present(phba->sli4_hba.curr_disp_cpu))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005272 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart222e9232019-01-28 11:14:35 -08005273 "CPU %02d not present\n",
5274 phba->sli4_hba.curr_disp_cpu);
James Smartdcaa2132019-11-04 16:57:06 -08005275 else if (cpup->eq == LPFC_VECTOR_MAP_EMPTY) {
James Smartb3295c22019-01-28 11:14:30 -08005276 if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005277 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005278 buf + len, PAGE_SIZE - len,
5279 "CPU %02d hdwq None "
James Smartd9954a22019-05-21 17:49:05 -07005280 "physid %d coreid %d ht %d ua %d\n",
James Smart76fd07a2014-02-20 09:57:18 -05005281 phba->sli4_hba.curr_disp_cpu,
James Smartd9954a22019-05-21 17:49:05 -07005282 cpup->phys_id, cpup->core_id,
5283 (cpup->flag & LPFC_CPU_MAP_HYPER),
5284 (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
James Smartb3295c22019-01-28 11:14:30 -08005285 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005286 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005287 buf + len, PAGE_SIZE - len,
James Smartdcaa2132019-11-04 16:57:06 -08005288 "CPU %02d EQ None hdwq %04d "
James Smartd9954a22019-05-21 17:49:05 -07005289 "physid %d coreid %d ht %d ua %d\n",
James Smartb3295c22019-01-28 11:14:30 -08005290 phba->sli4_hba.curr_disp_cpu,
James Smartdcaa2132019-11-04 16:57:06 -08005291 cpup->hdwq, cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005292 cpup->core_id,
5293 (cpup->flag & LPFC_CPU_MAP_HYPER),
5294 (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
James Smartb3295c22019-01-28 11:14:30 -08005295 } else {
5296 if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005297 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005298 buf + len, PAGE_SIZE - len,
5299 "CPU %02d hdwq None "
James Smartd9954a22019-05-21 17:49:05 -07005300 "physid %d coreid %d ht %d ua %d IRQ %d\n",
James Smart76fd07a2014-02-20 09:57:18 -05005301 phba->sli4_hba.curr_disp_cpu,
James Smartb3295c22019-01-28 11:14:30 -08005302 cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005303 cpup->core_id,
5304 (cpup->flag & LPFC_CPU_MAP_HYPER),
5305 (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
James Smartdcaa2132019-11-04 16:57:06 -08005306 lpfc_get_irq(cpup->eq));
James Smartb3295c22019-01-28 11:14:30 -08005307 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005308 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005309 buf + len, PAGE_SIZE - len,
James Smart6a828b02019-01-28 11:14:31 -08005310 "CPU %02d EQ %04d hdwq %04d "
James Smartd9954a22019-05-21 17:49:05 -07005311 "physid %d coreid %d ht %d ua %d IRQ %d\n",
James Smartb3295c22019-01-28 11:14:30 -08005312 phba->sli4_hba.curr_disp_cpu,
James Smart6a828b02019-01-28 11:14:31 -08005313 cpup->eq, cpup->hdwq, cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005314 cpup->core_id,
5315 (cpup->flag & LPFC_CPU_MAP_HYPER),
5316 (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
James Smartdcaa2132019-11-04 16:57:06 -08005317 lpfc_get_irq(cpup->eq));
James Smartb3295c22019-01-28 11:14:30 -08005318 }
James Smart7bb03bb2013-04-17 20:19:16 -04005319
James Smart76fd07a2014-02-20 09:57:18 -05005320 phba->sli4_hba.curr_disp_cpu++;
5321
5322 /* display max number of CPUs keeping some margin */
5323 if (phba->sli4_hba.curr_disp_cpu <
James Smart222e9232019-01-28 11:14:35 -08005324 phba->sli4_hba.num_possible_cpu &&
James Smart76fd07a2014-02-20 09:57:18 -05005325 (len >= (PAGE_SIZE - 64))) {
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005326 len += scnprintf(buf + len,
James Smart222e9232019-01-28 11:14:35 -08005327 PAGE_SIZE - len, "more...\n");
James Smart76fd07a2014-02-20 09:57:18 -05005328 break;
5329 }
James Smart7bb03bb2013-04-17 20:19:16 -04005330 }
James Smart76fd07a2014-02-20 09:57:18 -05005331
James Smart222e9232019-01-28 11:14:35 -08005332 if (phba->sli4_hba.curr_disp_cpu == phba->sli4_hba.num_possible_cpu)
James Smart76fd07a2014-02-20 09:57:18 -05005333 phba->sli4_hba.curr_disp_cpu = 0;
5334
James Smart7bb03bb2013-04-17 20:19:16 -04005335 return len;
5336}
5337
5338/**
5339 * lpfc_fcp_cpu_map_store - Change CPU affinity of driver vectors
5340 * @dev: class device that is converted into a Scsi_host.
5341 * @attr: device attribute, not used.
5342 * @buf: one or more lpfc_polling_flags values.
5343 * @count: not used.
5344 *
5345 * Returns:
5346 * -EINVAL - Not implemented yet.
5347 **/
5348static ssize_t
5349lpfc_fcp_cpu_map_store(struct device *dev, struct device_attribute *attr,
5350 const char *buf, size_t count)
5351{
Ye Bin37fa4292020-09-16 10:28:59 +08005352 return -EINVAL;
James Smart7bb03bb2013-04-17 20:19:16 -04005353}
5354
5355/*
5356# lpfc_fcp_cpu_map: Defines how to map CPUs to IRQ vectors
5357# for the HBA.
5358#
James Smart6a828b02019-01-28 11:14:31 -08005359# Value range is [0 to 1]. Default value is LPFC_HBA_CPU_MAP (1).
James Smart7bb03bb2013-04-17 20:19:16 -04005360# 0 - Do not affinitze IRQ vectors
5361# 1 - Affintize HBA vectors with respect to each HBA
5362# (start with CPU0 for each HBA)
James Smart6a828b02019-01-28 11:14:31 -08005363# This also defines how Hardware Queues are mapped to specific CPUs.
James Smart7bb03bb2013-04-17 20:19:16 -04005364*/
James Smart6a828b02019-01-28 11:14:31 -08005365static int lpfc_fcp_cpu_map = LPFC_HBA_CPU_MAP;
James Smart7bb03bb2013-04-17 20:19:16 -04005366module_param(lpfc_fcp_cpu_map, int, S_IRUGO|S_IWUSR);
5367MODULE_PARM_DESC(lpfc_fcp_cpu_map,
5368 "Defines how to map CPUs to IRQ vectors per HBA");
5369
5370/**
5371 * lpfc_fcp_cpu_map_init - Set the initial sr-iov virtual function enable
5372 * @phba: lpfc_hba pointer.
5373 * @val: link speed value.
5374 *
5375 * Description:
5376 * If val is in a valid range [0-2], then affinitze the adapter's
5377 * MSIX vectors.
5378 *
5379 * Returns:
5380 * zero if val saved.
5381 * -EINVAL val out of range
5382 **/
5383static int
5384lpfc_fcp_cpu_map_init(struct lpfc_hba *phba, int val)
5385{
5386 if (phba->sli_rev != LPFC_SLI_REV4) {
5387 phba->cfg_fcp_cpu_map = 0;
5388 return 0;
5389 }
5390
5391 if (val >= LPFC_MIN_CPU_MAP && val <= LPFC_MAX_CPU_MAP) {
5392 phba->cfg_fcp_cpu_map = val;
5393 return 0;
5394 }
5395
5396 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07005397 "3326 lpfc_fcp_cpu_map: %d out of range, using "
5398 "default\n", val);
James Smart6a828b02019-01-28 11:14:31 -08005399 phba->cfg_fcp_cpu_map = LPFC_HBA_CPU_MAP;
James Smart7bb03bb2013-04-17 20:19:16 -04005400
5401 return 0;
5402}
5403
Joe Perchesb6b996b2017-12-19 10:15:07 -08005404static DEVICE_ATTR_RW(lpfc_fcp_cpu_map);
James Smart7bb03bb2013-04-17 20:19:16 -04005405
James Smart0d878412009-10-02 15:16:56 -04005406/*
dea31012005-04-17 16:05:31 -05005407# lpfc_fcp_class: Determines FC class to use for the FCP protocol.
5408# Value range is [2,3]. Default value is 3.
5409*/
James Smart3de2a652007-08-02 11:09:59 -04005410LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3,
5411 "Select Fibre Channel class of service for FCP sequences");
dea31012005-04-17 16:05:31 -05005412
5413/*
5414# lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
5415# is [0,1]. Default value is 0.
5416*/
James Smart3de2a652007-08-02 11:09:59 -04005417LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1,
5418 "Use ADISC on rediscovery to authenticate FCP devices");
dea31012005-04-17 16:05:31 -05005419
5420/*
James Smart3cb01c52013-07-15 18:35:04 -04005421# lpfc_first_burst_size: First burst size to use on the NPorts
5422# that support first burst.
5423# Value range is [0,65536]. Default value is 0.
5424*/
5425LPFC_VPORT_ATTR_RW(first_burst_size, 0, 0, 65536,
5426 "First burst size for Targets that support first burst");
5427
5428/*
James Smart2d7dbc42017-02-12 13:52:35 -08005429* lpfc_nvmet_fb_size: NVME Target mode supported first burst size.
5430* When the driver is configured as an NVME target, this value is
5431* communicated to the NVME initiator in the PRLI response. It is
5432* used only when the lpfc_nvme_enable_fb and lpfc_nvmet_support
5433* parameters are set and the target is sending the PRLI RSP.
James Smart895427b2017-02-12 13:52:30 -08005434* Parameter supported on physical port only - no NPIV support.
James Smart2d7dbc42017-02-12 13:52:35 -08005435* Value range is [0,65536]. Default value is 0.
James Smart895427b2017-02-12 13:52:30 -08005436*/
James Smart2d7dbc42017-02-12 13:52:35 -08005437LPFC_ATTR_RW(nvmet_fb_size, 0, 0, 65536,
5438 "NVME Target mode first burst size in 512B increments.");
5439
5440/*
5441 * lpfc_nvme_enable_fb: Enable NVME first burst on I and T functions.
5442 * For the Initiator (I), enabling this parameter means that an NVMET
5443 * PRLI response with FBA enabled and an FB_SIZE set to a nonzero value will be
James Smartdb197bc2019-08-14 16:57:03 -07005444 * processed by the initiator for subsequent NVME FCP IO.
5445 * Currently, this feature is not supported on the NVME target
James Smart2d7dbc42017-02-12 13:52:35 -08005446 * Value range is [0,1]. Default value is 0 (disabled).
5447 */
James Smart895427b2017-02-12 13:52:30 -08005448LPFC_ATTR_RW(nvme_enable_fb, 0, 0, 1,
James Smartdb197bc2019-08-14 16:57:03 -07005449 "Enable First Burst feature for NVME Initiator.");
James Smart895427b2017-02-12 13:52:30 -08005450
5451/*
James Smart977b5a02008-09-07 11:52:04 -04005452# lpfc_max_scsicmpl_time: Use scsi command completion time to control I/O queue
5453# depth. Default value is 0. When the value of this parameter is zero the
5454# SCSI command completion time is not used for controlling I/O queue depth. When
5455# the parameter is set to a non-zero value, the I/O queue depth is controlled
5456# to limit the I/O completion time to the parameter value.
5457# The value is set in milliseconds.
5458*/
James Smarted5b1522016-10-13 15:06:11 -07005459LPFC_VPORT_ATTR(max_scsicmpl_time, 0, 0, 60000,
James Smart977b5a02008-09-07 11:52:04 -04005460 "Use command completion time to control queue depth");
James Smarted5b1522016-10-13 15:06:11 -07005461
James Smart977b5a02008-09-07 11:52:04 -04005462lpfc_vport_param_show(max_scsicmpl_time);
James Smart977b5a02008-09-07 11:52:04 -04005463static int
5464lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val)
5465{
5466 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5467 struct lpfc_nodelist *ndlp, *next_ndlp;
5468
5469 if (val == vport->cfg_max_scsicmpl_time)
5470 return 0;
5471 if ((val < 0) || (val > 60000))
5472 return -EINVAL;
5473 vport->cfg_max_scsicmpl_time = val;
5474
5475 spin_lock_irq(shost->host_lock);
5476 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
James Smart977b5a02008-09-07 11:52:04 -04005477 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
5478 continue;
James Smart7dc517d2010-07-14 15:32:10 -04005479 ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
James Smart977b5a02008-09-07 11:52:04 -04005480 }
5481 spin_unlock_irq(shost->host_lock);
5482 return 0;
5483}
5484lpfc_vport_param_store(max_scsicmpl_time);
Joe Perchesb6b996b2017-12-19 10:15:07 -08005485static DEVICE_ATTR_RW(lpfc_max_scsicmpl_time);
James Smart977b5a02008-09-07 11:52:04 -04005486
5487/*
dea31012005-04-17 16:05:31 -05005488# lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
5489# range is [0,1]. Default value is 0.
5490*/
5491LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
5492
5493/*
James Smartc4908502019-01-28 11:14:28 -08005494# lpfc_xri_rebalancing: enable or disable XRI rebalancing feature
5495# range is [0,1]. Default value is 1.
5496*/
5497LPFC_ATTR_R(xri_rebalancing, 1, 0, 1, "Enable/Disable XRI rebalancing");
5498
5499/*
James Smart895427b2017-02-12 13:52:30 -08005500 * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds
5501 * range is [0,1]. Default value is 0.
James Smart45aa3122019-01-28 11:14:29 -08005502 * For [0], FCP commands are issued to Work Queues based on upper layer
5503 * hardware queue index.
James Smart895427b2017-02-12 13:52:30 -08005504 * For [1], FCP commands are issued to a Work Queue associated with the
5505 * current CPU.
5506 *
James Smart45aa3122019-01-28 11:14:29 -08005507 * LPFC_FCP_SCHED_BY_HDWQ == 0
James Smart895427b2017-02-12 13:52:30 -08005508 * LPFC_FCP_SCHED_BY_CPU == 1
5509 *
5510 * The driver dynamically sets this to 1 (BY_CPU) if it's able to set up cpu
5511 * affinity for FCP/NVME I/Os through Work Queues associated with the current
5512 * CPU. Otherwise, the default 0 (Round Robin) scheduling of FCP/NVME I/Os
5513 * through WQs will be used.
5514 */
James Smart6a828b02019-01-28 11:14:31 -08005515LPFC_ATTR_RW(fcp_io_sched, LPFC_FCP_SCHED_BY_CPU,
James Smart45aa3122019-01-28 11:14:29 -08005516 LPFC_FCP_SCHED_BY_HDWQ,
James Smart895427b2017-02-12 13:52:30 -08005517 LPFC_FCP_SCHED_BY_CPU,
5518 "Determine scheduling algorithm for "
James Smart45aa3122019-01-28 11:14:29 -08005519 "issuing commands [0] - Hardware Queue, [1] - Current CPU");
James Smart49aa1432012-08-03 12:36:42 -04005520
5521/*
James Smart7ea92eb2018-10-23 13:41:10 -07005522 * lpfc_ns_query: Determine algrithmn for NameServer queries after RSCN
5523 * range is [0,1]. Default value is 0.
5524 * For [0], GID_FT is used for NameServer queries after RSCN (default)
5525 * For [1], GID_PT is used for NameServer queries after RSCN
5526 *
5527 */
5528LPFC_ATTR_RW(ns_query, LPFC_NS_QUERY_GID_FT,
5529 LPFC_NS_QUERY_GID_FT, LPFC_NS_QUERY_GID_PT,
5530 "Determine algorithm NameServer queries after RSCN "
5531 "[0] - GID_FT, [1] - GID_PT");
5532
5533/*
James Smarta6571c62012-10-31 14:44:42 -04005534# lpfc_fcp2_no_tgt_reset: Determine bus reset behavior
5535# range is [0,1]. Default value is 0.
5536# For [0], bus reset issues target reset to ALL devices
5537# For [1], bus reset issues target reset to non-FCP2 devices
5538*/
5539LPFC_ATTR_RW(fcp2_no_tgt_reset, 0, 0, 1, "Determine bus reset behavior for "
5540 "FCP2 devices [0] - issue tgt reset, [1] - no tgt reset");
5541
5542
5543/*
dea31012005-04-17 16:05:31 -05005544# lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
5545# cr_delay (msec) or cr_count outstanding commands. cr_delay can take
James Smart7054a602007-04-25 09:52:34 -04005546# value [0,63]. cr_count can take value [1,255]. Default value of cr_delay
dea31012005-04-17 16:05:31 -05005547# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
5548# cr_delay is set to 0.
5549*/
Jamie Wellnitz8189fd12006-02-28 19:25:35 -05005550LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an "
dea31012005-04-17 16:05:31 -05005551 "interrupt response is generated");
5552
Jamie Wellnitz8189fd12006-02-28 19:25:35 -05005553LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "
dea31012005-04-17 16:05:31 -05005554 "interrupt response is generated");
5555
5556/*
Jamie Wellnitzcf5bf972006-02-28 22:33:08 -05005557# lpfc_multi_ring_support: Determines how many rings to spread available
5558# cmd/rsp IOCB entries across.
5559# Value range is [1,2]. Default value is 1.
5560*/
5561LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
5562 "SLI rings to spread IOCB entries across");
5563
5564/*
James Smarta4bc3372006-12-02 13:34:16 -05005565# lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this
5566# identifies what rctl value to configure the additional ring for.
5567# Value range is [1,0xff]. Default value is 4 (Unsolicated Data).
5568*/
James Smart6a9c52c2009-10-02 15:16:51 -04005569LPFC_ATTR_R(multi_ring_rctl, FC_RCTL_DD_UNSOL_DATA, 1,
James Smarta4bc3372006-12-02 13:34:16 -05005570 255, "Identifies RCTL for additional ring configuration");
5571
5572/*
5573# lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this
5574# identifies what type value to configure the additional ring for.
5575# Value range is [1,0xff]. Default value is 5 (LLC/SNAP).
5576*/
James Smart6a9c52c2009-10-02 15:16:51 -04005577LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP, 1,
James Smarta4bc3372006-12-02 13:34:16 -05005578 255, "Identifies TYPE for additional ring configuration");
5579
5580/*
James Smart4258e982015-12-16 18:11:58 -05005581# lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN
5582# 0 = SmartSAN functionality disabled (default)
5583# 1 = SmartSAN functionality enabled
5584# This parameter will override the value of lpfc_fdmi_on module parameter.
5585# Value range is [0,1]. Default value is 0.
dea31012005-04-17 16:05:31 -05005586*/
James Smart4258e982015-12-16 18:11:58 -05005587LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality");
5588
5589/*
5590# lpfc_fdmi_on: Controls FDMI support.
James Smart9abd9992018-08-14 12:55:05 -07005591# 0 No FDMI support
5592# 1 Traditional FDMI support (default)
James Smart8663cbb2016-03-31 14:12:33 -07005593# Traditional FDMI support means the driver will assume FDMI-2 support;
5594# however, if that fails, it will fallback to FDMI-1.
5595# If lpfc_enable_SmartSAN is set to 1, the driver ignores lpfc_fdmi_on.
5596# If lpfc_enable_SmartSAN is set 0, the driver uses the current value of
5597# lpfc_fdmi_on.
James Smart9abd9992018-08-14 12:55:05 -07005598# Value range [0,1]. Default value is 1.
James Smart4258e982015-12-16 18:11:58 -05005599*/
James Smart9abd9992018-08-14 12:55:05 -07005600LPFC_ATTR_R(fdmi_on, 1, 0, 1, "Enable FDMI support");
dea31012005-04-17 16:05:31 -05005601
5602/*
5603# Specifies the maximum number of ELS cmds we can have outstanding (for
5604# discovery). Value range is [1,64]. Default value = 32.
5605*/
James Smart3de2a652007-08-02 11:09:59 -04005606LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
dea31012005-04-17 16:05:31 -05005607 "during discovery");
5608
5609/*
James Smartc4a7c922013-05-31 17:04:59 -04005610# lpfc_max_luns: maximum allowed LUN ID. This is the highest LUN ID that
5611# will be scanned by the SCSI midlayer when sequential scanning is
5612# used; and is also the highest LUN ID allowed when the SCSI midlayer
5613# parses REPORT_LUN responses. The lpfc driver has no LUN count or
5614# LUN ID limit, but the SCSI midlayer requires this field for the uses
5615# above. The lpfc driver limits the default value to 255 for two reasons.
5616# As it bounds the sequential scan loop, scanning for thousands of luns
5617# on a target can take minutes of wall clock time. Additionally,
5618# there are FC targets, such as JBODs, that only recognize 8-bits of
5619# LUN ID. When they receive a value greater than 8 bits, they chop off
5620# the high order bits. In other words, they see LUN IDs 0, 256, 512,
5621# and so on all as LUN ID 0. This causes the linux kernel, which sees
5622# valid responses at each of the LUN IDs, to believe there are multiple
5623# devices present, when in fact, there is only 1.
5624# A customer that is aware of their target behaviors, and the results as
5625# indicated above, is welcome to increase the lpfc_max_luns value.
5626# As mentioned, this value is not used by the lpfc driver, only the
5627# SCSI midlayer.
James Smart65a29c12006-07-06 15:50:50 -04005628# Value range is [0,65535]. Default value is 255.
5629# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
dea31012005-04-17 16:05:31 -05005630*/
Hannes Reinecke1abf6352014-06-25 15:27:38 +02005631LPFC_VPORT_ULL_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN ID");
dea31012005-04-17 16:05:31 -05005632
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05005633/*
5634# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
5635# Value range is [1,255], default value is 10.
5636*/
5637LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
5638 "Milliseconds driver will wait between polling FCP ring");
5639
James Smart4ff43242006-12-02 13:34:56 -05005640/*
James Smart0c411222013-09-06 12:22:46 -04005641# lpfc_task_mgmt_tmo: Maximum time to wait for task management commands
5642# to complete in seconds. Value range is [5,180], default value is 60.
5643*/
5644LPFC_ATTR_RW(task_mgmt_tmo, 60, 5, 180,
5645 "Maximum time to wait for task management commands to complete");
5646/*
James Smart4ff43242006-12-02 13:34:56 -05005647# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
5648# support this feature
George Kadianakis8605c462010-01-17 21:19:31 +02005649# 0 = MSI disabled
James Smart4ff43242006-12-02 13:34:56 -05005650# 1 = MSI enabled
George Kadianakis8605c462010-01-17 21:19:31 +02005651# 2 = MSI-X enabled (default)
5652# Value range is [0,2]. Default value is 2.
James Smart4ff43242006-12-02 13:34:56 -05005653*/
George Kadianakis8605c462010-01-17 21:19:31 +02005654LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
James Smartdb2378e2008-02-08 18:49:51 -05005655 "MSI-X (2), if possible");
James Smart4ff43242006-12-02 13:34:56 -05005656
James Smart13815c82008-01-11 01:52:48 -05005657/*
James Smartf358dd02017-02-12 13:52:34 -08005658 * lpfc_nvme_oas: Use the oas bit when sending NVME/NVMET IOs
James Smart895427b2017-02-12 13:52:30 -08005659 *
5660 * 0 = NVME OAS disabled
5661 * 1 = NVME OAS enabled
5662 *
5663 * Value range is [0,1]. Default value is 0.
5664 */
5665LPFC_ATTR_RW(nvme_oas, 0, 0, 1,
5666 "Use OAS bit on NVME IOs");
5667
5668/*
James Smart4e565cf2018-02-22 08:18:50 -08005669 * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
5670 *
5671 * 0 = Put NVME Command in SGL
5672 * 1 = Embed NVME Command in WQE (unless G7)
5673 * 2 = Embed NVME Command in WQE (force)
5674 *
5675 * Value range is [0,2]. Default value is 1.
5676 */
5677LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
5678 "Embed NVME Command in WQE");
5679
5680/*
James Smart77ffd342019-08-15 19:36:49 -07005681 * lpfc_fcp_mq_threshold: Set the maximum number of Hardware Queues
5682 * the driver will advertise it supports to the SCSI layer.
5683 *
5684 * 0 = Set nr_hw_queues by the number of CPUs or HW queues.
James Smartdcaa2132019-11-04 16:57:06 -08005685 * 1,256 = Manually specify nr_hw_queue value to be advertised,
James Smart77ffd342019-08-15 19:36:49 -07005686 *
James Smart06228002019-08-27 14:28:23 -07005687 * Value range is [0,256]. Default value is 8.
James Smart77ffd342019-08-15 19:36:49 -07005688 */
5689LPFC_ATTR_R(fcp_mq_threshold, LPFC_FCP_MQ_THRESHOLD_DEF,
5690 LPFC_FCP_MQ_THRESHOLD_MIN, LPFC_FCP_MQ_THRESHOLD_MAX,
5691 "Set the number of SCSI Queues advertised");
5692
5693/*
James Smart6a828b02019-01-28 11:14:31 -08005694 * lpfc_hdw_queue: Set the number of Hardware Queues the driver
James Smartcdb42be2019-01-28 11:14:21 -08005695 * will advertise it supports to the NVME and SCSI layers. This also
James Smart6a828b02019-01-28 11:14:31 -08005696 * will map to the number of CQ/WQ pairs the driver will create.
James Smart895427b2017-02-12 13:52:30 -08005697 *
5698 * The NVME Layer will try to create this many, plus 1 administrative
5699 * hardware queue. The administrative queue will always map to WQ 0
James Smart6a828b02019-01-28 11:14:31 -08005700 * A hardware IO queue maps (qidx) to a specific driver CQ/WQ.
James Smart895427b2017-02-12 13:52:30 -08005701 *
James Smartcdb42be2019-01-28 11:14:21 -08005702 * 0 = Configure the number of hdw queues to the number of active CPUs.
James Smartdcaa2132019-11-04 16:57:06 -08005703 * 1,256 = Manually specify how many hdw queues to use.
James Smart895427b2017-02-12 13:52:30 -08005704 *
James Smartdcaa2132019-11-04 16:57:06 -08005705 * Value range is [0,256]. Default value is 0.
James Smart895427b2017-02-12 13:52:30 -08005706 */
James Smartcdb42be2019-01-28 11:14:21 -08005707LPFC_ATTR_R(hdw_queue,
5708 LPFC_HBA_HDWQ_DEF,
5709 LPFC_HBA_HDWQ_MIN, LPFC_HBA_HDWQ_MAX,
5710 "Set the number of I/O Hardware Queues");
James Smart895427b2017-02-12 13:52:30 -08005711
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005712#if IS_ENABLED(CONFIG_X86)
5713/**
5714 * lpfc_cpumask_irq_mode_init - initalizes cpumask of phba based on
5715 * irq_chann_mode
5716 * @phba: Pointer to HBA context object.
5717 **/
5718static void
5719lpfc_cpumask_irq_mode_init(struct lpfc_hba *phba)
5720{
5721 unsigned int cpu, first_cpu, numa_node = NUMA_NO_NODE;
5722 const struct cpumask *sibling_mask;
5723 struct cpumask *aff_mask = &phba->sli4_hba.irq_aff_mask;
5724
5725 cpumask_clear(aff_mask);
5726
5727 if (phba->irq_chann_mode == NUMA_MODE) {
5728 /* Check if we're a NUMA architecture */
5729 numa_node = dev_to_node(&phba->pcidev->dev);
5730 if (numa_node == NUMA_NO_NODE) {
5731 phba->irq_chann_mode = NORMAL_MODE;
5732 return;
5733 }
5734 }
5735
5736 for_each_possible_cpu(cpu) {
5737 switch (phba->irq_chann_mode) {
5738 case NUMA_MODE:
5739 if (cpu_to_node(cpu) == numa_node)
5740 cpumask_set_cpu(cpu, aff_mask);
5741 break;
5742 case NHT_MODE:
5743 sibling_mask = topology_sibling_cpumask(cpu);
5744 first_cpu = cpumask_first(sibling_mask);
5745 if (first_cpu < nr_cpu_ids)
5746 cpumask_set_cpu(first_cpu, aff_mask);
5747 break;
5748 default:
5749 break;
5750 }
5751 }
5752}
5753#endif
5754
5755static void
5756lpfc_assign_default_irq_chann(struct lpfc_hba *phba)
James Smartdcaa2132019-11-04 16:57:06 -08005757{
5758#if IS_ENABLED(CONFIG_X86)
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005759 switch (boot_cpu_data.x86_vendor) {
5760 case X86_VENDOR_AMD:
5761 /* If AMD architecture, then default is NUMA_MODE */
5762 phba->irq_chann_mode = NUMA_MODE;
5763 break;
5764 case X86_VENDOR_INTEL:
5765 /* If Intel architecture, then default is no hyperthread mode */
5766 phba->irq_chann_mode = NHT_MODE;
5767 break;
5768 default:
5769 phba->irq_chann_mode = NORMAL_MODE;
5770 break;
5771 }
5772 lpfc_cpumask_irq_mode_init(phba);
James Smartdcaa2132019-11-04 16:57:06 -08005773#else
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005774 phba->irq_chann_mode = NORMAL_MODE;
James Smartdcaa2132019-11-04 16:57:06 -08005775#endif
5776}
5777
James Smart895427b2017-02-12 13:52:30 -08005778/*
James Smart6a828b02019-01-28 11:14:31 -08005779 * lpfc_irq_chann: Set the number of IRQ vectors that are available
5780 * for Hardware Queues to utilize. This also will map to the number
5781 * of EQ / MSI-X vectors the driver will create. This should never be
5782 * more than the number of Hardware Queues
5783 *
James Smartdcaa2132019-11-04 16:57:06 -08005784 * 0 = Configure number of IRQ Channels to:
5785 * if AMD architecture, number of CPUs on HBA's NUMA node
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005786 * if Intel architecture, number of physical CPUs.
James Smartdcaa2132019-11-04 16:57:06 -08005787 * otherwise, number of active CPUs.
5788 * [1,256] = Manually specify how many IRQ Channels to use.
James Smart6a828b02019-01-28 11:14:31 -08005789 *
James Smartdcaa2132019-11-04 16:57:06 -08005790 * Value range is [0,256]. Default value is [0].
James Smart6a828b02019-01-28 11:14:31 -08005791 */
James Smartdcaa2132019-11-04 16:57:06 -08005792static uint lpfc_irq_chann = LPFC_IRQ_CHANN_DEF;
5793module_param(lpfc_irq_chann, uint, 0444);
5794MODULE_PARM_DESC(lpfc_irq_chann, "Set number of interrupt vectors to allocate");
5795
5796/* lpfc_irq_chann_init - Set the hba irq_chann initial value
5797 * @phba: lpfc_hba pointer.
5798 * @val: contains the initial value
5799 *
5800 * Description:
5801 * Validates the initial value is within range and assigns it to the
5802 * adapter. If not in range, an error message is posted and the
5803 * default value is assigned.
5804 *
5805 * Returns:
5806 * zero if value is in range and is set
5807 * -EINVAL if value was out of range
5808 **/
5809static int
5810lpfc_irq_chann_init(struct lpfc_hba *phba, uint32_t val)
5811{
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005812 const struct cpumask *aff_mask;
James Smartdcaa2132019-11-04 16:57:06 -08005813
5814 if (phba->cfg_use_msi != 2) {
5815 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5816 "8532 use_msi = %u ignoring cfg_irq_numa\n",
5817 phba->cfg_use_msi);
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005818 phba->irq_chann_mode = NORMAL_MODE;
5819 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005820 return 0;
5821 }
5822
5823 /* Check if default setting was passed */
James Smartd3de0d12021-04-11 18:31:21 -07005824 if (val == LPFC_IRQ_CHANN_DEF &&
5825 phba->cfg_hdw_queue == LPFC_HBA_HDWQ_DEF &&
5826 phba->sli_rev == LPFC_SLI_REV4)
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005827 lpfc_assign_default_irq_chann(phba);
James Smartdcaa2132019-11-04 16:57:06 -08005828
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005829 if (phba->irq_chann_mode != NORMAL_MODE) {
5830 aff_mask = &phba->sli4_hba.irq_aff_mask;
James Smartdcaa2132019-11-04 16:57:06 -08005831
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005832 if (cpumask_empty(aff_mask)) {
James Smartdcaa2132019-11-04 16:57:06 -08005833 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005834 "8533 Could not identify CPUS for "
5835 "mode %d, ignoring\n",
5836 phba->irq_chann_mode);
5837 phba->irq_chann_mode = NORMAL_MODE;
5838 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005839 } else {
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005840 phba->cfg_irq_chann = cpumask_weight(aff_mask);
5841
5842 /* If no hyperthread mode, then set hdwq count to
5843 * aff_mask weight as well
5844 */
5845 if (phba->irq_chann_mode == NHT_MODE)
5846 phba->cfg_hdw_queue = phba->cfg_irq_chann;
5847
James Smartdcaa2132019-11-04 16:57:06 -08005848 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5849 "8543 lpfc_irq_chann set to %u "
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005850 "(mode: %d)\n", phba->cfg_irq_chann,
5851 phba->irq_chann_mode);
James Smartdcaa2132019-11-04 16:57:06 -08005852 }
5853 } else {
5854 if (val > LPFC_IRQ_CHANN_MAX) {
5855 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5856 "8545 lpfc_irq_chann attribute cannot "
5857 "be set to %u, allowed range is "
5858 "[%u,%u]\n",
5859 val,
5860 LPFC_IRQ_CHANN_MIN,
5861 LPFC_IRQ_CHANN_MAX);
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005862 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005863 return -EINVAL;
5864 }
James Smartd3de0d12021-04-11 18:31:21 -07005865 if (phba->sli_rev == LPFC_SLI_REV4) {
5866 phba->cfg_irq_chann = val;
5867 } else {
5868 phba->cfg_irq_chann = 2;
5869 phba->cfg_hdw_queue = 1;
5870 }
James Smartdcaa2132019-11-04 16:57:06 -08005871 }
5872
5873 return 0;
5874}
5875
5876/**
5877 * lpfc_irq_chann_show - Display value of irq_chann
5878 * @dev: class converted to a Scsi_host structure.
5879 * @attr: device attribute, not used.
5880 * @buf: on return contains a string with the list sizes
5881 *
5882 * Returns: size of formatted string.
5883 **/
5884static ssize_t
5885lpfc_irq_chann_show(struct device *dev, struct device_attribute *attr,
5886 char *buf)
5887{
5888 struct Scsi_Host *shost = class_to_shost(dev);
5889 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5890 struct lpfc_hba *phba = vport->phba;
5891
5892 return scnprintf(buf, PAGE_SIZE, "%u\n", phba->cfg_irq_chann);
5893}
5894
5895static DEVICE_ATTR_RO(lpfc_irq_chann);
James Smart6a828b02019-01-28 11:14:31 -08005896
5897/*
James Smart13815c82008-01-11 01:52:48 -05005898# lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware.
5899# 0 = HBA resets disabled
5900# 1 = HBA resets enabled (default)
James Smart50212672018-12-13 15:17:57 -08005901# 2 = HBA reset via PCI bus reset enabled
5902# Value range is [0,2]. Default value is 1.
James Smart13815c82008-01-11 01:52:48 -05005903*/
James Smart50212672018-12-13 15:17:57 -08005904LPFC_ATTR_RW(enable_hba_reset, 1, 0, 2, "Enable HBA resets from the driver.");
James Smartc3f28af2006-08-18 17:47:18 -04005905
James Smart13815c82008-01-11 01:52:48 -05005906/*
James Smarteb7a3392010-11-20 23:12:02 -05005907# lpfc_enable_hba_heartbeat: Disable HBA heartbeat timer..
James Smart13815c82008-01-11 01:52:48 -05005908# 0 = HBA Heartbeat disabled
5909# 1 = HBA Heartbeat enabled (default)
5910# Value range is [0,1]. Default value is 1.
5911*/
James Smarteb7a3392010-11-20 23:12:02 -05005912LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat.");
James Smart92d7f7b2007-06-17 19:56:38 -05005913
James Smart83108bd2008-01-11 01:53:09 -05005914/*
James Smart1ba981f2014-02-20 09:56:45 -05005915# lpfc_EnableXLane: Enable Express Lane Feature
5916# 0x0 Express Lane Feature disabled
5917# 0x1 Express Lane Feature enabled
5918# Value range is [0,1]. Default value is 0.
5919*/
5920LPFC_ATTR_R(EnableXLane, 0, 0, 1, "Enable Express Lane Feature.");
5921
5922/*
5923# lpfc_XLanePriority: Define CS_CTL priority for Express Lane Feature
5924# 0x0 - 0x7f = CS_CTL field in FC header (high 7 bits)
5925# Value range is [0x0,0x7f]. Default value is 0
5926*/
James Smart28d7f3d2014-05-21 08:05:28 -04005927LPFC_ATTR_RW(XLanePriority, 0, 0x0, 0x7f, "CS_CTL for Express Lane Feature.");
James Smart1ba981f2014-02-20 09:56:45 -05005928
5929/*
James Smart81301a92008-12-04 22:39:46 -05005930# lpfc_enable_bg: Enable BlockGuard (Emulex's Implementation of T10-DIF)
5931# 0 = BlockGuard disabled (default)
5932# 1 = BlockGuard enabled
5933# Value range is [0,1]. Default value is 0.
5934*/
5935LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
5936
James Smart6fb120a2009-05-22 14:52:59 -04005937/*
James Smart3bfab8a2021-04-11 18:31:23 -07005938# lpfc_prot_mask:
James Smart81301a92008-12-04 22:39:46 -05005939# - Bit mask of host protection capabilities used to register with the
5940# SCSI mid-layer
5941# - Only meaningful if BG is turned on (lpfc_enable_bg=1).
5942# - Allows you to ultimately specify which profiles to use
5943# - Default will result in registering capabilities for all profiles.
James Smart005ffa72012-09-29 11:29:17 -04005944# - SHOST_DIF_TYPE1_PROTECTION 1
5945# HBA supports T10 DIF Type 1: HBA to Target Type 1 Protection
5946# - SHOST_DIX_TYPE0_PROTECTION 8
5947# HBA supports DIX Type 0: Host to HBA protection only
5948# - SHOST_DIX_TYPE1_PROTECTION 16
5949# HBA supports DIX Type 1: Host to HBA Type 1 protection
James Smart81301a92008-12-04 22:39:46 -05005950#
5951*/
James Smartb3b98b72016-10-13 15:06:06 -07005952LPFC_ATTR(prot_mask,
5953 (SHOST_DIF_TYPE1_PROTECTION |
5954 SHOST_DIX_TYPE0_PROTECTION |
5955 SHOST_DIX_TYPE1_PROTECTION),
5956 0,
5957 (SHOST_DIF_TYPE1_PROTECTION |
5958 SHOST_DIX_TYPE0_PROTECTION |
5959 SHOST_DIX_TYPE1_PROTECTION),
5960 "T10-DIF host protection capabilities mask");
James Smart81301a92008-12-04 22:39:46 -05005961
5962/*
James Smart3bfab8a2021-04-11 18:31:23 -07005963# lpfc_prot_guard:
James Smart81301a92008-12-04 22:39:46 -05005964# - Bit mask of protection guard types to register with the SCSI mid-layer
James Smart005ffa72012-09-29 11:29:17 -04005965# - Guard types are currently either 1) T10-DIF CRC 2) IP checksum
James Smart81301a92008-12-04 22:39:46 -05005966# - Allows you to ultimately specify which profiles to use
5967# - Default will result in registering capabilities for all guard types
5968#
5969*/
James Smartb3b98b72016-10-13 15:06:06 -07005970LPFC_ATTR(prot_guard,
5971 SHOST_DIX_GUARD_IP, SHOST_DIX_GUARD_CRC, SHOST_DIX_GUARD_IP,
5972 "T10-DIF host protection guard type");
James Smart81301a92008-12-04 22:39:46 -05005973
James Smart92494142011-02-16 12:39:44 -05005974/*
5975 * Delay initial NPort discovery when Clean Address bit is cleared in
5976 * FLOGI/FDISC accept and FCID/Fabric name/Fabric portname is changed.
5977 * This parameter can have value 0 or 1.
5978 * When this parameter is set to 0, no delay is added to the initial
5979 * discovery.
5980 * When this parameter is set to non-zero value, initial Nport discovery is
5981 * delayed by ra_tov seconds when Clean Address bit is cleared in FLOGI/FDISC
5982 * accept and FCID/Fabric name/Fabric portname is changed.
5983 * Driver always delay Nport discovery for subsequent FLOGI/FDISC completion
5984 * when Clean Address bit is cleared in FLOGI/FDISC
5985 * accept and FCID/Fabric name/Fabric portname is changed.
5986 * Default value is 0.
5987 */
James Smart8eb8b962016-07-06 12:36:08 -07005988LPFC_ATTR(delay_discovery, 0, 0, 1,
5989 "Delay NPort discovery when Clean Address bit is cleared.");
James Smart81301a92008-12-04 22:39:46 -05005990
5991/*
James Smart3621a712009-04-06 18:47:14 -04005992 * lpfc_sg_seg_cnt - Initial Maximum DMA Segment Count
James Smart5b9e70b2018-09-10 10:30:42 -07005993 * This value can be set to values between 64 and 4096. The default value
5994 * is 64, but may be increased to allow for larger Max I/O sizes. The scsi
5995 * and nvme layers will allow I/O sizes up to (MAX_SEG_COUNT * SEG_SIZE).
James Smart96f70772013-04-17 20:16:15 -04005996 * Because of the additional overhead involved in setting up T10-DIF,
5997 * this parameter will be limited to 128 if BlockGuard is enabled under SLI4
5998 * and will be limited to 512 if BlockGuard is enabled under SLI3.
James Smart83108bd2008-01-11 01:53:09 -05005999 */
James Smart5b9e70b2018-09-10 10:30:42 -07006000static uint lpfc_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
6001module_param(lpfc_sg_seg_cnt, uint, 0444);
6002MODULE_PARM_DESC(lpfc_sg_seg_cnt, "Max Scatter Gather Segment Count");
6003
6004/**
6005 * lpfc_sg_seg_cnt_show - Display the scatter/gather list sizes
6006 * configured for the adapter
6007 * @dev: class converted to a Scsi_host structure.
6008 * @attr: device attribute, not used.
6009 * @buf: on return contains a string with the list sizes
6010 *
6011 * Returns: size of formatted string.
6012 **/
6013static ssize_t
6014lpfc_sg_seg_cnt_show(struct device *dev, struct device_attribute *attr,
6015 char *buf)
6016{
6017 struct Scsi_Host *shost = class_to_shost(dev);
6018 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
6019 struct lpfc_hba *phba = vport->phba;
6020 int len;
6021
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07006022 len = scnprintf(buf, PAGE_SIZE, "SGL sz: %d total SGEs: %d\n",
James Smart5b9e70b2018-09-10 10:30:42 -07006023 phba->cfg_sg_dma_buf_size, phba->cfg_total_seg_cnt);
6024
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07006025 len += scnprintf(buf + len, PAGE_SIZE, "Cfg: %d SCSI: %d NVME: %d\n",
James Smart5b9e70b2018-09-10 10:30:42 -07006026 phba->cfg_sg_seg_cnt, phba->cfg_scsi_seg_cnt,
6027 phba->cfg_nvme_seg_cnt);
6028 return len;
6029}
6030
6031static DEVICE_ATTR_RO(lpfc_sg_seg_cnt);
6032
6033/**
6034 * lpfc_sg_seg_cnt_init - Set the hba sg_seg_cnt initial value
6035 * @phba: lpfc_hba pointer.
6036 * @val: contains the initial value
6037 *
6038 * Description:
6039 * Validates the initial value is within range and assigns it to the
6040 * adapter. If not in range, an error message is posted and the
6041 * default value is assigned.
6042 *
6043 * Returns:
6044 * zero if value is in range and is set
6045 * -EINVAL if value was out of range
6046 **/
6047static int
6048lpfc_sg_seg_cnt_init(struct lpfc_hba *phba, int val)
6049{
6050 if (val >= LPFC_MIN_SG_SEG_CNT && val <= LPFC_MAX_SG_SEG_CNT) {
6051 phba->cfg_sg_seg_cnt = val;
6052 return 0;
6053 }
6054 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart5b1f5082021-04-11 18:31:25 -07006055 "0409 lpfc_sg_seg_cnt attribute cannot be set to %d, "
6056 "allowed range is [%d, %d]\n",
James Smart5b9e70b2018-09-10 10:30:42 -07006057 val, LPFC_MIN_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT);
6058 phba->cfg_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
6059 return -EINVAL;
6060}
James Smart83108bd2008-01-11 01:53:09 -05006061
James Smart96f70772013-04-17 20:16:15 -04006062/*
James Smart7bdedb32016-07-06 12:36:00 -07006063 * lpfc_enable_mds_diags: Enable MDS Diagnostics
6064 * 0 = MDS Diagnostics disabled (default)
6065 * 1 = MDS Diagnostics enabled
6066 * Value range is [0,1]. Default value is 0.
6067 */
James Smarte62245d2019-08-14 16:57:08 -07006068LPFC_ATTR_RW(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");
James Smart7bdedb32016-07-06 12:36:00 -07006069
James Smart44fd7fe2017-08-23 16:55:47 -07006070/*
James Smartd2cc9bc2018-09-10 10:30:50 -07006071 * lpfc_ras_fwlog_buffsize: Firmware logging host buffer size
6072 * 0 = Disable firmware logging (default)
6073 * [1-4] = Multiple of 1/4th Mb of host memory for FW logging
6074 * Value range [0..4]. Default value is 0
6075 */
James Smart95bfc6d2019-10-18 14:18:27 -07006076LPFC_ATTR(ras_fwlog_buffsize, 0, 0, 4, "Host memory for FW logging");
6077lpfc_param_show(ras_fwlog_buffsize);
6078
6079static ssize_t
6080lpfc_ras_fwlog_buffsize_set(struct lpfc_hba *phba, uint val)
6081{
6082 int ret = 0;
6083 enum ras_state state;
6084
6085 if (!lpfc_rangecheck(val, 0, 4))
6086 return -EINVAL;
6087
6088 if (phba->cfg_ras_fwlog_buffsize == val)
6089 return 0;
6090
James Smartdda5bdf2019-11-04 16:57:02 -08006091 if (phba->cfg_ras_fwlog_func != PCI_FUNC(phba->pcidev->devfn))
James Smart95bfc6d2019-10-18 14:18:27 -07006092 return -EINVAL;
6093
6094 spin_lock_irq(&phba->hbalock);
6095 state = phba->ras_fwlog.state;
6096 spin_unlock_irq(&phba->hbalock);
6097
6098 if (state == REG_INPROGRESS) {
6099 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "6147 RAS Logging "
6100 "registration is in progress\n");
6101 return -EBUSY;
6102 }
6103
6104 /* For disable logging: stop the logs and free the DMA.
6105 * For ras_fwlog_buffsize size change we still need to free and
6106 * reallocate the DMA in lpfc_sli4_ras_fwlog_init.
6107 */
6108 phba->cfg_ras_fwlog_buffsize = val;
6109 if (state == ACTIVE) {
6110 lpfc_ras_stop_fwlog(phba);
6111 lpfc_sli4_ras_dma_free(phba);
6112 }
6113
6114 lpfc_sli4_ras_init(phba);
6115 if (phba->ras_fwlog.ras_enabled)
6116 ret = lpfc_sli4_ras_fwlog_init(phba, phba->cfg_ras_fwlog_level,
6117 LPFC_RAS_ENABLE_LOGGING);
6118 return ret;
6119}
6120
6121lpfc_param_store(ras_fwlog_buffsize);
6122static DEVICE_ATTR_RW(lpfc_ras_fwlog_buffsize);
James Smartd2cc9bc2018-09-10 10:30:50 -07006123
6124/*
6125 * lpfc_ras_fwlog_level: Firmware logging verbosity level
6126 * Valid only if firmware logging is enabled
6127 * 0(Least Verbosity) 4 (most verbosity)
6128 * Value range is [0..4]. Default value is 0
6129 */
6130LPFC_ATTR_RW(ras_fwlog_level, 0, 0, 4, "Firmware Logging Level");
6131
6132/*
6133 * lpfc_ras_fwlog_func: Firmware logging enabled on function number
6134 * Default function which has RAS support : 0
6135 * Value Range is [0..7].
6136 * FW logging is a global action and enablement is via a specific
6137 * port.
6138 */
6139LPFC_ATTR_RW(ras_fwlog_func, 0, 0, 7, "Firmware Logging Enabled on Function");
6140
6141/*
James Smart44fd7fe2017-08-23 16:55:47 -07006142 * lpfc_enable_bbcr: Enable BB Credit Recovery
6143 * 0 = BB Credit Recovery disabled
6144 * 1 = BB Credit Recovery enabled (default)
6145 * Value range is [0,1]. Default value is 1.
6146 */
6147LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
6148
James Smart1351e692018-02-22 08:18:43 -08006149/*
6150 * lpfc_enable_dpp: Enable DPP on G7
6151 * 0 = DPP on G7 disabled
6152 * 1 = DPP on G7 enabled (default)
6153 * Value range is [0,1]. Default value is 1.
6154 */
6155LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
6156
James Smart8aaa7bc2020-10-20 13:27:17 -07006157/*
6158 * lpfc_enable_mi: Enable FDMI MIB
6159 * 0 = disabled
6160 * 1 = enabled (default)
6161 * Value range is [0,1].
6162 */
6163LPFC_ATTR_R(enable_mi, 1, 0, 1, "Enable MI");
6164
Gaurav Srivastava7ba22722021-06-08 10:05:48 +05306165/*
6166 * lpfc_max_vmid: Maximum number of VMs to be tagged. This is valid only if
6167 * either vmid_app_header or vmid_priority_tagging is enabled.
6168 * 4 - 255 = vmid support enabled for 4-255 VMs
6169 * Value range is [4,255].
6170 */
6171LPFC_ATTR_RW(max_vmid, LPFC_MIN_VMID, LPFC_MIN_VMID, LPFC_MAX_VMID,
6172 "Maximum number of VMs supported");
6173
6174/*
6175 * lpfc_vmid_inactivity_timeout: Inactivity timeout duration in hours
6176 * 0 = Timeout is disabled
6177 * Value range is [0,24].
6178 */
6179LPFC_ATTR_RW(vmid_inactivity_timeout, 4, 0, 24,
6180 "Inactivity timeout in hours");
6181
6182/*
6183 * lpfc_vmid_app_header: Enable App Header VMID support
6184 * 0 = Support is disabled (default)
6185 * 1 = Support is enabled
6186 * Value range is [0,1].
6187 */
6188LPFC_ATTR_RW(vmid_app_header, LPFC_VMID_APP_HEADER_DISABLE,
6189 LPFC_VMID_APP_HEADER_DISABLE, LPFC_VMID_APP_HEADER_ENABLE,
6190 "Enable App Header VMID support");
6191
6192/*
6193 * lpfc_vmid_priority_tagging: Enable Priority Tagging VMID support
6194 * 0 = Support is disabled (default)
6195 * 1 = Allow supported targets only
6196 * 2 = Allow all targets
6197 * Value range is [0,2].
6198 */
6199LPFC_ATTR_RW(vmid_priority_tagging, LPFC_VMID_PRIO_TAG_DISABLE,
6200 LPFC_VMID_PRIO_TAG_DISABLE,
6201 LPFC_VMID_PRIO_TAG_ALL_TARGETS,
6202 "Enable Priority Tagging VMID support");
6203
Tony Jonesee959b02008-02-22 00:13:36 +01006204struct device_attribute *lpfc_hba_attrs[] = {
James Smart895427b2017-02-12 13:52:30 -08006205 &dev_attr_nvme_info,
James Smart4c47efc2019-01-28 11:14:25 -08006206 &dev_attr_scsi_stat,
James Smart81301a92008-12-04 22:39:46 -05006207 &dev_attr_bg_info,
6208 &dev_attr_bg_guard_err,
6209 &dev_attr_bg_apptag_err,
6210 &dev_attr_bg_reftag_err,
Tony Jonesee959b02008-02-22 00:13:36 +01006211 &dev_attr_info,
6212 &dev_attr_serialnum,
6213 &dev_attr_modeldesc,
6214 &dev_attr_modelname,
6215 &dev_attr_programtype,
6216 &dev_attr_portnum,
6217 &dev_attr_fwrev,
6218 &dev_attr_hdw,
6219 &dev_attr_option_rom_version,
Hannes Reineckebbd1ae42008-03-18 14:32:28 +01006220 &dev_attr_link_state,
Tony Jonesee959b02008-02-22 00:13:36 +01006221 &dev_attr_num_discovered_ports,
James Smart84774a42008-08-24 21:50:06 -04006222 &dev_attr_menlo_mgmt_mode,
Tony Jonesee959b02008-02-22 00:13:36 +01006223 &dev_attr_lpfc_drvr_version,
James Smart45ed1192009-10-02 15:17:02 -04006224 &dev_attr_lpfc_enable_fip,
Tony Jonesee959b02008-02-22 00:13:36 +01006225 &dev_attr_lpfc_temp_sensor,
6226 &dev_attr_lpfc_log_verbose,
6227 &dev_attr_lpfc_lun_queue_depth,
James Smart7dc517d2010-07-14 15:32:10 -04006228 &dev_attr_lpfc_tgt_queue_depth,
Tony Jonesee959b02008-02-22 00:13:36 +01006229 &dev_attr_lpfc_hba_queue_depth,
6230 &dev_attr_lpfc_peer_port_login,
6231 &dev_attr_lpfc_nodev_tmo,
6232 &dev_attr_lpfc_devloss_tmo,
James Smart895427b2017-02-12 13:52:30 -08006233 &dev_attr_lpfc_enable_fc4_type,
Tony Jonesee959b02008-02-22 00:13:36 +01006234 &dev_attr_lpfc_fcp_class,
6235 &dev_attr_lpfc_use_adisc,
James Smart3cb01c52013-07-15 18:35:04 -04006236 &dev_attr_lpfc_first_burst_size,
Tony Jonesee959b02008-02-22 00:13:36 +01006237 &dev_attr_lpfc_ack0,
James Smartc4908502019-01-28 11:14:28 -08006238 &dev_attr_lpfc_xri_rebalancing,
Tony Jonesee959b02008-02-22 00:13:36 +01006239 &dev_attr_lpfc_topology,
6240 &dev_attr_lpfc_scan_down,
6241 &dev_attr_lpfc_link_speed,
James Smart49aa1432012-08-03 12:36:42 -04006242 &dev_attr_lpfc_fcp_io_sched,
James Smart7ea92eb2018-10-23 13:41:10 -07006243 &dev_attr_lpfc_ns_query,
James Smarta6571c62012-10-31 14:44:42 -04006244 &dev_attr_lpfc_fcp2_no_tgt_reset,
Tony Jonesee959b02008-02-22 00:13:36 +01006245 &dev_attr_lpfc_cr_delay,
6246 &dev_attr_lpfc_cr_count,
6247 &dev_attr_lpfc_multi_ring_support,
6248 &dev_attr_lpfc_multi_ring_rctl,
6249 &dev_attr_lpfc_multi_ring_type,
6250 &dev_attr_lpfc_fdmi_on,
James Smart4258e982015-12-16 18:11:58 -05006251 &dev_attr_lpfc_enable_SmartSAN,
Tony Jonesee959b02008-02-22 00:13:36 +01006252 &dev_attr_lpfc_max_luns,
6253 &dev_attr_lpfc_enable_npiv,
James Smart7d791df2011-07-22 18:37:52 -04006254 &dev_attr_lpfc_fcf_failover_policy,
James Smart19ca7602010-11-20 23:11:55 -05006255 &dev_attr_lpfc_enable_rrq,
James Smart3e49af92021-05-14 12:55:57 -07006256 &dev_attr_lpfc_fcp_wait_abts_rsp,
Tony Jonesee959b02008-02-22 00:13:36 +01006257 &dev_attr_nport_evt_cnt,
6258 &dev_attr_board_mode,
6259 &dev_attr_max_vpi,
6260 &dev_attr_used_vpi,
6261 &dev_attr_max_rpi,
6262 &dev_attr_used_rpi,
6263 &dev_attr_max_xri,
6264 &dev_attr_used_xri,
6265 &dev_attr_npiv_info,
6266 &dev_attr_issue_reset,
6267 &dev_attr_lpfc_poll,
6268 &dev_attr_lpfc_poll_tmo,
James Smart0c411222013-09-06 12:22:46 -04006269 &dev_attr_lpfc_task_mgmt_tmo,
Tony Jonesee959b02008-02-22 00:13:36 +01006270 &dev_attr_lpfc_use_msi,
James Smart895427b2017-02-12 13:52:30 -08006271 &dev_attr_lpfc_nvme_oas,
James Smart4e565cf2018-02-22 08:18:50 -08006272 &dev_attr_lpfc_nvme_embed_cmd,
James Smartda0436e2009-05-22 14:51:39 -04006273 &dev_attr_lpfc_fcp_imax,
James Smart41b194b2019-05-14 14:58:08 -07006274 &dev_attr_lpfc_force_rscn,
James Smart32517fc2019-01-28 11:14:33 -08006275 &dev_attr_lpfc_cq_poll_threshold,
6276 &dev_attr_lpfc_cq_max_proc_limit,
James Smart7bb03bb2013-04-17 20:19:16 -04006277 &dev_attr_lpfc_fcp_cpu_map,
James Smart77ffd342019-08-15 19:36:49 -07006278 &dev_attr_lpfc_fcp_mq_threshold,
James Smartcdb42be2019-01-28 11:14:21 -08006279 &dev_attr_lpfc_hdw_queue,
James Smart6a828b02019-01-28 11:14:31 -08006280 &dev_attr_lpfc_irq_chann,
James Smartf358dd02017-02-12 13:52:34 -08006281 &dev_attr_lpfc_suppress_rsp,
James Smart2d7dbc42017-02-12 13:52:35 -08006282 &dev_attr_lpfc_nvmet_mrq,
James Smart2448e482018-04-09 14:24:24 -07006283 &dev_attr_lpfc_nvmet_mrq_post,
James Smart895427b2017-02-12 13:52:30 -08006284 &dev_attr_lpfc_nvme_enable_fb,
James Smart2d7dbc42017-02-12 13:52:35 -08006285 &dev_attr_lpfc_nvmet_fb_size,
James Smart81301a92008-12-04 22:39:46 -05006286 &dev_attr_lpfc_enable_bg,
James Smart352e5fd2016-12-30 06:57:47 -08006287 &dev_attr_lpfc_soft_wwnn,
6288 &dev_attr_lpfc_soft_wwpn,
6289 &dev_attr_lpfc_soft_wwn_enable,
Tony Jonesee959b02008-02-22 00:13:36 +01006290 &dev_attr_lpfc_enable_hba_reset,
6291 &dev_attr_lpfc_enable_hba_heartbeat,
James Smart1ba981f2014-02-20 09:56:45 -05006292 &dev_attr_lpfc_EnableXLane,
6293 &dev_attr_lpfc_XLanePriority,
6294 &dev_attr_lpfc_xlane_lun,
6295 &dev_attr_lpfc_xlane_tgt,
6296 &dev_attr_lpfc_xlane_vpt,
6297 &dev_attr_lpfc_xlane_lun_state,
6298 &dev_attr_lpfc_xlane_lun_status,
James Smartc92c8412016-07-06 12:36:05 -07006299 &dev_attr_lpfc_xlane_priority,
Tony Jonesee959b02008-02-22 00:13:36 +01006300 &dev_attr_lpfc_sg_seg_cnt,
James Smart977b5a02008-09-07 11:52:04 -04006301 &dev_attr_lpfc_max_scsicmpl_time,
James Smartea2151b2008-09-07 11:52:10 -04006302 &dev_attr_lpfc_stat_data_ctrl,
James Smart0d878412009-10-02 15:16:56 -04006303 &dev_attr_lpfc_aer_support,
6304 &dev_attr_lpfc_aer_state_cleanup,
James Smart912e3ac2011-05-24 11:42:11 -04006305 &dev_attr_lpfc_sriov_nr_virtfn,
James Smartc71ab862012-10-31 14:44:33 -04006306 &dev_attr_lpfc_req_fw_upgrade,
James Smart84d1b002010-02-12 14:42:33 -05006307 &dev_attr_lpfc_suppress_link_up,
James Smart2a9bf3d2010-06-07 15:24:45 -04006308 &dev_attr_iocb_hw,
James Smart83c6cb12019-10-18 14:18:30 -07006309 &dev_attr_pls,
6310 &dev_attr_pt,
James Smart2a9bf3d2010-06-07 15:24:45 -04006311 &dev_attr_txq_hw,
6312 &dev_attr_txcmplq_hw,
James Smart912e3ac2011-05-24 11:42:11 -04006313 &dev_attr_lpfc_sriov_hw_max_virtfn,
James Smart026abb82011-12-13 13:20:45 -05006314 &dev_attr_protocol,
James Smart1ba981f2014-02-20 09:56:45 -05006315 &dev_attr_lpfc_xlane_supported,
James Smart7bdedb32016-07-06 12:36:00 -07006316 &dev_attr_lpfc_enable_mds_diags,
James Smartd2cc9bc2018-09-10 10:30:50 -07006317 &dev_attr_lpfc_ras_fwlog_buffsize,
6318 &dev_attr_lpfc_ras_fwlog_level,
6319 &dev_attr_lpfc_ras_fwlog_func,
James Smart44fd7fe2017-08-23 16:55:47 -07006320 &dev_attr_lpfc_enable_bbcr,
James Smart1351e692018-02-22 08:18:43 -08006321 &dev_attr_lpfc_enable_dpp,
James Smart8aaa7bc2020-10-20 13:27:17 -07006322 &dev_attr_lpfc_enable_mi,
Gaurav Srivastava7ba22722021-06-08 10:05:48 +05306323 &dev_attr_lpfc_max_vmid,
6324 &dev_attr_lpfc_vmid_inactivity_timeout,
6325 &dev_attr_lpfc_vmid_app_header,
6326 &dev_attr_lpfc_vmid_priority_tagging,
dea31012005-04-17 16:05:31 -05006327 NULL,
6328};
6329
Tony Jonesee959b02008-02-22 00:13:36 +01006330struct device_attribute *lpfc_vport_attrs[] = {
6331 &dev_attr_info,
Hannes Reineckebbd1ae42008-03-18 14:32:28 +01006332 &dev_attr_link_state,
Tony Jonesee959b02008-02-22 00:13:36 +01006333 &dev_attr_num_discovered_ports,
6334 &dev_attr_lpfc_drvr_version,
6335 &dev_attr_lpfc_log_verbose,
6336 &dev_attr_lpfc_lun_queue_depth,
James Smart7dc517d2010-07-14 15:32:10 -04006337 &dev_attr_lpfc_tgt_queue_depth,
Tony Jonesee959b02008-02-22 00:13:36 +01006338 &dev_attr_lpfc_nodev_tmo,
6339 &dev_attr_lpfc_devloss_tmo,
6340 &dev_attr_lpfc_hba_queue_depth,
6341 &dev_attr_lpfc_peer_port_login,
6342 &dev_attr_lpfc_restrict_login,
6343 &dev_attr_lpfc_fcp_class,
6344 &dev_attr_lpfc_use_adisc,
James Smart3cb01c52013-07-15 18:35:04 -04006345 &dev_attr_lpfc_first_burst_size,
Tony Jonesee959b02008-02-22 00:13:36 +01006346 &dev_attr_lpfc_max_luns,
6347 &dev_attr_nport_evt_cnt,
6348 &dev_attr_npiv_info,
6349 &dev_attr_lpfc_enable_da_id,
James Smartea2151b2008-09-07 11:52:10 -04006350 &dev_attr_lpfc_max_scsicmpl_time,
6351 &dev_attr_lpfc_stat_data_ctrl,
James Smart21e9a0a2009-05-22 14:53:21 -04006352 &dev_attr_lpfc_static_vport,
James Smart3de2a652007-08-02 11:09:59 -04006353 NULL,
6354};
6355
James Smarte59058c2008-08-24 21:49:00 -04006356/**
James Smart3621a712009-04-06 18:47:14 -04006357 * sysfs_ctlreg_write - Write method for writing to ctlreg
Chris Wright2c3c8be2010-05-12 18:28:57 -07006358 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006359 * @kobj: kernel kobject that contains the kernel class device.
6360 * @bin_attr: kernel attributes passed to us.
6361 * @buf: contains the data to be written to the adapter IOREG space.
6362 * @off: offset into buffer to beginning of data.
6363 * @count: bytes to transfer.
6364 *
6365 * Description:
6366 * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
6367 * Uses the adapter io control registers to send buf contents to the adapter.
6368 *
6369 * Returns:
6370 * -ERANGE off and count combo out of range
6371 * -EINVAL off, count or buff address invalid
6372 * -EPERM adapter is offline
6373 * value of count, buf contents written
6374 **/
dea31012005-04-17 16:05:31 -05006375static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006376sysfs_ctlreg_write(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;
Tony Jonesee959b02008-02-22 00:13:36 +01006381 struct device *dev = container_of(kobj, struct device, kobj);
6382 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05006383 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6384 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006385
James Smartf1126682009-06-10 17:22:44 -04006386 if (phba->sli_rev >= LPFC_SLI_REV4)
6387 return -EPERM;
6388
dea31012005-04-17 16:05:31 -05006389 if ((off + count) > FF_REG_AREA_SIZE)
6390 return -ERANGE;
6391
James Smartf7a919b2011-08-21 21:49:16 -04006392 if (count <= LPFC_REG_WRITE_KEY_SIZE)
6393 return 0;
dea31012005-04-17 16:05:31 -05006394
6395 if (off % 4 || count % 4 || (unsigned long)buf % 4)
6396 return -EINVAL;
6397
James Smartf7a919b2011-08-21 21:49:16 -04006398 /* This is to protect HBA registers from accidental writes. */
6399 if (memcmp(buf, LPFC_REG_WRITE_KEY, LPFC_REG_WRITE_KEY_SIZE))
6400 return -EINVAL;
6401
6402 if (!(vport->fc_flag & FC_OFFLINE_MODE))
dea31012005-04-17 16:05:31 -05006403 return -EPERM;
dea31012005-04-17 16:05:31 -05006404
James Smart2e0fef82007-06-17 19:56:36 -05006405 spin_lock_irq(&phba->hbalock);
James Smartf7a919b2011-08-21 21:49:16 -04006406 for (buf_off = 0; buf_off < count - LPFC_REG_WRITE_KEY_SIZE;
6407 buf_off += sizeof(uint32_t))
6408 writel(*((uint32_t *)(buf + buf_off + LPFC_REG_WRITE_KEY_SIZE)),
dea31012005-04-17 16:05:31 -05006409 phba->ctrl_regs_memmap_p + off + buf_off);
6410
James Smart2e0fef82007-06-17 19:56:36 -05006411 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006412
6413 return count;
6414}
6415
James Smarte59058c2008-08-24 21:49:00 -04006416/**
James Smart3621a712009-04-06 18:47:14 -04006417 * sysfs_ctlreg_read - Read method for reading from ctlreg
Chris Wright2c3c8be2010-05-12 18:28:57 -07006418 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006419 * @kobj: kernel kobject that contains the kernel class device.
6420 * @bin_attr: kernel attributes passed to us.
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02006421 * @buf: if successful contains the data from the adapter IOREG space.
James Smarte59058c2008-08-24 21:49:00 -04006422 * @off: offset into buffer to beginning of data.
6423 * @count: bytes to transfer.
6424 *
6425 * Description:
6426 * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
6427 * Uses the adapter io control registers to read data into buf.
6428 *
6429 * Returns:
6430 * -ERANGE off and count combo out of range
6431 * -EINVAL off, count or buff address invalid
6432 * value of count, buf contents read
6433 **/
dea31012005-04-17 16:05:31 -05006434static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006435sysfs_ctlreg_read(struct file *filp, struct kobject *kobj,
6436 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006437 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006438{
6439 size_t buf_off;
6440 uint32_t * tmp_ptr;
Tony Jonesee959b02008-02-22 00:13:36 +01006441 struct device *dev = container_of(kobj, struct device, kobj);
6442 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05006443 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6444 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006445
James Smartf1126682009-06-10 17:22:44 -04006446 if (phba->sli_rev >= LPFC_SLI_REV4)
6447 return -EPERM;
6448
dea31012005-04-17 16:05:31 -05006449 if (off > FF_REG_AREA_SIZE)
6450 return -ERANGE;
6451
6452 if ((off + count) > FF_REG_AREA_SIZE)
6453 count = FF_REG_AREA_SIZE - off;
6454
6455 if (count == 0) return 0;
6456
6457 if (off % 4 || count % 4 || (unsigned long)buf % 4)
6458 return -EINVAL;
6459
James Smart2e0fef82007-06-17 19:56:36 -05006460 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006461
6462 for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {
6463 tmp_ptr = (uint32_t *)(buf + buf_off);
6464 *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);
6465 }
6466
James Smart2e0fef82007-06-17 19:56:36 -05006467 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006468
6469 return count;
6470}
6471
6472static struct bin_attribute sysfs_ctlreg_attr = {
6473 .attr = {
6474 .name = "ctlreg",
6475 .mode = S_IRUSR | S_IWUSR,
dea31012005-04-17 16:05:31 -05006476 },
6477 .size = 256,
6478 .read = sysfs_ctlreg_read,
6479 .write = sysfs_ctlreg_write,
6480};
6481
James Smarte59058c2008-08-24 21:49:00 -04006482/**
James Smart3621a712009-04-06 18:47:14 -04006483 * sysfs_mbox_write - Write method for writing information via mbox
Chris Wright2c3c8be2010-05-12 18:28:57 -07006484 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006485 * @kobj: kernel kobject that contains the kernel class device.
6486 * @bin_attr: kernel attributes passed to us.
6487 * @buf: contains the data to be written to sysfs mbox.
6488 * @off: offset into buffer to beginning of data.
6489 * @count: bytes to transfer.
6490 *
6491 * Description:
James Smart026abb82011-12-13 13:20:45 -05006492 * Deprecated function. All mailbox access from user space is performed via the
6493 * bsg interface.
James Smarte59058c2008-08-24 21:49:00 -04006494 *
6495 * Returns:
James Smart026abb82011-12-13 13:20:45 -05006496 * -EPERM operation not permitted
James Smarte59058c2008-08-24 21:49:00 -04006497 **/
dea31012005-04-17 16:05:31 -05006498static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006499sysfs_mbox_write(struct file *filp, struct kobject *kobj,
6500 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006501 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006502{
James Smart026abb82011-12-13 13:20:45 -05006503 return -EPERM;
dea31012005-04-17 16:05:31 -05006504}
6505
James Smarte59058c2008-08-24 21:49:00 -04006506/**
James Smart3621a712009-04-06 18:47:14 -04006507 * sysfs_mbox_read - Read method for reading information via mbox
Chris Wright2c3c8be2010-05-12 18:28:57 -07006508 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006509 * @kobj: kernel kobject that contains the kernel class device.
6510 * @bin_attr: kernel attributes passed to us.
6511 * @buf: contains the data to be read from sysfs mbox.
6512 * @off: offset into buffer to beginning of data.
6513 * @count: bytes to transfer.
6514 *
6515 * Description:
James Smart026abb82011-12-13 13:20:45 -05006516 * Deprecated function. All mailbox access from user space is performed via the
6517 * bsg interface.
James Smarte59058c2008-08-24 21:49:00 -04006518 *
6519 * Returns:
James Smart026abb82011-12-13 13:20:45 -05006520 * -EPERM operation not permitted
James Smarte59058c2008-08-24 21:49:00 -04006521 **/
dea31012005-04-17 16:05:31 -05006522static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006523sysfs_mbox_read(struct file *filp, struct kobject *kobj,
6524 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006525 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006526{
James Smart026abb82011-12-13 13:20:45 -05006527 return -EPERM;
dea31012005-04-17 16:05:31 -05006528}
6529
6530static struct bin_attribute sysfs_mbox_attr = {
6531 .attr = {
6532 .name = "mbox",
6533 .mode = S_IRUSR | S_IWUSR,
dea31012005-04-17 16:05:31 -05006534 },
James Smartc0c11512011-05-24 11:41:34 -04006535 .size = MAILBOX_SYSFS_MAX,
dea31012005-04-17 16:05:31 -05006536 .read = sysfs_mbox_read,
6537 .write = sysfs_mbox_write,
6538};
6539
James Smarte59058c2008-08-24 21:49:00 -04006540/**
James Smart3621a712009-04-06 18:47:14 -04006541 * lpfc_alloc_sysfs_attr - Creates the ctlreg and mbox entries
James Smarte59058c2008-08-24 21:49:00 -04006542 * @vport: address of lpfc vport structure.
6543 *
6544 * Return codes:
6545 * zero on success
6546 * error return code from sysfs_create_bin_file()
6547 **/
dea31012005-04-17 16:05:31 -05006548int
James Smart2e0fef82007-06-17 19:56:36 -05006549lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05006550{
James Smart2e0fef82007-06-17 19:56:36 -05006551 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05006552 int error;
6553
Tony Jonesee959b02008-02-22 00:13:36 +01006554 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smarteada2722008-12-04 22:39:13 -05006555 &sysfs_drvr_stat_data_attr);
6556
6557 /* Virtual ports do not need ctrl_reg and mbox */
6558 if (error || vport->port_type == LPFC_NPIV_PORT)
6559 goto out;
6560
6561 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smart92d7f7b2007-06-17 19:56:38 -05006562 &sysfs_ctlreg_attr);
dea31012005-04-17 16:05:31 -05006563 if (error)
James Smarteada2722008-12-04 22:39:13 -05006564 goto out_remove_stat_attr;
dea31012005-04-17 16:05:31 -05006565
Tony Jonesee959b02008-02-22 00:13:36 +01006566 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smart92d7f7b2007-06-17 19:56:38 -05006567 &sysfs_mbox_attr);
dea31012005-04-17 16:05:31 -05006568 if (error)
6569 goto out_remove_ctlreg_attr;
6570
6571 return 0;
6572out_remove_ctlreg_attr:
Tony Jonesee959b02008-02-22 00:13:36 +01006573 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
James Smarteada2722008-12-04 22:39:13 -05006574out_remove_stat_attr:
6575 sysfs_remove_bin_file(&shost->shost_dev.kobj,
6576 &sysfs_drvr_stat_data_attr);
dea31012005-04-17 16:05:31 -05006577out:
6578 return error;
6579}
6580
James Smarte59058c2008-08-24 21:49:00 -04006581/**
James Smart3621a712009-04-06 18:47:14 -04006582 * lpfc_free_sysfs_attr - Removes the ctlreg and mbox entries
James Smarte59058c2008-08-24 21:49:00 -04006583 * @vport: address of lpfc vport structure.
6584 **/
dea31012005-04-17 16:05:31 -05006585void
James Smart2e0fef82007-06-17 19:56:36 -05006586lpfc_free_sysfs_attr(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05006587{
James Smart2e0fef82007-06-17 19:56:36 -05006588 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smartea2151b2008-09-07 11:52:10 -04006589 sysfs_remove_bin_file(&shost->shost_dev.kobj,
6590 &sysfs_drvr_stat_data_attr);
James Smarteada2722008-12-04 22:39:13 -05006591 /* Virtual ports do not need ctrl_reg and mbox */
6592 if (vport->port_type == LPFC_NPIV_PORT)
6593 return;
Tony Jonesee959b02008-02-22 00:13:36 +01006594 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
6595 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
dea31012005-04-17 16:05:31 -05006596}
6597
dea31012005-04-17 16:05:31 -05006598/*
6599 * Dynamic FC Host Attributes Support
6600 */
6601
James Smarte59058c2008-08-24 21:49:00 -04006602/**
James Smart6c9231f2016-12-19 15:07:24 -08006603 * lpfc_get_host_symbolic_name - Copy symbolic name into the scsi host
6604 * @shost: kernel scsi host pointer.
6605 **/
6606static void
6607lpfc_get_host_symbolic_name(struct Scsi_Host *shost)
6608{
6609 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
6610
6611 lpfc_vport_symbolic_node_name(vport, fc_host_symbolic_name(shost),
6612 sizeof fc_host_symbolic_name(shost));
6613}
6614
6615/**
James Smart3621a712009-04-06 18:47:14 -04006616 * lpfc_get_host_port_id - Copy the vport DID into the scsi host port id
James Smarte59058c2008-08-24 21:49:00 -04006617 * @shost: kernel scsi host pointer.
6618 **/
dea31012005-04-17 16:05:31 -05006619static void
6620lpfc_get_host_port_id(struct Scsi_Host *shost)
6621{
James Smart2e0fef82007-06-17 19:56:36 -05006622 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6623
dea31012005-04-17 16:05:31 -05006624 /* note: fc_myDID already in cpu endianness */
James Smart2e0fef82007-06-17 19:56:36 -05006625 fc_host_port_id(shost) = vport->fc_myDID;
dea31012005-04-17 16:05:31 -05006626}
6627
James Smarte59058c2008-08-24 21:49:00 -04006628/**
James Smart3621a712009-04-06 18:47:14 -04006629 * lpfc_get_host_port_type - Set the value of the scsi host port type
James Smarte59058c2008-08-24 21:49:00 -04006630 * @shost: kernel scsi host pointer.
6631 **/
dea31012005-04-17 16:05:31 -05006632static void
6633lpfc_get_host_port_type(struct Scsi_Host *shost)
6634{
James Smart2e0fef82007-06-17 19:56:36 -05006635 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6636 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006637
6638 spin_lock_irq(shost->host_lock);
6639
James Smart92d7f7b2007-06-17 19:56:38 -05006640 if (vport->port_type == LPFC_NPIV_PORT) {
6641 fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
6642 } else if (lpfc_is_link_up(phba)) {
James Smart76a95d72010-11-20 23:11:48 -05006643 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smart2e0fef82007-06-17 19:56:36 -05006644 if (vport->fc_flag & FC_PUBLIC_LOOP)
dea31012005-04-17 16:05:31 -05006645 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
6646 else
6647 fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
6648 } else {
James Smart2e0fef82007-06-17 19:56:36 -05006649 if (vport->fc_flag & FC_FABRIC)
dea31012005-04-17 16:05:31 -05006650 fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
6651 else
6652 fc_host_port_type(shost) = FC_PORTTYPE_PTP;
6653 }
6654 } else
6655 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
6656
6657 spin_unlock_irq(shost->host_lock);
6658}
6659
James Smarte59058c2008-08-24 21:49:00 -04006660/**
James Smart3621a712009-04-06 18:47:14 -04006661 * lpfc_get_host_port_state - Set the value of the scsi host port state
James Smarte59058c2008-08-24 21:49:00 -04006662 * @shost: kernel scsi host pointer.
6663 **/
dea31012005-04-17 16:05:31 -05006664static void
6665lpfc_get_host_port_state(struct Scsi_Host *shost)
6666{
James Smart2e0fef82007-06-17 19:56:36 -05006667 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6668 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006669
6670 spin_lock_irq(shost->host_lock);
6671
James Smart2e0fef82007-06-17 19:56:36 -05006672 if (vport->fc_flag & FC_OFFLINE_MODE)
dea31012005-04-17 16:05:31 -05006673 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
6674 else {
James Smart2e0fef82007-06-17 19:56:36 -05006675 switch (phba->link_state) {
6676 case LPFC_LINK_UNKNOWN:
dea31012005-04-17 16:05:31 -05006677 case LPFC_LINK_DOWN:
6678 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
6679 break;
6680 case LPFC_LINK_UP:
dea31012005-04-17 16:05:31 -05006681 case LPFC_CLEAR_LA:
6682 case LPFC_HBA_READY:
James Smart026abb82011-12-13 13:20:45 -05006683 /* Links up, reports port state accordingly */
6684 if (vport->port_state < LPFC_VPORT_READY)
6685 fc_host_port_state(shost) =
6686 FC_PORTSTATE_BYPASSED;
6687 else
6688 fc_host_port_state(shost) =
6689 FC_PORTSTATE_ONLINE;
dea31012005-04-17 16:05:31 -05006690 break;
6691 case LPFC_HBA_ERROR:
6692 fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
6693 break;
6694 default:
6695 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
6696 break;
6697 }
6698 }
6699
6700 spin_unlock_irq(shost->host_lock);
6701}
6702
James Smarte59058c2008-08-24 21:49:00 -04006703/**
James Smart3621a712009-04-06 18:47:14 -04006704 * lpfc_get_host_speed - Set the value of the scsi host speed
James Smarte59058c2008-08-24 21:49:00 -04006705 * @shost: kernel scsi host pointer.
6706 **/
dea31012005-04-17 16:05:31 -05006707static void
6708lpfc_get_host_speed(struct Scsi_Host *shost)
6709{
James Smart2e0fef82007-06-17 19:56:36 -05006710 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6711 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006712
6713 spin_lock_irq(shost->host_lock);
6714
James Smarta085e872015-12-16 18:12:02 -05006715 if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) {
dea31012005-04-17 16:05:31 -05006716 switch(phba->fc_linkspeed) {
James Smart76a95d72010-11-20 23:11:48 -05006717 case LPFC_LINK_SPEED_1GHZ:
6718 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
dea31012005-04-17 16:05:31 -05006719 break;
James Smart76a95d72010-11-20 23:11:48 -05006720 case LPFC_LINK_SPEED_2GHZ:
6721 fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
dea31012005-04-17 16:05:31 -05006722 break;
James Smart76a95d72010-11-20 23:11:48 -05006723 case LPFC_LINK_SPEED_4GHZ:
6724 fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
dea31012005-04-17 16:05:31 -05006725 break;
James Smart76a95d72010-11-20 23:11:48 -05006726 case LPFC_LINK_SPEED_8GHZ:
6727 fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
James Smartb87eab32007-04-25 09:53:28 -04006728 break;
James Smart76a95d72010-11-20 23:11:48 -05006729 case LPFC_LINK_SPEED_10GHZ:
6730 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
James Smartf4b4c682009-05-22 14:53:12 -04006731 break;
James Smart76a95d72010-11-20 23:11:48 -05006732 case LPFC_LINK_SPEED_16GHZ:
6733 fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
6734 break;
James Smartd38dd522015-08-31 16:48:17 -04006735 case LPFC_LINK_SPEED_32GHZ:
6736 fc_host_speed(shost) = FC_PORTSPEED_32GBIT;
6737 break;
James Smartfbd8a6b2018-02-22 08:18:45 -08006738 case LPFC_LINK_SPEED_64GHZ:
6739 fc_host_speed(shost) = FC_PORTSPEED_64GBIT;
6740 break;
James Smart1dc5ec22018-10-23 13:41:11 -07006741 case LPFC_LINK_SPEED_128GHZ:
6742 fc_host_speed(shost) = FC_PORTSPEED_128GBIT;
6743 break;
James Smart76a95d72010-11-20 23:11:48 -05006744 default:
6745 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
dea31012005-04-17 16:05:31 -05006746 break;
6747 }
James Smartb615a202018-07-31 17:23:19 -07006748 } else if (lpfc_is_link_up(phba) && (phba->hba_flag & HBA_FCOE_MODE)) {
6749 switch (phba->fc_linkspeed) {
Dick Kennedya1e4d3d2020-08-03 14:02:22 -07006750 case LPFC_ASYNC_LINK_SPEED_1GBPS:
6751 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
6752 break;
James Smartb615a202018-07-31 17:23:19 -07006753 case LPFC_ASYNC_LINK_SPEED_10GBPS:
6754 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
6755 break;
Dick Kennedya1e4d3d2020-08-03 14:02:22 -07006756 case LPFC_ASYNC_LINK_SPEED_20GBPS:
6757 fc_host_speed(shost) = FC_PORTSPEED_20GBIT;
6758 break;
James Smartb615a202018-07-31 17:23:19 -07006759 case LPFC_ASYNC_LINK_SPEED_25GBPS:
6760 fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
6761 break;
6762 case LPFC_ASYNC_LINK_SPEED_40GBPS:
6763 fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
6764 break;
6765 case LPFC_ASYNC_LINK_SPEED_100GBPS:
6766 fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
6767 break;
6768 default:
6769 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
6770 break;
6771 }
James Smart09372822008-01-11 01:52:54 -05006772 } else
6773 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
dea31012005-04-17 16:05:31 -05006774
6775 spin_unlock_irq(shost->host_lock);
6776}
6777
James Smarte59058c2008-08-24 21:49:00 -04006778/**
James Smart3621a712009-04-06 18:47:14 -04006779 * lpfc_get_host_fabric_name - Set the value of the scsi host fabric name
James Smarte59058c2008-08-24 21:49:00 -04006780 * @shost: kernel scsi host pointer.
6781 **/
dea31012005-04-17 16:05:31 -05006782static void
6783lpfc_get_host_fabric_name (struct Scsi_Host *shost)
6784{
James Smart2e0fef82007-06-17 19:56:36 -05006785 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6786 struct lpfc_hba *phba = vport->phba;
Andrew Vasquezf631b4b2005-08-31 15:23:12 -07006787 u64 node_name;
dea31012005-04-17 16:05:31 -05006788
6789 spin_lock_irq(shost->host_lock);
6790
James Smart73d91e52011-10-10 21:32:10 -04006791 if ((vport->port_state > LPFC_FLOGI) &&
6792 ((vport->fc_flag & FC_FABRIC) ||
6793 ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
6794 (vport->fc_flag & FC_PUBLIC_LOOP))))
Andrew Morton68ce1eb2005-09-21 09:46:54 -07006795 node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
dea31012005-04-17 16:05:31 -05006796 else
6797 /* fabric is local port if there is no F/FL_Port */
James Smart09372822008-01-11 01:52:54 -05006798 node_name = 0;
dea31012005-04-17 16:05:31 -05006799
6800 spin_unlock_irq(shost->host_lock);
6801
Andrew Vasquezf631b4b2005-08-31 15:23:12 -07006802 fc_host_fabric_name(shost) = node_name;
dea31012005-04-17 16:05:31 -05006803}
6804
James Smarte59058c2008-08-24 21:49:00 -04006805/**
James Smart3621a712009-04-06 18:47:14 -04006806 * lpfc_get_stats - Return statistical information about the adapter
James Smarte59058c2008-08-24 21:49:00 -04006807 * @shost: kernel scsi host pointer.
6808 *
6809 * Notes:
6810 * NULL on error for link down, no mbox pool, sli2 active,
6811 * management not allowed, memory allocation error, or mbox error.
6812 *
6813 * Returns:
6814 * NULL for error
6815 * address of the adapter host statistics
6816 **/
dea31012005-04-17 16:05:31 -05006817static struct fc_host_statistics *
6818lpfc_get_stats(struct Scsi_Host *shost)
6819{
James Smart2e0fef82007-06-17 19:56:36 -05006820 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6821 struct lpfc_hba *phba = vport->phba;
6822 struct lpfc_sli *psli = &phba->sli;
James.Smart@Emulex.Comf888ba32005-08-10 15:03:01 -04006823 struct fc_host_statistics *hs = &phba->link_stats;
James Smart64ba8812006-08-02 15:24:34 -04006824 struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
dea31012005-04-17 16:05:31 -05006825 LPFC_MBOXQ_t *pmboxq;
6826 MAILBOX_t *pmb;
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006827 int rc = 0;
dea31012005-04-17 16:05:31 -05006828
James Smart92d7f7b2007-06-17 19:56:38 -05006829 /*
6830 * prevent udev from issuing mailbox commands until the port is
6831 * configured.
6832 */
James Smart2e0fef82007-06-17 19:56:36 -05006833 if (phba->link_state < LPFC_LINK_DOWN ||
6834 !phba->mbox_mem_pool ||
James Smartf4b4c682009-05-22 14:53:12 -04006835 (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
James Smart92d7f7b2007-06-17 19:56:38 -05006836 return NULL;
James Smart2e0fef82007-06-17 19:56:36 -05006837
6838 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
James Smart46fa3112007-04-25 09:51:45 -04006839 return NULL;
6840
dea31012005-04-17 16:05:31 -05006841 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
6842 if (!pmboxq)
6843 return NULL;
6844 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
6845
James Smart04c68492009-05-22 14:52:52 -04006846 pmb = &pmboxq->u.mb;
dea31012005-04-17 16:05:31 -05006847 pmb->mbxCommand = MBX_READ_STATUS;
6848 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006849 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006850 pmboxq->vport = vport;
dea31012005-04-17 16:05:31 -05006851
James Smart304ee432021-04-11 18:31:17 -07006852 if (vport->fc_flag & FC_OFFLINE_MODE) {
dea31012005-04-17 16:05:31 -05006853 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006854 if (rc != MBX_SUCCESS) {
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006855 mempool_free(pmboxq, phba->mbox_mem_pool);
James Smart304ee432021-04-11 18:31:17 -07006856 return NULL;
6857 }
6858 } else {
6859 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6860 if (rc != MBX_SUCCESS) {
6861 if (rc != MBX_TIMEOUT)
6862 mempool_free(pmboxq, phba->mbox_mem_pool);
6863 return NULL;
6864 }
dea31012005-04-17 16:05:31 -05006865 }
6866
James.Smart@Emulex.Comf888ba32005-08-10 15:03:01 -04006867 memset(hs, 0, sizeof (struct fc_host_statistics));
6868
dea31012005-04-17 16:05:31 -05006869 hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
James Smart73d91e52011-10-10 21:32:10 -04006870 /*
6871 * The MBX_READ_STATUS returns tx_k_bytes which has to
6872 * converted to words
6873 */
6874 hs->tx_words = (uint64_t)
6875 ((uint64_t)pmb->un.varRdStatus.xmitByteCnt
6876 * (uint64_t)256);
dea31012005-04-17 16:05:31 -05006877 hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
James Smart73d91e52011-10-10 21:32:10 -04006878 hs->rx_words = (uint64_t)
6879 ((uint64_t)pmb->un.varRdStatus.rcvByteCnt
6880 * (uint64_t)256);
dea31012005-04-17 16:05:31 -05006881
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006882 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
dea31012005-04-17 16:05:31 -05006883 pmb->mbxCommand = MBX_READ_LNK_STAT;
6884 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006885 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006886 pmboxq->vport = vport;
dea31012005-04-17 16:05:31 -05006887
James Smart304ee432021-04-11 18:31:17 -07006888 if (vport->fc_flag & FC_OFFLINE_MODE) {
dea31012005-04-17 16:05:31 -05006889 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006890 if (rc != MBX_SUCCESS) {
James Smart92d7f7b2007-06-17 19:56:38 -05006891 mempool_free(pmboxq, phba->mbox_mem_pool);
James Smart304ee432021-04-11 18:31:17 -07006892 return NULL;
6893 }
6894 } else {
6895 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6896 if (rc != MBX_SUCCESS) {
6897 if (rc != MBX_TIMEOUT)
6898 mempool_free(pmboxq, phba->mbox_mem_pool);
6899 return NULL;
6900 }
dea31012005-04-17 16:05:31 -05006901 }
6902
6903 hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
6904 hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
6905 hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
6906 hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
6907 hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
6908 hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
6909 hs->error_frames = pmb->un.varRdLnk.crcCnt;
6910
James Smart64ba8812006-08-02 15:24:34 -04006911 hs->link_failure_count -= lso->link_failure_count;
6912 hs->loss_of_sync_count -= lso->loss_of_sync_count;
6913 hs->loss_of_signal_count -= lso->loss_of_signal_count;
6914 hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count;
6915 hs->invalid_tx_word_count -= lso->invalid_tx_word_count;
6916 hs->invalid_crc_count -= lso->invalid_crc_count;
6917 hs->error_frames -= lso->error_frames;
6918
James Smart76a95d72010-11-20 23:11:48 -05006919 if (phba->hba_flag & HBA_FCOE_MODE) {
James Smart4d9ab992009-10-02 15:16:39 -04006920 hs->lip_count = -1;
6921 hs->nos_count = (phba->link_events >> 1);
6922 hs->nos_count -= lso->link_events;
James Smart76a95d72010-11-20 23:11:48 -05006923 } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
dea31012005-04-17 16:05:31 -05006924 hs->lip_count = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006925 hs->lip_count -= lso->link_events;
dea31012005-04-17 16:05:31 -05006926 hs->nos_count = -1;
6927 } else {
6928 hs->lip_count = -1;
6929 hs->nos_count = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006930 hs->nos_count -= lso->link_events;
dea31012005-04-17 16:05:31 -05006931 }
6932
6933 hs->dumped_frames = -1;
6934
Arnd Bergmannc4d6204d2018-06-18 17:28:23 +02006935 hs->seconds_since_last_reset = ktime_get_seconds() - psli->stats_start;
dea31012005-04-17 16:05:31 -05006936
James Smart1dcb58e2007-04-25 09:51:30 -04006937 mempool_free(pmboxq, phba->mbox_mem_pool);
6938
dea31012005-04-17 16:05:31 -05006939 return hs;
6940}
6941
James Smarte59058c2008-08-24 21:49:00 -04006942/**
James Smart3621a712009-04-06 18:47:14 -04006943 * lpfc_reset_stats - Copy the adapter link stats information
James Smarte59058c2008-08-24 21:49:00 -04006944 * @shost: kernel scsi host pointer.
6945 **/
James Smart64ba8812006-08-02 15:24:34 -04006946static void
6947lpfc_reset_stats(struct Scsi_Host *shost)
6948{
James Smart2e0fef82007-06-17 19:56:36 -05006949 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6950 struct lpfc_hba *phba = vport->phba;
6951 struct lpfc_sli *psli = &phba->sli;
6952 struct lpfc_lnk_stat *lso = &psli->lnk_stat_offsets;
James Smart64ba8812006-08-02 15:24:34 -04006953 LPFC_MBOXQ_t *pmboxq;
6954 MAILBOX_t *pmb;
6955 int rc = 0;
6956
James Smart2e0fef82007-06-17 19:56:36 -05006957 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
James Smart46fa3112007-04-25 09:51:45 -04006958 return;
6959
James Smart64ba8812006-08-02 15:24:34 -04006960 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
6961 if (!pmboxq)
6962 return;
6963 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
6964
James Smart04c68492009-05-22 14:52:52 -04006965 pmb = &pmboxq->u.mb;
James Smart64ba8812006-08-02 15:24:34 -04006966 pmb->mbxCommand = MBX_READ_STATUS;
6967 pmb->mbxOwner = OWN_HOST;
6968 pmb->un.varWords[0] = 0x1; /* reset request */
James Smart3e1f0712018-11-29 16:09:29 -08006969 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006970 pmboxq->vport = vport;
James Smart64ba8812006-08-02 15:24:34 -04006971
James Smart2e0fef82007-06-17 19:56:36 -05006972 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smart304ee432021-04-11 18:31:17 -07006973 (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
James Smart64ba8812006-08-02 15:24:34 -04006974 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006975 if (rc != MBX_SUCCESS) {
James Smart64ba8812006-08-02 15:24:34 -04006976 mempool_free(pmboxq, phba->mbox_mem_pool);
James Smart304ee432021-04-11 18:31:17 -07006977 return;
6978 }
6979 } else {
6980 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6981 if (rc != MBX_SUCCESS) {
6982 if (rc != MBX_TIMEOUT)
6983 mempool_free(pmboxq, phba->mbox_mem_pool);
6984 return;
6985 }
James Smart64ba8812006-08-02 15:24:34 -04006986 }
6987
6988 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
6989 pmb->mbxCommand = MBX_READ_LNK_STAT;
6990 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006991 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006992 pmboxq->vport = vport;
James Smart64ba8812006-08-02 15:24:34 -04006993
James Smart2e0fef82007-06-17 19:56:36 -05006994 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smart304ee432021-04-11 18:31:17 -07006995 (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
James Smart64ba8812006-08-02 15:24:34 -04006996 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006997 if (rc != MBX_SUCCESS) {
6998 mempool_free(pmboxq, phba->mbox_mem_pool);
6999 return;
7000 }
7001 } else {
James Smart64ba8812006-08-02 15:24:34 -04007002 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
James Smart304ee432021-04-11 18:31:17 -07007003 if (rc != MBX_SUCCESS) {
7004 if (rc != MBX_TIMEOUT)
7005 mempool_free(pmboxq, phba->mbox_mem_pool);
7006 return;
7007 }
James Smart64ba8812006-08-02 15:24:34 -04007008 }
7009
7010 lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
7011 lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
7012 lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
7013 lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
7014 lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
7015 lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
7016 lso->error_frames = pmb->un.varRdLnk.crcCnt;
James Smart76a95d72010-11-20 23:11:48 -05007017 if (phba->hba_flag & HBA_FCOE_MODE)
James Smart4d9ab992009-10-02 15:16:39 -04007018 lso->link_events = (phba->link_events >> 1);
7019 else
7020 lso->link_events = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04007021
Arnd Bergmannc4d6204d2018-06-18 17:28:23 +02007022 psli->stats_start = ktime_get_seconds();
James Smart64ba8812006-08-02 15:24:34 -04007023
James Smart1dcb58e2007-04-25 09:51:30 -04007024 mempool_free(pmboxq, phba->mbox_mem_pool);
7025
James Smart64ba8812006-08-02 15:24:34 -04007026 return;
7027}
dea31012005-04-17 16:05:31 -05007028
7029/*
7030 * The LPFC driver treats linkdown handling as target loss events so there
7031 * are no sysfs handlers for link_down_tmo.
7032 */
James Smart685f0bf2007-04-25 09:53:08 -04007033
James Smarte59058c2008-08-24 21:49:00 -04007034/**
James Smart3621a712009-04-06 18:47:14 -04007035 * lpfc_get_node_by_target - Return the nodelist for a target
James Smarte59058c2008-08-24 21:49:00 -04007036 * @starget: kernel scsi target pointer.
7037 *
7038 * Returns:
7039 * address of the node list if found
7040 * NULL target not found
7041 **/
James Smart685f0bf2007-04-25 09:53:08 -04007042static struct lpfc_nodelist *
7043lpfc_get_node_by_target(struct scsi_target *starget)
dea31012005-04-17 16:05:31 -05007044{
James Smart2e0fef82007-06-17 19:56:36 -05007045 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
7046 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
James Smart685f0bf2007-04-25 09:53:08 -04007047 struct lpfc_nodelist *ndlp;
dea31012005-04-17 16:05:31 -05007048
7049 spin_lock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04007050 /* Search for this, mapped, target ID */
James Smart2e0fef82007-06-17 19:56:36 -05007051 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart307e3382020-11-15 11:26:30 -08007052 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
James Smart685f0bf2007-04-25 09:53:08 -04007053 starget->id == ndlp->nlp_sid) {
7054 spin_unlock_irq(shost->host_lock);
7055 return ndlp;
dea31012005-04-17 16:05:31 -05007056 }
7057 }
7058 spin_unlock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04007059 return NULL;
7060}
dea31012005-04-17 16:05:31 -05007061
James Smarte59058c2008-08-24 21:49:00 -04007062/**
James Smart3621a712009-04-06 18:47:14 -04007063 * lpfc_get_starget_port_id - Set the target port id to the ndlp DID or -1
James Smarte59058c2008-08-24 21:49:00 -04007064 * @starget: kernel scsi target pointer.
7065 **/
James Smart685f0bf2007-04-25 09:53:08 -04007066static void
7067lpfc_get_starget_port_id(struct scsi_target *starget)
7068{
7069 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
7070
7071 fc_starget_port_id(starget) = ndlp ? ndlp->nlp_DID : -1;
dea31012005-04-17 16:05:31 -05007072}
7073
James Smarte59058c2008-08-24 21:49:00 -04007074/**
James Smart3621a712009-04-06 18:47:14 -04007075 * lpfc_get_starget_node_name - Set the target node name
James Smarte59058c2008-08-24 21:49:00 -04007076 * @starget: kernel scsi target pointer.
7077 *
7078 * Description: Set the target node name to the ndlp node name wwn or zero.
7079 **/
dea31012005-04-17 16:05:31 -05007080static void
7081lpfc_get_starget_node_name(struct scsi_target *starget)
7082{
James Smart685f0bf2007-04-25 09:53:08 -04007083 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
dea31012005-04-17 16:05:31 -05007084
James Smart685f0bf2007-04-25 09:53:08 -04007085 fc_starget_node_name(starget) =
7086 ndlp ? wwn_to_u64(ndlp->nlp_nodename.u.wwn) : 0;
dea31012005-04-17 16:05:31 -05007087}
7088
James Smarte59058c2008-08-24 21:49:00 -04007089/**
James Smart3621a712009-04-06 18:47:14 -04007090 * lpfc_get_starget_port_name - Set the target port name
James Smarte59058c2008-08-24 21:49:00 -04007091 * @starget: kernel scsi target pointer.
7092 *
7093 * Description: set the target port name to the ndlp port name wwn or zero.
7094 **/
dea31012005-04-17 16:05:31 -05007095static void
7096lpfc_get_starget_port_name(struct scsi_target *starget)
7097{
James Smart685f0bf2007-04-25 09:53:08 -04007098 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
dea31012005-04-17 16:05:31 -05007099
James Smart685f0bf2007-04-25 09:53:08 -04007100 fc_starget_port_name(starget) =
7101 ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0;
dea31012005-04-17 16:05:31 -05007102}
7103
James Smarte59058c2008-08-24 21:49:00 -04007104/**
James Smart3621a712009-04-06 18:47:14 -04007105 * lpfc_set_rport_loss_tmo - Set the rport dev loss tmo
James Smarte59058c2008-08-24 21:49:00 -04007106 * @rport: fc rport address.
7107 * @timeout: new value for dev loss tmo.
7108 *
7109 * Description:
7110 * If timeout is non zero set the dev_loss_tmo to timeout, else set
7111 * dev_loss_tmo to one.
7112 **/
dea31012005-04-17 16:05:31 -05007113static void
dea31012005-04-17 16:05:31 -05007114lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
7115{
James Smarta643c6d2019-08-14 16:56:48 -07007116 struct lpfc_rport_data *rdata = rport->dd_data;
7117 struct lpfc_nodelist *ndlp = rdata->pnode;
7118#if (IS_ENABLED(CONFIG_NVME_FC))
7119 struct lpfc_nvme_rport *nrport = NULL;
7120#endif
7121
dea31012005-04-17 16:05:31 -05007122 if (timeout)
James Smartc01f3202006-08-18 17:47:08 -04007123 rport->dev_loss_tmo = timeout;
dea31012005-04-17 16:05:31 -05007124 else
James Smartc01f3202006-08-18 17:47:08 -04007125 rport->dev_loss_tmo = 1;
James Smarta643c6d2019-08-14 16:56:48 -07007126
James Smart307e3382020-11-15 11:26:30 -08007127 if (!ndlp) {
James Smarta643c6d2019-08-14 16:56:48 -07007128 dev_info(&rport->dev, "Cannot find remote node to "
7129 "set rport dev loss tmo, port_id x%x\n",
7130 rport->port_id);
7131 return;
7132 }
7133
7134#if (IS_ENABLED(CONFIG_NVME_FC))
7135 nrport = lpfc_ndlp_get_nrport(ndlp);
7136
7137 if (nrport && nrport->remoteport)
7138 nvme_fc_set_remoteport_devloss(nrport->remoteport,
7139 rport->dev_loss_tmo);
7140#endif
dea31012005-04-17 16:05:31 -05007141}
7142
Lee Jones9176ad22020-11-02 14:23:44 +00007143/*
James Smart3621a712009-04-06 18:47:14 -04007144 * lpfc_rport_show_function - Return rport target information
James Smarte59058c2008-08-24 21:49:00 -04007145 *
7146 * Description:
7147 * Macro that uses field to generate a function with the name lpfc_show_rport_
7148 *
7149 * lpfc_show_rport_##field: returns the bytes formatted in buf
7150 * @cdev: class converted to an fc_rport.
7151 * @buf: on return contains the target_field or zero.
7152 *
7153 * Returns: size of formatted string.
7154 **/
dea31012005-04-17 16:05:31 -05007155#define lpfc_rport_show_function(field, format_string, sz, cast) \
7156static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01007157lpfc_show_rport_##field (struct device *dev, \
7158 struct device_attribute *attr, \
7159 char *buf) \
dea31012005-04-17 16:05:31 -05007160{ \
Tony Jonesee959b02008-02-22 00:13:36 +01007161 struct fc_rport *rport = transport_class_to_rport(dev); \
dea31012005-04-17 16:05:31 -05007162 struct lpfc_rport_data *rdata = rport->hostdata; \
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07007163 return scnprintf(buf, sz, format_string, \
dea31012005-04-17 16:05:31 -05007164 (rdata->target) ? cast rdata->target->field : 0); \
7165}
7166
7167#define lpfc_rport_rd_attr(field, format_string, sz) \
7168 lpfc_rport_show_function(field, format_string, sz, ) \
7169static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
7170
James Smarteada2722008-12-04 22:39:13 -05007171/**
James Smart3621a712009-04-06 18:47:14 -04007172 * lpfc_set_vport_symbolic_name - Set the vport's symbolic name
James Smarteada2722008-12-04 22:39:13 -05007173 * @fc_vport: The fc_vport who's symbolic name has been changed.
7174 *
7175 * Description:
7176 * This function is called by the transport after the @fc_vport's symbolic name
7177 * has been changed. This function re-registers the symbolic name with the
Lucas De Marchi25985ed2011-03-30 22:57:33 -03007178 * switch to propagate the change into the fabric if the vport is active.
James Smarteada2722008-12-04 22:39:13 -05007179 **/
7180static void
7181lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport)
7182{
7183 struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
7184
7185 if (vport->port_state == LPFC_VPORT_READY)
7186 lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
7187}
dea31012005-04-17 16:05:31 -05007188
James Smartf4b4c682009-05-22 14:53:12 -04007189/**
7190 * lpfc_hba_log_verbose_init - Set hba's log verbose level
7191 * @phba: Pointer to lpfc_hba struct.
Lee Jonesa738bd92020-11-02 14:23:45 +00007192 * @verbose: Verbose level to set.
James Smartf4b4c682009-05-22 14:53:12 -04007193 *
7194 * This function is called by the lpfc_get_cfgparam() routine to set the
7195 * module lpfc_log_verbose into the @phba cfg_log_verbose for use with
Justin P. Mattock70f23fd2011-05-10 10:16:21 +02007196 * log message according to the module's lpfc_log_verbose parameter setting
James Smartf4b4c682009-05-22 14:53:12 -04007197 * before hba port or vport created.
7198 **/
7199static void
7200lpfc_hba_log_verbose_init(struct lpfc_hba *phba, uint32_t verbose)
7201{
7202 phba->cfg_log_verbose = verbose;
7203}
7204
dea31012005-04-17 16:05:31 -05007205struct fc_function_template lpfc_transport_functions = {
7206 /* fixed attributes the driver supports */
7207 .show_host_node_name = 1,
7208 .show_host_port_name = 1,
7209 .show_host_supported_classes = 1,
7210 .show_host_supported_fc4s = 1,
dea31012005-04-17 16:05:31 -05007211 .show_host_supported_speeds = 1,
7212 .show_host_maxframe_size = 1,
James Smart6c9231f2016-12-19 15:07:24 -08007213
7214 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
James Smarteada2722008-12-04 22:39:13 -05007215 .show_host_symbolic_name = 1,
dea31012005-04-17 16:05:31 -05007216
7217 /* dynamic attributes the driver supports */
7218 .get_host_port_id = lpfc_get_host_port_id,
7219 .show_host_port_id = 1,
7220
7221 .get_host_port_type = lpfc_get_host_port_type,
7222 .show_host_port_type = 1,
7223
7224 .get_host_port_state = lpfc_get_host_port_state,
7225 .show_host_port_state = 1,
7226
7227 /* active_fc4s is shown but doesn't change (thus no get function) */
7228 .show_host_active_fc4s = 1,
7229
7230 .get_host_speed = lpfc_get_host_speed,
7231 .show_host_speed = 1,
7232
7233 .get_host_fabric_name = lpfc_get_host_fabric_name,
7234 .show_host_fabric_name = 1,
7235
7236 /*
7237 * The LPFC driver treats linkdown handling as target loss events
7238 * so there are no sysfs handlers for link_down_tmo.
7239 */
7240
7241 .get_fc_host_stats = lpfc_get_stats,
James Smart64ba8812006-08-02 15:24:34 -04007242 .reset_fc_host_stats = lpfc_reset_stats,
dea31012005-04-17 16:05:31 -05007243
7244 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
7245 .show_rport_maxframe_size = 1,
7246 .show_rport_supported_classes = 1,
7247
dea31012005-04-17 16:05:31 -05007248 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
7249 .show_rport_dev_loss_tmo = 1,
7250
7251 .get_starget_port_id = lpfc_get_starget_port_id,
7252 .show_starget_port_id = 1,
7253
7254 .get_starget_node_name = lpfc_get_starget_node_name,
7255 .show_starget_node_name = 1,
7256
7257 .get_starget_port_name = lpfc_get_starget_port_name,
7258 .show_starget_port_name = 1,
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07007259
7260 .issue_fc_host_lip = lpfc_issue_lip,
James Smartc01f3202006-08-18 17:47:08 -04007261 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
7262 .terminate_rport_io = lpfc_terminate_rport_io,
James Smart92d7f7b2007-06-17 19:56:38 -05007263
James Smart92d7f7b2007-06-17 19:56:38 -05007264 .dd_fcvport_size = sizeof(struct lpfc_vport *),
James Smarteada2722008-12-04 22:39:13 -05007265
7266 .vport_disable = lpfc_vport_disable,
7267
7268 .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
James Smartf1c3b0f2009-07-19 10:01:32 -04007269
7270 .bsg_request = lpfc_bsg_request,
7271 .bsg_timeout = lpfc_bsg_timeout,
James Smart92d7f7b2007-06-17 19:56:38 -05007272};
7273
James Smart98c9ea52007-10-27 13:37:33 -04007274struct fc_function_template lpfc_vport_transport_functions = {
7275 /* fixed attributes the driver supports */
7276 .show_host_node_name = 1,
7277 .show_host_port_name = 1,
7278 .show_host_supported_classes = 1,
7279 .show_host_supported_fc4s = 1,
7280 .show_host_supported_speeds = 1,
7281 .show_host_maxframe_size = 1,
James Smart6c9231f2016-12-19 15:07:24 -08007282
7283 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
James Smarteada2722008-12-04 22:39:13 -05007284 .show_host_symbolic_name = 1,
James Smart98c9ea52007-10-27 13:37:33 -04007285
7286 /* dynamic attributes the driver supports */
7287 .get_host_port_id = lpfc_get_host_port_id,
7288 .show_host_port_id = 1,
7289
7290 .get_host_port_type = lpfc_get_host_port_type,
7291 .show_host_port_type = 1,
7292
7293 .get_host_port_state = lpfc_get_host_port_state,
7294 .show_host_port_state = 1,
7295
7296 /* active_fc4s is shown but doesn't change (thus no get function) */
7297 .show_host_active_fc4s = 1,
7298
7299 .get_host_speed = lpfc_get_host_speed,
7300 .show_host_speed = 1,
7301
7302 .get_host_fabric_name = lpfc_get_host_fabric_name,
7303 .show_host_fabric_name = 1,
7304
7305 /*
7306 * The LPFC driver treats linkdown handling as target loss events
7307 * so there are no sysfs handlers for link_down_tmo.
7308 */
7309
7310 .get_fc_host_stats = lpfc_get_stats,
7311 .reset_fc_host_stats = lpfc_reset_stats,
7312
7313 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
7314 .show_rport_maxframe_size = 1,
7315 .show_rport_supported_classes = 1,
7316
7317 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
7318 .show_rport_dev_loss_tmo = 1,
7319
7320 .get_starget_port_id = lpfc_get_starget_port_id,
7321 .show_starget_port_id = 1,
7322
7323 .get_starget_node_name = lpfc_get_starget_node_name,
7324 .show_starget_node_name = 1,
7325
7326 .get_starget_port_name = lpfc_get_starget_port_name,
7327 .show_starget_port_name = 1,
7328
7329 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
7330 .terminate_rport_io = lpfc_terminate_rport_io,
7331
7332 .vport_disable = lpfc_vport_disable,
James Smarteada2722008-12-04 22:39:13 -05007333
7334 .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
James Smart98c9ea52007-10-27 13:37:33 -04007335};
7336
James Smarte59058c2008-08-24 21:49:00 -04007337/**
James Smart4945c0f2019-08-14 16:57:02 -07007338 * lpfc_get_hba_function_mode - Used to determine the HBA function in FCoE
7339 * Mode
7340 * @phba: lpfc_hba pointer.
7341 **/
7342static void
7343lpfc_get_hba_function_mode(struct lpfc_hba *phba)
7344{
James Smart412e7372019-09-21 20:59:04 -07007345 /* If the adapter supports FCoE mode */
7346 switch (phba->pcidev->device) {
7347 case PCI_DEVICE_ID_SKYHAWK:
7348 case PCI_DEVICE_ID_SKYHAWK_VF:
7349 case PCI_DEVICE_ID_LANCER_FCOE:
7350 case PCI_DEVICE_ID_LANCER_FCOE_VF:
7351 case PCI_DEVICE_ID_ZEPHYR_DCSP:
7352 case PCI_DEVICE_ID_HORNET:
7353 case PCI_DEVICE_ID_TIGERSHARK:
7354 case PCI_DEVICE_ID_TOMCAT:
James Smart4945c0f2019-08-14 16:57:02 -07007355 phba->hba_flag |= HBA_FCOE_MODE;
James Smart412e7372019-09-21 20:59:04 -07007356 break;
7357 default:
7358 /* for others, clear the flag */
James Smart4945c0f2019-08-14 16:57:02 -07007359 phba->hba_flag &= ~HBA_FCOE_MODE;
James Smart412e7372019-09-21 20:59:04 -07007360 }
James Smart4945c0f2019-08-14 16:57:02 -07007361}
7362
7363/**
James Smart3621a712009-04-06 18:47:14 -04007364 * lpfc_get_cfgparam - Used during probe_one to init the adapter structure
James Smarte59058c2008-08-24 21:49:00 -04007365 * @phba: lpfc_hba pointer.
7366 **/
dea31012005-04-17 16:05:31 -05007367void
7368lpfc_get_cfgparam(struct lpfc_hba *phba)
7369{
James Smartdcaa2132019-11-04 16:57:06 -08007370 lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
James Smart49aa1432012-08-03 12:36:42 -04007371 lpfc_fcp_io_sched_init(phba, lpfc_fcp_io_sched);
James Smart7ea92eb2018-10-23 13:41:10 -07007372 lpfc_ns_query_init(phba, lpfc_ns_query);
James Smarta6571c62012-10-31 14:44:42 -04007373 lpfc_fcp2_no_tgt_reset_init(phba, lpfc_fcp2_no_tgt_reset);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007374 lpfc_cr_delay_init(phba, lpfc_cr_delay);
7375 lpfc_cr_count_init(phba, lpfc_cr_count);
Jamie Wellnitzcf5bf972006-02-28 22:33:08 -05007376 lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
James Smarta4bc3372006-12-02 13:34:16 -05007377 lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
7378 lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007379 lpfc_ack0_init(phba, lpfc_ack0);
James Smartc4908502019-01-28 11:14:28 -08007380 lpfc_xri_rebalancing_init(phba, lpfc_xri_rebalancing);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007381 lpfc_topology_init(phba, lpfc_topology);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007382 lpfc_link_speed_init(phba, lpfc_link_speed);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05007383 lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
James Smart0c411222013-09-06 12:22:46 -04007384 lpfc_task_mgmt_tmo_init(phba, lpfc_task_mgmt_tmo);
James Smart78b2d852007-08-02 11:10:21 -04007385 lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
James Smart7d791df2011-07-22 18:37:52 -04007386 lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy);
James Smart19ca7602010-11-20 23:11:55 -05007387 lpfc_enable_rrq_init(phba, lpfc_enable_rrq);
James Smart3e49af92021-05-14 12:55:57 -07007388 lpfc_fcp_wait_abts_rsp_init(phba, lpfc_fcp_wait_abts_rsp);
James Smart4258e982015-12-16 18:11:58 -05007389 lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
7390 lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
James Smart4ff43242006-12-02 13:34:56 -05007391 lpfc_use_msi_init(phba, lpfc_use_msi);
James Smart895427b2017-02-12 13:52:30 -08007392 lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
James Smart4e565cf2018-02-22 08:18:50 -08007393 lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
James Smartda0436e2009-05-22 14:51:39 -04007394 lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
James Smart41b194b2019-05-14 14:58:08 -07007395 lpfc_force_rscn_init(phba, lpfc_force_rscn);
James Smart32517fc2019-01-28 11:14:33 -08007396 lpfc_cq_poll_threshold_init(phba, lpfc_cq_poll_threshold);
7397 lpfc_cq_max_proc_limit_init(phba, lpfc_cq_max_proc_limit);
James Smart7bb03bb2013-04-17 20:19:16 -04007398 lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
James Smart13815c82008-01-11 01:52:48 -05007399 lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
7400 lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
James Smart2ea259e2017-02-12 13:52:27 -08007401
James Smart1ba981f2014-02-20 09:56:45 -05007402 lpfc_EnableXLane_init(phba, lpfc_EnableXLane);
Gaurav Srivastava7ba22722021-06-08 10:05:48 +05307403 /* VMID Inits */
7404 lpfc_max_vmid_init(phba, lpfc_max_vmid);
7405 lpfc_vmid_inactivity_timeout_init(phba, lpfc_vmid_inactivity_timeout);
7406 lpfc_vmid_app_header_init(phba, lpfc_vmid_app_header);
7407 lpfc_vmid_priority_tagging_init(phba, lpfc_vmid_priority_tagging);
James Smart1ba981f2014-02-20 09:56:45 -05007408 if (phba->sli_rev != LPFC_SLI_REV4)
7409 phba->cfg_EnableXLane = 0;
7410 lpfc_XLanePriority_init(phba, lpfc_XLanePriority);
James Smart2ea259e2017-02-12 13:52:27 -08007411
James Smart1ba981f2014-02-20 09:56:45 -05007412 memset(phba->cfg_oas_tgt_wwpn, 0, (8 * sizeof(uint8_t)));
7413 memset(phba->cfg_oas_vpt_wwpn, 0, (8 * sizeof(uint8_t)));
7414 phba->cfg_oas_lun_state = 0;
7415 phba->cfg_oas_lun_status = 0;
7416 phba->cfg_oas_flags = 0;
James Smartc92c8412016-07-06 12:36:05 -07007417 phba->cfg_oas_priority = 0;
James Smart81301a92008-12-04 22:39:46 -05007418 lpfc_enable_bg_init(phba, lpfc_enable_bg);
James Smartb3b98b72016-10-13 15:06:06 -07007419 lpfc_prot_mask_init(phba, lpfc_prot_mask);
7420 lpfc_prot_guard_init(phba, lpfc_prot_guard);
James Smart45ed1192009-10-02 15:17:02 -04007421 if (phba->sli_rev == LPFC_SLI_REV4)
7422 phba->cfg_poll = 0;
7423 else
James Smart1ba981f2014-02-20 09:56:45 -05007424 phba->cfg_poll = lpfc_poll;
James Smartf44ac122018-03-05 12:04:08 -08007425
James Smart4945c0f2019-08-14 16:57:02 -07007426 /* Get the function mode */
7427 lpfc_get_hba_function_mode(phba);
7428
7429 /* BlockGuard allowed for FC only. */
7430 if (phba->cfg_enable_bg && phba->hba_flag & HBA_FCOE_MODE) {
7431 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
7432 "0581 BlockGuard feature not supported\n");
7433 /* If set, clear the BlockGuard support param */
7434 phba->cfg_enable_bg = 0;
7435 } else if (phba->cfg_enable_bg) {
James Smartf44ac122018-03-05 12:04:08 -08007436 phba->sli3_options |= LPFC_SLI3_BG_ENABLED;
James Smart4945c0f2019-08-14 16:57:02 -07007437 }
James Smartf44ac122018-03-05 12:04:08 -08007438
James Smartf358dd02017-02-12 13:52:34 -08007439 lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp);
James Smart4258e982015-12-16 18:11:58 -05007440
James Smart895427b2017-02-12 13:52:30 -08007441 lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type);
James Smart2d7dbc42017-02-12 13:52:35 -08007442 lpfc_nvmet_mrq_init(phba, lpfc_nvmet_mrq);
James Smart2448e482018-04-09 14:24:24 -07007443 lpfc_nvmet_mrq_post_init(phba, lpfc_nvmet_mrq_post);
James Smart895427b2017-02-12 13:52:30 -08007444
7445 /* Initialize first burst. Target vs Initiator are different. */
7446 lpfc_nvme_enable_fb_init(phba, lpfc_nvme_enable_fb);
James Smart2d7dbc42017-02-12 13:52:35 -08007447 lpfc_nvmet_fb_size_init(phba, lpfc_nvmet_fb_size);
James Smart77ffd342019-08-15 19:36:49 -07007448 lpfc_fcp_mq_threshold_init(phba, lpfc_fcp_mq_threshold);
James Smartcdb42be2019-01-28 11:14:21 -08007449 lpfc_hdw_queue_init(phba, lpfc_hdw_queue);
James Smart6a828b02019-01-28 11:14:31 -08007450 lpfc_irq_chann_init(phba, lpfc_irq_chann);
James Smart44fd7fe2017-08-23 16:55:47 -07007451 lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
James Smart1351e692018-02-22 08:18:43 -08007452 lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
James Smart8aaa7bc2020-10-20 13:27:17 -07007453 lpfc_enable_mi_init(phba, lpfc_enable_mi);
James Smart895427b2017-02-12 13:52:30 -08007454
7455 if (phba->sli_rev != LPFC_SLI_REV4) {
7456 /* NVME only supported on SLI4 */
7457 phba->nvmet_support = 0;
James Smart982ab122019-03-12 16:30:10 -07007458 phba->cfg_nvmet_mrq = 0;
James Smart895427b2017-02-12 13:52:30 -08007459 phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
James Smart44fd7fe2017-08-23 16:55:47 -07007460 phba->cfg_enable_bbcr = 0;
James Smartc4908502019-01-28 11:14:28 -08007461 phba->cfg_xri_rebalancing = 0;
James Smart895427b2017-02-12 13:52:30 -08007462 } else {
7463 /* We MUST have FCP support */
7464 if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
7465 phba->cfg_enable_fc4_type |= LPFC_ENABLE_FCP;
7466 }
7467
James Smart32517fc2019-01-28 11:14:33 -08007468 phba->cfg_auto_imax = (phba->cfg_fcp_imax) ? 0 : 1;
James Smart0cf07f842017-06-01 21:07:10 -07007469
James Smart06b6fa382018-07-31 17:23:24 -07007470 phba->cfg_enable_pbde = 0;
7471
James Smart895427b2017-02-12 13:52:30 -08007472 /* A value of 0 means use the number of CPUs found in the system */
James Smartcdb42be2019-01-28 11:14:21 -08007473 if (phba->cfg_hdw_queue == 0)
7474 phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
James Smart6a828b02019-01-28 11:14:31 -08007475 if (phba->cfg_irq_chann == 0)
7476 phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
James Smartd3de0d12021-04-11 18:31:21 -07007477 if (phba->cfg_irq_chann > phba->cfg_hdw_queue &&
7478 phba->sli_rev == LPFC_SLI_REV4)
James Smart6a828b02019-01-28 11:14:31 -08007479 phba->cfg_irq_chann = phba->cfg_hdw_queue;
James Smart4258e982015-12-16 18:11:58 -05007480
James Smart352e5fd2016-12-30 06:57:47 -08007481 phba->cfg_soft_wwnn = 0L;
7482 phba->cfg_soft_wwpn = 0L;
James Smart83108bd2008-01-11 01:53:09 -05007483 lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
James Smart7054a602007-04-25 09:52:34 -04007484 lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
James Smart0d878412009-10-02 15:16:56 -04007485 lpfc_aer_support_init(phba, lpfc_aer_support);
James Smart912e3ac2011-05-24 11:42:11 -04007486 lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn);
James Smartc71ab862012-10-31 14:44:33 -04007487 lpfc_request_firmware_upgrade_init(phba, lpfc_req_fw_upgrade);
James Smart84d1b002010-02-12 14:42:33 -05007488 lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up);
James Smart8eb8b962016-07-06 12:36:08 -07007489 lpfc_delay_discovery_init(phba, lpfc_delay_discovery);
James Smart12247e82016-07-06 12:36:09 -07007490 lpfc_sli_mode_init(phba, lpfc_sli_mode);
James Smart7bdedb32016-07-06 12:36:00 -07007491 lpfc_enable_mds_diags_init(phba, lpfc_enable_mds_diags);
James Smartd2cc9bc2018-09-10 10:30:50 -07007492 lpfc_ras_fwlog_buffsize_init(phba, lpfc_ras_fwlog_buffsize);
7493 lpfc_ras_fwlog_level_init(phba, lpfc_ras_fwlog_level);
7494 lpfc_ras_fwlog_func_init(phba, lpfc_ras_fwlog_func);
7495
James Smart3de2a652007-08-02 11:09:59 -04007496 return;
7497}
Jamie Wellnitzb28485a2006-02-28 19:25:21 -05007498
James Smarte59058c2008-08-24 21:49:00 -04007499/**
James Smart895427b2017-02-12 13:52:30 -08007500 * lpfc_nvme_mod_param_dep - Adjust module parameter value based on
7501 * dependencies between protocols and roles.
7502 * @phba: lpfc_hba pointer.
7503 **/
7504void
7505lpfc_nvme_mod_param_dep(struct lpfc_hba *phba)
7506{
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007507 int logit = 0;
7508
7509 if (phba->cfg_hdw_queue > phba->sli4_hba.num_present_cpu) {
James Smartcdb42be2019-01-28 11:14:21 -08007510 phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007511 logit = 1;
7512 }
7513 if (phba->cfg_irq_chann > phba->sli4_hba.num_present_cpu) {
James Smart6a828b02019-01-28 11:14:31 -08007514 phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007515 logit = 1;
7516 }
7517 if (phba->cfg_irq_chann > phba->cfg_hdw_queue) {
James Smart6a828b02019-01-28 11:14:31 -08007518 phba->cfg_irq_chann = phba->cfg_hdw_queue;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007519 logit = 1;
7520 }
7521 if (logit)
7522 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
7523 "2006 Reducing Queues - CPU limitation: "
7524 "IRQ %d HDWQ %d\n",
7525 phba->cfg_irq_chann,
7526 phba->cfg_hdw_queue);
James Smart895427b2017-02-12 13:52:30 -08007527
James Smartf358dd02017-02-12 13:52:34 -08007528 if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME &&
7529 phba->nvmet_support) {
7530 phba->cfg_enable_fc4_type &= ~LPFC_ENABLE_FCP;
James Smart2d7dbc42017-02-12 13:52:35 -08007531
7532 lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
7533 "6013 %s x%x fb_size x%x, fb_max x%x\n",
7534 "NVME Target PRLI ACC enable_fb ",
7535 phba->cfg_nvme_enable_fb,
7536 phba->cfg_nvmet_fb_size,
7537 LPFC_NVMET_FB_SZ_MAX);
7538
7539 if (phba->cfg_nvme_enable_fb == 0)
7540 phba->cfg_nvmet_fb_size = 0;
7541 else {
7542 if (phba->cfg_nvmet_fb_size > LPFC_NVMET_FB_SZ_MAX)
7543 phba->cfg_nvmet_fb_size = LPFC_NVMET_FB_SZ_MAX;
7544 }
7545
James Smartbcb24f62017-11-20 16:00:36 -08007546 if (!phba->cfg_nvmet_mrq)
James Smart97a9ed32019-10-18 14:18:17 -07007547 phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
James Smartbcb24f62017-11-20 16:00:36 -08007548
James Smart2d7dbc42017-02-12 13:52:35 -08007549 /* Adjust lpfc_nvmet_mrq to avoid running out of WQE slots */
James Smart97a9ed32019-10-18 14:18:17 -07007550 if (phba->cfg_nvmet_mrq > phba->cfg_hdw_queue) {
7551 phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
James Smart2d7dbc42017-02-12 13:52:35 -08007552 lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC,
7553 "6018 Adjust lpfc_nvmet_mrq to %d\n",
7554 phba->cfg_nvmet_mrq);
7555 }
James Smartbcb24f62017-11-20 16:00:36 -08007556 if (phba->cfg_nvmet_mrq > LPFC_NVMET_MRQ_MAX)
7557 phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_MAX;
7558
James Smart2d7dbc42017-02-12 13:52:35 -08007559 } else {
James Smartf358dd02017-02-12 13:52:34 -08007560 /* Not NVME Target mode. Turn off Target parameters. */
7561 phba->nvmet_support = 0;
James Smart982ab122019-03-12 16:30:10 -07007562 phba->cfg_nvmet_mrq = 0;
James Smart2d7dbc42017-02-12 13:52:35 -08007563 phba->cfg_nvmet_fb_size = 0;
7564 }
James Smart895427b2017-02-12 13:52:30 -08007565}
7566
7567/**
James Smart3621a712009-04-06 18:47:14 -04007568 * lpfc_get_vport_cfgparam - Used during port create, init the vport structure
James Smarte59058c2008-08-24 21:49:00 -04007569 * @vport: lpfc_vport pointer.
7570 **/
James Smart3de2a652007-08-02 11:09:59 -04007571void
7572lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
7573{
James Smarte8b62012007-08-02 11:10:09 -04007574 lpfc_log_verbose_init(vport, lpfc_log_verbose);
James Smart3de2a652007-08-02 11:09:59 -04007575 lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth);
James Smart7dc517d2010-07-14 15:32:10 -04007576 lpfc_tgt_queue_depth_init(vport, lpfc_tgt_queue_depth);
James Smart3de2a652007-08-02 11:09:59 -04007577 lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo);
7578 lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo);
7579 lpfc_peer_port_login_init(vport, lpfc_peer_port_login);
7580 lpfc_restrict_login_init(vport, lpfc_restrict_login);
7581 lpfc_fcp_class_init(vport, lpfc_fcp_class);
7582 lpfc_use_adisc_init(vport, lpfc_use_adisc);
James Smart3cb01c52013-07-15 18:35:04 -04007583 lpfc_first_burst_size_init(vport, lpfc_first_burst_size);
James Smart977b5a02008-09-07 11:52:04 -04007584 lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time);
James Smart3de2a652007-08-02 11:09:59 -04007585 lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
7586 lpfc_max_luns_init(vport, lpfc_max_luns);
7587 lpfc_scan_down_init(vport, lpfc_scan_down);
James Smart7ee5d432007-10-27 13:37:17 -04007588 lpfc_enable_da_id_init(vport, lpfc_enable_da_id);
dea31012005-04-17 16:05:31 -05007589 return;
7590}