blob: a5154856bc0f698c4f8b95ef3027ade39bf4053e [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 Smartf6c5e6c2021-07-22 15:17:18 -07004041 u8 sli_family, if_type;
James Smarta257bf92009-04-06 18:48:10 -04004042
4043 if (!strncmp(buf, "nolip ", strlen("nolip "))) {
4044 nolip = 1;
4045 val_buf = &buf[strlen("nolip ")];
4046 }
4047
4048 if (!isdigit(val_buf[0]))
4049 return -EINVAL;
4050 if (sscanf(val_buf, "%i", &val) != 1)
4051 return -EINVAL;
4052
James Smart83108bd2008-01-11 01:53:09 -05004053 if (val >= 0 && val <= 6) {
4054 prev_val = phba->cfg_topology;
James Smartff78d8f2011-12-13 13:21:35 -05004055 if (phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G &&
4056 val == 4) {
4057 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4058 "3113 Loop mode not supported at speed %d\n",
James Smartd38dd522015-08-31 16:48:17 -04004059 val);
James Smartff78d8f2011-12-13 13:21:35 -05004060 return -EINVAL;
4061 }
James Smart83c6cb12019-10-18 14:18:30 -07004062 /*
4063 * The 'topology' is not a configurable parameter if :
4064 * - persistent topology enabled
James Smartf6c5e6c2021-07-22 15:17:18 -07004065 * - ASIC_GEN_NUM >= 0xC, with no private loop support
James Smart83c6cb12019-10-18 14:18:30 -07004066 */
James Smartf6c5e6c2021-07-22 15:17:18 -07004067 sli_family = bf_get(lpfc_sli_intf_sli_family,
4068 &phba->sli4_hba.sli_intf);
4069 if_type = bf_get(lpfc_sli_intf_if_type,
4070 &phba->sli4_hba.sli_intf);
James Smarta052ce82019-12-18 15:58:04 -08004071 if ((phba->hba_flag & HBA_PERSISTENT_TOPO ||
James Smartf6c5e6c2021-07-22 15:17:18 -07004072 (!phba->sli4_hba.pc_sli4_params.pls &&
4073 (sli_family == LPFC_SLI_INTF_FAMILY_G6 ||
4074 if_type == LPFC_SLI_INTF_IF_TYPE_6))) &&
James Smartf6978f42019-05-21 17:48:57 -07004075 val == 4) {
James Smartd38dd522015-08-31 16:48:17 -04004076 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartf6978f42019-05-21 17:48:57 -07004077 "3114 Loop mode not supported\n");
James Smartd38dd522015-08-31 16:48:17 -04004078 return -EINVAL;
4079 }
4080 phba->cfg_topology = val;
James Smarta257bf92009-04-06 18:48:10 -04004081 if (nolip)
4082 return strlen(buf);
4083
James Smart88a2cfb2011-07-22 18:36:33 -04004084 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4085 "3054 lpfc_topology changed from %d to %d\n",
4086 prev_val, val);
James Smarte74c03c2013-04-17 20:15:19 -04004087 if (prev_val != val && phba->sli_rev == LPFC_SLI_REV4)
4088 phba->fc_topology_changed = 1;
James Smart83108bd2008-01-11 01:53:09 -05004089 err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
James Smarta257bf92009-04-06 18:48:10 -04004090 if (err) {
James Smart83108bd2008-01-11 01:53:09 -05004091 phba->cfg_topology = prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004092 return -EINVAL;
4093 } else
4094 return strlen(buf);
James Smart83108bd2008-01-11 01:53:09 -05004095 }
4096 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4097 "%d:0467 lpfc_topology attribute cannot be set to %d, "
4098 "allowed range is [0, 6]\n",
4099 phba->brd_no, val);
4100 return -EINVAL;
4101}
James Smart0a035432016-10-13 15:06:10 -07004102
James Smart83108bd2008-01-11 01:53:09 -05004103lpfc_param_show(topology)
Joe Perchesb6b996b2017-12-19 10:15:07 -08004104static DEVICE_ATTR_RW(lpfc_topology);
dea31012005-04-17 16:05:31 -05004105
James Smart21e9a0a2009-05-22 14:53:21 -04004106/**
4107 * lpfc_static_vport_show: Read callback function for
4108 * lpfc_static_vport sysfs file.
4109 * @dev: Pointer to class device object.
4110 * @attr: device attribute structure.
4111 * @buf: Data buffer.
4112 *
4113 * This function is the read call back function for
4114 * lpfc_static_vport sysfs file. The lpfc_static_vport
4115 * sysfs file report the mageability of the vport.
4116 **/
4117static ssize_t
4118lpfc_static_vport_show(struct device *dev, struct device_attribute *attr,
4119 char *buf)
4120{
4121 struct Scsi_Host *shost = class_to_shost(dev);
4122 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4123 if (vport->vport_flag & STATIC_VPORT)
4124 sprintf(buf, "1\n");
4125 else
4126 sprintf(buf, "0\n");
4127
4128 return strlen(buf);
4129}
4130
4131/*
4132 * Sysfs attribute to control the statistical data collection.
4133 */
Joe Perchesc828a892017-12-19 10:15:08 -08004134static DEVICE_ATTR_RO(lpfc_static_vport);
James Smartea2151b2008-09-07 11:52:10 -04004135
4136/**
James Smart3621a712009-04-06 18:47:14 -04004137 * lpfc_stat_data_ctrl_store - write call back for lpfc_stat_data_ctrl sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004138 * @dev: Pointer to class device.
Lee Jonesa738bd92020-11-02 14:23:45 +00004139 * @attr: Unused.
James Smartea2151b2008-09-07 11:52:10 -04004140 * @buf: Data buffer.
4141 * @count: Size of the data buffer.
4142 *
Masahiro Yamada9332ef92017-02-27 14:28:47 -08004143 * This function get called when a user write to the lpfc_stat_data_ctrl
James Smartea2151b2008-09-07 11:52:10 -04004144 * sysfs file. This function parse the command written to the sysfs file
4145 * and take appropriate action. These commands are used for controlling
4146 * driver statistical data collection.
4147 * Following are the command this function handles.
4148 *
4149 * setbucket <bucket_type> <base> <step>
4150 * = Set the latency buckets.
4151 * destroybucket = destroy all the buckets.
4152 * start = start data collection
4153 * stop = stop data collection
4154 * reset = reset the collected data
4155 **/
4156static ssize_t
4157lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
4158 const char *buf, size_t count)
4159{
4160 struct Scsi_Host *shost = class_to_shost(dev);
4161 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4162 struct lpfc_hba *phba = vport->phba;
4163#define LPFC_MAX_DATA_CTRL_LEN 1024
4164 static char bucket_data[LPFC_MAX_DATA_CTRL_LEN];
4165 unsigned long i;
4166 char *str_ptr, *token;
4167 struct lpfc_vport **vports;
4168 struct Scsi_Host *v_shost;
4169 char *bucket_type_str, *base_str, *step_str;
4170 unsigned long base, step, bucket_type;
4171
4172 if (!strncmp(buf, "setbucket", strlen("setbucket"))) {
James Smarta257bf92009-04-06 18:48:10 -04004173 if (strlen(buf) > (LPFC_MAX_DATA_CTRL_LEN - 1))
James Smartea2151b2008-09-07 11:52:10 -04004174 return -EINVAL;
4175
James Smarteb016562014-09-03 12:58:06 -04004176 strncpy(bucket_data, buf, LPFC_MAX_DATA_CTRL_LEN);
James Smartea2151b2008-09-07 11:52:10 -04004177 str_ptr = &bucket_data[0];
4178 /* Ignore this token - this is command token */
4179 token = strsep(&str_ptr, "\t ");
4180 if (!token)
4181 return -EINVAL;
4182
4183 bucket_type_str = strsep(&str_ptr, "\t ");
4184 if (!bucket_type_str)
4185 return -EINVAL;
4186
4187 if (!strncmp(bucket_type_str, "linear", strlen("linear")))
4188 bucket_type = LPFC_LINEAR_BUCKET;
4189 else if (!strncmp(bucket_type_str, "power2", strlen("power2")))
4190 bucket_type = LPFC_POWER2_BUCKET;
4191 else
4192 return -EINVAL;
4193
4194 base_str = strsep(&str_ptr, "\t ");
4195 if (!base_str)
4196 return -EINVAL;
4197 base = simple_strtoul(base_str, NULL, 0);
4198
4199 step_str = strsep(&str_ptr, "\t ");
4200 if (!step_str)
4201 return -EINVAL;
4202 step = simple_strtoul(step_str, NULL, 0);
4203 if (!step)
4204 return -EINVAL;
4205
4206 /* Block the data collection for every vport */
4207 vports = lpfc_create_vport_work_array(phba);
4208 if (vports == NULL)
4209 return -ENOMEM;
4210
James Smartf4b4c682009-05-22 14:53:12 -04004211 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004212 v_shost = lpfc_shost_from_vport(vports[i]);
4213 spin_lock_irq(v_shost->host_lock);
4214 /* Block and reset data collection */
4215 vports[i]->stat_data_blocked = 1;
4216 if (vports[i]->stat_data_enabled)
4217 lpfc_vport_reset_stat_data(vports[i]);
4218 spin_unlock_irq(v_shost->host_lock);
4219 }
4220
4221 /* Set the bucket attributes */
4222 phba->bucket_type = bucket_type;
4223 phba->bucket_base = base;
4224 phba->bucket_step = step;
4225
James Smartf4b4c682009-05-22 14:53:12 -04004226 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004227 v_shost = lpfc_shost_from_vport(vports[i]);
4228
4229 /* Unblock data collection */
4230 spin_lock_irq(v_shost->host_lock);
4231 vports[i]->stat_data_blocked = 0;
4232 spin_unlock_irq(v_shost->host_lock);
4233 }
4234 lpfc_destroy_vport_work_array(phba, vports);
4235 return strlen(buf);
4236 }
4237
4238 if (!strncmp(buf, "destroybucket", strlen("destroybucket"))) {
4239 vports = lpfc_create_vport_work_array(phba);
4240 if (vports == NULL)
4241 return -ENOMEM;
4242
James Smartf4b4c682009-05-22 14:53:12 -04004243 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004244 v_shost = lpfc_shost_from_vport(vports[i]);
4245 spin_lock_irq(shost->host_lock);
4246 vports[i]->stat_data_blocked = 1;
4247 lpfc_free_bucket(vport);
4248 vport->stat_data_enabled = 0;
4249 vports[i]->stat_data_blocked = 0;
4250 spin_unlock_irq(shost->host_lock);
4251 }
4252 lpfc_destroy_vport_work_array(phba, vports);
4253 phba->bucket_type = LPFC_NO_BUCKET;
4254 phba->bucket_base = 0;
4255 phba->bucket_step = 0;
4256 return strlen(buf);
4257 }
4258
4259 if (!strncmp(buf, "start", strlen("start"))) {
4260 /* If no buckets configured return error */
4261 if (phba->bucket_type == LPFC_NO_BUCKET)
4262 return -EINVAL;
4263 spin_lock_irq(shost->host_lock);
4264 if (vport->stat_data_enabled) {
4265 spin_unlock_irq(shost->host_lock);
4266 return strlen(buf);
4267 }
4268 lpfc_alloc_bucket(vport);
4269 vport->stat_data_enabled = 1;
4270 spin_unlock_irq(shost->host_lock);
4271 return strlen(buf);
4272 }
4273
4274 if (!strncmp(buf, "stop", strlen("stop"))) {
4275 spin_lock_irq(shost->host_lock);
4276 if (vport->stat_data_enabled == 0) {
4277 spin_unlock_irq(shost->host_lock);
4278 return strlen(buf);
4279 }
4280 lpfc_free_bucket(vport);
4281 vport->stat_data_enabled = 0;
4282 spin_unlock_irq(shost->host_lock);
4283 return strlen(buf);
4284 }
4285
4286 if (!strncmp(buf, "reset", strlen("reset"))) {
4287 if ((phba->bucket_type == LPFC_NO_BUCKET)
4288 || !vport->stat_data_enabled)
4289 return strlen(buf);
4290 spin_lock_irq(shost->host_lock);
4291 vport->stat_data_blocked = 1;
4292 lpfc_vport_reset_stat_data(vport);
4293 vport->stat_data_blocked = 0;
4294 spin_unlock_irq(shost->host_lock);
4295 return strlen(buf);
4296 }
4297 return -EINVAL;
4298}
4299
4300
4301/**
James Smart3621a712009-04-06 18:47:14 -04004302 * lpfc_stat_data_ctrl_show - Read function for lpfc_stat_data_ctrl sysfs file
Lee Jonesa738bd92020-11-02 14:23:45 +00004303 * @dev: Pointer to class device.
4304 * @attr: Unused.
James Smartea2151b2008-09-07 11:52:10 -04004305 * @buf: Data buffer.
4306 *
4307 * This function is the read call back function for
4308 * lpfc_stat_data_ctrl sysfs file. This function report the
4309 * current statistical data collection state.
4310 **/
4311static ssize_t
4312lpfc_stat_data_ctrl_show(struct device *dev, struct device_attribute *attr,
4313 char *buf)
4314{
4315 struct Scsi_Host *shost = class_to_shost(dev);
4316 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4317 struct lpfc_hba *phba = vport->phba;
4318 int index = 0;
4319 int i;
4320 char *bucket_type;
4321 unsigned long bucket_value;
4322
4323 switch (phba->bucket_type) {
4324 case LPFC_LINEAR_BUCKET:
4325 bucket_type = "linear";
4326 break;
4327 case LPFC_POWER2_BUCKET:
4328 bucket_type = "power2";
4329 break;
4330 default:
4331 bucket_type = "No Bucket";
4332 break;
4333 }
4334
4335 sprintf(&buf[index], "Statistical Data enabled :%d, "
4336 "blocked :%d, Bucket type :%s, Bucket base :%d,"
4337 " Bucket step :%d\nLatency Ranges :",
4338 vport->stat_data_enabled, vport->stat_data_blocked,
4339 bucket_type, phba->bucket_base, phba->bucket_step);
4340 index = strlen(buf);
4341 if (phba->bucket_type != LPFC_NO_BUCKET) {
4342 for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
4343 if (phba->bucket_type == LPFC_LINEAR_BUCKET)
4344 bucket_value = phba->bucket_base +
4345 phba->bucket_step * i;
4346 else
4347 bucket_value = phba->bucket_base +
4348 (1 << i) * phba->bucket_step;
4349
4350 if (index + 10 > PAGE_SIZE)
4351 break;
4352 sprintf(&buf[index], "%08ld ", bucket_value);
4353 index = strlen(buf);
4354 }
4355 }
4356 sprintf(&buf[index], "\n");
4357 return strlen(buf);
4358}
4359
4360/*
4361 * Sysfs attribute to control the statistical data collection.
4362 */
Joe Perchesb6b996b2017-12-19 10:15:07 -08004363static DEVICE_ATTR_RW(lpfc_stat_data_ctrl);
James Smartea2151b2008-09-07 11:52:10 -04004364
4365/*
4366 * lpfc_drvr_stat_data: sysfs attr to get driver statistical data.
4367 */
4368
4369/*
4370 * Each Bucket takes 11 characters and 1 new line + 17 bytes WWN
4371 * for each target.
4372 */
4373#define STAT_DATA_SIZE_PER_TARGET(NUM_BUCKETS) ((NUM_BUCKETS) * 11 + 18)
4374#define MAX_STAT_DATA_SIZE_PER_TARGET \
4375 STAT_DATA_SIZE_PER_TARGET(LPFC_MAX_BUCKET_COUNT)
4376
4377
4378/**
James Smart3621a712009-04-06 18:47:14 -04004379 * sysfs_drvr_stat_data_read - Read function for lpfc_drvr_stat_data attribute
Chris Wright2c3c8be2010-05-12 18:28:57 -07004380 * @filp: sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004381 * @kobj: Pointer to the kernel object
4382 * @bin_attr: Attribute object
Lee Jonesa738bd92020-11-02 14:23:45 +00004383 * @buf: Buffer pointer
James Smartea2151b2008-09-07 11:52:10 -04004384 * @off: File offset
4385 * @count: Buffer size
4386 *
4387 * This function is the read call back function for lpfc_drvr_stat_data
4388 * sysfs file. This function export the statistical data to user
4389 * applications.
4390 **/
4391static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07004392sysfs_drvr_stat_data_read(struct file *filp, struct kobject *kobj,
4393 struct bin_attribute *bin_attr,
James Smartea2151b2008-09-07 11:52:10 -04004394 char *buf, loff_t off, size_t count)
4395{
4396 struct device *dev = container_of(kobj, struct device,
4397 kobj);
4398 struct Scsi_Host *shost = class_to_shost(dev);
4399 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4400 struct lpfc_hba *phba = vport->phba;
4401 int i = 0, index = 0;
4402 unsigned long nport_index;
4403 struct lpfc_nodelist *ndlp = NULL;
4404 nport_index = (unsigned long)off /
4405 MAX_STAT_DATA_SIZE_PER_TARGET;
4406
4407 if (!vport->stat_data_enabled || vport->stat_data_blocked
4408 || (phba->bucket_type == LPFC_NO_BUCKET))
4409 return 0;
4410
4411 spin_lock_irq(shost->host_lock);
4412 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart307e3382020-11-15 11:26:30 -08004413 if (!ndlp->lat_data)
James Smartea2151b2008-09-07 11:52:10 -04004414 continue;
4415
4416 if (nport_index > 0) {
4417 nport_index--;
4418 continue;
4419 }
4420
4421 if ((index + MAX_STAT_DATA_SIZE_PER_TARGET)
4422 > count)
4423 break;
4424
4425 if (!ndlp->lat_data)
4426 continue;
4427
4428 /* Print the WWN */
4429 sprintf(&buf[index], "%02x%02x%02x%02x%02x%02x%02x%02x:",
4430 ndlp->nlp_portname.u.wwn[0],
4431 ndlp->nlp_portname.u.wwn[1],
4432 ndlp->nlp_portname.u.wwn[2],
4433 ndlp->nlp_portname.u.wwn[3],
4434 ndlp->nlp_portname.u.wwn[4],
4435 ndlp->nlp_portname.u.wwn[5],
4436 ndlp->nlp_portname.u.wwn[6],
4437 ndlp->nlp_portname.u.wwn[7]);
4438
4439 index = strlen(buf);
4440
4441 for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
4442 sprintf(&buf[index], "%010u,",
4443 ndlp->lat_data[i].cmd_count);
4444 index = strlen(buf);
4445 }
4446 sprintf(&buf[index], "\n");
4447 index = strlen(buf);
4448 }
4449 spin_unlock_irq(shost->host_lock);
4450 return index;
4451}
4452
4453static struct bin_attribute sysfs_drvr_stat_data_attr = {
4454 .attr = {
4455 .name = "lpfc_drvr_stat_data",
4456 .mode = S_IRUSR,
James Smartea2151b2008-09-07 11:52:10 -04004457 },
4458 .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET,
4459 .read = sysfs_drvr_stat_data_read,
4460 .write = NULL,
4461};
4462
dea31012005-04-17 16:05:31 -05004463/*
4464# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
4465# connection.
James Smart76a95d72010-11-20 23:11:48 -05004466# Value range is [0,16]. Default value is 0.
dea31012005-04-17 16:05:31 -05004467*/
James Smarte59058c2008-08-24 21:49:00 -04004468/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00004469 * lpfc_link_speed_store - Set the adapters link speed
Lee Jonesa738bd92020-11-02 14:23:45 +00004470 * @dev: Pointer to class device.
4471 * @attr: Unused.
4472 * @buf: Data buffer.
4473 * @count: Size of the data buffer.
James Smarte59058c2008-08-24 21:49:00 -04004474 *
4475 * Description:
4476 * If val is in a valid range then set the adapter's link speed field and
4477 * issue a lip; if the lip fails reset the link speed to the old value.
4478 *
4479 * Notes:
4480 * If the value is not in range log a kernel error message and return an error.
4481 *
4482 * Returns:
4483 * zero if val is in range and lip okay.
4484 * non-zero return value from lpfc_issue_lip()
4485 * -EINVAL val out of range
4486 **/
James Smarta257bf92009-04-06 18:48:10 -04004487static ssize_t
4488lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
4489 const char *buf, size_t count)
James Smart83108bd2008-01-11 01:53:09 -05004490{
James Smarta257bf92009-04-06 18:48:10 -04004491 struct Scsi_Host *shost = class_to_shost(dev);
4492 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4493 struct lpfc_hba *phba = vport->phba;
James Smart76a95d72010-11-20 23:11:48 -05004494 int val = LPFC_USER_LINK_SPEED_AUTO;
James Smarta257bf92009-04-06 18:48:10 -04004495 int nolip = 0;
4496 const char *val_buf = buf;
James Smart83108bd2008-01-11 01:53:09 -05004497 int err;
James Smartc6918162016-10-13 15:06:16 -07004498 uint32_t prev_val, if_type;
4499
4500 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
James Smart719162b2018-12-10 19:37:01 -08004501 if (if_type >= LPFC_SLI_INTF_IF_TYPE_2 &&
James Smartc6918162016-10-13 15:06:16 -07004502 phba->hba_flag & HBA_FORCED_LINK_SPEED)
4503 return -EPERM;
James Smart83108bd2008-01-11 01:53:09 -05004504
James Smarta257bf92009-04-06 18:48:10 -04004505 if (!strncmp(buf, "nolip ", strlen("nolip "))) {
4506 nolip = 1;
4507 val_buf = &buf[strlen("nolip ")];
4508 }
4509
4510 if (!isdigit(val_buf[0]))
4511 return -EINVAL;
4512 if (sscanf(val_buf, "%i", &val) != 1)
4513 return -EINVAL;
4514
James Smart88a2cfb2011-07-22 18:36:33 -04004515 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4516 "3055 lpfc_link_speed changed from %d to %d %s\n",
4517 phba->cfg_link_speed, val, nolip ? "(nolip)" : "(lip)");
4518
James Smart76a95d72010-11-20 23:11:48 -05004519 if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
4520 ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
4521 ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
4522 ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
4523 ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
James Smartd38dd522015-08-31 16:48:17 -04004524 ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
James Smartfbd8a6b2018-02-22 08:18:45 -08004525 ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
4526 ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
James Smart76a95d72010-11-20 23:11:48 -05004527 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4528 "2879 lpfc_link_speed attribute cannot be set "
4529 "to %d. Speed is not supported by this port.\n",
4530 val);
James Smart83108bd2008-01-11 01:53:09 -05004531 return -EINVAL;
James Smart76a95d72010-11-20 23:11:48 -05004532 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004533 if (val >= LPFC_USER_LINK_SPEED_16G &&
4534 phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smartff78d8f2011-12-13 13:21:35 -05004535 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4536 "3112 lpfc_link_speed attribute cannot be set "
4537 "to %d. Speed is not supported in loop mode.\n",
4538 val);
4539 return -EINVAL;
4540 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004541
4542 switch (val) {
4543 case LPFC_USER_LINK_SPEED_AUTO:
4544 case LPFC_USER_LINK_SPEED_1G:
4545 case LPFC_USER_LINK_SPEED_2G:
4546 case LPFC_USER_LINK_SPEED_4G:
4547 case LPFC_USER_LINK_SPEED_8G:
4548 case LPFC_USER_LINK_SPEED_16G:
4549 case LPFC_USER_LINK_SPEED_32G:
4550 case LPFC_USER_LINK_SPEED_64G:
James Smart83108bd2008-01-11 01:53:09 -05004551 prev_val = phba->cfg_link_speed;
4552 phba->cfg_link_speed = val;
James Smarta257bf92009-04-06 18:48:10 -04004553 if (nolip)
4554 return strlen(buf);
4555
James Smart83108bd2008-01-11 01:53:09 -05004556 err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
James Smarta257bf92009-04-06 18:48:10 -04004557 if (err) {
James Smart83108bd2008-01-11 01:53:09 -05004558 phba->cfg_link_speed = prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004559 return -EINVAL;
James Smartfbd8a6b2018-02-22 08:18:45 -08004560 }
4561 return strlen(buf);
4562 default:
4563 break;
James Smart83108bd2008-01-11 01:53:09 -05004564 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004565
James Smart83108bd2008-01-11 01:53:09 -05004566 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smartfbd8a6b2018-02-22 08:18:45 -08004567 "0469 lpfc_link_speed attribute cannot be set to %d, "
4568 "allowed values are [%s]\n",
4569 val, LPFC_LINK_SPEED_STRING);
James Smart83108bd2008-01-11 01:53:09 -05004570 return -EINVAL;
James Smartfbd8a6b2018-02-22 08:18:45 -08004571
James Smart83108bd2008-01-11 01:53:09 -05004572}
4573
4574static int lpfc_link_speed = 0;
James Smartab56dc22011-02-16 12:39:57 -05004575module_param(lpfc_link_speed, int, S_IRUGO);
James Smart83108bd2008-01-11 01:53:09 -05004576MODULE_PARM_DESC(lpfc_link_speed, "Select link speed");
4577lpfc_param_show(link_speed)
James Smarte59058c2008-08-24 21:49:00 -04004578
4579/**
James Smart3621a712009-04-06 18:47:14 -04004580 * lpfc_link_speed_init - Set the adapters link speed
James Smarte59058c2008-08-24 21:49:00 -04004581 * @phba: lpfc_hba pointer.
4582 * @val: link speed value.
4583 *
4584 * Description:
4585 * If val is in a valid range then set the adapter's link speed field.
4586 *
4587 * Notes:
4588 * If the value is not in range log a kernel error message, clear the link
4589 * speed and return an error.
4590 *
4591 * Returns:
4592 * zero if val saved.
4593 * -EINVAL val out of range
4594 **/
James Smart83108bd2008-01-11 01:53:09 -05004595static int
4596lpfc_link_speed_init(struct lpfc_hba *phba, int val)
4597{
James Smartfbd8a6b2018-02-22 08:18:45 -08004598 if (val >= LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) {
James Smartff78d8f2011-12-13 13:21:35 -05004599 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4600 "3111 lpfc_link_speed of %d cannot "
4601 "support loop mode, setting topology to default.\n",
4602 val);
4603 phba->cfg_topology = 0;
4604 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004605
4606 switch (val) {
4607 case LPFC_USER_LINK_SPEED_AUTO:
4608 case LPFC_USER_LINK_SPEED_1G:
4609 case LPFC_USER_LINK_SPEED_2G:
4610 case LPFC_USER_LINK_SPEED_4G:
4611 case LPFC_USER_LINK_SPEED_8G:
4612 case LPFC_USER_LINK_SPEED_16G:
4613 case LPFC_USER_LINK_SPEED_32G:
4614 case LPFC_USER_LINK_SPEED_64G:
James Smart83108bd2008-01-11 01:53:09 -05004615 phba->cfg_link_speed = val;
4616 return 0;
James Smartfbd8a6b2018-02-22 08:18:45 -08004617 default:
4618 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4619 "0405 lpfc_link_speed attribute cannot "
4620 "be set to %d, allowed values are "
4621 "["LPFC_LINK_SPEED_STRING"]\n", val);
4622 phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
4623 return -EINVAL;
James Smart83108bd2008-01-11 01:53:09 -05004624 }
James Smart83108bd2008-01-11 01:53:09 -05004625}
4626
Joe Perchesb6b996b2017-12-19 10:15:07 -08004627static DEVICE_ATTR_RW(lpfc_link_speed);
dea31012005-04-17 16:05:31 -05004628
4629/*
James Smart0d878412009-10-02 15:16:56 -04004630# lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
4631# 0 = aer disabled or not supported
4632# 1 = aer supported and enabled (default)
4633# Value range is [0,1]. Default value is 1.
4634*/
James Smart506139a2016-10-13 15:06:09 -07004635LPFC_ATTR(aer_support, 1, 0, 1,
4636 "Enable PCIe device AER support");
4637lpfc_param_show(aer_support)
James Smart0d878412009-10-02 15:16:56 -04004638
4639/**
4640 * lpfc_aer_support_store - Set the adapter for aer support
4641 *
4642 * @dev: class device that is converted into a Scsi_host.
4643 * @attr: device attribute, not used.
James Smart912e3ac2011-05-24 11:42:11 -04004644 * @buf: containing enable or disable aer flag.
James Smart0d878412009-10-02 15:16:56 -04004645 * @count: unused variable.
4646 *
4647 * Description:
4648 * If the val is 1 and currently the device's AER capability was not
4649 * enabled, invoke the kernel's enable AER helper routine, trying to
4650 * enable the device's AER capability. If the helper routine enabling
4651 * AER returns success, update the device's cfg_aer_support flag to
4652 * indicate AER is supported by the device; otherwise, if the device
4653 * AER capability is already enabled to support AER, then do nothing.
4654 *
4655 * If the val is 0 and currently the device's AER support was enabled,
4656 * invoke the kernel's disable AER helper routine. After that, update
4657 * the device's cfg_aer_support flag to indicate AER is not supported
4658 * by the device; otherwise, if the device AER capability is already
4659 * disabled from supporting AER, then do nothing.
4660 *
4661 * Returns:
4662 * length of the buf on success if val is in range the intended mode
4663 * is supported.
4664 * -EINVAL if val out of range or intended mode is not supported.
4665 **/
4666static ssize_t
4667lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
4668 const char *buf, size_t count)
4669{
4670 struct Scsi_Host *shost = class_to_shost(dev);
4671 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4672 struct lpfc_hba *phba = vport->phba;
4673 int val = 0, rc = -EINVAL;
4674
4675 if (!isdigit(buf[0]))
4676 return -EINVAL;
4677 if (sscanf(buf, "%i", &val) != 1)
4678 return -EINVAL;
4679
4680 switch (val) {
4681 case 0:
4682 if (phba->hba_flag & HBA_AER_ENABLED) {
4683 rc = pci_disable_pcie_error_reporting(phba->pcidev);
4684 if (!rc) {
4685 spin_lock_irq(&phba->hbalock);
4686 phba->hba_flag &= ~HBA_AER_ENABLED;
4687 spin_unlock_irq(&phba->hbalock);
4688 phba->cfg_aer_support = 0;
4689 rc = strlen(buf);
4690 } else
James Smart891478a2009-11-18 15:40:23 -05004691 rc = -EPERM;
4692 } else {
James Smart0d878412009-10-02 15:16:56 -04004693 phba->cfg_aer_support = 0;
James Smart891478a2009-11-18 15:40:23 -05004694 rc = strlen(buf);
4695 }
James Smart0d878412009-10-02 15:16:56 -04004696 break;
4697 case 1:
4698 if (!(phba->hba_flag & HBA_AER_ENABLED)) {
4699 rc = pci_enable_pcie_error_reporting(phba->pcidev);
4700 if (!rc) {
4701 spin_lock_irq(&phba->hbalock);
4702 phba->hba_flag |= HBA_AER_ENABLED;
4703 spin_unlock_irq(&phba->hbalock);
4704 phba->cfg_aer_support = 1;
4705 rc = strlen(buf);
4706 } else
James Smart891478a2009-11-18 15:40:23 -05004707 rc = -EPERM;
4708 } else {
James Smart0d878412009-10-02 15:16:56 -04004709 phba->cfg_aer_support = 1;
James Smart891478a2009-11-18 15:40:23 -05004710 rc = strlen(buf);
4711 }
James Smart0d878412009-10-02 15:16:56 -04004712 break;
4713 default:
4714 rc = -EINVAL;
4715 break;
4716 }
4717 return rc;
4718}
4719
Joe Perchesb6b996b2017-12-19 10:15:07 -08004720static DEVICE_ATTR_RW(lpfc_aer_support);
James Smart0d878412009-10-02 15:16:56 -04004721
4722/**
4723 * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device
4724 * @dev: class device that is converted into a Scsi_host.
4725 * @attr: device attribute, not used.
James Smart912e3ac2011-05-24 11:42:11 -04004726 * @buf: containing flag 1 for aer cleanup state.
James Smart0d878412009-10-02 15:16:56 -04004727 * @count: unused variable.
4728 *
4729 * Description:
4730 * If the @buf contains 1 and the device currently has the AER support
4731 * enabled, then invokes the kernel AER helper routine
Kuppuswamy Sathyanarayanan894020f2020-03-23 17:26:08 -07004732 * pci_aer_clear_nonfatal_status() to clean up the uncorrectable
James Smart0d878412009-10-02 15:16:56 -04004733 * error status register.
4734 *
4735 * Notes:
4736 *
4737 * Returns:
4738 * -EINVAL if the buf does not contain the 1 or the device is not currently
4739 * enabled with the AER support.
4740 **/
4741static ssize_t
4742lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr,
4743 const char *buf, size_t count)
4744{
4745 struct Scsi_Host *shost = class_to_shost(dev);
4746 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4747 struct lpfc_hba *phba = vport->phba;
4748 int val, rc = -1;
4749
4750 if (!isdigit(buf[0]))
4751 return -EINVAL;
4752 if (sscanf(buf, "%i", &val) != 1)
4753 return -EINVAL;
James Smart891478a2009-11-18 15:40:23 -05004754 if (val != 1)
4755 return -EINVAL;
James Smart0d878412009-10-02 15:16:56 -04004756
James Smart891478a2009-11-18 15:40:23 -05004757 if (phba->hba_flag & HBA_AER_ENABLED)
Kuppuswamy Sathyanarayanan894020f2020-03-23 17:26:08 -07004758 rc = pci_aer_clear_nonfatal_status(phba->pcidev);
James Smart0d878412009-10-02 15:16:56 -04004759
4760 if (rc == 0)
4761 return strlen(buf);
4762 else
James Smart891478a2009-11-18 15:40:23 -05004763 return -EPERM;
James Smart0d878412009-10-02 15:16:56 -04004764}
4765
4766static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
4767 lpfc_aer_cleanup_state);
4768
James Smart912e3ac2011-05-24 11:42:11 -04004769/**
4770 * lpfc_sriov_nr_virtfn_store - Enable the adapter for sr-iov virtual functions
4771 *
4772 * @dev: class device that is converted into a Scsi_host.
4773 * @attr: device attribute, not used.
4774 * @buf: containing the string the number of vfs to be enabled.
4775 * @count: unused variable.
4776 *
4777 * Description:
4778 * When this api is called either through user sysfs, the driver shall
4779 * try to enable or disable SR-IOV virtual functions according to the
4780 * following:
4781 *
4782 * If zero virtual function has been enabled to the physical function,
4783 * the driver shall invoke the pci enable virtual function api trying
4784 * to enable the virtual functions. If the nr_vfn provided is greater
4785 * than the maximum supported, the maximum virtual function number will
4786 * be used for invoking the api; otherwise, the nr_vfn provided shall
4787 * be used for invoking the api. If the api call returned success, the
4788 * actual number of virtual functions enabled will be set to the driver
4789 * cfg_sriov_nr_virtfn; otherwise, -EINVAL shall be returned and driver
4790 * cfg_sriov_nr_virtfn remains zero.
4791 *
4792 * If none-zero virtual functions have already been enabled to the
4793 * physical function, as reflected by the driver's cfg_sriov_nr_virtfn,
4794 * -EINVAL will be returned and the driver does nothing;
4795 *
4796 * If the nr_vfn provided is zero and none-zero virtual functions have
4797 * been enabled, as indicated by the driver's cfg_sriov_nr_virtfn, the
4798 * disabling virtual function api shall be invoded to disable all the
4799 * virtual functions and driver's cfg_sriov_nr_virtfn shall be set to
4800 * zero. Otherwise, if zero virtual function has been enabled, do
4801 * nothing.
4802 *
4803 * Returns:
4804 * length of the buf on success if val is in range the intended mode
4805 * is supported.
4806 * -EINVAL if val out of range or intended mode is not supported.
4807 **/
4808static ssize_t
4809lpfc_sriov_nr_virtfn_store(struct device *dev, struct device_attribute *attr,
4810 const char *buf, size_t count)
4811{
4812 struct Scsi_Host *shost = class_to_shost(dev);
4813 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4814 struct lpfc_hba *phba = vport->phba;
4815 struct pci_dev *pdev = phba->pcidev;
4816 int val = 0, rc = -EINVAL;
4817
4818 /* Sanity check on user data */
4819 if (!isdigit(buf[0]))
4820 return -EINVAL;
4821 if (sscanf(buf, "%i", &val) != 1)
4822 return -EINVAL;
4823 if (val < 0)
4824 return -EINVAL;
4825
4826 /* Request disabling virtual functions */
4827 if (val == 0) {
4828 if (phba->cfg_sriov_nr_virtfn > 0) {
4829 pci_disable_sriov(pdev);
4830 phba->cfg_sriov_nr_virtfn = 0;
4831 }
4832 return strlen(buf);
4833 }
4834
4835 /* Request enabling virtual functions */
4836 if (phba->cfg_sriov_nr_virtfn > 0) {
4837 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4838 "3018 There are %d virtual functions "
4839 "enabled on physical function.\n",
4840 phba->cfg_sriov_nr_virtfn);
4841 return -EEXIST;
4842 }
4843
4844 if (val <= LPFC_MAX_VFN_PER_PFN)
4845 phba->cfg_sriov_nr_virtfn = val;
4846 else {
4847 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4848 "3019 Enabling %d virtual functions is not "
4849 "allowed.\n", val);
4850 return -EINVAL;
4851 }
4852
4853 rc = lpfc_sli_probe_sriov_nr_virtfn(phba, phba->cfg_sriov_nr_virtfn);
4854 if (rc) {
4855 phba->cfg_sriov_nr_virtfn = 0;
4856 rc = -EPERM;
4857 } else
4858 rc = strlen(buf);
4859
4860 return rc;
4861}
4862
James Smart0cfbbf22016-10-13 15:06:12 -07004863LPFC_ATTR(sriov_nr_virtfn, LPFC_DEF_VFN_PER_PFN, 0, LPFC_MAX_VFN_PER_PFN,
4864 "Enable PCIe device SR-IOV virtual fn");
4865
James Smart912e3ac2011-05-24 11:42:11 -04004866lpfc_param_show(sriov_nr_virtfn)
Joe Perchesb6b996b2017-12-19 10:15:07 -08004867static DEVICE_ATTR_RW(lpfc_sriov_nr_virtfn);
James Smart912e3ac2011-05-24 11:42:11 -04004868
James Smart173edbb2012-06-12 13:54:50 -04004869/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00004870 * lpfc_request_firmware_upgrade_store - Request for Linux generic firmware upgrade
James Smartc71ab862012-10-31 14:44:33 -04004871 *
4872 * @dev: class device that is converted into a Scsi_host.
4873 * @attr: device attribute, not used.
4874 * @buf: containing the string the number of vfs to be enabled.
4875 * @count: unused variable.
4876 *
4877 * Description:
4878 *
4879 * Returns:
4880 * length of the buf on success if val is in range the intended mode
4881 * is supported.
4882 * -EINVAL if val out of range or intended mode is not supported.
4883 **/
4884static ssize_t
4885lpfc_request_firmware_upgrade_store(struct device *dev,
4886 struct device_attribute *attr,
4887 const char *buf, size_t count)
4888{
4889 struct Scsi_Host *shost = class_to_shost(dev);
4890 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4891 struct lpfc_hba *phba = vport->phba;
Colin Ian King6e27a862020-05-07 21:31:11 +01004892 int val = 0, rc;
James Smartc71ab862012-10-31 14:44:33 -04004893
4894 /* Sanity check on user data */
4895 if (!isdigit(buf[0]))
4896 return -EINVAL;
4897 if (sscanf(buf, "%i", &val) != 1)
4898 return -EINVAL;
4899 if (val != 1)
4900 return -EINVAL;
4901
4902 rc = lpfc_sli4_request_firmware_update(phba, RUN_FW_UPGRADE);
4903 if (rc)
4904 rc = -EPERM;
4905 else
4906 rc = strlen(buf);
4907 return rc;
4908}
4909
4910static int lpfc_req_fw_upgrade;
4911module_param(lpfc_req_fw_upgrade, int, S_IRUGO|S_IWUSR);
4912MODULE_PARM_DESC(lpfc_req_fw_upgrade, "Enable Linux generic firmware upgrade");
4913lpfc_param_show(request_firmware_upgrade)
4914
4915/**
4916 * lpfc_request_firmware_upgrade_init - Enable initial linux generic fw upgrade
4917 * @phba: lpfc_hba pointer.
4918 * @val: 0 or 1.
4919 *
4920 * Description:
4921 * Set the initial Linux generic firmware upgrade enable or disable flag.
4922 *
4923 * Returns:
4924 * zero if val saved.
4925 * -EINVAL val out of range
4926 **/
4927static int
4928lpfc_request_firmware_upgrade_init(struct lpfc_hba *phba, int val)
4929{
4930 if (val >= 0 && val <= 1) {
4931 phba->cfg_request_firmware_upgrade = val;
4932 return 0;
4933 }
4934 return -EINVAL;
4935}
4936static DEVICE_ATTR(lpfc_req_fw_upgrade, S_IRUGO | S_IWUSR,
4937 lpfc_request_firmware_upgrade_show,
4938 lpfc_request_firmware_upgrade_store);
4939
4940/**
James Smart41b194b2019-05-14 14:58:08 -07004941 * lpfc_force_rscn_store
4942 *
4943 * @dev: class device that is converted into a Scsi_host.
4944 * @attr: device attribute, not used.
4945 * @buf: unused string
4946 * @count: unused variable.
4947 *
4948 * Description:
4949 * Force the switch to send a RSCN to all other NPorts in our zone
4950 * If we are direct connect pt2pt, build the RSCN command ourself
4951 * and send to the other NPort. Not supported for private loop.
4952 *
4953 * Returns:
4954 * 0 - on success
4955 * -EIO - if command is not sent
4956 **/
4957static ssize_t
4958lpfc_force_rscn_store(struct device *dev, struct device_attribute *attr,
4959 const char *buf, size_t count)
4960{
4961 struct Scsi_Host *shost = class_to_shost(dev);
4962 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4963 int i;
4964
4965 i = lpfc_issue_els_rscn(vport, 0);
4966 if (i)
4967 return -EIO;
4968 return strlen(buf);
4969}
4970
4971/*
4972 * lpfc_force_rscn: Force an RSCN to be sent to all remote NPorts
4973 * connected to the HBA.
4974 *
4975 * Value range is any ascii value
4976 */
4977static int lpfc_force_rscn;
4978module_param(lpfc_force_rscn, int, 0644);
4979MODULE_PARM_DESC(lpfc_force_rscn,
4980 "Force an RSCN to be sent to all remote NPorts");
4981lpfc_param_show(force_rscn)
4982
4983/**
4984 * lpfc_force_rscn_init - Force an RSCN to be sent to all remote NPorts
4985 * @phba: lpfc_hba pointer.
4986 * @val: unused value.
4987 *
4988 * Returns:
4989 * zero if val saved.
4990 **/
4991static int
4992lpfc_force_rscn_init(struct lpfc_hba *phba, int val)
4993{
4994 return 0;
4995}
4996static DEVICE_ATTR_RW(lpfc_force_rscn);
4997
4998/**
James Smart173edbb2012-06-12 13:54:50 -04004999 * lpfc_fcp_imax_store
5000 *
5001 * @dev: class device that is converted into a Scsi_host.
5002 * @attr: device attribute, not used.
5003 * @buf: string with the number of fast-path FCP interrupts per second.
5004 * @count: unused variable.
5005 *
5006 * Description:
5007 * If val is in a valid range [636,651042], then set the adapter's
5008 * maximum number of fast-path FCP interrupts per second.
5009 *
5010 * Returns:
5011 * length of the buf on success if val is in range the intended mode
5012 * is supported.
5013 * -EINVAL if val out of range or intended mode is not supported.
5014 **/
5015static ssize_t
5016lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr,
5017 const char *buf, size_t count)
5018{
5019 struct Scsi_Host *shost = class_to_shost(dev);
5020 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5021 struct lpfc_hba *phba = vport->phba;
James Smart32517fc2019-01-28 11:14:33 -08005022 struct lpfc_eq_intr_info *eqi;
James Smartcb733e32019-01-28 11:14:32 -08005023 uint32_t usdelay;
James Smart173edbb2012-06-12 13:54:50 -04005024 int val = 0, i;
5025
James Smartbf8dae82012-08-03 12:36:24 -04005026 /* fcp_imax is only valid for SLI4 */
5027 if (phba->sli_rev != LPFC_SLI_REV4)
5028 return -EINVAL;
5029
James Smart173edbb2012-06-12 13:54:50 -04005030 /* Sanity check on user data */
5031 if (!isdigit(buf[0]))
5032 return -EINVAL;
5033 if (sscanf(buf, "%i", &val) != 1)
5034 return -EINVAL;
5035
James Smartbf8dae82012-08-03 12:36:24 -04005036 /*
5037 * Value range for the HBA is [5000,5000000]
5038 * The value for each EQ depends on how many EQs are configured.
James Smart895427b2017-02-12 13:52:30 -08005039 * Allow value == 0
James Smartbf8dae82012-08-03 12:36:24 -04005040 */
James Smart895427b2017-02-12 13:52:30 -08005041 if (val && (val < LPFC_MIN_IMAX || val > LPFC_MAX_IMAX))
James Smart173edbb2012-06-12 13:54:50 -04005042 return -EINVAL;
5043
James Smart32517fc2019-01-28 11:14:33 -08005044 phba->cfg_auto_imax = (val) ? 0 : 1;
5045 if (phba->cfg_fcp_imax && !val) {
5046 queue_delayed_work(phba->wq, &phba->eq_delay_work,
5047 msecs_to_jiffies(LPFC_EQ_DELAY_MSECS));
5048
5049 for_each_present_cpu(i) {
5050 eqi = per_cpu_ptr(phba->sli4_hba.eq_info, i);
5051 eqi->icnt = 0;
5052 }
5053 }
5054
James Smart173edbb2012-06-12 13:54:50 -04005055 phba->cfg_fcp_imax = (uint32_t)val;
James Smart43140ca2017-03-04 09:30:34 -08005056
James Smartcb733e32019-01-28 11:14:32 -08005057 if (phba->cfg_fcp_imax)
5058 usdelay = LPFC_SEC_TO_USEC / phba->cfg_fcp_imax;
5059 else
5060 usdelay = 0;
5061
James Smart6a828b02019-01-28 11:14:31 -08005062 for (i = 0; i < phba->cfg_irq_chann; i += LPFC_MAX_EQ_DELAY_EQID_CNT)
James Smart0cf07f842017-06-01 21:07:10 -07005063 lpfc_modify_hba_eq_delay(phba, i, LPFC_MAX_EQ_DELAY_EQID_CNT,
James Smartcb733e32019-01-28 11:14:32 -08005064 usdelay);
James Smart173edbb2012-06-12 13:54:50 -04005065
5066 return strlen(buf);
5067}
5068
5069/*
5070# lpfc_fcp_imax: The maximum number of fast-path FCP interrupts per second
James Smartbf8dae82012-08-03 12:36:24 -04005071# for the HBA.
James Smart173edbb2012-06-12 13:54:50 -04005072#
James Smartbf8dae82012-08-03 12:36:24 -04005073# Value range is [5,000 to 5,000,000]. Default value is 50,000.
James Smart173edbb2012-06-12 13:54:50 -04005074*/
James Smartbf8dae82012-08-03 12:36:24 -04005075static int lpfc_fcp_imax = LPFC_DEF_IMAX;
James Smart173edbb2012-06-12 13:54:50 -04005076module_param(lpfc_fcp_imax, int, S_IRUGO|S_IWUSR);
5077MODULE_PARM_DESC(lpfc_fcp_imax,
James Smartbf8dae82012-08-03 12:36:24 -04005078 "Set the maximum number of FCP interrupts per second per HBA");
James Smart173edbb2012-06-12 13:54:50 -04005079lpfc_param_show(fcp_imax)
5080
5081/**
5082 * lpfc_fcp_imax_init - Set the initial sr-iov virtual function enable
5083 * @phba: lpfc_hba pointer.
5084 * @val: link speed value.
5085 *
5086 * Description:
5087 * If val is in a valid range [636,651042], then initialize the adapter's
5088 * maximum number of fast-path FCP interrupts per second.
5089 *
5090 * Returns:
5091 * zero if val saved.
5092 * -EINVAL val out of range
5093 **/
5094static int
5095lpfc_fcp_imax_init(struct lpfc_hba *phba, int val)
5096{
James Smartbf8dae82012-08-03 12:36:24 -04005097 if (phba->sli_rev != LPFC_SLI_REV4) {
5098 phba->cfg_fcp_imax = 0;
5099 return 0;
5100 }
5101
James Smart895427b2017-02-12 13:52:30 -08005102 if ((val >= LPFC_MIN_IMAX && val <= LPFC_MAX_IMAX) ||
5103 (val == 0)) {
James Smart173edbb2012-06-12 13:54:50 -04005104 phba->cfg_fcp_imax = val;
5105 return 0;
5106 }
5107
5108 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07005109 "3016 lpfc_fcp_imax: %d out of range, using default\n",
5110 val);
James Smartbf8dae82012-08-03 12:36:24 -04005111 phba->cfg_fcp_imax = LPFC_DEF_IMAX;
James Smart173edbb2012-06-12 13:54:50 -04005112
5113 return 0;
5114}
5115
Joe Perchesb6b996b2017-12-19 10:15:07 -08005116static DEVICE_ATTR_RW(lpfc_fcp_imax);
James Smart173edbb2012-06-12 13:54:50 -04005117
James Smart32517fc2019-01-28 11:14:33 -08005118/**
5119 * lpfc_cq_max_proc_limit_store
5120 *
5121 * @dev: class device that is converted into a Scsi_host.
5122 * @attr: device attribute, not used.
5123 * @buf: string with the cq max processing limit of cqes
5124 * @count: unused variable.
5125 *
5126 * Description:
5127 * If val is in a valid range, then set value on each cq
5128 *
5129 * Returns:
5130 * The length of the buf: if successful
5131 * -ERANGE: if val is not in the valid range
5132 * -EINVAL: if bad value format or intended mode is not supported.
5133 **/
5134static ssize_t
5135lpfc_cq_max_proc_limit_store(struct device *dev, struct device_attribute *attr,
5136 const char *buf, size_t count)
5137{
5138 struct Scsi_Host *shost = class_to_shost(dev);
5139 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5140 struct lpfc_hba *phba = vport->phba;
5141 struct lpfc_queue *eq, *cq;
5142 unsigned long val;
5143 int i;
5144
5145 /* cq_max_proc_limit is only valid for SLI4 */
5146 if (phba->sli_rev != LPFC_SLI_REV4)
5147 return -EINVAL;
5148
5149 /* Sanity check on user data */
5150 if (!isdigit(buf[0]))
5151 return -EINVAL;
5152 if (kstrtoul(buf, 0, &val))
5153 return -EINVAL;
5154
5155 if (val < LPFC_CQ_MIN_PROC_LIMIT || val > LPFC_CQ_MAX_PROC_LIMIT)
5156 return -ERANGE;
5157
5158 phba->cfg_cq_max_proc_limit = (uint32_t)val;
5159
5160 /* set the values on the cq's */
5161 for (i = 0; i < phba->cfg_irq_chann; i++) {
James Smart657add42019-05-21 17:49:06 -07005162 /* Get the EQ corresponding to the IRQ vector */
5163 eq = phba->sli4_hba.hba_eq_hdl[i].eq;
James Smart32517fc2019-01-28 11:14:33 -08005164 if (!eq)
5165 continue;
5166
5167 list_for_each_entry(cq, &eq->child_list, list)
5168 cq->max_proc_limit = min(phba->cfg_cq_max_proc_limit,
5169 cq->entry_count);
5170 }
5171
5172 return strlen(buf);
5173}
5174
James Smart0cf07f842017-06-01 21:07:10 -07005175/*
James Smart32517fc2019-01-28 11:14:33 -08005176 * lpfc_cq_max_proc_limit: The maximum number CQE entries processed in an
5177 * itteration of CQ processing.
James Smart0cf07f842017-06-01 21:07:10 -07005178 */
James Smart32517fc2019-01-28 11:14:33 -08005179static int lpfc_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
5180module_param(lpfc_cq_max_proc_limit, int, 0644);
5181MODULE_PARM_DESC(lpfc_cq_max_proc_limit,
5182 "Set the maximum number CQEs processed in an iteration of "
5183 "CQ processing");
5184lpfc_param_show(cq_max_proc_limit)
5185
5186/*
5187 * lpfc_cq_poll_threshold: Set the threshold of CQE completions in a
5188 * single handler call which should request a polled completion rather
5189 * than re-enabling interrupts.
5190 */
5191LPFC_ATTR_RW(cq_poll_threshold, LPFC_CQ_DEF_THRESHOLD_TO_POLL,
5192 LPFC_CQ_MIN_THRESHOLD_TO_POLL,
5193 LPFC_CQ_MAX_THRESHOLD_TO_POLL,
5194 "CQE Processing Threshold to enable Polling");
5195
5196/**
5197 * lpfc_cq_max_proc_limit_init - Set the initial cq max_proc_limit
5198 * @phba: lpfc_hba pointer.
5199 * @val: entry limit
5200 *
5201 * Description:
5202 * If val is in a valid range, then initialize the adapter's maximum
5203 * value.
5204 *
5205 * Returns:
5206 * Always returns 0 for success, even if value not always set to
5207 * requested value. If value out of range or not supported, will fall
5208 * back to default.
5209 **/
5210static int
5211lpfc_cq_max_proc_limit_init(struct lpfc_hba *phba, int val)
5212{
5213 phba->cfg_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
5214
5215 if (phba->sli_rev != LPFC_SLI_REV4)
5216 return 0;
5217
5218 if (val >= LPFC_CQ_MIN_PROC_LIMIT && val <= LPFC_CQ_MAX_PROC_LIMIT) {
5219 phba->cfg_cq_max_proc_limit = val;
5220 return 0;
5221 }
5222
5223 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart5b1f5082021-04-11 18:31:25 -07005224 "0371 lpfc_cq_max_proc_limit: %d out of range, using "
5225 "default\n",
James Smart32517fc2019-01-28 11:14:33 -08005226 phba->cfg_cq_max_proc_limit);
5227
5228 return 0;
5229}
5230
5231static DEVICE_ATTR_RW(lpfc_cq_max_proc_limit);
James Smart0cf07f842017-06-01 21:07:10 -07005232
James Smart7bb03bb2013-04-17 20:19:16 -04005233/**
Lee Jonesa3dbf512021-03-12 09:47:12 +00005234 * lpfc_fcp_cpu_map_show - Display current driver CPU affinity
James Smart7bb03bb2013-04-17 20:19:16 -04005235 * @dev: class converted to a Scsi_host structure.
5236 * @attr: device attribute, not used.
5237 * @buf: on return contains text describing the state of the link.
5238 *
5239 * Returns: size of formatted string.
5240 **/
5241static ssize_t
5242lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr,
5243 char *buf)
5244{
5245 struct Scsi_Host *shost = class_to_shost(dev);
5246 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5247 struct lpfc_hba *phba = vport->phba;
5248 struct lpfc_vector_map_info *cpup;
James Smart76fd07a2014-02-20 09:57:18 -05005249 int len = 0;
James Smart7bb03bb2013-04-17 20:19:16 -04005250
5251 if ((phba->sli_rev != LPFC_SLI_REV4) ||
5252 (phba->intr_type != MSIX))
5253 return len;
5254
5255 switch (phba->cfg_fcp_cpu_map) {
5256 case 0:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005257 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart7bb03bb2013-04-17 20:19:16 -04005258 "fcp_cpu_map: No mapping (%d)\n",
5259 phba->cfg_fcp_cpu_map);
5260 return len;
5261 case 1:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005262 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart7bb03bb2013-04-17 20:19:16 -04005263 "fcp_cpu_map: HBA centric mapping (%d): "
James Smart222e9232019-01-28 11:14:35 -08005264 "%d of %d CPUs online from %d possible CPUs\n",
5265 phba->cfg_fcp_cpu_map, num_online_cpus(),
5266 num_present_cpus(),
5267 phba->sli4_hba.num_possible_cpu);
James Smart7bb03bb2013-04-17 20:19:16 -04005268 break;
James Smart7bb03bb2013-04-17 20:19:16 -04005269 }
5270
James Smart222e9232019-01-28 11:14:35 -08005271 while (phba->sli4_hba.curr_disp_cpu <
5272 phba->sli4_hba.num_possible_cpu) {
James Smart76fd07a2014-02-20 09:57:18 -05005273 cpup = &phba->sli4_hba.cpu_map[phba->sli4_hba.curr_disp_cpu];
5274
James Smart222e9232019-01-28 11:14:35 -08005275 if (!cpu_present(phba->sli4_hba.curr_disp_cpu))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005276 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart222e9232019-01-28 11:14:35 -08005277 "CPU %02d not present\n",
5278 phba->sli4_hba.curr_disp_cpu);
James Smartdcaa2132019-11-04 16:57:06 -08005279 else if (cpup->eq == LPFC_VECTOR_MAP_EMPTY) {
James Smartb3295c22019-01-28 11:14:30 -08005280 if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005281 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005282 buf + len, PAGE_SIZE - len,
5283 "CPU %02d hdwq None "
James Smartd9954a22019-05-21 17:49:05 -07005284 "physid %d coreid %d ht %d ua %d\n",
James Smart76fd07a2014-02-20 09:57:18 -05005285 phba->sli4_hba.curr_disp_cpu,
James Smartd9954a22019-05-21 17:49:05 -07005286 cpup->phys_id, cpup->core_id,
5287 (cpup->flag & LPFC_CPU_MAP_HYPER),
5288 (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
James Smartb3295c22019-01-28 11:14:30 -08005289 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005290 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005291 buf + len, PAGE_SIZE - len,
James Smartdcaa2132019-11-04 16:57:06 -08005292 "CPU %02d EQ None hdwq %04d "
James Smartd9954a22019-05-21 17:49:05 -07005293 "physid %d coreid %d ht %d ua %d\n",
James Smartb3295c22019-01-28 11:14:30 -08005294 phba->sli4_hba.curr_disp_cpu,
James Smartdcaa2132019-11-04 16:57:06 -08005295 cpup->hdwq, cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005296 cpup->core_id,
5297 (cpup->flag & LPFC_CPU_MAP_HYPER),
5298 (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
James Smartb3295c22019-01-28 11:14:30 -08005299 } else {
5300 if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005301 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005302 buf + len, PAGE_SIZE - len,
5303 "CPU %02d hdwq None "
James Smartd9954a22019-05-21 17:49:05 -07005304 "physid %d coreid %d ht %d ua %d IRQ %d\n",
James Smart76fd07a2014-02-20 09:57:18 -05005305 phba->sli4_hba.curr_disp_cpu,
James Smartb3295c22019-01-28 11:14:30 -08005306 cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005307 cpup->core_id,
5308 (cpup->flag & LPFC_CPU_MAP_HYPER),
5309 (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
James Smartdcaa2132019-11-04 16:57:06 -08005310 lpfc_get_irq(cpup->eq));
James Smartb3295c22019-01-28 11:14:30 -08005311 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005312 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005313 buf + len, PAGE_SIZE - len,
James Smart6a828b02019-01-28 11:14:31 -08005314 "CPU %02d EQ %04d hdwq %04d "
James Smartd9954a22019-05-21 17:49:05 -07005315 "physid %d coreid %d ht %d ua %d IRQ %d\n",
James Smartb3295c22019-01-28 11:14:30 -08005316 phba->sli4_hba.curr_disp_cpu,
James Smart6a828b02019-01-28 11:14:31 -08005317 cpup->eq, cpup->hdwq, cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005318 cpup->core_id,
5319 (cpup->flag & LPFC_CPU_MAP_HYPER),
5320 (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
James Smartdcaa2132019-11-04 16:57:06 -08005321 lpfc_get_irq(cpup->eq));
James Smartb3295c22019-01-28 11:14:30 -08005322 }
James Smart7bb03bb2013-04-17 20:19:16 -04005323
James Smart76fd07a2014-02-20 09:57:18 -05005324 phba->sli4_hba.curr_disp_cpu++;
5325
5326 /* display max number of CPUs keeping some margin */
5327 if (phba->sli4_hba.curr_disp_cpu <
James Smart222e9232019-01-28 11:14:35 -08005328 phba->sli4_hba.num_possible_cpu &&
James Smart76fd07a2014-02-20 09:57:18 -05005329 (len >= (PAGE_SIZE - 64))) {
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005330 len += scnprintf(buf + len,
James Smart222e9232019-01-28 11:14:35 -08005331 PAGE_SIZE - len, "more...\n");
James Smart76fd07a2014-02-20 09:57:18 -05005332 break;
5333 }
James Smart7bb03bb2013-04-17 20:19:16 -04005334 }
James Smart76fd07a2014-02-20 09:57:18 -05005335
James Smart222e9232019-01-28 11:14:35 -08005336 if (phba->sli4_hba.curr_disp_cpu == phba->sli4_hba.num_possible_cpu)
James Smart76fd07a2014-02-20 09:57:18 -05005337 phba->sli4_hba.curr_disp_cpu = 0;
5338
James Smart7bb03bb2013-04-17 20:19:16 -04005339 return len;
5340}
5341
5342/**
5343 * lpfc_fcp_cpu_map_store - Change CPU affinity of driver vectors
5344 * @dev: class device that is converted into a Scsi_host.
5345 * @attr: device attribute, not used.
5346 * @buf: one or more lpfc_polling_flags values.
5347 * @count: not used.
5348 *
5349 * Returns:
5350 * -EINVAL - Not implemented yet.
5351 **/
5352static ssize_t
5353lpfc_fcp_cpu_map_store(struct device *dev, struct device_attribute *attr,
5354 const char *buf, size_t count)
5355{
Ye Bin37fa4292020-09-16 10:28:59 +08005356 return -EINVAL;
James Smart7bb03bb2013-04-17 20:19:16 -04005357}
5358
5359/*
5360# lpfc_fcp_cpu_map: Defines how to map CPUs to IRQ vectors
5361# for the HBA.
5362#
James Smart6a828b02019-01-28 11:14:31 -08005363# Value range is [0 to 1]. Default value is LPFC_HBA_CPU_MAP (1).
James Smart7bb03bb2013-04-17 20:19:16 -04005364# 0 - Do not affinitze IRQ vectors
5365# 1 - Affintize HBA vectors with respect to each HBA
5366# (start with CPU0 for each HBA)
James Smart6a828b02019-01-28 11:14:31 -08005367# This also defines how Hardware Queues are mapped to specific CPUs.
James Smart7bb03bb2013-04-17 20:19:16 -04005368*/
James Smart6a828b02019-01-28 11:14:31 -08005369static int lpfc_fcp_cpu_map = LPFC_HBA_CPU_MAP;
James Smart7bb03bb2013-04-17 20:19:16 -04005370module_param(lpfc_fcp_cpu_map, int, S_IRUGO|S_IWUSR);
5371MODULE_PARM_DESC(lpfc_fcp_cpu_map,
5372 "Defines how to map CPUs to IRQ vectors per HBA");
5373
5374/**
5375 * lpfc_fcp_cpu_map_init - Set the initial sr-iov virtual function enable
5376 * @phba: lpfc_hba pointer.
5377 * @val: link speed value.
5378 *
5379 * Description:
5380 * If val is in a valid range [0-2], then affinitze the adapter's
5381 * MSIX vectors.
5382 *
5383 * Returns:
5384 * zero if val saved.
5385 * -EINVAL val out of range
5386 **/
5387static int
5388lpfc_fcp_cpu_map_init(struct lpfc_hba *phba, int val)
5389{
5390 if (phba->sli_rev != LPFC_SLI_REV4) {
5391 phba->cfg_fcp_cpu_map = 0;
5392 return 0;
5393 }
5394
5395 if (val >= LPFC_MIN_CPU_MAP && val <= LPFC_MAX_CPU_MAP) {
5396 phba->cfg_fcp_cpu_map = val;
5397 return 0;
5398 }
5399
5400 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07005401 "3326 lpfc_fcp_cpu_map: %d out of range, using "
5402 "default\n", val);
James Smart6a828b02019-01-28 11:14:31 -08005403 phba->cfg_fcp_cpu_map = LPFC_HBA_CPU_MAP;
James Smart7bb03bb2013-04-17 20:19:16 -04005404
5405 return 0;
5406}
5407
Joe Perchesb6b996b2017-12-19 10:15:07 -08005408static DEVICE_ATTR_RW(lpfc_fcp_cpu_map);
James Smart7bb03bb2013-04-17 20:19:16 -04005409
James Smart0d878412009-10-02 15:16:56 -04005410/*
dea31012005-04-17 16:05:31 -05005411# lpfc_fcp_class: Determines FC class to use for the FCP protocol.
5412# Value range is [2,3]. Default value is 3.
5413*/
James Smart3de2a652007-08-02 11:09:59 -04005414LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3,
5415 "Select Fibre Channel class of service for FCP sequences");
dea31012005-04-17 16:05:31 -05005416
5417/*
5418# lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
James Smart816bd882021-07-07 11:43:45 -07005419# is [0,1]. Default value is 1.
dea31012005-04-17 16:05:31 -05005420*/
James Smart816bd882021-07-07 11:43:45 -07005421LPFC_VPORT_ATTR_RW(use_adisc, 1, 0, 1,
James Smart3de2a652007-08-02 11:09:59 -04005422 "Use ADISC on rediscovery to authenticate FCP devices");
dea31012005-04-17 16:05:31 -05005423
5424/*
James Smart3cb01c52013-07-15 18:35:04 -04005425# lpfc_first_burst_size: First burst size to use on the NPorts
5426# that support first burst.
5427# Value range is [0,65536]. Default value is 0.
5428*/
5429LPFC_VPORT_ATTR_RW(first_burst_size, 0, 0, 65536,
5430 "First burst size for Targets that support first burst");
5431
5432/*
James Smart2d7dbc42017-02-12 13:52:35 -08005433* lpfc_nvmet_fb_size: NVME Target mode supported first burst size.
5434* When the driver is configured as an NVME target, this value is
5435* communicated to the NVME initiator in the PRLI response. It is
5436* used only when the lpfc_nvme_enable_fb and lpfc_nvmet_support
5437* parameters are set and the target is sending the PRLI RSP.
James Smart895427b2017-02-12 13:52:30 -08005438* Parameter supported on physical port only - no NPIV support.
James Smart2d7dbc42017-02-12 13:52:35 -08005439* Value range is [0,65536]. Default value is 0.
James Smart895427b2017-02-12 13:52:30 -08005440*/
James Smart2d7dbc42017-02-12 13:52:35 -08005441LPFC_ATTR_RW(nvmet_fb_size, 0, 0, 65536,
5442 "NVME Target mode first burst size in 512B increments.");
5443
5444/*
5445 * lpfc_nvme_enable_fb: Enable NVME first burst on I and T functions.
5446 * For the Initiator (I), enabling this parameter means that an NVMET
5447 * PRLI response with FBA enabled and an FB_SIZE set to a nonzero value will be
James Smartdb197bc2019-08-14 16:57:03 -07005448 * processed by the initiator for subsequent NVME FCP IO.
5449 * Currently, this feature is not supported on the NVME target
James Smart2d7dbc42017-02-12 13:52:35 -08005450 * Value range is [0,1]. Default value is 0 (disabled).
5451 */
James Smart895427b2017-02-12 13:52:30 -08005452LPFC_ATTR_RW(nvme_enable_fb, 0, 0, 1,
James Smartdb197bc2019-08-14 16:57:03 -07005453 "Enable First Burst feature for NVME Initiator.");
James Smart895427b2017-02-12 13:52:30 -08005454
5455/*
James Smart977b5a02008-09-07 11:52:04 -04005456# lpfc_max_scsicmpl_time: Use scsi command completion time to control I/O queue
5457# depth. Default value is 0. When the value of this parameter is zero the
5458# SCSI command completion time is not used for controlling I/O queue depth. When
5459# the parameter is set to a non-zero value, the I/O queue depth is controlled
5460# to limit the I/O completion time to the parameter value.
5461# The value is set in milliseconds.
5462*/
James Smarted5b1522016-10-13 15:06:11 -07005463LPFC_VPORT_ATTR(max_scsicmpl_time, 0, 0, 60000,
James Smart977b5a02008-09-07 11:52:04 -04005464 "Use command completion time to control queue depth");
James Smarted5b1522016-10-13 15:06:11 -07005465
James Smart977b5a02008-09-07 11:52:04 -04005466lpfc_vport_param_show(max_scsicmpl_time);
James Smart977b5a02008-09-07 11:52:04 -04005467static int
5468lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val)
5469{
5470 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5471 struct lpfc_nodelist *ndlp, *next_ndlp;
5472
5473 if (val == vport->cfg_max_scsicmpl_time)
5474 return 0;
5475 if ((val < 0) || (val > 60000))
5476 return -EINVAL;
5477 vport->cfg_max_scsicmpl_time = val;
5478
5479 spin_lock_irq(shost->host_lock);
5480 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
James Smart977b5a02008-09-07 11:52:04 -04005481 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
5482 continue;
James Smart7dc517d2010-07-14 15:32:10 -04005483 ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
James Smart977b5a02008-09-07 11:52:04 -04005484 }
5485 spin_unlock_irq(shost->host_lock);
5486 return 0;
5487}
5488lpfc_vport_param_store(max_scsicmpl_time);
Joe Perchesb6b996b2017-12-19 10:15:07 -08005489static DEVICE_ATTR_RW(lpfc_max_scsicmpl_time);
James Smart977b5a02008-09-07 11:52:04 -04005490
5491/*
dea31012005-04-17 16:05:31 -05005492# lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
5493# range is [0,1]. Default value is 0.
5494*/
5495LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
5496
5497/*
James Smartc4908502019-01-28 11:14:28 -08005498# lpfc_xri_rebalancing: enable or disable XRI rebalancing feature
5499# range is [0,1]. Default value is 1.
5500*/
5501LPFC_ATTR_R(xri_rebalancing, 1, 0, 1, "Enable/Disable XRI rebalancing");
5502
5503/*
James Smart895427b2017-02-12 13:52:30 -08005504 * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds
5505 * range is [0,1]. Default value is 0.
James Smart45aa3122019-01-28 11:14:29 -08005506 * For [0], FCP commands are issued to Work Queues based on upper layer
5507 * hardware queue index.
James Smart895427b2017-02-12 13:52:30 -08005508 * For [1], FCP commands are issued to a Work Queue associated with the
5509 * current CPU.
5510 *
James Smart45aa3122019-01-28 11:14:29 -08005511 * LPFC_FCP_SCHED_BY_HDWQ == 0
James Smart895427b2017-02-12 13:52:30 -08005512 * LPFC_FCP_SCHED_BY_CPU == 1
5513 *
5514 * The driver dynamically sets this to 1 (BY_CPU) if it's able to set up cpu
5515 * affinity for FCP/NVME I/Os through Work Queues associated with the current
5516 * CPU. Otherwise, the default 0 (Round Robin) scheduling of FCP/NVME I/Os
5517 * through WQs will be used.
5518 */
James Smart6a828b02019-01-28 11:14:31 -08005519LPFC_ATTR_RW(fcp_io_sched, LPFC_FCP_SCHED_BY_CPU,
James Smart45aa3122019-01-28 11:14:29 -08005520 LPFC_FCP_SCHED_BY_HDWQ,
James Smart895427b2017-02-12 13:52:30 -08005521 LPFC_FCP_SCHED_BY_CPU,
5522 "Determine scheduling algorithm for "
James Smart45aa3122019-01-28 11:14:29 -08005523 "issuing commands [0] - Hardware Queue, [1] - Current CPU");
James Smart49aa1432012-08-03 12:36:42 -04005524
5525/*
James Smart7ea92eb2018-10-23 13:41:10 -07005526 * lpfc_ns_query: Determine algrithmn for NameServer queries after RSCN
5527 * range is [0,1]. Default value is 0.
5528 * For [0], GID_FT is used for NameServer queries after RSCN (default)
5529 * For [1], GID_PT is used for NameServer queries after RSCN
5530 *
5531 */
5532LPFC_ATTR_RW(ns_query, LPFC_NS_QUERY_GID_FT,
5533 LPFC_NS_QUERY_GID_FT, LPFC_NS_QUERY_GID_PT,
5534 "Determine algorithm NameServer queries after RSCN "
5535 "[0] - GID_FT, [1] - GID_PT");
5536
5537/*
James Smarta6571c62012-10-31 14:44:42 -04005538# lpfc_fcp2_no_tgt_reset: Determine bus reset behavior
5539# range is [0,1]. Default value is 0.
5540# For [0], bus reset issues target reset to ALL devices
5541# For [1], bus reset issues target reset to non-FCP2 devices
5542*/
5543LPFC_ATTR_RW(fcp2_no_tgt_reset, 0, 0, 1, "Determine bus reset behavior for "
5544 "FCP2 devices [0] - issue tgt reset, [1] - no tgt reset");
5545
5546
5547/*
dea31012005-04-17 16:05:31 -05005548# lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
5549# cr_delay (msec) or cr_count outstanding commands. cr_delay can take
James Smart7054a602007-04-25 09:52:34 -04005550# value [0,63]. cr_count can take value [1,255]. Default value of cr_delay
dea31012005-04-17 16:05:31 -05005551# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
5552# cr_delay is set to 0.
5553*/
Jamie Wellnitz8189fd12006-02-28 19:25:35 -05005554LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an "
dea31012005-04-17 16:05:31 -05005555 "interrupt response is generated");
5556
Jamie Wellnitz8189fd12006-02-28 19:25:35 -05005557LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "
dea31012005-04-17 16:05:31 -05005558 "interrupt response is generated");
5559
5560/*
Jamie Wellnitzcf5bf972006-02-28 22:33:08 -05005561# lpfc_multi_ring_support: Determines how many rings to spread available
5562# cmd/rsp IOCB entries across.
5563# Value range is [1,2]. Default value is 1.
5564*/
5565LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
5566 "SLI rings to spread IOCB entries across");
5567
5568/*
James Smarta4bc3372006-12-02 13:34:16 -05005569# lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this
5570# identifies what rctl value to configure the additional ring for.
5571# Value range is [1,0xff]. Default value is 4 (Unsolicated Data).
5572*/
James Smart6a9c52c2009-10-02 15:16:51 -04005573LPFC_ATTR_R(multi_ring_rctl, FC_RCTL_DD_UNSOL_DATA, 1,
James Smarta4bc3372006-12-02 13:34:16 -05005574 255, "Identifies RCTL for additional ring configuration");
5575
5576/*
5577# lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this
5578# identifies what type value to configure the additional ring for.
5579# Value range is [1,0xff]. Default value is 5 (LLC/SNAP).
5580*/
James Smart6a9c52c2009-10-02 15:16:51 -04005581LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP, 1,
James Smarta4bc3372006-12-02 13:34:16 -05005582 255, "Identifies TYPE for additional ring configuration");
5583
5584/*
James Smart4258e982015-12-16 18:11:58 -05005585# lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN
5586# 0 = SmartSAN functionality disabled (default)
5587# 1 = SmartSAN functionality enabled
5588# This parameter will override the value of lpfc_fdmi_on module parameter.
5589# Value range is [0,1]. Default value is 0.
dea31012005-04-17 16:05:31 -05005590*/
James Smart4258e982015-12-16 18:11:58 -05005591LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality");
5592
5593/*
5594# lpfc_fdmi_on: Controls FDMI support.
James Smart9abd9992018-08-14 12:55:05 -07005595# 0 No FDMI support
5596# 1 Traditional FDMI support (default)
James Smart8663cbb2016-03-31 14:12:33 -07005597# Traditional FDMI support means the driver will assume FDMI-2 support;
5598# however, if that fails, it will fallback to FDMI-1.
5599# If lpfc_enable_SmartSAN is set to 1, the driver ignores lpfc_fdmi_on.
5600# If lpfc_enable_SmartSAN is set 0, the driver uses the current value of
5601# lpfc_fdmi_on.
James Smart9abd9992018-08-14 12:55:05 -07005602# Value range [0,1]. Default value is 1.
James Smart4258e982015-12-16 18:11:58 -05005603*/
James Smart9abd9992018-08-14 12:55:05 -07005604LPFC_ATTR_R(fdmi_on, 1, 0, 1, "Enable FDMI support");
dea31012005-04-17 16:05:31 -05005605
5606/*
5607# Specifies the maximum number of ELS cmds we can have outstanding (for
5608# discovery). Value range is [1,64]. Default value = 32.
5609*/
James Smart3de2a652007-08-02 11:09:59 -04005610LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
dea31012005-04-17 16:05:31 -05005611 "during discovery");
5612
5613/*
James Smartc4a7c922013-05-31 17:04:59 -04005614# lpfc_max_luns: maximum allowed LUN ID. This is the highest LUN ID that
5615# will be scanned by the SCSI midlayer when sequential scanning is
5616# used; and is also the highest LUN ID allowed when the SCSI midlayer
5617# parses REPORT_LUN responses. The lpfc driver has no LUN count or
5618# LUN ID limit, but the SCSI midlayer requires this field for the uses
5619# above. The lpfc driver limits the default value to 255 for two reasons.
5620# As it bounds the sequential scan loop, scanning for thousands of luns
5621# on a target can take minutes of wall clock time. Additionally,
5622# there are FC targets, such as JBODs, that only recognize 8-bits of
5623# LUN ID. When they receive a value greater than 8 bits, they chop off
5624# the high order bits. In other words, they see LUN IDs 0, 256, 512,
5625# and so on all as LUN ID 0. This causes the linux kernel, which sees
5626# valid responses at each of the LUN IDs, to believe there are multiple
5627# devices present, when in fact, there is only 1.
5628# A customer that is aware of their target behaviors, and the results as
5629# indicated above, is welcome to increase the lpfc_max_luns value.
5630# As mentioned, this value is not used by the lpfc driver, only the
5631# SCSI midlayer.
James Smart65a29c12006-07-06 15:50:50 -04005632# Value range is [0,65535]. Default value is 255.
5633# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
dea31012005-04-17 16:05:31 -05005634*/
Hannes Reinecke1abf6352014-06-25 15:27:38 +02005635LPFC_VPORT_ULL_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN ID");
dea31012005-04-17 16:05:31 -05005636
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05005637/*
5638# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
5639# Value range is [1,255], default value is 10.
5640*/
5641LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
5642 "Milliseconds driver will wait between polling FCP ring");
5643
James Smart4ff43242006-12-02 13:34:56 -05005644/*
James Smart0c411222013-09-06 12:22:46 -04005645# lpfc_task_mgmt_tmo: Maximum time to wait for task management commands
5646# to complete in seconds. Value range is [5,180], default value is 60.
5647*/
5648LPFC_ATTR_RW(task_mgmt_tmo, 60, 5, 180,
5649 "Maximum time to wait for task management commands to complete");
5650/*
James Smart4ff43242006-12-02 13:34:56 -05005651# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
5652# support this feature
George Kadianakis8605c462010-01-17 21:19:31 +02005653# 0 = MSI disabled
James Smart4ff43242006-12-02 13:34:56 -05005654# 1 = MSI enabled
George Kadianakis8605c462010-01-17 21:19:31 +02005655# 2 = MSI-X enabled (default)
5656# Value range is [0,2]. Default value is 2.
James Smart4ff43242006-12-02 13:34:56 -05005657*/
George Kadianakis8605c462010-01-17 21:19:31 +02005658LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
James Smartdb2378e2008-02-08 18:49:51 -05005659 "MSI-X (2), if possible");
James Smart4ff43242006-12-02 13:34:56 -05005660
James Smart13815c82008-01-11 01:52:48 -05005661/*
James Smartf358dd02017-02-12 13:52:34 -08005662 * lpfc_nvme_oas: Use the oas bit when sending NVME/NVMET IOs
James Smart895427b2017-02-12 13:52:30 -08005663 *
5664 * 0 = NVME OAS disabled
5665 * 1 = NVME OAS enabled
5666 *
5667 * Value range is [0,1]. Default value is 0.
5668 */
5669LPFC_ATTR_RW(nvme_oas, 0, 0, 1,
5670 "Use OAS bit on NVME IOs");
5671
5672/*
James Smart4e565cf2018-02-22 08:18:50 -08005673 * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
5674 *
5675 * 0 = Put NVME Command in SGL
5676 * 1 = Embed NVME Command in WQE (unless G7)
5677 * 2 = Embed NVME Command in WQE (force)
5678 *
5679 * Value range is [0,2]. Default value is 1.
5680 */
5681LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
5682 "Embed NVME Command in WQE");
5683
5684/*
James Smart77ffd342019-08-15 19:36:49 -07005685 * lpfc_fcp_mq_threshold: Set the maximum number of Hardware Queues
5686 * the driver will advertise it supports to the SCSI layer.
5687 *
5688 * 0 = Set nr_hw_queues by the number of CPUs or HW queues.
James Smartdcaa2132019-11-04 16:57:06 -08005689 * 1,256 = Manually specify nr_hw_queue value to be advertised,
James Smart77ffd342019-08-15 19:36:49 -07005690 *
James Smart06228002019-08-27 14:28:23 -07005691 * Value range is [0,256]. Default value is 8.
James Smart77ffd342019-08-15 19:36:49 -07005692 */
5693LPFC_ATTR_R(fcp_mq_threshold, LPFC_FCP_MQ_THRESHOLD_DEF,
5694 LPFC_FCP_MQ_THRESHOLD_MIN, LPFC_FCP_MQ_THRESHOLD_MAX,
5695 "Set the number of SCSI Queues advertised");
5696
5697/*
James Smart6a828b02019-01-28 11:14:31 -08005698 * lpfc_hdw_queue: Set the number of Hardware Queues the driver
James Smartcdb42be2019-01-28 11:14:21 -08005699 * will advertise it supports to the NVME and SCSI layers. This also
James Smart6a828b02019-01-28 11:14:31 -08005700 * will map to the number of CQ/WQ pairs the driver will create.
James Smart895427b2017-02-12 13:52:30 -08005701 *
5702 * The NVME Layer will try to create this many, plus 1 administrative
5703 * hardware queue. The administrative queue will always map to WQ 0
James Smart6a828b02019-01-28 11:14:31 -08005704 * A hardware IO queue maps (qidx) to a specific driver CQ/WQ.
James Smart895427b2017-02-12 13:52:30 -08005705 *
James Smartcdb42be2019-01-28 11:14:21 -08005706 * 0 = Configure the number of hdw queues to the number of active CPUs.
James Smartdcaa2132019-11-04 16:57:06 -08005707 * 1,256 = Manually specify how many hdw queues to use.
James Smart895427b2017-02-12 13:52:30 -08005708 *
James Smartdcaa2132019-11-04 16:57:06 -08005709 * Value range is [0,256]. Default value is 0.
James Smart895427b2017-02-12 13:52:30 -08005710 */
James Smartcdb42be2019-01-28 11:14:21 -08005711LPFC_ATTR_R(hdw_queue,
5712 LPFC_HBA_HDWQ_DEF,
5713 LPFC_HBA_HDWQ_MIN, LPFC_HBA_HDWQ_MAX,
5714 "Set the number of I/O Hardware Queues");
James Smart895427b2017-02-12 13:52:30 -08005715
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005716#if IS_ENABLED(CONFIG_X86)
5717/**
5718 * lpfc_cpumask_irq_mode_init - initalizes cpumask of phba based on
5719 * irq_chann_mode
5720 * @phba: Pointer to HBA context object.
5721 **/
5722static void
5723lpfc_cpumask_irq_mode_init(struct lpfc_hba *phba)
5724{
5725 unsigned int cpu, first_cpu, numa_node = NUMA_NO_NODE;
5726 const struct cpumask *sibling_mask;
5727 struct cpumask *aff_mask = &phba->sli4_hba.irq_aff_mask;
5728
5729 cpumask_clear(aff_mask);
5730
5731 if (phba->irq_chann_mode == NUMA_MODE) {
5732 /* Check if we're a NUMA architecture */
5733 numa_node = dev_to_node(&phba->pcidev->dev);
5734 if (numa_node == NUMA_NO_NODE) {
5735 phba->irq_chann_mode = NORMAL_MODE;
5736 return;
5737 }
5738 }
5739
5740 for_each_possible_cpu(cpu) {
5741 switch (phba->irq_chann_mode) {
5742 case NUMA_MODE:
5743 if (cpu_to_node(cpu) == numa_node)
5744 cpumask_set_cpu(cpu, aff_mask);
5745 break;
5746 case NHT_MODE:
5747 sibling_mask = topology_sibling_cpumask(cpu);
5748 first_cpu = cpumask_first(sibling_mask);
5749 if (first_cpu < nr_cpu_ids)
5750 cpumask_set_cpu(first_cpu, aff_mask);
5751 break;
5752 default:
5753 break;
5754 }
5755 }
5756}
5757#endif
5758
5759static void
5760lpfc_assign_default_irq_chann(struct lpfc_hba *phba)
James Smartdcaa2132019-11-04 16:57:06 -08005761{
5762#if IS_ENABLED(CONFIG_X86)
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005763 switch (boot_cpu_data.x86_vendor) {
5764 case X86_VENDOR_AMD:
5765 /* If AMD architecture, then default is NUMA_MODE */
5766 phba->irq_chann_mode = NUMA_MODE;
5767 break;
5768 case X86_VENDOR_INTEL:
5769 /* If Intel architecture, then default is no hyperthread mode */
5770 phba->irq_chann_mode = NHT_MODE;
5771 break;
5772 default:
5773 phba->irq_chann_mode = NORMAL_MODE;
5774 break;
5775 }
5776 lpfc_cpumask_irq_mode_init(phba);
James Smartdcaa2132019-11-04 16:57:06 -08005777#else
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005778 phba->irq_chann_mode = NORMAL_MODE;
James Smartdcaa2132019-11-04 16:57:06 -08005779#endif
5780}
5781
James Smart895427b2017-02-12 13:52:30 -08005782/*
James Smart6a828b02019-01-28 11:14:31 -08005783 * lpfc_irq_chann: Set the number of IRQ vectors that are available
5784 * for Hardware Queues to utilize. This also will map to the number
5785 * of EQ / MSI-X vectors the driver will create. This should never be
5786 * more than the number of Hardware Queues
5787 *
James Smartdcaa2132019-11-04 16:57:06 -08005788 * 0 = Configure number of IRQ Channels to:
5789 * if AMD architecture, number of CPUs on HBA's NUMA node
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005790 * if Intel architecture, number of physical CPUs.
James Smartdcaa2132019-11-04 16:57:06 -08005791 * otherwise, number of active CPUs.
5792 * [1,256] = Manually specify how many IRQ Channels to use.
James Smart6a828b02019-01-28 11:14:31 -08005793 *
James Smartdcaa2132019-11-04 16:57:06 -08005794 * Value range is [0,256]. Default value is [0].
James Smart6a828b02019-01-28 11:14:31 -08005795 */
James Smartdcaa2132019-11-04 16:57:06 -08005796static uint lpfc_irq_chann = LPFC_IRQ_CHANN_DEF;
5797module_param(lpfc_irq_chann, uint, 0444);
5798MODULE_PARM_DESC(lpfc_irq_chann, "Set number of interrupt vectors to allocate");
5799
5800/* lpfc_irq_chann_init - Set the hba irq_chann initial value
5801 * @phba: lpfc_hba pointer.
5802 * @val: contains the initial value
5803 *
5804 * Description:
5805 * Validates the initial value is within range and assigns it to the
5806 * adapter. If not in range, an error message is posted and the
5807 * default value is assigned.
5808 *
5809 * Returns:
5810 * zero if value is in range and is set
5811 * -EINVAL if value was out of range
5812 **/
5813static int
5814lpfc_irq_chann_init(struct lpfc_hba *phba, uint32_t val)
5815{
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005816 const struct cpumask *aff_mask;
James Smartdcaa2132019-11-04 16:57:06 -08005817
5818 if (phba->cfg_use_msi != 2) {
5819 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5820 "8532 use_msi = %u ignoring cfg_irq_numa\n",
5821 phba->cfg_use_msi);
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005822 phba->irq_chann_mode = NORMAL_MODE;
5823 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005824 return 0;
5825 }
5826
5827 /* Check if default setting was passed */
James Smartd3de0d12021-04-11 18:31:21 -07005828 if (val == LPFC_IRQ_CHANN_DEF &&
5829 phba->cfg_hdw_queue == LPFC_HBA_HDWQ_DEF &&
5830 phba->sli_rev == LPFC_SLI_REV4)
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005831 lpfc_assign_default_irq_chann(phba);
James Smartdcaa2132019-11-04 16:57:06 -08005832
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005833 if (phba->irq_chann_mode != NORMAL_MODE) {
5834 aff_mask = &phba->sli4_hba.irq_aff_mask;
James Smartdcaa2132019-11-04 16:57:06 -08005835
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005836 if (cpumask_empty(aff_mask)) {
James Smartdcaa2132019-11-04 16:57:06 -08005837 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005838 "8533 Could not identify CPUS for "
5839 "mode %d, ignoring\n",
5840 phba->irq_chann_mode);
5841 phba->irq_chann_mode = NORMAL_MODE;
5842 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005843 } else {
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005844 phba->cfg_irq_chann = cpumask_weight(aff_mask);
5845
5846 /* If no hyperthread mode, then set hdwq count to
5847 * aff_mask weight as well
5848 */
5849 if (phba->irq_chann_mode == NHT_MODE)
5850 phba->cfg_hdw_queue = phba->cfg_irq_chann;
5851
James Smartdcaa2132019-11-04 16:57:06 -08005852 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5853 "8543 lpfc_irq_chann set to %u "
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005854 "(mode: %d)\n", phba->cfg_irq_chann,
5855 phba->irq_chann_mode);
James Smartdcaa2132019-11-04 16:57:06 -08005856 }
5857 } else {
5858 if (val > LPFC_IRQ_CHANN_MAX) {
5859 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
5860 "8545 lpfc_irq_chann attribute cannot "
5861 "be set to %u, allowed range is "
5862 "[%u,%u]\n",
5863 val,
5864 LPFC_IRQ_CHANN_MIN,
5865 LPFC_IRQ_CHANN_MAX);
Dick Kennedy3048e3e2020-05-01 14:43:06 -07005866 phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
James Smartdcaa2132019-11-04 16:57:06 -08005867 return -EINVAL;
5868 }
James Smartd3de0d12021-04-11 18:31:21 -07005869 if (phba->sli_rev == LPFC_SLI_REV4) {
5870 phba->cfg_irq_chann = val;
5871 } else {
5872 phba->cfg_irq_chann = 2;
5873 phba->cfg_hdw_queue = 1;
5874 }
James Smartdcaa2132019-11-04 16:57:06 -08005875 }
5876
5877 return 0;
5878}
5879
5880/**
5881 * lpfc_irq_chann_show - Display value of irq_chann
5882 * @dev: class converted to a Scsi_host structure.
5883 * @attr: device attribute, not used.
5884 * @buf: on return contains a string with the list sizes
5885 *
5886 * Returns: size of formatted string.
5887 **/
5888static ssize_t
5889lpfc_irq_chann_show(struct device *dev, struct device_attribute *attr,
5890 char *buf)
5891{
5892 struct Scsi_Host *shost = class_to_shost(dev);
5893 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5894 struct lpfc_hba *phba = vport->phba;
5895
5896 return scnprintf(buf, PAGE_SIZE, "%u\n", phba->cfg_irq_chann);
5897}
5898
5899static DEVICE_ATTR_RO(lpfc_irq_chann);
James Smart6a828b02019-01-28 11:14:31 -08005900
5901/*
James Smart13815c82008-01-11 01:52:48 -05005902# lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware.
5903# 0 = HBA resets disabled
5904# 1 = HBA resets enabled (default)
James Smart50212672018-12-13 15:17:57 -08005905# 2 = HBA reset via PCI bus reset enabled
5906# Value range is [0,2]. Default value is 1.
James Smart13815c82008-01-11 01:52:48 -05005907*/
James Smart50212672018-12-13 15:17:57 -08005908LPFC_ATTR_RW(enable_hba_reset, 1, 0, 2, "Enable HBA resets from the driver.");
James Smartc3f28af2006-08-18 17:47:18 -04005909
James Smart13815c82008-01-11 01:52:48 -05005910/*
James Smarteb7a3392010-11-20 23:12:02 -05005911# lpfc_enable_hba_heartbeat: Disable HBA heartbeat timer..
James Smart13815c82008-01-11 01:52:48 -05005912# 0 = HBA Heartbeat disabled
5913# 1 = HBA Heartbeat enabled (default)
5914# Value range is [0,1]. Default value is 1.
5915*/
James Smarteb7a3392010-11-20 23:12:02 -05005916LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat.");
James Smart92d7f7b2007-06-17 19:56:38 -05005917
James Smart83108bd2008-01-11 01:53:09 -05005918/*
James Smart1ba981f2014-02-20 09:56:45 -05005919# lpfc_EnableXLane: Enable Express Lane Feature
5920# 0x0 Express Lane Feature disabled
5921# 0x1 Express Lane Feature enabled
5922# Value range is [0,1]. Default value is 0.
5923*/
5924LPFC_ATTR_R(EnableXLane, 0, 0, 1, "Enable Express Lane Feature.");
5925
5926/*
5927# lpfc_XLanePriority: Define CS_CTL priority for Express Lane Feature
5928# 0x0 - 0x7f = CS_CTL field in FC header (high 7 bits)
5929# Value range is [0x0,0x7f]. Default value is 0
5930*/
James Smart28d7f3d2014-05-21 08:05:28 -04005931LPFC_ATTR_RW(XLanePriority, 0, 0x0, 0x7f, "CS_CTL for Express Lane Feature.");
James Smart1ba981f2014-02-20 09:56:45 -05005932
5933/*
James Smart81301a92008-12-04 22:39:46 -05005934# lpfc_enable_bg: Enable BlockGuard (Emulex's Implementation of T10-DIF)
5935# 0 = BlockGuard disabled (default)
5936# 1 = BlockGuard enabled
5937# Value range is [0,1]. Default value is 0.
5938*/
5939LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
5940
James Smart6fb120a2009-05-22 14:52:59 -04005941/*
James Smart3bfab8a2021-04-11 18:31:23 -07005942# lpfc_prot_mask:
James Smart81301a92008-12-04 22:39:46 -05005943# - Bit mask of host protection capabilities used to register with the
5944# SCSI mid-layer
5945# - Only meaningful if BG is turned on (lpfc_enable_bg=1).
5946# - Allows you to ultimately specify which profiles to use
5947# - Default will result in registering capabilities for all profiles.
James Smart005ffa72012-09-29 11:29:17 -04005948# - SHOST_DIF_TYPE1_PROTECTION 1
5949# HBA supports T10 DIF Type 1: HBA to Target Type 1 Protection
5950# - SHOST_DIX_TYPE0_PROTECTION 8
5951# HBA supports DIX Type 0: Host to HBA protection only
5952# - SHOST_DIX_TYPE1_PROTECTION 16
5953# HBA supports DIX Type 1: Host to HBA Type 1 protection
James Smart81301a92008-12-04 22:39:46 -05005954#
5955*/
James Smartb3b98b72016-10-13 15:06:06 -07005956LPFC_ATTR(prot_mask,
5957 (SHOST_DIF_TYPE1_PROTECTION |
5958 SHOST_DIX_TYPE0_PROTECTION |
5959 SHOST_DIX_TYPE1_PROTECTION),
5960 0,
5961 (SHOST_DIF_TYPE1_PROTECTION |
5962 SHOST_DIX_TYPE0_PROTECTION |
5963 SHOST_DIX_TYPE1_PROTECTION),
5964 "T10-DIF host protection capabilities mask");
James Smart81301a92008-12-04 22:39:46 -05005965
5966/*
James Smart3bfab8a2021-04-11 18:31:23 -07005967# lpfc_prot_guard:
James Smart81301a92008-12-04 22:39:46 -05005968# - Bit mask of protection guard types to register with the SCSI mid-layer
James Smart005ffa72012-09-29 11:29:17 -04005969# - Guard types are currently either 1) T10-DIF CRC 2) IP checksum
James Smart81301a92008-12-04 22:39:46 -05005970# - Allows you to ultimately specify which profiles to use
5971# - Default will result in registering capabilities for all guard types
5972#
5973*/
James Smartb3b98b72016-10-13 15:06:06 -07005974LPFC_ATTR(prot_guard,
5975 SHOST_DIX_GUARD_IP, SHOST_DIX_GUARD_CRC, SHOST_DIX_GUARD_IP,
5976 "T10-DIF host protection guard type");
James Smart81301a92008-12-04 22:39:46 -05005977
James Smart92494142011-02-16 12:39:44 -05005978/*
5979 * Delay initial NPort discovery when Clean Address bit is cleared in
5980 * FLOGI/FDISC accept and FCID/Fabric name/Fabric portname is changed.
5981 * This parameter can have value 0 or 1.
5982 * When this parameter is set to 0, no delay is added to the initial
5983 * discovery.
5984 * When this parameter is set to non-zero value, initial Nport discovery is
5985 * delayed by ra_tov seconds when Clean Address bit is cleared in FLOGI/FDISC
5986 * accept and FCID/Fabric name/Fabric portname is changed.
5987 * Driver always delay Nport discovery for subsequent FLOGI/FDISC completion
5988 * when Clean Address bit is cleared in FLOGI/FDISC
5989 * accept and FCID/Fabric name/Fabric portname is changed.
5990 * Default value is 0.
5991 */
James Smart8eb8b962016-07-06 12:36:08 -07005992LPFC_ATTR(delay_discovery, 0, 0, 1,
5993 "Delay NPort discovery when Clean Address bit is cleared.");
James Smart81301a92008-12-04 22:39:46 -05005994
5995/*
James Smart3621a712009-04-06 18:47:14 -04005996 * lpfc_sg_seg_cnt - Initial Maximum DMA Segment Count
James Smart5b9e70b2018-09-10 10:30:42 -07005997 * This value can be set to values between 64 and 4096. The default value
5998 * is 64, but may be increased to allow for larger Max I/O sizes. The scsi
5999 * and nvme layers will allow I/O sizes up to (MAX_SEG_COUNT * SEG_SIZE).
James Smart96f70772013-04-17 20:16:15 -04006000 * Because of the additional overhead involved in setting up T10-DIF,
6001 * this parameter will be limited to 128 if BlockGuard is enabled under SLI4
6002 * and will be limited to 512 if BlockGuard is enabled under SLI3.
James Smart83108bd2008-01-11 01:53:09 -05006003 */
James Smart5b9e70b2018-09-10 10:30:42 -07006004static uint lpfc_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
6005module_param(lpfc_sg_seg_cnt, uint, 0444);
6006MODULE_PARM_DESC(lpfc_sg_seg_cnt, "Max Scatter Gather Segment Count");
6007
6008/**
6009 * lpfc_sg_seg_cnt_show - Display the scatter/gather list sizes
6010 * configured for the adapter
6011 * @dev: class converted to a Scsi_host structure.
6012 * @attr: device attribute, not used.
6013 * @buf: on return contains a string with the list sizes
6014 *
6015 * Returns: size of formatted string.
6016 **/
6017static ssize_t
6018lpfc_sg_seg_cnt_show(struct device *dev, struct device_attribute *attr,
6019 char *buf)
6020{
6021 struct Scsi_Host *shost = class_to_shost(dev);
6022 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
6023 struct lpfc_hba *phba = vport->phba;
6024 int len;
6025
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07006026 len = scnprintf(buf, PAGE_SIZE, "SGL sz: %d total SGEs: %d\n",
James Smart5b9e70b2018-09-10 10:30:42 -07006027 phba->cfg_sg_dma_buf_size, phba->cfg_total_seg_cnt);
6028
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07006029 len += scnprintf(buf + len, PAGE_SIZE, "Cfg: %d SCSI: %d NVME: %d\n",
James Smart5b9e70b2018-09-10 10:30:42 -07006030 phba->cfg_sg_seg_cnt, phba->cfg_scsi_seg_cnt,
6031 phba->cfg_nvme_seg_cnt);
6032 return len;
6033}
6034
6035static DEVICE_ATTR_RO(lpfc_sg_seg_cnt);
6036
6037/**
6038 * lpfc_sg_seg_cnt_init - Set the hba sg_seg_cnt initial value
6039 * @phba: lpfc_hba pointer.
6040 * @val: contains the initial value
6041 *
6042 * Description:
6043 * Validates the initial value is within range and assigns it to the
6044 * adapter. If not in range, an error message is posted and the
6045 * default value is assigned.
6046 *
6047 * Returns:
6048 * zero if value is in range and is set
6049 * -EINVAL if value was out of range
6050 **/
6051static int
6052lpfc_sg_seg_cnt_init(struct lpfc_hba *phba, int val)
6053{
6054 if (val >= LPFC_MIN_SG_SEG_CNT && val <= LPFC_MAX_SG_SEG_CNT) {
6055 phba->cfg_sg_seg_cnt = val;
6056 return 0;
6057 }
6058 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart5b1f5082021-04-11 18:31:25 -07006059 "0409 lpfc_sg_seg_cnt attribute cannot be set to %d, "
6060 "allowed range is [%d, %d]\n",
James Smart5b9e70b2018-09-10 10:30:42 -07006061 val, LPFC_MIN_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT);
6062 phba->cfg_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
6063 return -EINVAL;
6064}
James Smart83108bd2008-01-11 01:53:09 -05006065
James Smart96f70772013-04-17 20:16:15 -04006066/*
James Smart7bdedb32016-07-06 12:36:00 -07006067 * lpfc_enable_mds_diags: Enable MDS Diagnostics
6068 * 0 = MDS Diagnostics disabled (default)
6069 * 1 = MDS Diagnostics enabled
6070 * Value range is [0,1]. Default value is 0.
6071 */
James Smarte62245d2019-08-14 16:57:08 -07006072LPFC_ATTR_RW(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");
James Smart7bdedb32016-07-06 12:36:00 -07006073
James Smart44fd7fe2017-08-23 16:55:47 -07006074/*
James Smartd2cc9bc2018-09-10 10:30:50 -07006075 * lpfc_ras_fwlog_buffsize: Firmware logging host buffer size
6076 * 0 = Disable firmware logging (default)
6077 * [1-4] = Multiple of 1/4th Mb of host memory for FW logging
6078 * Value range [0..4]. Default value is 0
6079 */
James Smart95bfc6d2019-10-18 14:18:27 -07006080LPFC_ATTR(ras_fwlog_buffsize, 0, 0, 4, "Host memory for FW logging");
6081lpfc_param_show(ras_fwlog_buffsize);
6082
6083static ssize_t
6084lpfc_ras_fwlog_buffsize_set(struct lpfc_hba *phba, uint val)
6085{
6086 int ret = 0;
6087 enum ras_state state;
6088
6089 if (!lpfc_rangecheck(val, 0, 4))
6090 return -EINVAL;
6091
6092 if (phba->cfg_ras_fwlog_buffsize == val)
6093 return 0;
6094
James Smartdda5bdf2019-11-04 16:57:02 -08006095 if (phba->cfg_ras_fwlog_func != PCI_FUNC(phba->pcidev->devfn))
James Smart95bfc6d2019-10-18 14:18:27 -07006096 return -EINVAL;
6097
6098 spin_lock_irq(&phba->hbalock);
6099 state = phba->ras_fwlog.state;
6100 spin_unlock_irq(&phba->hbalock);
6101
6102 if (state == REG_INPROGRESS) {
6103 lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "6147 RAS Logging "
6104 "registration is in progress\n");
6105 return -EBUSY;
6106 }
6107
6108 /* For disable logging: stop the logs and free the DMA.
6109 * For ras_fwlog_buffsize size change we still need to free and
6110 * reallocate the DMA in lpfc_sli4_ras_fwlog_init.
6111 */
6112 phba->cfg_ras_fwlog_buffsize = val;
6113 if (state == ACTIVE) {
6114 lpfc_ras_stop_fwlog(phba);
6115 lpfc_sli4_ras_dma_free(phba);
6116 }
6117
6118 lpfc_sli4_ras_init(phba);
6119 if (phba->ras_fwlog.ras_enabled)
6120 ret = lpfc_sli4_ras_fwlog_init(phba, phba->cfg_ras_fwlog_level,
6121 LPFC_RAS_ENABLE_LOGGING);
6122 return ret;
6123}
6124
6125lpfc_param_store(ras_fwlog_buffsize);
6126static DEVICE_ATTR_RW(lpfc_ras_fwlog_buffsize);
James Smartd2cc9bc2018-09-10 10:30:50 -07006127
6128/*
6129 * lpfc_ras_fwlog_level: Firmware logging verbosity level
6130 * Valid only if firmware logging is enabled
6131 * 0(Least Verbosity) 4 (most verbosity)
6132 * Value range is [0..4]. Default value is 0
6133 */
6134LPFC_ATTR_RW(ras_fwlog_level, 0, 0, 4, "Firmware Logging Level");
6135
6136/*
6137 * lpfc_ras_fwlog_func: Firmware logging enabled on function number
6138 * Default function which has RAS support : 0
6139 * Value Range is [0..7].
6140 * FW logging is a global action and enablement is via a specific
6141 * port.
6142 */
6143LPFC_ATTR_RW(ras_fwlog_func, 0, 0, 7, "Firmware Logging Enabled on Function");
6144
6145/*
James Smart44fd7fe2017-08-23 16:55:47 -07006146 * lpfc_enable_bbcr: Enable BB Credit Recovery
6147 * 0 = BB Credit Recovery disabled
6148 * 1 = BB Credit Recovery enabled (default)
6149 * Value range is [0,1]. Default value is 1.
6150 */
6151LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
6152
James Smart1351e692018-02-22 08:18:43 -08006153/*
6154 * lpfc_enable_dpp: Enable DPP on G7
6155 * 0 = DPP on G7 disabled
6156 * 1 = DPP on G7 enabled (default)
6157 * Value range is [0,1]. Default value is 1.
6158 */
6159LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
6160
James Smart8aaa7bc2020-10-20 13:27:17 -07006161/*
6162 * lpfc_enable_mi: Enable FDMI MIB
6163 * 0 = disabled
6164 * 1 = enabled (default)
6165 * Value range is [0,1].
6166 */
6167LPFC_ATTR_R(enable_mi, 1, 0, 1, "Enable MI");
6168
Gaurav Srivastava7ba22722021-06-08 10:05:48 +05306169/*
6170 * lpfc_max_vmid: Maximum number of VMs to be tagged. This is valid only if
6171 * either vmid_app_header or vmid_priority_tagging is enabled.
6172 * 4 - 255 = vmid support enabled for 4-255 VMs
6173 * Value range is [4,255].
6174 */
6175LPFC_ATTR_RW(max_vmid, LPFC_MIN_VMID, LPFC_MIN_VMID, LPFC_MAX_VMID,
6176 "Maximum number of VMs supported");
6177
6178/*
6179 * lpfc_vmid_inactivity_timeout: Inactivity timeout duration in hours
6180 * 0 = Timeout is disabled
6181 * Value range is [0,24].
6182 */
6183LPFC_ATTR_RW(vmid_inactivity_timeout, 4, 0, 24,
6184 "Inactivity timeout in hours");
6185
6186/*
6187 * lpfc_vmid_app_header: Enable App Header VMID support
6188 * 0 = Support is disabled (default)
6189 * 1 = Support is enabled
6190 * Value range is [0,1].
6191 */
6192LPFC_ATTR_RW(vmid_app_header, LPFC_VMID_APP_HEADER_DISABLE,
6193 LPFC_VMID_APP_HEADER_DISABLE, LPFC_VMID_APP_HEADER_ENABLE,
6194 "Enable App Header VMID support");
6195
6196/*
6197 * lpfc_vmid_priority_tagging: Enable Priority Tagging VMID support
6198 * 0 = Support is disabled (default)
6199 * 1 = Allow supported targets only
6200 * 2 = Allow all targets
6201 * Value range is [0,2].
6202 */
6203LPFC_ATTR_RW(vmid_priority_tagging, LPFC_VMID_PRIO_TAG_DISABLE,
6204 LPFC_VMID_PRIO_TAG_DISABLE,
6205 LPFC_VMID_PRIO_TAG_ALL_TARGETS,
6206 "Enable Priority Tagging VMID support");
6207
Tony Jonesee959b02008-02-22 00:13:36 +01006208struct device_attribute *lpfc_hba_attrs[] = {
James Smart895427b2017-02-12 13:52:30 -08006209 &dev_attr_nvme_info,
James Smart4c47efc2019-01-28 11:14:25 -08006210 &dev_attr_scsi_stat,
James Smart81301a92008-12-04 22:39:46 -05006211 &dev_attr_bg_info,
6212 &dev_attr_bg_guard_err,
6213 &dev_attr_bg_apptag_err,
6214 &dev_attr_bg_reftag_err,
Tony Jonesee959b02008-02-22 00:13:36 +01006215 &dev_attr_info,
6216 &dev_attr_serialnum,
6217 &dev_attr_modeldesc,
6218 &dev_attr_modelname,
6219 &dev_attr_programtype,
6220 &dev_attr_portnum,
6221 &dev_attr_fwrev,
6222 &dev_attr_hdw,
6223 &dev_attr_option_rom_version,
Hannes Reineckebbd1ae42008-03-18 14:32:28 +01006224 &dev_attr_link_state,
Tony Jonesee959b02008-02-22 00:13:36 +01006225 &dev_attr_num_discovered_ports,
James Smart84774a42008-08-24 21:50:06 -04006226 &dev_attr_menlo_mgmt_mode,
Tony Jonesee959b02008-02-22 00:13:36 +01006227 &dev_attr_lpfc_drvr_version,
James Smart45ed1192009-10-02 15:17:02 -04006228 &dev_attr_lpfc_enable_fip,
Tony Jonesee959b02008-02-22 00:13:36 +01006229 &dev_attr_lpfc_temp_sensor,
6230 &dev_attr_lpfc_log_verbose,
6231 &dev_attr_lpfc_lun_queue_depth,
James Smart7dc517d2010-07-14 15:32:10 -04006232 &dev_attr_lpfc_tgt_queue_depth,
Tony Jonesee959b02008-02-22 00:13:36 +01006233 &dev_attr_lpfc_hba_queue_depth,
6234 &dev_attr_lpfc_peer_port_login,
6235 &dev_attr_lpfc_nodev_tmo,
6236 &dev_attr_lpfc_devloss_tmo,
James Smart895427b2017-02-12 13:52:30 -08006237 &dev_attr_lpfc_enable_fc4_type,
Tony Jonesee959b02008-02-22 00:13:36 +01006238 &dev_attr_lpfc_fcp_class,
6239 &dev_attr_lpfc_use_adisc,
James Smart3cb01c52013-07-15 18:35:04 -04006240 &dev_attr_lpfc_first_burst_size,
Tony Jonesee959b02008-02-22 00:13:36 +01006241 &dev_attr_lpfc_ack0,
James Smartc4908502019-01-28 11:14:28 -08006242 &dev_attr_lpfc_xri_rebalancing,
Tony Jonesee959b02008-02-22 00:13:36 +01006243 &dev_attr_lpfc_topology,
6244 &dev_attr_lpfc_scan_down,
6245 &dev_attr_lpfc_link_speed,
James Smart49aa1432012-08-03 12:36:42 -04006246 &dev_attr_lpfc_fcp_io_sched,
James Smart7ea92eb2018-10-23 13:41:10 -07006247 &dev_attr_lpfc_ns_query,
James Smarta6571c62012-10-31 14:44:42 -04006248 &dev_attr_lpfc_fcp2_no_tgt_reset,
Tony Jonesee959b02008-02-22 00:13:36 +01006249 &dev_attr_lpfc_cr_delay,
6250 &dev_attr_lpfc_cr_count,
6251 &dev_attr_lpfc_multi_ring_support,
6252 &dev_attr_lpfc_multi_ring_rctl,
6253 &dev_attr_lpfc_multi_ring_type,
6254 &dev_attr_lpfc_fdmi_on,
James Smart4258e982015-12-16 18:11:58 -05006255 &dev_attr_lpfc_enable_SmartSAN,
Tony Jonesee959b02008-02-22 00:13:36 +01006256 &dev_attr_lpfc_max_luns,
6257 &dev_attr_lpfc_enable_npiv,
James Smart7d791df2011-07-22 18:37:52 -04006258 &dev_attr_lpfc_fcf_failover_policy,
James Smart19ca7602010-11-20 23:11:55 -05006259 &dev_attr_lpfc_enable_rrq,
James Smart3e49af92021-05-14 12:55:57 -07006260 &dev_attr_lpfc_fcp_wait_abts_rsp,
Tony Jonesee959b02008-02-22 00:13:36 +01006261 &dev_attr_nport_evt_cnt,
6262 &dev_attr_board_mode,
6263 &dev_attr_max_vpi,
6264 &dev_attr_used_vpi,
6265 &dev_attr_max_rpi,
6266 &dev_attr_used_rpi,
6267 &dev_attr_max_xri,
6268 &dev_attr_used_xri,
6269 &dev_attr_npiv_info,
6270 &dev_attr_issue_reset,
6271 &dev_attr_lpfc_poll,
6272 &dev_attr_lpfc_poll_tmo,
James Smart0c411222013-09-06 12:22:46 -04006273 &dev_attr_lpfc_task_mgmt_tmo,
Tony Jonesee959b02008-02-22 00:13:36 +01006274 &dev_attr_lpfc_use_msi,
James Smart895427b2017-02-12 13:52:30 -08006275 &dev_attr_lpfc_nvme_oas,
James Smart4e565cf2018-02-22 08:18:50 -08006276 &dev_attr_lpfc_nvme_embed_cmd,
James Smartda0436e2009-05-22 14:51:39 -04006277 &dev_attr_lpfc_fcp_imax,
James Smart41b194b2019-05-14 14:58:08 -07006278 &dev_attr_lpfc_force_rscn,
James Smart32517fc2019-01-28 11:14:33 -08006279 &dev_attr_lpfc_cq_poll_threshold,
6280 &dev_attr_lpfc_cq_max_proc_limit,
James Smart7bb03bb2013-04-17 20:19:16 -04006281 &dev_attr_lpfc_fcp_cpu_map,
James Smart77ffd342019-08-15 19:36:49 -07006282 &dev_attr_lpfc_fcp_mq_threshold,
James Smartcdb42be2019-01-28 11:14:21 -08006283 &dev_attr_lpfc_hdw_queue,
James Smart6a828b02019-01-28 11:14:31 -08006284 &dev_attr_lpfc_irq_chann,
James Smartf358dd02017-02-12 13:52:34 -08006285 &dev_attr_lpfc_suppress_rsp,
James Smart2d7dbc42017-02-12 13:52:35 -08006286 &dev_attr_lpfc_nvmet_mrq,
James Smart2448e482018-04-09 14:24:24 -07006287 &dev_attr_lpfc_nvmet_mrq_post,
James Smart895427b2017-02-12 13:52:30 -08006288 &dev_attr_lpfc_nvme_enable_fb,
James Smart2d7dbc42017-02-12 13:52:35 -08006289 &dev_attr_lpfc_nvmet_fb_size,
James Smart81301a92008-12-04 22:39:46 -05006290 &dev_attr_lpfc_enable_bg,
James Smart352e5fd2016-12-30 06:57:47 -08006291 &dev_attr_lpfc_soft_wwnn,
6292 &dev_attr_lpfc_soft_wwpn,
6293 &dev_attr_lpfc_soft_wwn_enable,
Tony Jonesee959b02008-02-22 00:13:36 +01006294 &dev_attr_lpfc_enable_hba_reset,
6295 &dev_attr_lpfc_enable_hba_heartbeat,
James Smart1ba981f2014-02-20 09:56:45 -05006296 &dev_attr_lpfc_EnableXLane,
6297 &dev_attr_lpfc_XLanePriority,
6298 &dev_attr_lpfc_xlane_lun,
6299 &dev_attr_lpfc_xlane_tgt,
6300 &dev_attr_lpfc_xlane_vpt,
6301 &dev_attr_lpfc_xlane_lun_state,
6302 &dev_attr_lpfc_xlane_lun_status,
James Smartc92c8412016-07-06 12:36:05 -07006303 &dev_attr_lpfc_xlane_priority,
Tony Jonesee959b02008-02-22 00:13:36 +01006304 &dev_attr_lpfc_sg_seg_cnt,
James Smart977b5a02008-09-07 11:52:04 -04006305 &dev_attr_lpfc_max_scsicmpl_time,
James Smartea2151b2008-09-07 11:52:10 -04006306 &dev_attr_lpfc_stat_data_ctrl,
James Smart0d878412009-10-02 15:16:56 -04006307 &dev_attr_lpfc_aer_support,
6308 &dev_attr_lpfc_aer_state_cleanup,
James Smart912e3ac2011-05-24 11:42:11 -04006309 &dev_attr_lpfc_sriov_nr_virtfn,
James Smartc71ab862012-10-31 14:44:33 -04006310 &dev_attr_lpfc_req_fw_upgrade,
James Smart84d1b002010-02-12 14:42:33 -05006311 &dev_attr_lpfc_suppress_link_up,
James Smart2a9bf3d2010-06-07 15:24:45 -04006312 &dev_attr_iocb_hw,
James Smart83c6cb12019-10-18 14:18:30 -07006313 &dev_attr_pls,
6314 &dev_attr_pt,
James Smart2a9bf3d2010-06-07 15:24:45 -04006315 &dev_attr_txq_hw,
6316 &dev_attr_txcmplq_hw,
James Smart912e3ac2011-05-24 11:42:11 -04006317 &dev_attr_lpfc_sriov_hw_max_virtfn,
James Smart026abb82011-12-13 13:20:45 -05006318 &dev_attr_protocol,
James Smart1ba981f2014-02-20 09:56:45 -05006319 &dev_attr_lpfc_xlane_supported,
James Smart7bdedb32016-07-06 12:36:00 -07006320 &dev_attr_lpfc_enable_mds_diags,
James Smartd2cc9bc2018-09-10 10:30:50 -07006321 &dev_attr_lpfc_ras_fwlog_buffsize,
6322 &dev_attr_lpfc_ras_fwlog_level,
6323 &dev_attr_lpfc_ras_fwlog_func,
James Smart44fd7fe2017-08-23 16:55:47 -07006324 &dev_attr_lpfc_enable_bbcr,
James Smart1351e692018-02-22 08:18:43 -08006325 &dev_attr_lpfc_enable_dpp,
James Smart8aaa7bc2020-10-20 13:27:17 -07006326 &dev_attr_lpfc_enable_mi,
Gaurav Srivastava7ba22722021-06-08 10:05:48 +05306327 &dev_attr_lpfc_max_vmid,
6328 &dev_attr_lpfc_vmid_inactivity_timeout,
6329 &dev_attr_lpfc_vmid_app_header,
6330 &dev_attr_lpfc_vmid_priority_tagging,
dea31012005-04-17 16:05:31 -05006331 NULL,
6332};
6333
Tony Jonesee959b02008-02-22 00:13:36 +01006334struct device_attribute *lpfc_vport_attrs[] = {
6335 &dev_attr_info,
Hannes Reineckebbd1ae42008-03-18 14:32:28 +01006336 &dev_attr_link_state,
Tony Jonesee959b02008-02-22 00:13:36 +01006337 &dev_attr_num_discovered_ports,
6338 &dev_attr_lpfc_drvr_version,
6339 &dev_attr_lpfc_log_verbose,
6340 &dev_attr_lpfc_lun_queue_depth,
James Smart7dc517d2010-07-14 15:32:10 -04006341 &dev_attr_lpfc_tgt_queue_depth,
Tony Jonesee959b02008-02-22 00:13:36 +01006342 &dev_attr_lpfc_nodev_tmo,
6343 &dev_attr_lpfc_devloss_tmo,
6344 &dev_attr_lpfc_hba_queue_depth,
6345 &dev_attr_lpfc_peer_port_login,
6346 &dev_attr_lpfc_restrict_login,
6347 &dev_attr_lpfc_fcp_class,
6348 &dev_attr_lpfc_use_adisc,
James Smart3cb01c52013-07-15 18:35:04 -04006349 &dev_attr_lpfc_first_burst_size,
Tony Jonesee959b02008-02-22 00:13:36 +01006350 &dev_attr_lpfc_max_luns,
6351 &dev_attr_nport_evt_cnt,
6352 &dev_attr_npiv_info,
6353 &dev_attr_lpfc_enable_da_id,
James Smartea2151b2008-09-07 11:52:10 -04006354 &dev_attr_lpfc_max_scsicmpl_time,
6355 &dev_attr_lpfc_stat_data_ctrl,
James Smart21e9a0a2009-05-22 14:53:21 -04006356 &dev_attr_lpfc_static_vport,
James Smart3de2a652007-08-02 11:09:59 -04006357 NULL,
6358};
6359
James Smarte59058c2008-08-24 21:49:00 -04006360/**
James Smart3621a712009-04-06 18:47:14 -04006361 * sysfs_ctlreg_write - Write method for writing to ctlreg
Chris Wright2c3c8be2010-05-12 18:28:57 -07006362 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006363 * @kobj: kernel kobject that contains the kernel class device.
6364 * @bin_attr: kernel attributes passed to us.
6365 * @buf: contains the data to be written to the adapter IOREG space.
6366 * @off: offset into buffer to beginning of data.
6367 * @count: bytes to transfer.
6368 *
6369 * Description:
6370 * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
6371 * Uses the adapter io control registers to send buf contents to the adapter.
6372 *
6373 * Returns:
6374 * -ERANGE off and count combo out of range
6375 * -EINVAL off, count or buff address invalid
6376 * -EPERM adapter is offline
6377 * value of count, buf contents written
6378 **/
dea31012005-04-17 16:05:31 -05006379static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006380sysfs_ctlreg_write(struct file *filp, struct kobject *kobj,
6381 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006382 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006383{
6384 size_t buf_off;
Tony Jonesee959b02008-02-22 00:13:36 +01006385 struct device *dev = container_of(kobj, struct device, kobj);
6386 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05006387 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6388 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006389
James Smartf1126682009-06-10 17:22:44 -04006390 if (phba->sli_rev >= LPFC_SLI_REV4)
6391 return -EPERM;
6392
dea31012005-04-17 16:05:31 -05006393 if ((off + count) > FF_REG_AREA_SIZE)
6394 return -ERANGE;
6395
James Smartf7a919b2011-08-21 21:49:16 -04006396 if (count <= LPFC_REG_WRITE_KEY_SIZE)
6397 return 0;
dea31012005-04-17 16:05:31 -05006398
6399 if (off % 4 || count % 4 || (unsigned long)buf % 4)
6400 return -EINVAL;
6401
James Smartf7a919b2011-08-21 21:49:16 -04006402 /* This is to protect HBA registers from accidental writes. */
6403 if (memcmp(buf, LPFC_REG_WRITE_KEY, LPFC_REG_WRITE_KEY_SIZE))
6404 return -EINVAL;
6405
6406 if (!(vport->fc_flag & FC_OFFLINE_MODE))
dea31012005-04-17 16:05:31 -05006407 return -EPERM;
dea31012005-04-17 16:05:31 -05006408
James Smart2e0fef82007-06-17 19:56:36 -05006409 spin_lock_irq(&phba->hbalock);
James Smartf7a919b2011-08-21 21:49:16 -04006410 for (buf_off = 0; buf_off < count - LPFC_REG_WRITE_KEY_SIZE;
6411 buf_off += sizeof(uint32_t))
6412 writel(*((uint32_t *)(buf + buf_off + LPFC_REG_WRITE_KEY_SIZE)),
dea31012005-04-17 16:05:31 -05006413 phba->ctrl_regs_memmap_p + off + buf_off);
6414
James Smart2e0fef82007-06-17 19:56:36 -05006415 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006416
6417 return count;
6418}
6419
James Smarte59058c2008-08-24 21:49:00 -04006420/**
James Smart3621a712009-04-06 18:47:14 -04006421 * sysfs_ctlreg_read - Read method for reading from ctlreg
Chris Wright2c3c8be2010-05-12 18:28:57 -07006422 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006423 * @kobj: kernel kobject that contains the kernel class device.
6424 * @bin_attr: kernel attributes passed to us.
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02006425 * @buf: if successful contains the data from the adapter IOREG space.
James Smarte59058c2008-08-24 21:49:00 -04006426 * @off: offset into buffer to beginning of data.
6427 * @count: bytes to transfer.
6428 *
6429 * Description:
6430 * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
6431 * Uses the adapter io control registers to read data into buf.
6432 *
6433 * Returns:
6434 * -ERANGE off and count combo out of range
6435 * -EINVAL off, count or buff address invalid
6436 * value of count, buf contents read
6437 **/
dea31012005-04-17 16:05:31 -05006438static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006439sysfs_ctlreg_read(struct file *filp, struct kobject *kobj,
6440 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006441 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006442{
6443 size_t buf_off;
6444 uint32_t * tmp_ptr;
Tony Jonesee959b02008-02-22 00:13:36 +01006445 struct device *dev = container_of(kobj, struct device, kobj);
6446 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05006447 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6448 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006449
James Smartf1126682009-06-10 17:22:44 -04006450 if (phba->sli_rev >= LPFC_SLI_REV4)
6451 return -EPERM;
6452
dea31012005-04-17 16:05:31 -05006453 if (off > FF_REG_AREA_SIZE)
6454 return -ERANGE;
6455
6456 if ((off + count) > FF_REG_AREA_SIZE)
6457 count = FF_REG_AREA_SIZE - off;
6458
6459 if (count == 0) return 0;
6460
6461 if (off % 4 || count % 4 || (unsigned long)buf % 4)
6462 return -EINVAL;
6463
James Smart2e0fef82007-06-17 19:56:36 -05006464 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006465
6466 for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {
6467 tmp_ptr = (uint32_t *)(buf + buf_off);
6468 *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);
6469 }
6470
James Smart2e0fef82007-06-17 19:56:36 -05006471 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006472
6473 return count;
6474}
6475
6476static struct bin_attribute sysfs_ctlreg_attr = {
6477 .attr = {
6478 .name = "ctlreg",
6479 .mode = S_IRUSR | S_IWUSR,
dea31012005-04-17 16:05:31 -05006480 },
6481 .size = 256,
6482 .read = sysfs_ctlreg_read,
6483 .write = sysfs_ctlreg_write,
6484};
6485
James Smarte59058c2008-08-24 21:49:00 -04006486/**
James Smart3621a712009-04-06 18:47:14 -04006487 * sysfs_mbox_write - Write method for writing information via mbox
Chris Wright2c3c8be2010-05-12 18:28:57 -07006488 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006489 * @kobj: kernel kobject that contains the kernel class device.
6490 * @bin_attr: kernel attributes passed to us.
6491 * @buf: contains the data to be written to sysfs mbox.
6492 * @off: offset into buffer to beginning of data.
6493 * @count: bytes to transfer.
6494 *
6495 * Description:
James Smart026abb82011-12-13 13:20:45 -05006496 * Deprecated function. All mailbox access from user space is performed via the
6497 * bsg interface.
James Smarte59058c2008-08-24 21:49:00 -04006498 *
6499 * Returns:
James Smart026abb82011-12-13 13:20:45 -05006500 * -EPERM operation not permitted
James Smarte59058c2008-08-24 21:49:00 -04006501 **/
dea31012005-04-17 16:05:31 -05006502static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006503sysfs_mbox_write(struct file *filp, struct kobject *kobj,
6504 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006505 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006506{
James Smart026abb82011-12-13 13:20:45 -05006507 return -EPERM;
dea31012005-04-17 16:05:31 -05006508}
6509
James Smarte59058c2008-08-24 21:49:00 -04006510/**
James Smart3621a712009-04-06 18:47:14 -04006511 * sysfs_mbox_read - Read method for reading information via mbox
Chris Wright2c3c8be2010-05-12 18:28:57 -07006512 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006513 * @kobj: kernel kobject that contains the kernel class device.
6514 * @bin_attr: kernel attributes passed to us.
6515 * @buf: contains the data to be read from sysfs mbox.
6516 * @off: offset into buffer to beginning of data.
6517 * @count: bytes to transfer.
6518 *
6519 * Description:
James Smart026abb82011-12-13 13:20:45 -05006520 * Deprecated function. All mailbox access from user space is performed via the
6521 * bsg interface.
James Smarte59058c2008-08-24 21:49:00 -04006522 *
6523 * Returns:
James Smart026abb82011-12-13 13:20:45 -05006524 * -EPERM operation not permitted
James Smarte59058c2008-08-24 21:49:00 -04006525 **/
dea31012005-04-17 16:05:31 -05006526static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006527sysfs_mbox_read(struct file *filp, struct kobject *kobj,
6528 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006529 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006530{
James Smart026abb82011-12-13 13:20:45 -05006531 return -EPERM;
dea31012005-04-17 16:05:31 -05006532}
6533
6534static struct bin_attribute sysfs_mbox_attr = {
6535 .attr = {
6536 .name = "mbox",
6537 .mode = S_IRUSR | S_IWUSR,
dea31012005-04-17 16:05:31 -05006538 },
James Smartc0c11512011-05-24 11:41:34 -04006539 .size = MAILBOX_SYSFS_MAX,
dea31012005-04-17 16:05:31 -05006540 .read = sysfs_mbox_read,
6541 .write = sysfs_mbox_write,
6542};
6543
James Smarte59058c2008-08-24 21:49:00 -04006544/**
James Smart3621a712009-04-06 18:47:14 -04006545 * lpfc_alloc_sysfs_attr - Creates the ctlreg and mbox entries
James Smarte59058c2008-08-24 21:49:00 -04006546 * @vport: address of lpfc vport structure.
6547 *
6548 * Return codes:
6549 * zero on success
6550 * error return code from sysfs_create_bin_file()
6551 **/
dea31012005-04-17 16:05:31 -05006552int
James Smart2e0fef82007-06-17 19:56:36 -05006553lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05006554{
James Smart2e0fef82007-06-17 19:56:36 -05006555 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05006556 int error;
6557
Tony Jonesee959b02008-02-22 00:13:36 +01006558 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smarteada2722008-12-04 22:39:13 -05006559 &sysfs_drvr_stat_data_attr);
6560
6561 /* Virtual ports do not need ctrl_reg and mbox */
6562 if (error || vport->port_type == LPFC_NPIV_PORT)
6563 goto out;
6564
6565 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smart92d7f7b2007-06-17 19:56:38 -05006566 &sysfs_ctlreg_attr);
dea31012005-04-17 16:05:31 -05006567 if (error)
James Smarteada2722008-12-04 22:39:13 -05006568 goto out_remove_stat_attr;
dea31012005-04-17 16:05:31 -05006569
Tony Jonesee959b02008-02-22 00:13:36 +01006570 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smart92d7f7b2007-06-17 19:56:38 -05006571 &sysfs_mbox_attr);
dea31012005-04-17 16:05:31 -05006572 if (error)
6573 goto out_remove_ctlreg_attr;
6574
6575 return 0;
6576out_remove_ctlreg_attr:
Tony Jonesee959b02008-02-22 00:13:36 +01006577 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
James Smarteada2722008-12-04 22:39:13 -05006578out_remove_stat_attr:
6579 sysfs_remove_bin_file(&shost->shost_dev.kobj,
6580 &sysfs_drvr_stat_data_attr);
dea31012005-04-17 16:05:31 -05006581out:
6582 return error;
6583}
6584
James Smarte59058c2008-08-24 21:49:00 -04006585/**
James Smart3621a712009-04-06 18:47:14 -04006586 * lpfc_free_sysfs_attr - Removes the ctlreg and mbox entries
James Smarte59058c2008-08-24 21:49:00 -04006587 * @vport: address of lpfc vport structure.
6588 **/
dea31012005-04-17 16:05:31 -05006589void
James Smart2e0fef82007-06-17 19:56:36 -05006590lpfc_free_sysfs_attr(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05006591{
James Smart2e0fef82007-06-17 19:56:36 -05006592 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smartea2151b2008-09-07 11:52:10 -04006593 sysfs_remove_bin_file(&shost->shost_dev.kobj,
6594 &sysfs_drvr_stat_data_attr);
James Smarteada2722008-12-04 22:39:13 -05006595 /* Virtual ports do not need ctrl_reg and mbox */
6596 if (vport->port_type == LPFC_NPIV_PORT)
6597 return;
Tony Jonesee959b02008-02-22 00:13:36 +01006598 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
6599 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
dea31012005-04-17 16:05:31 -05006600}
6601
dea31012005-04-17 16:05:31 -05006602/*
6603 * Dynamic FC Host Attributes Support
6604 */
6605
James Smarte59058c2008-08-24 21:49:00 -04006606/**
James Smart6c9231f2016-12-19 15:07:24 -08006607 * lpfc_get_host_symbolic_name - Copy symbolic name into the scsi host
6608 * @shost: kernel scsi host pointer.
6609 **/
6610static void
6611lpfc_get_host_symbolic_name(struct Scsi_Host *shost)
6612{
6613 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
6614
6615 lpfc_vport_symbolic_node_name(vport, fc_host_symbolic_name(shost),
6616 sizeof fc_host_symbolic_name(shost));
6617}
6618
6619/**
James Smart3621a712009-04-06 18:47:14 -04006620 * lpfc_get_host_port_id - Copy the vport DID into the scsi host port id
James Smarte59058c2008-08-24 21:49:00 -04006621 * @shost: kernel scsi host pointer.
6622 **/
dea31012005-04-17 16:05:31 -05006623static void
6624lpfc_get_host_port_id(struct Scsi_Host *shost)
6625{
James Smart2e0fef82007-06-17 19:56:36 -05006626 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6627
dea31012005-04-17 16:05:31 -05006628 /* note: fc_myDID already in cpu endianness */
James Smart2e0fef82007-06-17 19:56:36 -05006629 fc_host_port_id(shost) = vport->fc_myDID;
dea31012005-04-17 16:05:31 -05006630}
6631
James Smarte59058c2008-08-24 21:49:00 -04006632/**
James Smart3621a712009-04-06 18:47:14 -04006633 * lpfc_get_host_port_type - Set the value of the scsi host port type
James Smarte59058c2008-08-24 21:49:00 -04006634 * @shost: kernel scsi host pointer.
6635 **/
dea31012005-04-17 16:05:31 -05006636static void
6637lpfc_get_host_port_type(struct Scsi_Host *shost)
6638{
James Smart2e0fef82007-06-17 19:56:36 -05006639 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6640 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006641
6642 spin_lock_irq(shost->host_lock);
6643
James Smart92d7f7b2007-06-17 19:56:38 -05006644 if (vport->port_type == LPFC_NPIV_PORT) {
6645 fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
6646 } else if (lpfc_is_link_up(phba)) {
James Smart76a95d72010-11-20 23:11:48 -05006647 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smart2e0fef82007-06-17 19:56:36 -05006648 if (vport->fc_flag & FC_PUBLIC_LOOP)
dea31012005-04-17 16:05:31 -05006649 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
6650 else
6651 fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
6652 } else {
James Smart2e0fef82007-06-17 19:56:36 -05006653 if (vport->fc_flag & FC_FABRIC)
dea31012005-04-17 16:05:31 -05006654 fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
6655 else
6656 fc_host_port_type(shost) = FC_PORTTYPE_PTP;
6657 }
6658 } else
6659 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
6660
6661 spin_unlock_irq(shost->host_lock);
6662}
6663
James Smarte59058c2008-08-24 21:49:00 -04006664/**
James Smart3621a712009-04-06 18:47:14 -04006665 * lpfc_get_host_port_state - Set the value of the scsi host port state
James Smarte59058c2008-08-24 21:49:00 -04006666 * @shost: kernel scsi host pointer.
6667 **/
dea31012005-04-17 16:05:31 -05006668static void
6669lpfc_get_host_port_state(struct Scsi_Host *shost)
6670{
James Smart2e0fef82007-06-17 19:56:36 -05006671 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6672 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006673
6674 spin_lock_irq(shost->host_lock);
6675
James Smart2e0fef82007-06-17 19:56:36 -05006676 if (vport->fc_flag & FC_OFFLINE_MODE)
dea31012005-04-17 16:05:31 -05006677 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
6678 else {
James Smart2e0fef82007-06-17 19:56:36 -05006679 switch (phba->link_state) {
6680 case LPFC_LINK_UNKNOWN:
dea31012005-04-17 16:05:31 -05006681 case LPFC_LINK_DOWN:
6682 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
6683 break;
6684 case LPFC_LINK_UP:
dea31012005-04-17 16:05:31 -05006685 case LPFC_CLEAR_LA:
6686 case LPFC_HBA_READY:
James Smart026abb82011-12-13 13:20:45 -05006687 /* Links up, reports port state accordingly */
6688 if (vport->port_state < LPFC_VPORT_READY)
6689 fc_host_port_state(shost) =
6690 FC_PORTSTATE_BYPASSED;
6691 else
6692 fc_host_port_state(shost) =
6693 FC_PORTSTATE_ONLINE;
dea31012005-04-17 16:05:31 -05006694 break;
6695 case LPFC_HBA_ERROR:
6696 fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
6697 break;
6698 default:
6699 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
6700 break;
6701 }
6702 }
6703
6704 spin_unlock_irq(shost->host_lock);
6705}
6706
James Smarte59058c2008-08-24 21:49:00 -04006707/**
James Smart3621a712009-04-06 18:47:14 -04006708 * lpfc_get_host_speed - Set the value of the scsi host speed
James Smarte59058c2008-08-24 21:49:00 -04006709 * @shost: kernel scsi host pointer.
6710 **/
dea31012005-04-17 16:05:31 -05006711static void
6712lpfc_get_host_speed(struct Scsi_Host *shost)
6713{
James Smart2e0fef82007-06-17 19:56:36 -05006714 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6715 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006716
6717 spin_lock_irq(shost->host_lock);
6718
James Smarta085e872015-12-16 18:12:02 -05006719 if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) {
dea31012005-04-17 16:05:31 -05006720 switch(phba->fc_linkspeed) {
James Smart76a95d72010-11-20 23:11:48 -05006721 case LPFC_LINK_SPEED_1GHZ:
6722 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
dea31012005-04-17 16:05:31 -05006723 break;
James Smart76a95d72010-11-20 23:11:48 -05006724 case LPFC_LINK_SPEED_2GHZ:
6725 fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
dea31012005-04-17 16:05:31 -05006726 break;
James Smart76a95d72010-11-20 23:11:48 -05006727 case LPFC_LINK_SPEED_4GHZ:
6728 fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
dea31012005-04-17 16:05:31 -05006729 break;
James Smart76a95d72010-11-20 23:11:48 -05006730 case LPFC_LINK_SPEED_8GHZ:
6731 fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
James Smartb87eab32007-04-25 09:53:28 -04006732 break;
James Smart76a95d72010-11-20 23:11:48 -05006733 case LPFC_LINK_SPEED_10GHZ:
6734 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
James Smartf4b4c682009-05-22 14:53:12 -04006735 break;
James Smart76a95d72010-11-20 23:11:48 -05006736 case LPFC_LINK_SPEED_16GHZ:
6737 fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
6738 break;
James Smartd38dd522015-08-31 16:48:17 -04006739 case LPFC_LINK_SPEED_32GHZ:
6740 fc_host_speed(shost) = FC_PORTSPEED_32GBIT;
6741 break;
James Smartfbd8a6b2018-02-22 08:18:45 -08006742 case LPFC_LINK_SPEED_64GHZ:
6743 fc_host_speed(shost) = FC_PORTSPEED_64GBIT;
6744 break;
James Smart1dc5ec22018-10-23 13:41:11 -07006745 case LPFC_LINK_SPEED_128GHZ:
6746 fc_host_speed(shost) = FC_PORTSPEED_128GBIT;
6747 break;
James Smart76a95d72010-11-20 23:11:48 -05006748 default:
6749 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
dea31012005-04-17 16:05:31 -05006750 break;
6751 }
James Smartb615a202018-07-31 17:23:19 -07006752 } else if (lpfc_is_link_up(phba) && (phba->hba_flag & HBA_FCOE_MODE)) {
6753 switch (phba->fc_linkspeed) {
Dick Kennedya1e4d3d2020-08-03 14:02:22 -07006754 case LPFC_ASYNC_LINK_SPEED_1GBPS:
6755 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
6756 break;
James Smartb615a202018-07-31 17:23:19 -07006757 case LPFC_ASYNC_LINK_SPEED_10GBPS:
6758 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
6759 break;
Dick Kennedya1e4d3d2020-08-03 14:02:22 -07006760 case LPFC_ASYNC_LINK_SPEED_20GBPS:
6761 fc_host_speed(shost) = FC_PORTSPEED_20GBIT;
6762 break;
James Smartb615a202018-07-31 17:23:19 -07006763 case LPFC_ASYNC_LINK_SPEED_25GBPS:
6764 fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
6765 break;
6766 case LPFC_ASYNC_LINK_SPEED_40GBPS:
6767 fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
6768 break;
6769 case LPFC_ASYNC_LINK_SPEED_100GBPS:
6770 fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
6771 break;
6772 default:
6773 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
6774 break;
6775 }
James Smart09372822008-01-11 01:52:54 -05006776 } else
6777 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
dea31012005-04-17 16:05:31 -05006778
6779 spin_unlock_irq(shost->host_lock);
6780}
6781
James Smarte59058c2008-08-24 21:49:00 -04006782/**
James Smart3621a712009-04-06 18:47:14 -04006783 * lpfc_get_host_fabric_name - Set the value of the scsi host fabric name
James Smarte59058c2008-08-24 21:49:00 -04006784 * @shost: kernel scsi host pointer.
6785 **/
dea31012005-04-17 16:05:31 -05006786static void
6787lpfc_get_host_fabric_name (struct Scsi_Host *shost)
6788{
James Smart2e0fef82007-06-17 19:56:36 -05006789 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6790 struct lpfc_hba *phba = vport->phba;
Andrew Vasquezf631b4b2005-08-31 15:23:12 -07006791 u64 node_name;
dea31012005-04-17 16:05:31 -05006792
6793 spin_lock_irq(shost->host_lock);
6794
James Smart73d91e52011-10-10 21:32:10 -04006795 if ((vport->port_state > LPFC_FLOGI) &&
6796 ((vport->fc_flag & FC_FABRIC) ||
6797 ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
6798 (vport->fc_flag & FC_PUBLIC_LOOP))))
Andrew Morton68ce1eb2005-09-21 09:46:54 -07006799 node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
dea31012005-04-17 16:05:31 -05006800 else
6801 /* fabric is local port if there is no F/FL_Port */
James Smart09372822008-01-11 01:52:54 -05006802 node_name = 0;
dea31012005-04-17 16:05:31 -05006803
6804 spin_unlock_irq(shost->host_lock);
6805
Andrew Vasquezf631b4b2005-08-31 15:23:12 -07006806 fc_host_fabric_name(shost) = node_name;
dea31012005-04-17 16:05:31 -05006807}
6808
James Smarte59058c2008-08-24 21:49:00 -04006809/**
James Smart3621a712009-04-06 18:47:14 -04006810 * lpfc_get_stats - Return statistical information about the adapter
James Smarte59058c2008-08-24 21:49:00 -04006811 * @shost: kernel scsi host pointer.
6812 *
6813 * Notes:
6814 * NULL on error for link down, no mbox pool, sli2 active,
6815 * management not allowed, memory allocation error, or mbox error.
6816 *
6817 * Returns:
6818 * NULL for error
6819 * address of the adapter host statistics
6820 **/
dea31012005-04-17 16:05:31 -05006821static struct fc_host_statistics *
6822lpfc_get_stats(struct Scsi_Host *shost)
6823{
James Smart2e0fef82007-06-17 19:56:36 -05006824 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6825 struct lpfc_hba *phba = vport->phba;
6826 struct lpfc_sli *psli = &phba->sli;
James.Smart@Emulex.Comf888ba32005-08-10 15:03:01 -04006827 struct fc_host_statistics *hs = &phba->link_stats;
James Smart64ba8812006-08-02 15:24:34 -04006828 struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
dea31012005-04-17 16:05:31 -05006829 LPFC_MBOXQ_t *pmboxq;
6830 MAILBOX_t *pmb;
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006831 int rc = 0;
dea31012005-04-17 16:05:31 -05006832
James Smart92d7f7b2007-06-17 19:56:38 -05006833 /*
6834 * prevent udev from issuing mailbox commands until the port is
6835 * configured.
6836 */
James Smart2e0fef82007-06-17 19:56:36 -05006837 if (phba->link_state < LPFC_LINK_DOWN ||
6838 !phba->mbox_mem_pool ||
James Smartf4b4c682009-05-22 14:53:12 -04006839 (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
James Smart92d7f7b2007-06-17 19:56:38 -05006840 return NULL;
James Smart2e0fef82007-06-17 19:56:36 -05006841
6842 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
James Smart46fa3112007-04-25 09:51:45 -04006843 return NULL;
6844
dea31012005-04-17 16:05:31 -05006845 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
6846 if (!pmboxq)
6847 return NULL;
6848 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
6849
James Smart04c68492009-05-22 14:52:52 -04006850 pmb = &pmboxq->u.mb;
dea31012005-04-17 16:05:31 -05006851 pmb->mbxCommand = MBX_READ_STATUS;
6852 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006853 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006854 pmboxq->vport = vport;
dea31012005-04-17 16:05:31 -05006855
James Smart304ee432021-04-11 18:31:17 -07006856 if (vport->fc_flag & FC_OFFLINE_MODE) {
dea31012005-04-17 16:05:31 -05006857 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006858 if (rc != MBX_SUCCESS) {
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006859 mempool_free(pmboxq, phba->mbox_mem_pool);
James Smart304ee432021-04-11 18:31:17 -07006860 return NULL;
6861 }
6862 } else {
6863 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6864 if (rc != MBX_SUCCESS) {
6865 if (rc != MBX_TIMEOUT)
6866 mempool_free(pmboxq, phba->mbox_mem_pool);
6867 return NULL;
6868 }
dea31012005-04-17 16:05:31 -05006869 }
6870
James.Smart@Emulex.Comf888ba32005-08-10 15:03:01 -04006871 memset(hs, 0, sizeof (struct fc_host_statistics));
6872
dea31012005-04-17 16:05:31 -05006873 hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
James Smart73d91e52011-10-10 21:32:10 -04006874 /*
6875 * The MBX_READ_STATUS returns tx_k_bytes which has to
6876 * converted to words
6877 */
6878 hs->tx_words = (uint64_t)
6879 ((uint64_t)pmb->un.varRdStatus.xmitByteCnt
6880 * (uint64_t)256);
dea31012005-04-17 16:05:31 -05006881 hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
James Smart73d91e52011-10-10 21:32:10 -04006882 hs->rx_words = (uint64_t)
6883 ((uint64_t)pmb->un.varRdStatus.rcvByteCnt
6884 * (uint64_t)256);
dea31012005-04-17 16:05:31 -05006885
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006886 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
dea31012005-04-17 16:05:31 -05006887 pmb->mbxCommand = MBX_READ_LNK_STAT;
6888 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006889 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006890 pmboxq->vport = vport;
dea31012005-04-17 16:05:31 -05006891
James Smart304ee432021-04-11 18:31:17 -07006892 if (vport->fc_flag & FC_OFFLINE_MODE) {
dea31012005-04-17 16:05:31 -05006893 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006894 if (rc != MBX_SUCCESS) {
James Smart92d7f7b2007-06-17 19:56:38 -05006895 mempool_free(pmboxq, phba->mbox_mem_pool);
James Smart304ee432021-04-11 18:31:17 -07006896 return NULL;
6897 }
6898 } else {
6899 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6900 if (rc != MBX_SUCCESS) {
6901 if (rc != MBX_TIMEOUT)
6902 mempool_free(pmboxq, phba->mbox_mem_pool);
6903 return NULL;
6904 }
dea31012005-04-17 16:05:31 -05006905 }
6906
6907 hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
6908 hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
6909 hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
6910 hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
6911 hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
6912 hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
6913 hs->error_frames = pmb->un.varRdLnk.crcCnt;
6914
James Smart64ba8812006-08-02 15:24:34 -04006915 hs->link_failure_count -= lso->link_failure_count;
6916 hs->loss_of_sync_count -= lso->loss_of_sync_count;
6917 hs->loss_of_signal_count -= lso->loss_of_signal_count;
6918 hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count;
6919 hs->invalid_tx_word_count -= lso->invalid_tx_word_count;
6920 hs->invalid_crc_count -= lso->invalid_crc_count;
6921 hs->error_frames -= lso->error_frames;
6922
James Smart76a95d72010-11-20 23:11:48 -05006923 if (phba->hba_flag & HBA_FCOE_MODE) {
James Smart4d9ab992009-10-02 15:16:39 -04006924 hs->lip_count = -1;
6925 hs->nos_count = (phba->link_events >> 1);
6926 hs->nos_count -= lso->link_events;
James Smart76a95d72010-11-20 23:11:48 -05006927 } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
dea31012005-04-17 16:05:31 -05006928 hs->lip_count = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006929 hs->lip_count -= lso->link_events;
dea31012005-04-17 16:05:31 -05006930 hs->nos_count = -1;
6931 } else {
6932 hs->lip_count = -1;
6933 hs->nos_count = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006934 hs->nos_count -= lso->link_events;
dea31012005-04-17 16:05:31 -05006935 }
6936
6937 hs->dumped_frames = -1;
6938
Arnd Bergmannc4d6204d2018-06-18 17:28:23 +02006939 hs->seconds_since_last_reset = ktime_get_seconds() - psli->stats_start;
dea31012005-04-17 16:05:31 -05006940
James Smart1dcb58e2007-04-25 09:51:30 -04006941 mempool_free(pmboxq, phba->mbox_mem_pool);
6942
dea31012005-04-17 16:05:31 -05006943 return hs;
6944}
6945
James Smarte59058c2008-08-24 21:49:00 -04006946/**
James Smart3621a712009-04-06 18:47:14 -04006947 * lpfc_reset_stats - Copy the adapter link stats information
James Smarte59058c2008-08-24 21:49:00 -04006948 * @shost: kernel scsi host pointer.
6949 **/
James Smart64ba8812006-08-02 15:24:34 -04006950static void
6951lpfc_reset_stats(struct Scsi_Host *shost)
6952{
James Smart2e0fef82007-06-17 19:56:36 -05006953 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6954 struct lpfc_hba *phba = vport->phba;
6955 struct lpfc_sli *psli = &phba->sli;
6956 struct lpfc_lnk_stat *lso = &psli->lnk_stat_offsets;
James Smart64ba8812006-08-02 15:24:34 -04006957 LPFC_MBOXQ_t *pmboxq;
6958 MAILBOX_t *pmb;
6959 int rc = 0;
6960
James Smart2e0fef82007-06-17 19:56:36 -05006961 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
James Smart46fa3112007-04-25 09:51:45 -04006962 return;
6963
James Smart64ba8812006-08-02 15:24:34 -04006964 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
6965 if (!pmboxq)
6966 return;
6967 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
6968
James Smart04c68492009-05-22 14:52:52 -04006969 pmb = &pmboxq->u.mb;
James Smart64ba8812006-08-02 15:24:34 -04006970 pmb->mbxCommand = MBX_READ_STATUS;
6971 pmb->mbxOwner = OWN_HOST;
6972 pmb->un.varWords[0] = 0x1; /* reset request */
James Smart3e1f0712018-11-29 16:09:29 -08006973 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006974 pmboxq->vport = vport;
James Smart64ba8812006-08-02 15:24:34 -04006975
James Smart2e0fef82007-06-17 19:56:36 -05006976 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smart304ee432021-04-11 18:31:17 -07006977 (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
James Smart64ba8812006-08-02 15:24:34 -04006978 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07006979 if (rc != MBX_SUCCESS) {
James Smart64ba8812006-08-02 15:24:34 -04006980 mempool_free(pmboxq, phba->mbox_mem_pool);
James Smart304ee432021-04-11 18:31:17 -07006981 return;
6982 }
6983 } else {
6984 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6985 if (rc != MBX_SUCCESS) {
6986 if (rc != MBX_TIMEOUT)
6987 mempool_free(pmboxq, phba->mbox_mem_pool);
6988 return;
6989 }
James Smart64ba8812006-08-02 15:24:34 -04006990 }
6991
6992 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
6993 pmb->mbxCommand = MBX_READ_LNK_STAT;
6994 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006995 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006996 pmboxq->vport = vport;
James Smart64ba8812006-08-02 15:24:34 -04006997
James Smart2e0fef82007-06-17 19:56:36 -05006998 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smart304ee432021-04-11 18:31:17 -07006999 (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
James Smart64ba8812006-08-02 15:24:34 -04007000 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James Smart304ee432021-04-11 18:31:17 -07007001 if (rc != MBX_SUCCESS) {
7002 mempool_free(pmboxq, phba->mbox_mem_pool);
7003 return;
7004 }
7005 } else {
James Smart64ba8812006-08-02 15:24:34 -04007006 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
James Smart304ee432021-04-11 18:31:17 -07007007 if (rc != MBX_SUCCESS) {
7008 if (rc != MBX_TIMEOUT)
7009 mempool_free(pmboxq, phba->mbox_mem_pool);
7010 return;
7011 }
James Smart64ba8812006-08-02 15:24:34 -04007012 }
7013
7014 lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
7015 lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
7016 lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
7017 lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
7018 lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
7019 lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
7020 lso->error_frames = pmb->un.varRdLnk.crcCnt;
James Smart76a95d72010-11-20 23:11:48 -05007021 if (phba->hba_flag & HBA_FCOE_MODE)
James Smart4d9ab992009-10-02 15:16:39 -04007022 lso->link_events = (phba->link_events >> 1);
7023 else
7024 lso->link_events = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04007025
Arnd Bergmannc4d6204d2018-06-18 17:28:23 +02007026 psli->stats_start = ktime_get_seconds();
James Smart64ba8812006-08-02 15:24:34 -04007027
James Smart1dcb58e2007-04-25 09:51:30 -04007028 mempool_free(pmboxq, phba->mbox_mem_pool);
7029
James Smart64ba8812006-08-02 15:24:34 -04007030 return;
7031}
dea31012005-04-17 16:05:31 -05007032
7033/*
7034 * The LPFC driver treats linkdown handling as target loss events so there
7035 * are no sysfs handlers for link_down_tmo.
7036 */
James Smart685f0bf2007-04-25 09:53:08 -04007037
James Smarte59058c2008-08-24 21:49:00 -04007038/**
James Smart3621a712009-04-06 18:47:14 -04007039 * lpfc_get_node_by_target - Return the nodelist for a target
James Smarte59058c2008-08-24 21:49:00 -04007040 * @starget: kernel scsi target pointer.
7041 *
7042 * Returns:
7043 * address of the node list if found
7044 * NULL target not found
7045 **/
James Smart685f0bf2007-04-25 09:53:08 -04007046static struct lpfc_nodelist *
7047lpfc_get_node_by_target(struct scsi_target *starget)
dea31012005-04-17 16:05:31 -05007048{
James Smart2e0fef82007-06-17 19:56:36 -05007049 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
7050 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
James Smart685f0bf2007-04-25 09:53:08 -04007051 struct lpfc_nodelist *ndlp;
dea31012005-04-17 16:05:31 -05007052
7053 spin_lock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04007054 /* Search for this, mapped, target ID */
James Smart2e0fef82007-06-17 19:56:36 -05007055 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart307e3382020-11-15 11:26:30 -08007056 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
James Smart685f0bf2007-04-25 09:53:08 -04007057 starget->id == ndlp->nlp_sid) {
7058 spin_unlock_irq(shost->host_lock);
7059 return ndlp;
dea31012005-04-17 16:05:31 -05007060 }
7061 }
7062 spin_unlock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04007063 return NULL;
7064}
dea31012005-04-17 16:05:31 -05007065
James Smarte59058c2008-08-24 21:49:00 -04007066/**
James Smart3621a712009-04-06 18:47:14 -04007067 * lpfc_get_starget_port_id - Set the target port id to the ndlp DID or -1
James Smarte59058c2008-08-24 21:49:00 -04007068 * @starget: kernel scsi target pointer.
7069 **/
James Smart685f0bf2007-04-25 09:53:08 -04007070static void
7071lpfc_get_starget_port_id(struct scsi_target *starget)
7072{
7073 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
7074
7075 fc_starget_port_id(starget) = ndlp ? ndlp->nlp_DID : -1;
dea31012005-04-17 16:05:31 -05007076}
7077
James Smarte59058c2008-08-24 21:49:00 -04007078/**
James Smart3621a712009-04-06 18:47:14 -04007079 * lpfc_get_starget_node_name - Set the target node name
James Smarte59058c2008-08-24 21:49:00 -04007080 * @starget: kernel scsi target pointer.
7081 *
7082 * Description: Set the target node name to the ndlp node name wwn or zero.
7083 **/
dea31012005-04-17 16:05:31 -05007084static void
7085lpfc_get_starget_node_name(struct scsi_target *starget)
7086{
James Smart685f0bf2007-04-25 09:53:08 -04007087 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
dea31012005-04-17 16:05:31 -05007088
James Smart685f0bf2007-04-25 09:53:08 -04007089 fc_starget_node_name(starget) =
7090 ndlp ? wwn_to_u64(ndlp->nlp_nodename.u.wwn) : 0;
dea31012005-04-17 16:05:31 -05007091}
7092
James Smarte59058c2008-08-24 21:49:00 -04007093/**
James Smart3621a712009-04-06 18:47:14 -04007094 * lpfc_get_starget_port_name - Set the target port name
James Smarte59058c2008-08-24 21:49:00 -04007095 * @starget: kernel scsi target pointer.
7096 *
7097 * Description: set the target port name to the ndlp port name wwn or zero.
7098 **/
dea31012005-04-17 16:05:31 -05007099static void
7100lpfc_get_starget_port_name(struct scsi_target *starget)
7101{
James Smart685f0bf2007-04-25 09:53:08 -04007102 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
dea31012005-04-17 16:05:31 -05007103
James Smart685f0bf2007-04-25 09:53:08 -04007104 fc_starget_port_name(starget) =
7105 ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0;
dea31012005-04-17 16:05:31 -05007106}
7107
James Smarte59058c2008-08-24 21:49:00 -04007108/**
James Smart3621a712009-04-06 18:47:14 -04007109 * lpfc_set_rport_loss_tmo - Set the rport dev loss tmo
James Smarte59058c2008-08-24 21:49:00 -04007110 * @rport: fc rport address.
7111 * @timeout: new value for dev loss tmo.
7112 *
7113 * Description:
7114 * If timeout is non zero set the dev_loss_tmo to timeout, else set
7115 * dev_loss_tmo to one.
7116 **/
dea31012005-04-17 16:05:31 -05007117static void
dea31012005-04-17 16:05:31 -05007118lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
7119{
James Smarta643c6d2019-08-14 16:56:48 -07007120 struct lpfc_rport_data *rdata = rport->dd_data;
7121 struct lpfc_nodelist *ndlp = rdata->pnode;
7122#if (IS_ENABLED(CONFIG_NVME_FC))
7123 struct lpfc_nvme_rport *nrport = NULL;
7124#endif
7125
dea31012005-04-17 16:05:31 -05007126 if (timeout)
James Smartc01f3202006-08-18 17:47:08 -04007127 rport->dev_loss_tmo = timeout;
dea31012005-04-17 16:05:31 -05007128 else
James Smartc01f3202006-08-18 17:47:08 -04007129 rport->dev_loss_tmo = 1;
James Smarta643c6d2019-08-14 16:56:48 -07007130
James Smart307e3382020-11-15 11:26:30 -08007131 if (!ndlp) {
James Smarta643c6d2019-08-14 16:56:48 -07007132 dev_info(&rport->dev, "Cannot find remote node to "
7133 "set rport dev loss tmo, port_id x%x\n",
7134 rport->port_id);
7135 return;
7136 }
7137
7138#if (IS_ENABLED(CONFIG_NVME_FC))
7139 nrport = lpfc_ndlp_get_nrport(ndlp);
7140
7141 if (nrport && nrport->remoteport)
7142 nvme_fc_set_remoteport_devloss(nrport->remoteport,
7143 rport->dev_loss_tmo);
7144#endif
dea31012005-04-17 16:05:31 -05007145}
7146
Lee Jones9176ad22020-11-02 14:23:44 +00007147/*
James Smart3621a712009-04-06 18:47:14 -04007148 * lpfc_rport_show_function - Return rport target information
James Smarte59058c2008-08-24 21:49:00 -04007149 *
7150 * Description:
7151 * Macro that uses field to generate a function with the name lpfc_show_rport_
7152 *
7153 * lpfc_show_rport_##field: returns the bytes formatted in buf
7154 * @cdev: class converted to an fc_rport.
7155 * @buf: on return contains the target_field or zero.
7156 *
7157 * Returns: size of formatted string.
7158 **/
dea31012005-04-17 16:05:31 -05007159#define lpfc_rport_show_function(field, format_string, sz, cast) \
7160static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01007161lpfc_show_rport_##field (struct device *dev, \
7162 struct device_attribute *attr, \
7163 char *buf) \
dea31012005-04-17 16:05:31 -05007164{ \
Tony Jonesee959b02008-02-22 00:13:36 +01007165 struct fc_rport *rport = transport_class_to_rport(dev); \
dea31012005-04-17 16:05:31 -05007166 struct lpfc_rport_data *rdata = rport->hostdata; \
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07007167 return scnprintf(buf, sz, format_string, \
dea31012005-04-17 16:05:31 -05007168 (rdata->target) ? cast rdata->target->field : 0); \
7169}
7170
7171#define lpfc_rport_rd_attr(field, format_string, sz) \
7172 lpfc_rport_show_function(field, format_string, sz, ) \
7173static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
7174
James Smarteada2722008-12-04 22:39:13 -05007175/**
James Smart3621a712009-04-06 18:47:14 -04007176 * lpfc_set_vport_symbolic_name - Set the vport's symbolic name
James Smarteada2722008-12-04 22:39:13 -05007177 * @fc_vport: The fc_vport who's symbolic name has been changed.
7178 *
7179 * Description:
7180 * This function is called by the transport after the @fc_vport's symbolic name
7181 * has been changed. This function re-registers the symbolic name with the
Lucas De Marchi25985ed2011-03-30 22:57:33 -03007182 * switch to propagate the change into the fabric if the vport is active.
James Smarteada2722008-12-04 22:39:13 -05007183 **/
7184static void
7185lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport)
7186{
7187 struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
7188
7189 if (vport->port_state == LPFC_VPORT_READY)
7190 lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
7191}
dea31012005-04-17 16:05:31 -05007192
James Smartf4b4c682009-05-22 14:53:12 -04007193/**
7194 * lpfc_hba_log_verbose_init - Set hba's log verbose level
7195 * @phba: Pointer to lpfc_hba struct.
Lee Jonesa738bd92020-11-02 14:23:45 +00007196 * @verbose: Verbose level to set.
James Smartf4b4c682009-05-22 14:53:12 -04007197 *
7198 * This function is called by the lpfc_get_cfgparam() routine to set the
7199 * module lpfc_log_verbose into the @phba cfg_log_verbose for use with
Justin P. Mattock70f23fd2011-05-10 10:16:21 +02007200 * log message according to the module's lpfc_log_verbose parameter setting
James Smartf4b4c682009-05-22 14:53:12 -04007201 * before hba port or vport created.
7202 **/
7203static void
7204lpfc_hba_log_verbose_init(struct lpfc_hba *phba, uint32_t verbose)
7205{
7206 phba->cfg_log_verbose = verbose;
7207}
7208
dea31012005-04-17 16:05:31 -05007209struct fc_function_template lpfc_transport_functions = {
7210 /* fixed attributes the driver supports */
7211 .show_host_node_name = 1,
7212 .show_host_port_name = 1,
7213 .show_host_supported_classes = 1,
7214 .show_host_supported_fc4s = 1,
dea31012005-04-17 16:05:31 -05007215 .show_host_supported_speeds = 1,
7216 .show_host_maxframe_size = 1,
James Smart6c9231f2016-12-19 15:07:24 -08007217
7218 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
James Smarteada2722008-12-04 22:39:13 -05007219 .show_host_symbolic_name = 1,
dea31012005-04-17 16:05:31 -05007220
7221 /* dynamic attributes the driver supports */
7222 .get_host_port_id = lpfc_get_host_port_id,
7223 .show_host_port_id = 1,
7224
7225 .get_host_port_type = lpfc_get_host_port_type,
7226 .show_host_port_type = 1,
7227
7228 .get_host_port_state = lpfc_get_host_port_state,
7229 .show_host_port_state = 1,
7230
7231 /* active_fc4s is shown but doesn't change (thus no get function) */
7232 .show_host_active_fc4s = 1,
7233
7234 .get_host_speed = lpfc_get_host_speed,
7235 .show_host_speed = 1,
7236
7237 .get_host_fabric_name = lpfc_get_host_fabric_name,
7238 .show_host_fabric_name = 1,
7239
7240 /*
7241 * The LPFC driver treats linkdown handling as target loss events
7242 * so there are no sysfs handlers for link_down_tmo.
7243 */
7244
7245 .get_fc_host_stats = lpfc_get_stats,
James Smart64ba8812006-08-02 15:24:34 -04007246 .reset_fc_host_stats = lpfc_reset_stats,
dea31012005-04-17 16:05:31 -05007247
7248 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
7249 .show_rport_maxframe_size = 1,
7250 .show_rport_supported_classes = 1,
7251
dea31012005-04-17 16:05:31 -05007252 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
7253 .show_rport_dev_loss_tmo = 1,
7254
7255 .get_starget_port_id = lpfc_get_starget_port_id,
7256 .show_starget_port_id = 1,
7257
7258 .get_starget_node_name = lpfc_get_starget_node_name,
7259 .show_starget_node_name = 1,
7260
7261 .get_starget_port_name = lpfc_get_starget_port_name,
7262 .show_starget_port_name = 1,
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07007263
7264 .issue_fc_host_lip = lpfc_issue_lip,
James Smartc01f3202006-08-18 17:47:08 -04007265 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
7266 .terminate_rport_io = lpfc_terminate_rport_io,
James Smart92d7f7b2007-06-17 19:56:38 -05007267
James Smart92d7f7b2007-06-17 19:56:38 -05007268 .dd_fcvport_size = sizeof(struct lpfc_vport *),
James Smarteada2722008-12-04 22:39:13 -05007269
7270 .vport_disable = lpfc_vport_disable,
7271
7272 .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
James Smartf1c3b0f2009-07-19 10:01:32 -04007273
7274 .bsg_request = lpfc_bsg_request,
7275 .bsg_timeout = lpfc_bsg_timeout,
James Smart92d7f7b2007-06-17 19:56:38 -05007276};
7277
James Smart98c9ea52007-10-27 13:37:33 -04007278struct fc_function_template lpfc_vport_transport_functions = {
7279 /* fixed attributes the driver supports */
7280 .show_host_node_name = 1,
7281 .show_host_port_name = 1,
7282 .show_host_supported_classes = 1,
7283 .show_host_supported_fc4s = 1,
7284 .show_host_supported_speeds = 1,
7285 .show_host_maxframe_size = 1,
James Smart6c9231f2016-12-19 15:07:24 -08007286
7287 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
James Smarteada2722008-12-04 22:39:13 -05007288 .show_host_symbolic_name = 1,
James Smart98c9ea52007-10-27 13:37:33 -04007289
7290 /* dynamic attributes the driver supports */
7291 .get_host_port_id = lpfc_get_host_port_id,
7292 .show_host_port_id = 1,
7293
7294 .get_host_port_type = lpfc_get_host_port_type,
7295 .show_host_port_type = 1,
7296
7297 .get_host_port_state = lpfc_get_host_port_state,
7298 .show_host_port_state = 1,
7299
7300 /* active_fc4s is shown but doesn't change (thus no get function) */
7301 .show_host_active_fc4s = 1,
7302
7303 .get_host_speed = lpfc_get_host_speed,
7304 .show_host_speed = 1,
7305
7306 .get_host_fabric_name = lpfc_get_host_fabric_name,
7307 .show_host_fabric_name = 1,
7308
7309 /*
7310 * The LPFC driver treats linkdown handling as target loss events
7311 * so there are no sysfs handlers for link_down_tmo.
7312 */
7313
7314 .get_fc_host_stats = lpfc_get_stats,
7315 .reset_fc_host_stats = lpfc_reset_stats,
7316
7317 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
7318 .show_rport_maxframe_size = 1,
7319 .show_rport_supported_classes = 1,
7320
7321 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
7322 .show_rport_dev_loss_tmo = 1,
7323
7324 .get_starget_port_id = lpfc_get_starget_port_id,
7325 .show_starget_port_id = 1,
7326
7327 .get_starget_node_name = lpfc_get_starget_node_name,
7328 .show_starget_node_name = 1,
7329
7330 .get_starget_port_name = lpfc_get_starget_port_name,
7331 .show_starget_port_name = 1,
7332
7333 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
7334 .terminate_rport_io = lpfc_terminate_rport_io,
7335
7336 .vport_disable = lpfc_vport_disable,
James Smarteada2722008-12-04 22:39:13 -05007337
7338 .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
James Smart98c9ea52007-10-27 13:37:33 -04007339};
7340
James Smarte59058c2008-08-24 21:49:00 -04007341/**
James Smart4945c0f2019-08-14 16:57:02 -07007342 * lpfc_get_hba_function_mode - Used to determine the HBA function in FCoE
7343 * Mode
7344 * @phba: lpfc_hba pointer.
7345 **/
7346static void
7347lpfc_get_hba_function_mode(struct lpfc_hba *phba)
7348{
James Smart412e7372019-09-21 20:59:04 -07007349 /* If the adapter supports FCoE mode */
7350 switch (phba->pcidev->device) {
7351 case PCI_DEVICE_ID_SKYHAWK:
7352 case PCI_DEVICE_ID_SKYHAWK_VF:
7353 case PCI_DEVICE_ID_LANCER_FCOE:
7354 case PCI_DEVICE_ID_LANCER_FCOE_VF:
7355 case PCI_DEVICE_ID_ZEPHYR_DCSP:
7356 case PCI_DEVICE_ID_HORNET:
7357 case PCI_DEVICE_ID_TIGERSHARK:
7358 case PCI_DEVICE_ID_TOMCAT:
James Smart4945c0f2019-08-14 16:57:02 -07007359 phba->hba_flag |= HBA_FCOE_MODE;
James Smart412e7372019-09-21 20:59:04 -07007360 break;
7361 default:
7362 /* for others, clear the flag */
James Smart4945c0f2019-08-14 16:57:02 -07007363 phba->hba_flag &= ~HBA_FCOE_MODE;
James Smart412e7372019-09-21 20:59:04 -07007364 }
James Smart4945c0f2019-08-14 16:57:02 -07007365}
7366
7367/**
James Smart3621a712009-04-06 18:47:14 -04007368 * lpfc_get_cfgparam - Used during probe_one to init the adapter structure
James Smarte59058c2008-08-24 21:49:00 -04007369 * @phba: lpfc_hba pointer.
7370 **/
dea31012005-04-17 16:05:31 -05007371void
7372lpfc_get_cfgparam(struct lpfc_hba *phba)
7373{
James Smartdcaa2132019-11-04 16:57:06 -08007374 lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
James Smart49aa1432012-08-03 12:36:42 -04007375 lpfc_fcp_io_sched_init(phba, lpfc_fcp_io_sched);
James Smart7ea92eb2018-10-23 13:41:10 -07007376 lpfc_ns_query_init(phba, lpfc_ns_query);
James Smarta6571c62012-10-31 14:44:42 -04007377 lpfc_fcp2_no_tgt_reset_init(phba, lpfc_fcp2_no_tgt_reset);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007378 lpfc_cr_delay_init(phba, lpfc_cr_delay);
7379 lpfc_cr_count_init(phba, lpfc_cr_count);
Jamie Wellnitzcf5bf972006-02-28 22:33:08 -05007380 lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
James Smarta4bc3372006-12-02 13:34:16 -05007381 lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
7382 lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007383 lpfc_ack0_init(phba, lpfc_ack0);
James Smartc4908502019-01-28 11:14:28 -08007384 lpfc_xri_rebalancing_init(phba, lpfc_xri_rebalancing);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007385 lpfc_topology_init(phba, lpfc_topology);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007386 lpfc_link_speed_init(phba, lpfc_link_speed);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05007387 lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
James Smart0c411222013-09-06 12:22:46 -04007388 lpfc_task_mgmt_tmo_init(phba, lpfc_task_mgmt_tmo);
James Smart78b2d852007-08-02 11:10:21 -04007389 lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
James Smart7d791df2011-07-22 18:37:52 -04007390 lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy);
James Smart19ca7602010-11-20 23:11:55 -05007391 lpfc_enable_rrq_init(phba, lpfc_enable_rrq);
James Smart3e49af92021-05-14 12:55:57 -07007392 lpfc_fcp_wait_abts_rsp_init(phba, lpfc_fcp_wait_abts_rsp);
James Smart4258e982015-12-16 18:11:58 -05007393 lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
7394 lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
James Smart4ff43242006-12-02 13:34:56 -05007395 lpfc_use_msi_init(phba, lpfc_use_msi);
James Smart895427b2017-02-12 13:52:30 -08007396 lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
James Smart4e565cf2018-02-22 08:18:50 -08007397 lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
James Smartda0436e2009-05-22 14:51:39 -04007398 lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
James Smart41b194b2019-05-14 14:58:08 -07007399 lpfc_force_rscn_init(phba, lpfc_force_rscn);
James Smart32517fc2019-01-28 11:14:33 -08007400 lpfc_cq_poll_threshold_init(phba, lpfc_cq_poll_threshold);
7401 lpfc_cq_max_proc_limit_init(phba, lpfc_cq_max_proc_limit);
James Smart7bb03bb2013-04-17 20:19:16 -04007402 lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
James Smart13815c82008-01-11 01:52:48 -05007403 lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
7404 lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
James Smart2ea259e2017-02-12 13:52:27 -08007405
James Smart1ba981f2014-02-20 09:56:45 -05007406 lpfc_EnableXLane_init(phba, lpfc_EnableXLane);
Gaurav Srivastava7ba22722021-06-08 10:05:48 +05307407 /* VMID Inits */
7408 lpfc_max_vmid_init(phba, lpfc_max_vmid);
7409 lpfc_vmid_inactivity_timeout_init(phba, lpfc_vmid_inactivity_timeout);
7410 lpfc_vmid_app_header_init(phba, lpfc_vmid_app_header);
7411 lpfc_vmid_priority_tagging_init(phba, lpfc_vmid_priority_tagging);
James Smart1ba981f2014-02-20 09:56:45 -05007412 if (phba->sli_rev != LPFC_SLI_REV4)
7413 phba->cfg_EnableXLane = 0;
7414 lpfc_XLanePriority_init(phba, lpfc_XLanePriority);
James Smart2ea259e2017-02-12 13:52:27 -08007415
James Smart1ba981f2014-02-20 09:56:45 -05007416 memset(phba->cfg_oas_tgt_wwpn, 0, (8 * sizeof(uint8_t)));
7417 memset(phba->cfg_oas_vpt_wwpn, 0, (8 * sizeof(uint8_t)));
7418 phba->cfg_oas_lun_state = 0;
7419 phba->cfg_oas_lun_status = 0;
7420 phba->cfg_oas_flags = 0;
James Smartc92c8412016-07-06 12:36:05 -07007421 phba->cfg_oas_priority = 0;
James Smart81301a92008-12-04 22:39:46 -05007422 lpfc_enable_bg_init(phba, lpfc_enable_bg);
James Smartb3b98b72016-10-13 15:06:06 -07007423 lpfc_prot_mask_init(phba, lpfc_prot_mask);
7424 lpfc_prot_guard_init(phba, lpfc_prot_guard);
James Smart45ed1192009-10-02 15:17:02 -04007425 if (phba->sli_rev == LPFC_SLI_REV4)
7426 phba->cfg_poll = 0;
7427 else
James Smart1ba981f2014-02-20 09:56:45 -05007428 phba->cfg_poll = lpfc_poll;
James Smartf44ac122018-03-05 12:04:08 -08007429
James Smart4945c0f2019-08-14 16:57:02 -07007430 /* Get the function mode */
7431 lpfc_get_hba_function_mode(phba);
7432
7433 /* BlockGuard allowed for FC only. */
7434 if (phba->cfg_enable_bg && phba->hba_flag & HBA_FCOE_MODE) {
7435 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
7436 "0581 BlockGuard feature not supported\n");
7437 /* If set, clear the BlockGuard support param */
7438 phba->cfg_enable_bg = 0;
7439 } else if (phba->cfg_enable_bg) {
James Smartf44ac122018-03-05 12:04:08 -08007440 phba->sli3_options |= LPFC_SLI3_BG_ENABLED;
James Smart4945c0f2019-08-14 16:57:02 -07007441 }
James Smartf44ac122018-03-05 12:04:08 -08007442
James Smartf358dd02017-02-12 13:52:34 -08007443 lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp);
James Smart4258e982015-12-16 18:11:58 -05007444
James Smart895427b2017-02-12 13:52:30 -08007445 lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type);
James Smart2d7dbc42017-02-12 13:52:35 -08007446 lpfc_nvmet_mrq_init(phba, lpfc_nvmet_mrq);
James Smart2448e482018-04-09 14:24:24 -07007447 lpfc_nvmet_mrq_post_init(phba, lpfc_nvmet_mrq_post);
James Smart895427b2017-02-12 13:52:30 -08007448
7449 /* Initialize first burst. Target vs Initiator are different. */
7450 lpfc_nvme_enable_fb_init(phba, lpfc_nvme_enable_fb);
James Smart2d7dbc42017-02-12 13:52:35 -08007451 lpfc_nvmet_fb_size_init(phba, lpfc_nvmet_fb_size);
James Smart77ffd342019-08-15 19:36:49 -07007452 lpfc_fcp_mq_threshold_init(phba, lpfc_fcp_mq_threshold);
James Smartcdb42be2019-01-28 11:14:21 -08007453 lpfc_hdw_queue_init(phba, lpfc_hdw_queue);
James Smart6a828b02019-01-28 11:14:31 -08007454 lpfc_irq_chann_init(phba, lpfc_irq_chann);
James Smart44fd7fe2017-08-23 16:55:47 -07007455 lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
James Smart1351e692018-02-22 08:18:43 -08007456 lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
James Smart8aaa7bc2020-10-20 13:27:17 -07007457 lpfc_enable_mi_init(phba, lpfc_enable_mi);
James Smart895427b2017-02-12 13:52:30 -08007458
7459 if (phba->sli_rev != LPFC_SLI_REV4) {
7460 /* NVME only supported on SLI4 */
7461 phba->nvmet_support = 0;
James Smart982ab122019-03-12 16:30:10 -07007462 phba->cfg_nvmet_mrq = 0;
James Smart895427b2017-02-12 13:52:30 -08007463 phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
James Smart44fd7fe2017-08-23 16:55:47 -07007464 phba->cfg_enable_bbcr = 0;
James Smartc4908502019-01-28 11:14:28 -08007465 phba->cfg_xri_rebalancing = 0;
James Smart895427b2017-02-12 13:52:30 -08007466 } else {
7467 /* We MUST have FCP support */
7468 if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
7469 phba->cfg_enable_fc4_type |= LPFC_ENABLE_FCP;
7470 }
7471
James Smart32517fc2019-01-28 11:14:33 -08007472 phba->cfg_auto_imax = (phba->cfg_fcp_imax) ? 0 : 1;
James Smart0cf07f842017-06-01 21:07:10 -07007473
James Smart06b6fa382018-07-31 17:23:24 -07007474 phba->cfg_enable_pbde = 0;
7475
James Smart895427b2017-02-12 13:52:30 -08007476 /* A value of 0 means use the number of CPUs found in the system */
James Smartcdb42be2019-01-28 11:14:21 -08007477 if (phba->cfg_hdw_queue == 0)
7478 phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
James Smart6a828b02019-01-28 11:14:31 -08007479 if (phba->cfg_irq_chann == 0)
7480 phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
James Smartd3de0d12021-04-11 18:31:21 -07007481 if (phba->cfg_irq_chann > phba->cfg_hdw_queue &&
7482 phba->sli_rev == LPFC_SLI_REV4)
James Smart6a828b02019-01-28 11:14:31 -08007483 phba->cfg_irq_chann = phba->cfg_hdw_queue;
James Smart4258e982015-12-16 18:11:58 -05007484
James Smart352e5fd2016-12-30 06:57:47 -08007485 phba->cfg_soft_wwnn = 0L;
7486 phba->cfg_soft_wwpn = 0L;
James Smart83108bd2008-01-11 01:53:09 -05007487 lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
James Smart7054a602007-04-25 09:52:34 -04007488 lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
James Smart0d878412009-10-02 15:16:56 -04007489 lpfc_aer_support_init(phba, lpfc_aer_support);
James Smart912e3ac2011-05-24 11:42:11 -04007490 lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn);
James Smartc71ab862012-10-31 14:44:33 -04007491 lpfc_request_firmware_upgrade_init(phba, lpfc_req_fw_upgrade);
James Smart84d1b002010-02-12 14:42:33 -05007492 lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up);
James Smart8eb8b962016-07-06 12:36:08 -07007493 lpfc_delay_discovery_init(phba, lpfc_delay_discovery);
James Smart12247e82016-07-06 12:36:09 -07007494 lpfc_sli_mode_init(phba, lpfc_sli_mode);
James Smart7bdedb32016-07-06 12:36:00 -07007495 lpfc_enable_mds_diags_init(phba, lpfc_enable_mds_diags);
James Smartd2cc9bc2018-09-10 10:30:50 -07007496 lpfc_ras_fwlog_buffsize_init(phba, lpfc_ras_fwlog_buffsize);
7497 lpfc_ras_fwlog_level_init(phba, lpfc_ras_fwlog_level);
7498 lpfc_ras_fwlog_func_init(phba, lpfc_ras_fwlog_func);
7499
James Smart3de2a652007-08-02 11:09:59 -04007500 return;
7501}
Jamie Wellnitzb28485a2006-02-28 19:25:21 -05007502
James Smarte59058c2008-08-24 21:49:00 -04007503/**
James Smart895427b2017-02-12 13:52:30 -08007504 * lpfc_nvme_mod_param_dep - Adjust module parameter value based on
7505 * dependencies between protocols and roles.
7506 * @phba: lpfc_hba pointer.
7507 **/
7508void
7509lpfc_nvme_mod_param_dep(struct lpfc_hba *phba)
7510{
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007511 int logit = 0;
7512
7513 if (phba->cfg_hdw_queue > phba->sli4_hba.num_present_cpu) {
James Smartcdb42be2019-01-28 11:14:21 -08007514 phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007515 logit = 1;
7516 }
7517 if (phba->cfg_irq_chann > phba->sli4_hba.num_present_cpu) {
James Smart6a828b02019-01-28 11:14:31 -08007518 phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007519 logit = 1;
7520 }
7521 if (phba->cfg_irq_chann > phba->cfg_hdw_queue) {
James Smart6a828b02019-01-28 11:14:31 -08007522 phba->cfg_irq_chann = phba->cfg_hdw_queue;
Dick Kennedy9e3e3652020-08-03 14:02:23 -07007523 logit = 1;
7524 }
7525 if (logit)
7526 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
7527 "2006 Reducing Queues - CPU limitation: "
7528 "IRQ %d HDWQ %d\n",
7529 phba->cfg_irq_chann,
7530 phba->cfg_hdw_queue);
James Smart895427b2017-02-12 13:52:30 -08007531
James Smartf358dd02017-02-12 13:52:34 -08007532 if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME &&
7533 phba->nvmet_support) {
7534 phba->cfg_enable_fc4_type &= ~LPFC_ENABLE_FCP;
James Smart2d7dbc42017-02-12 13:52:35 -08007535
7536 lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
7537 "6013 %s x%x fb_size x%x, fb_max x%x\n",
7538 "NVME Target PRLI ACC enable_fb ",
7539 phba->cfg_nvme_enable_fb,
7540 phba->cfg_nvmet_fb_size,
7541 LPFC_NVMET_FB_SZ_MAX);
7542
7543 if (phba->cfg_nvme_enable_fb == 0)
7544 phba->cfg_nvmet_fb_size = 0;
7545 else {
7546 if (phba->cfg_nvmet_fb_size > LPFC_NVMET_FB_SZ_MAX)
7547 phba->cfg_nvmet_fb_size = LPFC_NVMET_FB_SZ_MAX;
7548 }
7549
James Smartbcb24f62017-11-20 16:00:36 -08007550 if (!phba->cfg_nvmet_mrq)
James Smart97a9ed32019-10-18 14:18:17 -07007551 phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
James Smartbcb24f62017-11-20 16:00:36 -08007552
James Smart2d7dbc42017-02-12 13:52:35 -08007553 /* Adjust lpfc_nvmet_mrq to avoid running out of WQE slots */
James Smart97a9ed32019-10-18 14:18:17 -07007554 if (phba->cfg_nvmet_mrq > phba->cfg_hdw_queue) {
7555 phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
James Smart2d7dbc42017-02-12 13:52:35 -08007556 lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC,
7557 "6018 Adjust lpfc_nvmet_mrq to %d\n",
7558 phba->cfg_nvmet_mrq);
7559 }
James Smartbcb24f62017-11-20 16:00:36 -08007560 if (phba->cfg_nvmet_mrq > LPFC_NVMET_MRQ_MAX)
7561 phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_MAX;
7562
James Smart2d7dbc42017-02-12 13:52:35 -08007563 } else {
James Smartf358dd02017-02-12 13:52:34 -08007564 /* Not NVME Target mode. Turn off Target parameters. */
7565 phba->nvmet_support = 0;
James Smart982ab122019-03-12 16:30:10 -07007566 phba->cfg_nvmet_mrq = 0;
James Smart2d7dbc42017-02-12 13:52:35 -08007567 phba->cfg_nvmet_fb_size = 0;
7568 }
James Smart895427b2017-02-12 13:52:30 -08007569}
7570
7571/**
James Smart3621a712009-04-06 18:47:14 -04007572 * lpfc_get_vport_cfgparam - Used during port create, init the vport structure
James Smarte59058c2008-08-24 21:49:00 -04007573 * @vport: lpfc_vport pointer.
7574 **/
James Smart3de2a652007-08-02 11:09:59 -04007575void
7576lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
7577{
James Smarte8b62012007-08-02 11:10:09 -04007578 lpfc_log_verbose_init(vport, lpfc_log_verbose);
James Smart3de2a652007-08-02 11:09:59 -04007579 lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth);
James Smart7dc517d2010-07-14 15:32:10 -04007580 lpfc_tgt_queue_depth_init(vport, lpfc_tgt_queue_depth);
James Smart3de2a652007-08-02 11:09:59 -04007581 lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo);
7582 lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo);
7583 lpfc_peer_port_login_init(vport, lpfc_peer_port_login);
7584 lpfc_restrict_login_init(vport, lpfc_restrict_login);
7585 lpfc_fcp_class_init(vport, lpfc_fcp_class);
7586 lpfc_use_adisc_init(vport, lpfc_use_adisc);
James Smart3cb01c52013-07-15 18:35:04 -04007587 lpfc_first_burst_size_init(vport, lpfc_first_burst_size);
James Smart977b5a02008-09-07 11:52:04 -04007588 lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time);
James Smart3de2a652007-08-02 11:09:59 -04007589 lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
7590 lpfc_max_luns_init(vport, lpfc_max_luns);
7591 lpfc_scan_down_init(vport, lpfc_scan_down);
James Smart7ee5d432007-10-27 13:37:17 -04007592 lpfc_enable_da_id_init(vport, lpfc_enable_da_id);
dea31012005-04-17 16:05:31 -05007593 return;
7594}