blob: 0a8caa12a30d7a96b5099db116caa62d8905f14b [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 Smart0d041212019-01-28 11:14:41 -08004 * Copyright (C) 2017-2019 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 Smart895427b2017-02-12 13:52:30 -080040#include <linux/nvme-fc-driver.h>
41
James Smartda0436e2009-05-22 14:51:39 -040042#include "lpfc_hw4.h"
dea31012005-04-17 16:05:31 -050043#include "lpfc_hw.h"
44#include "lpfc_sli.h"
James Smartda0436e2009-05-22 14:51:39 -040045#include "lpfc_sli4.h"
James Smartea2151b2008-09-07 11:52:10 -040046#include "lpfc_nl.h"
dea31012005-04-17 16:05:31 -050047#include "lpfc_disc.h"
dea31012005-04-17 16:05:31 -050048#include "lpfc.h"
James Smart895427b2017-02-12 13:52:30 -080049#include "lpfc_scsi.h"
50#include "lpfc_nvme.h"
James Smartf358dd02017-02-12 13:52:34 -080051#include "lpfc_nvmet.h"
dea31012005-04-17 16:05:31 -050052#include "lpfc_logmsg.h"
53#include "lpfc_version.h"
54#include "lpfc_compat.h"
55#include "lpfc_crtn.h"
James Smart92d7f7b2007-06-17 19:56:38 -050056#include "lpfc_vport.h"
James Smart93dd1912016-07-06 12:36:10 -070057#include "lpfc_attr.h"
dea31012005-04-17 16:05:31 -050058
James Smart2ea259e2017-02-12 13:52:27 -080059#define LPFC_DEF_DEVLOSS_TMO 30
60#define LPFC_MIN_DEVLOSS_TMO 1
61#define LPFC_MAX_DEVLOSS_TMO 255
dea31012005-04-17 16:05:31 -050062
James Smart61f3d4b2017-05-15 15:20:41 -070063#define LPFC_DEF_MRQ_POST 512
64#define LPFC_MIN_MRQ_POST 512
65#define LPFC_MAX_MRQ_POST 2048
dea31012005-04-17 16:05:31 -050066
James Smartf7a919b2011-08-21 21:49:16 -040067/*
68 * Write key size should be multiple of 4. If write key is changed
69 * make sure that library write key is also changed.
70 */
71#define LPFC_REG_WRITE_KEY_SIZE 4
72#define LPFC_REG_WRITE_KEY "EMLX"
73
Bart Van Asschea73cb812019-03-28 11:06:19 -070074const char *const trunk_errmsg[] = { /* map errcode */
75 "", /* There is no such error code at index 0*/
76 "link negotiated speed does not match existing"
77 " trunk - link was \"low\" speed",
78 "link negotiated speed does not match"
79 " existing trunk - link was \"middle\" speed",
80 "link negotiated speed does not match existing"
81 " trunk - link was \"high\" speed",
82 "Attached to non-trunking port - F_Port",
83 "Attached to non-trunking port - N_Port",
84 "FLOGI response timeout",
85 "non-FLOGI frame received",
86 "Invalid FLOGI response",
87 "Trunking initialization protocol",
88 "Trunk peer device mismatch",
89};
90
James Smarte59058c2008-08-24 21:49:00 -040091/**
James Smart3621a712009-04-06 18:47:14 -040092 * lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules
James Smarte59058c2008-08-24 21:49:00 -040093 * @incr: integer to convert.
94 * @hdw: ascii string holding converted integer plus a string terminator.
95 *
96 * Description:
97 * JEDEC Joint Electron Device Engineering Council.
98 * Convert a 32 bit integer composed of 8 nibbles into an 8 byte ascii
99 * character string. The string is then terminated with a NULL in byte 9.
100 * Hex 0-9 becomes ascii '0' to '9'.
101 * Hex a-f becomes ascii '=' to 'B' capital B.
102 *
103 * Notes:
104 * Coded for 32 bit integers only.
105 **/
dea31012005-04-17 16:05:31 -0500106static void
107lpfc_jedec_to_ascii(int incr, char hdw[])
108{
109 int i, j;
110 for (i = 0; i < 8; i++) {
111 j = (incr & 0xf);
112 if (j <= 9)
113 hdw[7 - i] = 0x30 + j;
114 else
115 hdw[7 - i] = 0x61 + j - 10;
116 incr = (incr >> 4);
117 }
118 hdw[8] = 0;
119 return;
120}
121
James Smarte59058c2008-08-24 21:49:00 -0400122/**
James Smart3621a712009-04-06 18:47:14 -0400123 * lpfc_drvr_version_show - Return the Emulex driver string with version number
James Smarte59058c2008-08-24 21:49:00 -0400124 * @dev: class unused variable.
125 * @attr: device attribute, not used.
126 * @buf: on return contains the module description text.
127 *
128 * Returns: size of formatted string.
129 **/
dea31012005-04-17 16:05:31 -0500130static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100131lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr,
132 char *buf)
dea31012005-04-17 16:05:31 -0500133{
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700134 return scnprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n");
dea31012005-04-17 16:05:31 -0500135}
136
James Smart45ed1192009-10-02 15:17:02 -0400137/**
138 * lpfc_enable_fip_show - Return the fip mode of the HBA
139 * @dev: class unused variable.
140 * @attr: device attribute, not used.
141 * @buf: on return contains the module description text.
142 *
143 * Returns: size of formatted string.
144 **/
145static ssize_t
146lpfc_enable_fip_show(struct device *dev, struct device_attribute *attr,
147 char *buf)
148{
149 struct Scsi_Host *shost = class_to_shost(dev);
150 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
151 struct lpfc_hba *phba = vport->phba;
152
153 if (phba->hba_flag & HBA_FIP_SUPPORT)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700154 return scnprintf(buf, PAGE_SIZE, "1\n");
James Smart45ed1192009-10-02 15:17:02 -0400155 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700156 return scnprintf(buf, PAGE_SIZE, "0\n");
James Smart45ed1192009-10-02 15:17:02 -0400157}
158
James Smart81301a92008-12-04 22:39:46 -0500159static ssize_t
James Smart895427b2017-02-12 13:52:30 -0800160lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
161 char *buf)
162{
163 struct Scsi_Host *shost = class_to_shost(dev);
164 struct lpfc_vport *vport = shost_priv(shost);
165 struct lpfc_hba *phba = vport->phba;
James Smartf358dd02017-02-12 13:52:34 -0800166 struct lpfc_nvmet_tgtport *tgtp;
James Smart895427b2017-02-12 13:52:30 -0800167 struct nvme_fc_local_port *localport;
James Smart4b056682017-12-08 17:18:10 -0800168 struct lpfc_nvme_lport *lport;
James Smart01466022018-04-09 14:24:27 -0700169 struct lpfc_nvme_rport *rport;
James Smart80cc0042017-06-01 21:06:56 -0700170 struct lpfc_nodelist *ndlp;
James Smart895427b2017-02-12 13:52:30 -0800171 struct nvme_fc_remote_port *nrport;
James Smart4c47efc2019-01-28 11:14:25 -0800172 struct lpfc_fc4_ctrl_stat *cstat;
James Smart66a210f2018-04-09 14:24:23 -0700173 uint64_t data1, data2, data3;
174 uint64_t totin, totout, tot;
James Smart895427b2017-02-12 13:52:30 -0800175 char *statep;
James Smart66a210f2018-04-09 14:24:23 -0700176 int i;
James Smart895427b2017-02-12 13:52:30 -0800177 int len = 0;
James Smartafff0d22018-06-26 08:24:22 -0700178 char tmp[LPFC_MAX_NVME_INFO_TMP_LEN] = {0};
James Smarte2a8be52019-05-06 17:26:47 -0700179 unsigned long iflags = 0;
James Smart895427b2017-02-12 13:52:30 -0800180
James Smartf6e84792019-01-28 11:14:38 -0800181 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) {
James Smartafff0d22018-06-26 08:24:22 -0700182 len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n");
James Smart895427b2017-02-12 13:52:30 -0800183 return len;
184 }
James Smartf358dd02017-02-12 13:52:34 -0800185 if (phba->nvmet_support) {
186 if (!phba->targetport) {
James Smartafff0d22018-06-26 08:24:22 -0700187 len = scnprintf(buf, PAGE_SIZE,
James Smartf358dd02017-02-12 13:52:34 -0800188 "NVME Target: x%llx is not allocated\n",
189 wwn_to_u64(vport->fc_portname.u.wwn));
190 return len;
191 }
192 /* Port state is only one of two values for now. */
193 if (phba->targetport->port_id)
194 statep = "REGISTERED";
195 else
196 statep = "INIT";
James Smartafff0d22018-06-26 08:24:22 -0700197 scnprintf(tmp, sizeof(tmp),
198 "NVME Target Enabled State %s\n",
199 statep);
200 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
201 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800202
James Smartafff0d22018-06-26 08:24:22 -0700203 scnprintf(tmp, sizeof(tmp),
204 "%s%d WWPN x%llx WWNN x%llx DID x%06x\n",
205 "NVME Target: lpfc",
206 phba->brd_no,
207 wwn_to_u64(vport->fc_portname.u.wwn),
208 wwn_to_u64(vport->fc_nodename.u.wwn),
209 phba->targetport->port_id);
210 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
211 goto buffer_done;
212
213 if (strlcat(buf, "\nNVME Target: Statistics\n", PAGE_SIZE)
214 >= PAGE_SIZE)
215 goto buffer_done;
216
James Smartf358dd02017-02-12 13:52:34 -0800217 tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
James Smartafff0d22018-06-26 08:24:22 -0700218 scnprintf(tmp, sizeof(tmp),
219 "LS: Rcv %08x Drop %08x Abort %08x\n",
220 atomic_read(&tgtp->rcv_ls_req_in),
221 atomic_read(&tgtp->rcv_ls_req_drop),
222 atomic_read(&tgtp->xmt_ls_abort));
223 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
224 goto buffer_done;
225
James Smartf358dd02017-02-12 13:52:34 -0800226 if (atomic_read(&tgtp->rcv_ls_req_in) !=
227 atomic_read(&tgtp->rcv_ls_req_out)) {
James Smartafff0d22018-06-26 08:24:22 -0700228 scnprintf(tmp, sizeof(tmp),
229 "Rcv LS: in %08x != out %08x\n",
230 atomic_read(&tgtp->rcv_ls_req_in),
231 atomic_read(&tgtp->rcv_ls_req_out));
232 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
233 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800234 }
235
James Smartafff0d22018-06-26 08:24:22 -0700236 scnprintf(tmp, sizeof(tmp),
237 "LS: Xmt %08x Drop %08x Cmpl %08x\n",
238 atomic_read(&tgtp->xmt_ls_rsp),
239 atomic_read(&tgtp->xmt_ls_drop),
240 atomic_read(&tgtp->xmt_ls_rsp_cmpl));
241 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
242 goto buffer_done;
James Smart4b056682017-12-08 17:18:10 -0800243
James Smartafff0d22018-06-26 08:24:22 -0700244 scnprintf(tmp, sizeof(tmp),
245 "LS: RSP Abort %08x xb %08x Err %08x\n",
246 atomic_read(&tgtp->xmt_ls_rsp_aborted),
247 atomic_read(&tgtp->xmt_ls_rsp_xb_set),
248 atomic_read(&tgtp->xmt_ls_rsp_error));
249 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
250 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800251
James Smartafff0d22018-06-26 08:24:22 -0700252 scnprintf(tmp, sizeof(tmp),
253 "FCP: Rcv %08x Defer %08x Release %08x "
254 "Drop %08x\n",
255 atomic_read(&tgtp->rcv_fcp_cmd_in),
256 atomic_read(&tgtp->rcv_fcp_cmd_defer),
257 atomic_read(&tgtp->xmt_fcp_release),
258 atomic_read(&tgtp->rcv_fcp_cmd_drop));
259 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
260 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800261
262 if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
263 atomic_read(&tgtp->rcv_fcp_cmd_out)) {
James Smartafff0d22018-06-26 08:24:22 -0700264 scnprintf(tmp, sizeof(tmp),
265 "Rcv FCP: in %08x != out %08x\n",
266 atomic_read(&tgtp->rcv_fcp_cmd_in),
267 atomic_read(&tgtp->rcv_fcp_cmd_out));
268 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
269 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800270 }
271
James Smartafff0d22018-06-26 08:24:22 -0700272 scnprintf(tmp, sizeof(tmp),
273 "FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x "
274 "drop %08x\n",
275 atomic_read(&tgtp->xmt_fcp_read),
276 atomic_read(&tgtp->xmt_fcp_read_rsp),
277 atomic_read(&tgtp->xmt_fcp_write),
278 atomic_read(&tgtp->xmt_fcp_rsp),
279 atomic_read(&tgtp->xmt_fcp_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 Cmpl: %08x err %08x drop %08x\n",
285 atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
286 atomic_read(&tgtp->xmt_fcp_rsp_error),
287 atomic_read(&tgtp->xmt_fcp_rsp_drop));
288 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
289 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800290
James Smartafff0d22018-06-26 08:24:22 -0700291 scnprintf(tmp, sizeof(tmp),
292 "FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
293 atomic_read(&tgtp->xmt_fcp_rsp_aborted),
294 atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
295 atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
296 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
297 goto buffer_done;
James Smart4b056682017-12-08 17:18:10 -0800298
James Smartafff0d22018-06-26 08:24:22 -0700299 scnprintf(tmp, sizeof(tmp),
300 "ABORT: Xmt %08x Cmpl %08x\n",
301 atomic_read(&tgtp->xmt_fcp_abort),
302 atomic_read(&tgtp->xmt_fcp_abort_cmpl));
303 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
304 goto buffer_done;
James Smart547077a2017-05-15 15:20:40 -0700305
James Smartafff0d22018-06-26 08:24:22 -0700306 scnprintf(tmp, sizeof(tmp),
307 "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x\n",
308 atomic_read(&tgtp->xmt_abort_sol),
309 atomic_read(&tgtp->xmt_abort_unsol),
310 atomic_read(&tgtp->xmt_abort_rsp),
311 atomic_read(&tgtp->xmt_abort_rsp_error));
312 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
313 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800314
James Smartafff0d22018-06-26 08:24:22 -0700315 scnprintf(tmp, sizeof(tmp),
316 "DELAY: ctx %08x fod %08x wqfull %08x\n",
317 atomic_read(&tgtp->defer_ctx),
318 atomic_read(&tgtp->defer_fod),
319 atomic_read(&tgtp->defer_wqfull));
320 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
321 goto buffer_done;
James Smart411de512018-01-30 15:58:52 -0800322
Dick Kennedy66d7ce92017-08-23 16:55:42 -0700323 /* Calculate outstanding IOs */
324 tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
325 tot += atomic_read(&tgtp->xmt_fcp_release);
326 tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
James Smart2cee7802017-06-01 21:07:02 -0700327
James Smartafff0d22018-06-26 08:24:22 -0700328 scnprintf(tmp, sizeof(tmp),
329 "IO_CTX: %08x WAIT: cur %08x tot %08x\n"
330 "CTX Outstanding %08llx\n\n",
331 phba->sli4_hba.nvmet_xri_cnt,
332 phba->sli4_hba.nvmet_io_wait_cnt,
333 phba->sli4_hba.nvmet_io_wait_total,
334 tot);
335 strlcat(buf, tmp, PAGE_SIZE);
336 goto buffer_done;
James Smartf358dd02017-02-12 13:52:34 -0800337 }
James Smart895427b2017-02-12 13:52:30 -0800338
339 localport = vport->localport;
340 if (!localport) {
James Smartafff0d22018-06-26 08:24:22 -0700341 len = scnprintf(buf, PAGE_SIZE,
James Smart895427b2017-02-12 13:52:30 -0800342 "NVME Initiator x%llx is not allocated\n",
343 wwn_to_u64(vport->fc_portname.u.wwn));
344 return len;
345 }
Colin Ian King5c665ae2017-12-22 00:28:52 +0000346 lport = (struct lpfc_nvme_lport *)localport->private;
James Smartafff0d22018-06-26 08:24:22 -0700347 if (strlcat(buf, "\nNVME Initiator Enabled\n", PAGE_SIZE) >= PAGE_SIZE)
348 goto buffer_done;
James Smart895427b2017-02-12 13:52:30 -0800349
James Smartafff0d22018-06-26 08:24:22 -0700350 rcu_read_lock();
351 scnprintf(tmp, sizeof(tmp),
James Smart0794d602019-01-28 11:14:19 -0800352 "XRI Dist lpfc%d Total %d IO %d ELS %d\n",
James Smartafff0d22018-06-26 08:24:22 -0700353 phba->brd_no,
354 phba->sli4_hba.max_cfg_param.max_xri,
James Smart5e5b5112019-01-28 11:14:22 -0800355 phba->sli4_hba.io_xri_max,
James Smartafff0d22018-06-26 08:24:22 -0700356 lpfc_sli4_get_els_iocb_cnt(phba));
357 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700358 goto rcu_unlock_buf_done;
James Smart895427b2017-02-12 13:52:30 -0800359
360 /* Port state is only one of two values for now. */
361 if (localport->port_id)
362 statep = "ONLINE";
363 else
364 statep = "UNKNOWN ";
365
James Smartafff0d22018-06-26 08:24:22 -0700366 scnprintf(tmp, sizeof(tmp),
367 "%s%d WWPN x%llx WWNN x%llx DID x%06x %s\n",
368 "NVME LPORT lpfc",
369 phba->brd_no,
370 wwn_to_u64(vport->fc_portname.u.wwn),
371 wwn_to_u64(vport->fc_nodename.u.wwn),
372 localport->port_id, statep);
373 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700374 goto rcu_unlock_buf_done;
James Smart895427b2017-02-12 13:52:30 -0800375
James Smart80cc0042017-06-01 21:06:56 -0700376 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart9e210172018-09-13 15:41:10 -0700377 nrport = NULL;
James Smarte2a8be52019-05-06 17:26:47 -0700378 spin_lock_irqsave(&vport->phba->hbalock, iflags);
James Smart01466022018-04-09 14:24:27 -0700379 rport = lpfc_ndlp_get_nrport(ndlp);
James Smart9e210172018-09-13 15:41:10 -0700380 if (rport)
381 nrport = rport->remoteport;
James Smarte2a8be52019-05-06 17:26:47 -0700382 spin_unlock_irqrestore(&vport->phba->hbalock, iflags);
James Smart01466022018-04-09 14:24:27 -0700383 if (!nrport)
384 continue;
James Smart895427b2017-02-12 13:52:30 -0800385
386 /* Port state is only one of two values for now. */
387 switch (nrport->port_state) {
388 case FC_OBJSTATE_ONLINE:
389 statep = "ONLINE";
390 break;
391 case FC_OBJSTATE_UNKNOWN:
392 statep = "UNKNOWN ";
393 break;
394 default:
395 statep = "UNSUPPORTED";
396 break;
397 }
398
399 /* Tab in to show lport ownership. */
James Smartafff0d22018-06-26 08:24:22 -0700400 if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700401 goto rcu_unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700402 if (phba->brd_no >= 10) {
403 if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700404 goto rcu_unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700405 }
James Smart895427b2017-02-12 13:52:30 -0800406
James Smartafff0d22018-06-26 08:24:22 -0700407 scnprintf(tmp, sizeof(tmp), "WWPN x%llx ",
408 nrport->port_name);
409 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700410 goto rcu_unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700411
412 scnprintf(tmp, sizeof(tmp), "WWNN x%llx ",
413 nrport->node_name);
414 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700415 goto rcu_unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700416
417 scnprintf(tmp, sizeof(tmp), "DID x%06x ",
418 nrport->port_id);
419 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700420 goto rcu_unlock_buf_done;
James Smart895427b2017-02-12 13:52:30 -0800421
James Smart7d790f02017-06-01 21:06:57 -0700422 /* An NVME rport can have multiple roles. */
James Smartafff0d22018-06-26 08:24:22 -0700423 if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) {
424 if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700425 goto rcu_unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700426 }
427 if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) {
428 if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700429 goto rcu_unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700430 }
431 if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) {
432 if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700433 goto rcu_unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700434 }
James Smart7d790f02017-06-01 21:06:57 -0700435 if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
436 FC_PORT_ROLE_NVME_TARGET |
James Smartafff0d22018-06-26 08:24:22 -0700437 FC_PORT_ROLE_NVME_DISCOVERY)) {
438 scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x",
439 nrport->port_role);
440 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700441 goto rcu_unlock_buf_done;
James Smartafff0d22018-06-26 08:24:22 -0700442 }
James Smart7d790f02017-06-01 21:06:57 -0700443
James Smartafff0d22018-06-26 08:24:22 -0700444 scnprintf(tmp, sizeof(tmp), "%s\n", statep);
445 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
James Smart79080d32019-05-06 17:26:48 -0700446 goto rcu_unlock_buf_done;
James Smart895427b2017-02-12 13:52:30 -0800447 }
James Smartafff0d22018-06-26 08:24:22 -0700448 rcu_read_unlock();
James Smart895427b2017-02-12 13:52:30 -0800449
James Smart66a210f2018-04-09 14:24:23 -0700450 if (!lport)
James Smartafff0d22018-06-26 08:24:22 -0700451 goto buffer_done;
James Smart66a210f2018-04-09 14:24:23 -0700452
James Smartafff0d22018-06-26 08:24:22 -0700453 if (strlcat(buf, "\nNVME Statistics\n", PAGE_SIZE) >= PAGE_SIZE)
454 goto buffer_done;
James Smart4b056682017-12-08 17:18:10 -0800455
James Smartafff0d22018-06-26 08:24:22 -0700456 scnprintf(tmp, sizeof(tmp),
457 "LS: Xmt %010x Cmpl %010x Abort %08x\n",
458 atomic_read(&lport->fc4NvmeLsRequests),
459 atomic_read(&lport->fc4NvmeLsCmpls),
460 atomic_read(&lport->xmt_ls_abort));
461 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
462 goto buffer_done;
463
464 scnprintf(tmp, sizeof(tmp),
465 "LS XMIT: Err %08x CMPL: xb %08x Err %08x\n",
466 atomic_read(&lport->xmt_ls_err),
467 atomic_read(&lport->cmpl_ls_xb),
468 atomic_read(&lport->cmpl_ls_err));
469 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
470 goto buffer_done;
James Smart895427b2017-02-12 13:52:30 -0800471
James Smart66a210f2018-04-09 14:24:23 -0700472 totin = 0;
473 totout = 0;
James Smartcdb42be2019-01-28 11:14:21 -0800474 for (i = 0; i < phba->cfg_hdw_queue; i++) {
James Smart4c47efc2019-01-28 11:14:25 -0800475 cstat = &phba->sli4_hba.hdwq[i].nvme_cstat;
476 tot = cstat->io_cmpls;
James Smart66a210f2018-04-09 14:24:23 -0700477 totin += tot;
James Smart4c47efc2019-01-28 11:14:25 -0800478 data1 = cstat->input_requests;
479 data2 = cstat->output_requests;
480 data3 = cstat->control_requests;
James Smart66a210f2018-04-09 14:24:23 -0700481 totout += (data1 + data2 + data3);
482 }
James Smartafff0d22018-06-26 08:24:22 -0700483 scnprintf(tmp, sizeof(tmp),
484 "Total FCP Cmpl %016llx Issue %016llx "
485 "OutIO %016llx\n",
486 totin, totout, totout - totin);
487 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
488 goto buffer_done;
James Smart895427b2017-02-12 13:52:30 -0800489
James Smartafff0d22018-06-26 08:24:22 -0700490 scnprintf(tmp, sizeof(tmp),
491 "\tabort %08x noxri %08x nondlp %08x qdepth %08x "
492 "wqerr %08x err %08x\n",
493 atomic_read(&lport->xmt_fcp_abort),
494 atomic_read(&lport->xmt_fcp_noxri),
495 atomic_read(&lport->xmt_fcp_bad_ndlp),
496 atomic_read(&lport->xmt_fcp_qdepth),
497 atomic_read(&lport->xmt_fcp_err),
498 atomic_read(&lport->xmt_fcp_wqerr));
499 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
500 goto buffer_done;
James Smart4b056682017-12-08 17:18:10 -0800501
James Smartafff0d22018-06-26 08:24:22 -0700502 scnprintf(tmp, sizeof(tmp),
503 "FCP CMPL: xb %08x Err %08x\n",
504 atomic_read(&lport->cmpl_fcp_xb),
505 atomic_read(&lport->cmpl_fcp_err));
506 strlcat(buf, tmp, PAGE_SIZE);
507
James Smart79080d32019-05-06 17:26:48 -0700508 /* RCU is already unlocked. */
509 goto buffer_done;
510
511 rcu_unlock_buf_done:
512 rcu_read_unlock();
513
514 buffer_done:
James Smartafff0d22018-06-26 08:24:22 -0700515 len = strnlen(buf, PAGE_SIZE);
516
517 if (unlikely(len >= (PAGE_SIZE - 1))) {
518 lpfc_printf_log(phba, KERN_INFO, LOG_NVME,
519 "6314 Catching potential buffer "
520 "overflow > PAGE_SIZE = %lu bytes\n",
521 PAGE_SIZE);
522 strlcpy(buf + PAGE_SIZE - 1 -
523 strnlen(LPFC_NVME_INFO_MORE_STR, PAGE_SIZE - 1),
524 LPFC_NVME_INFO_MORE_STR,
525 strnlen(LPFC_NVME_INFO_MORE_STR, PAGE_SIZE - 1)
526 + 1);
527 }
528
James Smart895427b2017-02-12 13:52:30 -0800529 return len;
530}
531
532static ssize_t
James Smart4c47efc2019-01-28 11:14:25 -0800533lpfc_scsi_stat_show(struct device *dev, struct device_attribute *attr,
534 char *buf)
535{
536 struct Scsi_Host *shost = class_to_shost(dev);
537 struct lpfc_vport *vport = shost_priv(shost);
538 struct lpfc_hba *phba = vport->phba;
539 int len;
540 struct lpfc_fc4_ctrl_stat *cstat;
541 u64 data1, data2, data3;
542 u64 tot, totin, totout;
543 int i;
544 char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
545
James Smartf6e84792019-01-28 11:14:38 -0800546 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
James Smart4c47efc2019-01-28 11:14:25 -0800547 (phba->sli_rev != LPFC_SLI_REV4))
548 return 0;
549
550 scnprintf(buf, PAGE_SIZE, "SCSI HDWQ Statistics\n");
551
552 totin = 0;
553 totout = 0;
554 for (i = 0; i < phba->cfg_hdw_queue; i++) {
555 cstat = &phba->sli4_hba.hdwq[i].scsi_cstat;
556 tot = cstat->io_cmpls;
557 totin += tot;
558 data1 = cstat->input_requests;
559 data2 = cstat->output_requests;
560 data3 = cstat->control_requests;
561 totout += (data1 + data2 + data3);
562
563 scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
564 "IO %016llx ", i, data1, data2, data3);
565 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
566 goto buffer_done;
567
568 scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
569 tot, ((data1 + data2 + data3) - tot));
570 if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
571 goto buffer_done;
572 }
573 scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
574 "OutIO %016llx\n", totin, totout, totout - totin);
575 strlcat(buf, tmp, PAGE_SIZE);
576
577buffer_done:
578 len = strnlen(buf, PAGE_SIZE);
579
580 return len;
581}
582
583static ssize_t
James Smart81301a92008-12-04 22:39:46 -0500584lpfc_bg_info_show(struct device *dev, struct device_attribute *attr,
585 char *buf)
586{
587 struct Scsi_Host *shost = class_to_shost(dev);
588 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
589 struct lpfc_hba *phba = vport->phba;
590
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700591 if (phba->cfg_enable_bg) {
James Smart81301a92008-12-04 22:39:46 -0500592 if (phba->sli3_options & LPFC_SLI3_BG_ENABLED)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700593 return scnprintf(buf, PAGE_SIZE,
594 "BlockGuard Enabled\n");
James Smart81301a92008-12-04 22:39:46 -0500595 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700596 return scnprintf(buf, PAGE_SIZE,
James Smart81301a92008-12-04 22:39:46 -0500597 "BlockGuard Not Supported\n");
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700598 } else
599 return scnprintf(buf, PAGE_SIZE,
James Smart81301a92008-12-04 22:39:46 -0500600 "BlockGuard Disabled\n");
601}
602
603static ssize_t
604lpfc_bg_guard_err_show(struct device *dev, struct device_attribute *attr,
605 char *buf)
606{
607 struct Scsi_Host *shost = class_to_shost(dev);
608 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
609 struct lpfc_hba *phba = vport->phba;
610
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700611 return scnprintf(buf, PAGE_SIZE, "%llu\n",
James Smart87b5c322008-12-16 10:34:09 -0500612 (unsigned long long)phba->bg_guard_err_cnt);
James Smart81301a92008-12-04 22:39:46 -0500613}
614
615static ssize_t
616lpfc_bg_apptag_err_show(struct device *dev, struct device_attribute *attr,
617 char *buf)
618{
619 struct Scsi_Host *shost = class_to_shost(dev);
620 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
621 struct lpfc_hba *phba = vport->phba;
622
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700623 return scnprintf(buf, PAGE_SIZE, "%llu\n",
James Smart87b5c322008-12-16 10:34:09 -0500624 (unsigned long long)phba->bg_apptag_err_cnt);
James Smart81301a92008-12-04 22:39:46 -0500625}
626
627static ssize_t
628lpfc_bg_reftag_err_show(struct device *dev, struct device_attribute *attr,
629 char *buf)
630{
631 struct Scsi_Host *shost = class_to_shost(dev);
632 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
633 struct lpfc_hba *phba = vport->phba;
634
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700635 return scnprintf(buf, PAGE_SIZE, "%llu\n",
James Smart87b5c322008-12-16 10:34:09 -0500636 (unsigned long long)phba->bg_reftag_err_cnt);
James Smart81301a92008-12-04 22:39:46 -0500637}
638
James Smarte59058c2008-08-24 21:49:00 -0400639/**
James Smart3621a712009-04-06 18:47:14 -0400640 * lpfc_info_show - Return some pci info about the host in ascii
James Smarte59058c2008-08-24 21:49:00 -0400641 * @dev: class converted to a Scsi_host structure.
642 * @attr: device attribute, not used.
643 * @buf: on return contains the formatted text from lpfc_info().
644 *
645 * Returns: size of formatted string.
646 **/
dea31012005-04-17 16:05:31 -0500647static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100648lpfc_info_show(struct device *dev, struct device_attribute *attr,
649 char *buf)
dea31012005-04-17 16:05:31 -0500650{
Tony Jonesee959b02008-02-22 00:13:36 +0100651 struct Scsi_Host *host = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500652
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700653 return scnprintf(buf, PAGE_SIZE, "%s\n", lpfc_info(host));
dea31012005-04-17 16:05:31 -0500654}
655
James Smarte59058c2008-08-24 21:49:00 -0400656/**
James Smart3621a712009-04-06 18:47:14 -0400657 * lpfc_serialnum_show - Return the hba serial number in ascii
James Smarte59058c2008-08-24 21:49:00 -0400658 * @dev: class converted to a Scsi_host structure.
659 * @attr: device attribute, not used.
660 * @buf: on return contains the formatted text serial number.
661 *
662 * Returns: size of formatted string.
663 **/
dea31012005-04-17 16:05:31 -0500664static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100665lpfc_serialnum_show(struct device *dev, struct device_attribute *attr,
666 char *buf)
dea31012005-04-17 16:05:31 -0500667{
Tony Jonesee959b02008-02-22 00:13:36 +0100668 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500669 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
670 struct lpfc_hba *phba = vport->phba;
671
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700672 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->SerialNumber);
dea31012005-04-17 16:05:31 -0500673}
674
James Smarte59058c2008-08-24 21:49:00 -0400675/**
James Smart3621a712009-04-06 18:47:14 -0400676 * lpfc_temp_sensor_show - Return the temperature sensor level
James Smarte59058c2008-08-24 21:49:00 -0400677 * @dev: class converted to a Scsi_host structure.
678 * @attr: device attribute, not used.
679 * @buf: on return contains the formatted support level.
680 *
681 * Description:
682 * Returns a number indicating the temperature sensor level currently
683 * supported, zero or one in ascii.
684 *
685 * Returns: size of formatted string.
686 **/
dea31012005-04-17 16:05:31 -0500687static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100688lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr,
689 char *buf)
James Smart57127f12007-10-27 13:37:05 -0400690{
Tony Jonesee959b02008-02-22 00:13:36 +0100691 struct Scsi_Host *shost = class_to_shost(dev);
James Smart57127f12007-10-27 13:37:05 -0400692 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
693 struct lpfc_hba *phba = vport->phba;
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700694 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->temp_sensor_support);
James Smart57127f12007-10-27 13:37:05 -0400695}
696
James Smarte59058c2008-08-24 21:49:00 -0400697/**
James Smart3621a712009-04-06 18:47:14 -0400698 * lpfc_modeldesc_show - Return the model description of the hba
James Smarte59058c2008-08-24 21:49:00 -0400699 * @dev: class converted to a Scsi_host structure.
700 * @attr: device attribute, not used.
701 * @buf: on return contains the scsi vpd model description.
702 *
703 * Returns: size of formatted string.
704 **/
James Smart57127f12007-10-27 13:37:05 -0400705static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100706lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr,
707 char *buf)
dea31012005-04-17 16:05:31 -0500708{
Tony Jonesee959b02008-02-22 00:13:36 +0100709 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500710 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
711 struct lpfc_hba *phba = vport->phba;
712
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700713 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ModelDesc);
dea31012005-04-17 16:05:31 -0500714}
715
James Smarte59058c2008-08-24 21:49:00 -0400716/**
James Smart3621a712009-04-06 18:47:14 -0400717 * lpfc_modelname_show - Return the model name of the hba
James Smarte59058c2008-08-24 21:49:00 -0400718 * @dev: class converted to a Scsi_host structure.
719 * @attr: device attribute, not used.
720 * @buf: on return contains the scsi vpd model name.
721 *
722 * Returns: size of formatted string.
723 **/
dea31012005-04-17 16:05:31 -0500724static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100725lpfc_modelname_show(struct device *dev, struct device_attribute *attr,
726 char *buf)
dea31012005-04-17 16:05:31 -0500727{
Tony Jonesee959b02008-02-22 00:13:36 +0100728 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500729 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
730 struct lpfc_hba *phba = vport->phba;
731
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700732 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ModelName);
dea31012005-04-17 16:05:31 -0500733}
734
James Smarte59058c2008-08-24 21:49:00 -0400735/**
James Smart3621a712009-04-06 18:47:14 -0400736 * lpfc_programtype_show - Return the program type of the hba
James Smarte59058c2008-08-24 21:49:00 -0400737 * @dev: class converted to a Scsi_host structure.
738 * @attr: device attribute, not used.
739 * @buf: on return contains the scsi vpd program type.
740 *
741 * Returns: size of formatted string.
742 **/
dea31012005-04-17 16:05:31 -0500743static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100744lpfc_programtype_show(struct device *dev, struct device_attribute *attr,
745 char *buf)
dea31012005-04-17 16:05:31 -0500746{
Tony Jonesee959b02008-02-22 00:13:36 +0100747 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500748 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
749 struct lpfc_hba *phba = vport->phba;
750
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700751 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ProgramType);
dea31012005-04-17 16:05:31 -0500752}
753
James Smarte59058c2008-08-24 21:49:00 -0400754/**
James Smart3621a712009-04-06 18:47:14 -0400755 * lpfc_mlomgmt_show - Return the Menlo Maintenance sli flag
James Smart84774a42008-08-24 21:50:06 -0400756 * @dev: class converted to a Scsi_host structure.
757 * @attr: device attribute, not used.
758 * @buf: on return contains the Menlo Maintenance sli flag.
759 *
760 * Returns: size of formatted string.
761 **/
762static ssize_t
763lpfc_mlomgmt_show(struct device *dev, struct device_attribute *attr, char *buf)
764{
765 struct Scsi_Host *shost = class_to_shost(dev);
766 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
767 struct lpfc_hba *phba = vport->phba;
768
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700769 return scnprintf(buf, PAGE_SIZE, "%d\n",
James Smart84774a42008-08-24 21:50:06 -0400770 (phba->sli.sli_flag & LPFC_MENLO_MAINT));
771}
772
773/**
James Smart3621a712009-04-06 18:47:14 -0400774 * lpfc_vportnum_show - Return the port number in ascii of the hba
James Smarte59058c2008-08-24 21:49:00 -0400775 * @dev: class converted to a Scsi_host structure.
776 * @attr: device attribute, not used.
777 * @buf: on return contains scsi vpd program type.
778 *
779 * Returns: size of formatted string.
780 **/
dea31012005-04-17 16:05:31 -0500781static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100782lpfc_vportnum_show(struct device *dev, struct device_attribute *attr,
783 char *buf)
dea31012005-04-17 16:05:31 -0500784{
Tony Jonesee959b02008-02-22 00:13:36 +0100785 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500786 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
787 struct lpfc_hba *phba = vport->phba;
788
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700789 return scnprintf(buf, PAGE_SIZE, "%s\n", phba->Port);
dea31012005-04-17 16:05:31 -0500790}
791
James Smarte59058c2008-08-24 21:49:00 -0400792/**
James Smart3621a712009-04-06 18:47:14 -0400793 * lpfc_fwrev_show - Return the firmware rev running in the hba
James Smarte59058c2008-08-24 21:49:00 -0400794 * @dev: class converted to a Scsi_host structure.
795 * @attr: device attribute, not used.
796 * @buf: on return contains the scsi vpd program type.
797 *
798 * Returns: size of formatted string.
799 **/
dea31012005-04-17 16:05:31 -0500800static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100801lpfc_fwrev_show(struct device *dev, struct device_attribute *attr,
802 char *buf)
dea31012005-04-17 16:05:31 -0500803{
Tony Jonesee959b02008-02-22 00:13:36 +0100804 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500805 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
806 struct lpfc_hba *phba = vport->phba;
James Smart026abb82011-12-13 13:20:45 -0500807 uint32_t if_type;
808 uint8_t sli_family;
James Smart6b5151f2012-01-18 16:24:06 -0500809 char fwrev[FW_REV_STR_SIZE];
James Smart026abb82011-12-13 13:20:45 -0500810 int len;
James Smart2e0fef82007-06-17 19:56:36 -0500811
dea31012005-04-17 16:05:31 -0500812 lpfc_decode_firmware_rev(phba, fwrev, 1);
James Smart026abb82011-12-13 13:20:45 -0500813 if_type = phba->sli4_hba.pc_sli4_params.if_type;
814 sli_family = phba->sli4_hba.pc_sli4_params.sli_family;
815
816 if (phba->sli_rev < LPFC_SLI_REV4)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700817 len = scnprintf(buf, PAGE_SIZE, "%s, sli-%d\n",
James Smart026abb82011-12-13 13:20:45 -0500818 fwrev, phba->sli_rev);
819 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700820 len = scnprintf(buf, PAGE_SIZE, "%s, sli-%d:%d:%x\n",
James Smart026abb82011-12-13 13:20:45 -0500821 fwrev, phba->sli_rev, if_type, sli_family);
822
823 return len;
dea31012005-04-17 16:05:31 -0500824}
825
James Smarte59058c2008-08-24 21:49:00 -0400826/**
James Smart3621a712009-04-06 18:47:14 -0400827 * lpfc_hdw_show - Return the jedec information about the hba
James Smarte59058c2008-08-24 21:49:00 -0400828 * @dev: class converted to a Scsi_host structure.
829 * @attr: device attribute, not used.
830 * @buf: on return contains the scsi vpd program type.
831 *
832 * Returns: size of formatted string.
833 **/
dea31012005-04-17 16:05:31 -0500834static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100835lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf)
dea31012005-04-17 16:05:31 -0500836{
837 char hdw[9];
Tony Jonesee959b02008-02-22 00:13:36 +0100838 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500839 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
840 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -0500841 lpfc_vpd_t *vp = &phba->vpd;
James Smart2e0fef82007-06-17 19:56:36 -0500842
dea31012005-04-17 16:05:31 -0500843 lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
James Smartec762422019-08-14 16:57:07 -0700844 return scnprintf(buf, PAGE_SIZE, "%s %08x %08x\n", hdw,
845 vp->rev.smRev, vp->rev.smFwRev);
dea31012005-04-17 16:05:31 -0500846}
James Smarte59058c2008-08-24 21:49:00 -0400847
848/**
James Smart3621a712009-04-06 18:47:14 -0400849 * lpfc_option_rom_version_show - Return the adapter ROM FCode version
James Smarte59058c2008-08-24 21:49:00 -0400850 * @dev: class converted to a Scsi_host structure.
851 * @attr: device attribute, not used.
852 * @buf: on return contains the ROM and FCode ascii strings.
853 *
854 * Returns: size of formatted string.
855 **/
dea31012005-04-17 16:05:31 -0500856static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +0100857lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr,
858 char *buf)
dea31012005-04-17 16:05:31 -0500859{
Tony Jonesee959b02008-02-22 00:13:36 +0100860 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500861 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
862 struct lpfc_hba *phba = vport->phba;
James Smarta0683bf2015-04-07 15:07:16 -0400863 char fwrev[FW_REV_STR_SIZE];
James Smart2e0fef82007-06-17 19:56:36 -0500864
James Smarta0683bf2015-04-07 15:07:16 -0400865 if (phba->sli_rev < LPFC_SLI_REV4)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700866 return scnprintf(buf, PAGE_SIZE, "%s\n",
867 phba->OptionROMVersion);
James Smarta0683bf2015-04-07 15:07:16 -0400868
869 lpfc_decode_firmware_rev(phba, fwrev, 1);
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700870 return scnprintf(buf, PAGE_SIZE, "%s\n", fwrev);
dea31012005-04-17 16:05:31 -0500871}
James Smarte59058c2008-08-24 21:49:00 -0400872
873/**
James Smart3621a712009-04-06 18:47:14 -0400874 * lpfc_state_show - Return the link state of the port
James Smarte59058c2008-08-24 21:49:00 -0400875 * @dev: class converted to a Scsi_host structure.
876 * @attr: device attribute, not used.
877 * @buf: on return contains text describing the state of the link.
878 *
879 * Notes:
880 * The switch statement has no default so zero will be returned.
881 *
882 * Returns: size of formatted string.
883 **/
dea31012005-04-17 16:05:31 -0500884static ssize_t
Hannes Reineckebbd1ae42008-03-18 14:32:28 +0100885lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
886 char *buf)
dea31012005-04-17 16:05:31 -0500887{
Tony Jonesee959b02008-02-22 00:13:36 +0100888 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -0500889 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
890 struct lpfc_hba *phba = vport->phba;
891 int len = 0;
892
893 switch (phba->link_state) {
894 case LPFC_LINK_UNKNOWN:
Jamie Wellnitz41415862006-02-28 19:25:27 -0500895 case LPFC_WARM_START:
dea31012005-04-17 16:05:31 -0500896 case LPFC_INIT_START:
897 case LPFC_INIT_MBX_CMDS:
898 case LPFC_LINK_DOWN:
James Smart2e0fef82007-06-17 19:56:36 -0500899 case LPFC_HBA_ERROR:
James Smarta0c87cb2009-07-19 10:01:10 -0400900 if (phba->hba_flag & LINK_DISABLED)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700901 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smarta0c87cb2009-07-19 10:01:10 -0400902 "Link Down - User disabled\n");
903 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700904 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smarta0c87cb2009-07-19 10:01:10 -0400905 "Link Down\n");
dea31012005-04-17 16:05:31 -0500906 break;
907 case LPFC_LINK_UP:
dea31012005-04-17 16:05:31 -0500908 case LPFC_CLEAR_LA:
dea31012005-04-17 16:05:31 -0500909 case LPFC_HBA_READY:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700910 len += scnprintf(buf + len, PAGE_SIZE-len, "Link Up - ");
James Smart2e0fef82007-06-17 19:56:36 -0500911
912 switch (vport->port_state) {
James Smart2e0fef82007-06-17 19:56:36 -0500913 case LPFC_LOCAL_CFG_LINK:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700914 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart92d7f7b2007-06-17 19:56:38 -0500915 "Configuring Link\n");
James Smart2e0fef82007-06-17 19:56:36 -0500916 break;
James Smart92d7f7b2007-06-17 19:56:38 -0500917 case LPFC_FDISC:
James Smart2e0fef82007-06-17 19:56:36 -0500918 case LPFC_FLOGI:
919 case LPFC_FABRIC_CFG_LINK:
920 case LPFC_NS_REG:
921 case LPFC_NS_QRY:
922 case LPFC_BUILD_DISC_LIST:
923 case LPFC_DISC_AUTH:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700924 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart2e0fef82007-06-17 19:56:36 -0500925 "Discovery\n");
926 break;
927 case LPFC_VPORT_READY:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700928 len += scnprintf(buf + len, PAGE_SIZE - len,
929 "Ready\n");
James Smart2e0fef82007-06-17 19:56:36 -0500930 break;
931
James Smart92d7f7b2007-06-17 19:56:38 -0500932 case LPFC_VPORT_FAILED:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700933 len += scnprintf(buf + len, PAGE_SIZE - len,
934 "Failed\n");
James Smart92d7f7b2007-06-17 19:56:38 -0500935 break;
936
937 case LPFC_VPORT_UNKNOWN:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700938 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart2e0fef82007-06-17 19:56:36 -0500939 "Unknown\n");
940 break;
941 }
James Smart84774a42008-08-24 21:50:06 -0400942 if (phba->sli.sli_flag & LPFC_MENLO_MAINT)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700943 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart84774a42008-08-24 21:50:06 -0400944 " Menlo Maint Mode\n");
James Smart76a95d72010-11-20 23:11:48 -0500945 else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smart2e0fef82007-06-17 19:56:36 -0500946 if (vport->fc_flag & FC_PUBLIC_LOOP)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700947 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500948 " Public Loop\n");
949 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700950 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500951 " Private Loop\n");
952 } else {
James Smart2e0fef82007-06-17 19:56:36 -0500953 if (vport->fc_flag & FC_FABRIC)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700954 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500955 " Fabric\n");
956 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700957 len += scnprintf(buf + len, PAGE_SIZE-len,
dea31012005-04-17 16:05:31 -0500958 " Point-2-Point\n");
959 }
960 }
James Smart2e0fef82007-06-17 19:56:36 -0500961
James Smart1dc5ec22018-10-23 13:41:11 -0700962 if ((phba->sli_rev == LPFC_SLI_REV4) &&
963 ((bf_get(lpfc_sli_intf_if_type,
964 &phba->sli4_hba.sli_intf) ==
965 LPFC_SLI_INTF_IF_TYPE_6))) {
966 struct lpfc_trunk_link link = phba->trunk_link;
967
968 if (bf_get(lpfc_conf_trunk_port0, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700969 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700970 "Trunk port 0: Link %s %s\n",
971 (link.link0.state == LPFC_LINK_UP) ?
972 "Up" : "Down. ",
973 trunk_errmsg[link.link0.fault]);
974
975 if (bf_get(lpfc_conf_trunk_port1, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700976 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700977 "Trunk port 1: Link %s %s\n",
978 (link.link1.state == LPFC_LINK_UP) ?
979 "Up" : "Down. ",
980 trunk_errmsg[link.link1.fault]);
981
982 if (bf_get(lpfc_conf_trunk_port2, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700983 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700984 "Trunk port 2: Link %s %s\n",
985 (link.link2.state == LPFC_LINK_UP) ?
986 "Up" : "Down. ",
987 trunk_errmsg[link.link2.fault]);
988
989 if (bf_get(lpfc_conf_trunk_port3, &phba->sli4_hba))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -0700990 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart1dc5ec22018-10-23 13:41:11 -0700991 "Trunk port 3: Link %s %s\n",
992 (link.link3.state == LPFC_LINK_UP) ?
993 "Up" : "Down. ",
994 trunk_errmsg[link.link3.fault]);
995
996 }
997
dea31012005-04-17 16:05:31 -0500998 return len;
999}
1000
James Smarte59058c2008-08-24 21:49:00 -04001001/**
James Smart026abb82011-12-13 13:20:45 -05001002 * lpfc_sli4_protocol_show - Return the fip mode of the HBA
1003 * @dev: class unused variable.
1004 * @attr: device attribute, not used.
1005 * @buf: on return contains the module description text.
1006 *
1007 * Returns: size of formatted string.
1008 **/
1009static ssize_t
1010lpfc_sli4_protocol_show(struct device *dev, struct device_attribute *attr,
1011 char *buf)
1012{
1013 struct Scsi_Host *shost = class_to_shost(dev);
1014 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1015 struct lpfc_hba *phba = vport->phba;
1016
1017 if (phba->sli_rev < LPFC_SLI_REV4)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001018 return scnprintf(buf, PAGE_SIZE, "fc\n");
James Smart026abb82011-12-13 13:20:45 -05001019
1020 if (phba->sli4_hba.lnk_info.lnk_dv == LPFC_LNK_DAT_VAL) {
1021 if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_GE)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001022 return scnprintf(buf, PAGE_SIZE, "fcoe\n");
James Smart026abb82011-12-13 13:20:45 -05001023 if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001024 return scnprintf(buf, PAGE_SIZE, "fc\n");
James Smart026abb82011-12-13 13:20:45 -05001025 }
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001026 return scnprintf(buf, PAGE_SIZE, "unknown\n");
James Smart026abb82011-12-13 13:20:45 -05001027}
1028
1029/**
James Smart1ba981f2014-02-20 09:56:45 -05001030 * lpfc_oas_supported_show - Return whether or not Optimized Access Storage
1031 * (OAS) is supported.
1032 * @dev: class unused variable.
1033 * @attr: device attribute, not used.
1034 * @buf: on return contains the module description text.
1035 *
1036 * Returns: size of formatted string.
1037 **/
1038static ssize_t
1039lpfc_oas_supported_show(struct device *dev, struct device_attribute *attr,
1040 char *buf)
1041{
1042 struct Scsi_Host *shost = class_to_shost(dev);
1043 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
1044 struct lpfc_hba *phba = vport->phba;
1045
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001046 return scnprintf(buf, PAGE_SIZE, "%d\n",
James Smart1ba981f2014-02-20 09:56:45 -05001047 phba->sli4_hba.pc_sli4_params.oas_supported);
1048}
1049
1050/**
James Smart84d1b002010-02-12 14:42:33 -05001051 * lpfc_link_state_store - Transition the link_state on an HBA port
1052 * @dev: class device that is converted into a Scsi_host.
1053 * @attr: device attribute, not used.
1054 * @buf: one or more lpfc_polling_flags values.
1055 * @count: not used.
1056 *
1057 * Returns:
1058 * -EINVAL if the buffer is not "up" or "down"
1059 * return from link state change function if non-zero
1060 * length of the buf on success
1061 **/
1062static ssize_t
1063lpfc_link_state_store(struct device *dev, struct device_attribute *attr,
1064 const char *buf, size_t count)
1065{
1066 struct Scsi_Host *shost = class_to_shost(dev);
1067 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1068 struct lpfc_hba *phba = vport->phba;
1069
1070 int status = -EINVAL;
1071
1072 if ((strncmp(buf, "up", sizeof("up") - 1) == 0) &&
1073 (phba->link_state == LPFC_LINK_DOWN))
James Smart6e7288d2010-06-07 15:23:35 -04001074 status = phba->lpfc_hba_init_link(phba, MBX_NOWAIT);
James Smart84d1b002010-02-12 14:42:33 -05001075 else if ((strncmp(buf, "down", sizeof("down") - 1) == 0) &&
1076 (phba->link_state >= LPFC_LINK_UP))
James Smart6e7288d2010-06-07 15:23:35 -04001077 status = phba->lpfc_hba_down_link(phba, MBX_NOWAIT);
James Smart84d1b002010-02-12 14:42:33 -05001078
1079 if (status == 0)
1080 return strlen(buf);
1081 else
1082 return status;
1083}
1084
1085/**
James Smart3621a712009-04-06 18:47:14 -04001086 * lpfc_num_discovered_ports_show - Return sum of mapped and unmapped vports
James Smarte59058c2008-08-24 21:49:00 -04001087 * @dev: class device that is converted into a Scsi_host.
1088 * @attr: device attribute, not used.
1089 * @buf: on return contains the sum of fc mapped and unmapped.
1090 *
1091 * Description:
1092 * Returns the ascii text number of the sum of the fc mapped and unmapped
1093 * vport counts.
1094 *
1095 * Returns: size of formatted string.
1096 **/
dea31012005-04-17 16:05:31 -05001097static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001098lpfc_num_discovered_ports_show(struct device *dev,
1099 struct device_attribute *attr, char *buf)
dea31012005-04-17 16:05:31 -05001100{
Tony Jonesee959b02008-02-22 00:13:36 +01001101 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001102 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1103
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001104 return scnprintf(buf, PAGE_SIZE, "%d\n",
James Smart2e0fef82007-06-17 19:56:36 -05001105 vport->fc_map_cnt + vport->fc_unmap_cnt);
dea31012005-04-17 16:05:31 -05001106}
1107
James Smarte59058c2008-08-24 21:49:00 -04001108/**
James Smart3621a712009-04-06 18:47:14 -04001109 * lpfc_issue_lip - Misnomer, name carried over from long ago
James Smarte59058c2008-08-24 21:49:00 -04001110 * @shost: Scsi_Host pointer.
1111 *
1112 * Description:
1113 * Bring the link down gracefully then re-init the link. The firmware will
1114 * re-init the fiber channel interface as required. Does not issue a LIP.
1115 *
1116 * Returns:
1117 * -EPERM port offline or management commands are being blocked
1118 * -ENOMEM cannot allocate memory for the mailbox command
1119 * -EIO error sending the mailbox command
1120 * zero for success
1121 **/
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07001122static int
James Smart2e0fef82007-06-17 19:56:36 -05001123lpfc_issue_lip(struct Scsi_Host *shost)
dea31012005-04-17 16:05:31 -05001124{
James Smart2e0fef82007-06-17 19:56:36 -05001125 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1126 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05001127 LPFC_MBOXQ_t *pmboxq;
1128 int mbxstatus = MBXERR_ERROR;
1129
James Smart2289e952018-01-30 15:58:55 -08001130 /*
1131 * If the link is offline, disabled or BLOCK_MGMT_IO
1132 * it doesn't make any sense to allow issue_lip
1133 */
James Smart2e0fef82007-06-17 19:56:36 -05001134 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smart2289e952018-01-30 15:58:55 -08001135 (phba->hba_flag & LINK_DISABLED) ||
James Smart83108bd2008-01-11 01:53:09 -05001136 (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO))
dea31012005-04-17 16:05:31 -05001137 return -EPERM;
1138
1139 pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);
1140
1141 if (!pmboxq)
1142 return -ENOMEM;
1143
1144 memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
James Smart04c68492009-05-22 14:52:52 -04001145 pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK;
1146 pmboxq->u.mb.mbxOwner = OWN_HOST;
James Smart4db621e2006-07-06 15:49:49 -04001147
James Smart33ccf8d2006-08-17 11:57:58 -04001148 mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2);
dea31012005-04-17 16:05:31 -05001149
James Smart04c68492009-05-22 14:52:52 -04001150 if ((mbxstatus == MBX_SUCCESS) &&
1151 (pmboxq->u.mb.mbxStatus == 0 ||
1152 pmboxq->u.mb.mbxStatus == MBXERR_LINK_DOWN)) {
James Smart4db621e2006-07-06 15:49:49 -04001153 memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
1154 lpfc_init_link(phba, pmboxq, phba->cfg_topology,
1155 phba->cfg_link_speed);
1156 mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq,
1157 phba->fc_ratov * 2);
James Smartdcf2a4e2010-09-29 11:18:53 -04001158 if ((mbxstatus == MBX_SUCCESS) &&
1159 (pmboxq->u.mb.mbxStatus == MBXERR_SEC_NO_PERMISSION))
1160 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
1161 "2859 SLI authentication is required "
1162 "for INIT_LINK but has not done yet\n");
James Smart4db621e2006-07-06 15:49:49 -04001163 }
1164
James Smart5b8bd0c2007-04-25 09:52:49 -04001165 lpfc_set_loopback_flag(phba);
James Smart858c9f62007-06-17 19:56:39 -05001166 if (mbxstatus != MBX_TIMEOUT)
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04001167 mempool_free(pmboxq, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05001168
1169 if (mbxstatus == MBXERR_ERROR)
1170 return -EIO;
1171
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07001172 return 0;
dea31012005-04-17 16:05:31 -05001173}
1174
James Smart895427b2017-02-12 13:52:30 -08001175int
1176lpfc_emptyq_wait(struct lpfc_hba *phba, struct list_head *q, spinlock_t *lock)
1177{
1178 int cnt = 0;
1179
1180 spin_lock_irq(lock);
1181 while (!list_empty(q)) {
1182 spin_unlock_irq(lock);
1183 msleep(20);
1184 if (cnt++ > 250) { /* 5 secs */
1185 lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
1186 "0466 %s %s\n",
1187 "Outstanding IO when ",
1188 "bringing Adapter offline\n");
1189 return 0;
1190 }
1191 spin_lock_irq(lock);
1192 }
1193 spin_unlock_irq(lock);
1194 return 1;
1195}
1196
James Smarte59058c2008-08-24 21:49:00 -04001197/**
James Smart3621a712009-04-06 18:47:14 -04001198 * lpfc_do_offline - Issues a mailbox command to bring the link down
James Smarte59058c2008-08-24 21:49:00 -04001199 * @phba: lpfc_hba pointer.
1200 * @type: LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL.
1201 *
1202 * Notes:
1203 * Assumes any error from lpfc_do_offline() will be negative.
1204 * Can wait up to 5 seconds for the port ring buffers count
1205 * to reach zero, prints a warning if it is not zero and continues.
James Smart3621a712009-04-06 18:47:14 -04001206 * lpfc_workq_post_event() returns a non-zero return code if call fails.
James Smarte59058c2008-08-24 21:49:00 -04001207 *
1208 * Returns:
1209 * -EIO error posting the event
1210 * zero for success
1211 **/
James Smart40496f02006-07-06 15:50:22 -04001212static int
James Smart46fa3112007-04-25 09:51:45 -04001213lpfc_do_offline(struct lpfc_hba *phba, uint32_t type)
1214{
1215 struct completion online_compl;
James Smart895427b2017-02-12 13:52:30 -08001216 struct lpfc_queue *qp = NULL;
James Smart46fa3112007-04-25 09:51:45 -04001217 struct lpfc_sli_ring *pring;
1218 struct lpfc_sli *psli;
1219 int status = 0;
James Smart46fa3112007-04-25 09:51:45 -04001220 int i;
James Smartfedd3b72011-02-16 12:39:24 -05001221 int rc;
James Smart46fa3112007-04-25 09:51:45 -04001222
1223 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001224 rc = lpfc_workq_post_event(phba, &status, &online_compl,
James Smart46fa3112007-04-25 09:51:45 -04001225 LPFC_EVT_OFFLINE_PREP);
James Smartfedd3b72011-02-16 12:39:24 -05001226 if (rc == 0)
1227 return -ENOMEM;
1228
James Smart46fa3112007-04-25 09:51:45 -04001229 wait_for_completion(&online_compl);
1230
1231 if (status != 0)
1232 return -EIO;
1233
1234 psli = &phba->sli;
1235
James Smart4645f7b2019-03-12 16:30:14 -07001236 /*
1237 * If freeing the queues have already started, don't access them.
1238 * Otherwise set FREE_WAIT to indicate that queues are being used
1239 * to hold the freeing process until we finish.
1240 */
1241 spin_lock_irq(&phba->hbalock);
1242 if (!(psli->sli_flag & LPFC_QUEUE_FREE_INIT)) {
1243 psli->sli_flag |= LPFC_QUEUE_FREE_WAIT;
1244 } else {
1245 spin_unlock_irq(&phba->hbalock);
1246 goto skip_wait;
1247 }
1248 spin_unlock_irq(&phba->hbalock);
1249
James Smart09372822008-01-11 01:52:54 -05001250 /* Wait a little for things to settle down, but not
1251 * long enough for dev loss timeout to expire.
1252 */
James Smart895427b2017-02-12 13:52:30 -08001253 if (phba->sli_rev != LPFC_SLI_REV4) {
1254 for (i = 0; i < psli->num_rings; i++) {
1255 pring = &psli->sli3_ring[i];
1256 if (!lpfc_emptyq_wait(phba, &pring->txcmplq,
1257 &phba->hbalock))
1258 goto out;
1259 }
1260 } else {
1261 list_for_each_entry(qp, &phba->sli4_hba.lpfc_wq_list, wq_list) {
1262 pring = qp->pring;
1263 if (!pring)
1264 continue;
1265 if (!lpfc_emptyq_wait(phba, &pring->txcmplq,
1266 &pring->ring_lock))
1267 goto out;
James Smart46fa3112007-04-25 09:51:45 -04001268 }
1269 }
James Smart895427b2017-02-12 13:52:30 -08001270out:
James Smart4645f7b2019-03-12 16:30:14 -07001271 spin_lock_irq(&phba->hbalock);
1272 psli->sli_flag &= ~LPFC_QUEUE_FREE_WAIT;
1273 spin_unlock_irq(&phba->hbalock);
1274
1275skip_wait:
James Smart46fa3112007-04-25 09:51:45 -04001276 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001277 rc = lpfc_workq_post_event(phba, &status, &online_compl, type);
1278 if (rc == 0)
1279 return -ENOMEM;
1280
James Smart46fa3112007-04-25 09:51:45 -04001281 wait_for_completion(&online_compl);
1282
1283 if (status != 0)
1284 return -EIO;
1285
1286 return 0;
1287}
1288
James Smarte59058c2008-08-24 21:49:00 -04001289/**
James Smart50212672018-12-13 15:17:57 -08001290 * lpfc_reset_pci_bus - resets PCI bridge controller's secondary bus of an HBA
1291 * @phba: lpfc_hba pointer.
1292 *
1293 * Description:
1294 * Issues a PCI secondary bus reset for the phba->pcidev.
1295 *
1296 * Notes:
1297 * First walks the bus_list to ensure only PCI devices with Emulex
1298 * vendor id, device ids that support hot reset, only one occurrence
1299 * of function 0, and all ports on the bus are in offline mode to ensure the
1300 * hot reset only affects one valid HBA.
1301 *
1302 * Returns:
1303 * -ENOTSUPP, cfg_enable_hba_reset must be of value 2
1304 * -ENODEV, NULL ptr to pcidev
1305 * -EBADSLT, detected invalid device
1306 * -EBUSY, port is not in offline state
1307 * 0, successful
1308 */
Bart Van Assche3999df72019-03-28 11:06:16 -07001309static int
James Smart50212672018-12-13 15:17:57 -08001310lpfc_reset_pci_bus(struct lpfc_hba *phba)
1311{
1312 struct pci_dev *pdev = phba->pcidev;
1313 struct Scsi_Host *shost = NULL;
1314 struct lpfc_hba *phba_other = NULL;
1315 struct pci_dev *ptr = NULL;
1316 int res;
1317
1318 if (phba->cfg_enable_hba_reset != 2)
1319 return -ENOTSUPP;
1320
1321 if (!pdev) {
1322 lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "8345 pdev NULL!\n");
1323 return -ENODEV;
1324 }
1325
1326 res = lpfc_check_pci_resettable(phba);
1327 if (res)
1328 return res;
1329
1330 /* Walk the list of devices on the pci_dev's bus */
1331 list_for_each_entry(ptr, &pdev->bus->devices, bus_list) {
1332 /* Check port is offline */
1333 shost = pci_get_drvdata(ptr);
1334 if (shost) {
1335 phba_other =
1336 ((struct lpfc_vport *)shost->hostdata)->phba;
1337 if (!(phba_other->pport->fc_flag & FC_OFFLINE_MODE)) {
1338 lpfc_printf_log(phba_other, KERN_INFO, LOG_INIT,
1339 "8349 WWPN = 0x%02x%02x%02x%02x"
1340 "%02x%02x%02x%02x is not "
1341 "offline!\n",
1342 phba_other->wwpn[0],
1343 phba_other->wwpn[1],
1344 phba_other->wwpn[2],
1345 phba_other->wwpn[3],
1346 phba_other->wwpn[4],
1347 phba_other->wwpn[5],
1348 phba_other->wwpn[6],
1349 phba_other->wwpn[7]);
1350 return -EBUSY;
1351 }
1352 }
1353 }
1354
1355 /* Issue PCI bus reset */
1356 res = pci_reset_bus(pdev);
1357 if (res) {
1358 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
1359 "8350 PCI reset bus failed: %d\n", res);
1360 }
1361
1362 return res;
1363}
1364
1365/**
James Smart3621a712009-04-06 18:47:14 -04001366 * lpfc_selective_reset - Offline then onlines the port
James Smarte59058c2008-08-24 21:49:00 -04001367 * @phba: lpfc_hba pointer.
1368 *
1369 * Description:
1370 * If the port is configured to allow a reset then the hba is brought
1371 * offline then online.
1372 *
1373 * Notes:
1374 * Assumes any error from lpfc_do_offline() will be negative.
James Smartab56dc22011-02-16 12:39:57 -05001375 * Do not make this function static.
James Smarte59058c2008-08-24 21:49:00 -04001376 *
1377 * Returns:
1378 * lpfc_do_offline() return code if not zero
1379 * -EIO reset not configured or error posting the event
1380 * zero for success
1381 **/
James Smart7f860592011-03-11 16:05:52 -05001382int
James Smart40496f02006-07-06 15:50:22 -04001383lpfc_selective_reset(struct lpfc_hba *phba)
1384{
1385 struct completion online_compl;
1386 int status = 0;
James Smartfedd3b72011-02-16 12:39:24 -05001387 int rc;
James Smart40496f02006-07-06 15:50:22 -04001388
James Smart71157c92013-07-15 18:34:36 -04001389 if (!phba->cfg_enable_hba_reset)
James Smartf7a919b2011-08-21 21:49:16 -04001390 return -EACCES;
James Smart13815c82008-01-11 01:52:48 -05001391
James Smart71157c92013-07-15 18:34:36 -04001392 if (!(phba->pport->fc_flag & FC_OFFLINE_MODE)) {
1393 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
James Smart40496f02006-07-06 15:50:22 -04001394
James Smart71157c92013-07-15 18:34:36 -04001395 if (status != 0)
1396 return status;
1397 }
James Smart40496f02006-07-06 15:50:22 -04001398
1399 init_completion(&online_compl);
James Smartfedd3b72011-02-16 12:39:24 -05001400 rc = lpfc_workq_post_event(phba, &status, &online_compl,
James Smart40496f02006-07-06 15:50:22 -04001401 LPFC_EVT_ONLINE);
James Smartfedd3b72011-02-16 12:39:24 -05001402 if (rc == 0)
1403 return -ENOMEM;
1404
James Smart40496f02006-07-06 15:50:22 -04001405 wait_for_completion(&online_compl);
1406
1407 if (status != 0)
1408 return -EIO;
1409
1410 return 0;
1411}
1412
James Smarte59058c2008-08-24 21:49:00 -04001413/**
James Smart3621a712009-04-06 18:47:14 -04001414 * lpfc_issue_reset - Selectively resets an adapter
James Smarte59058c2008-08-24 21:49:00 -04001415 * @dev: class device that is converted into a Scsi_host.
1416 * @attr: device attribute, not used.
1417 * @buf: containing the string "selective".
1418 * @count: unused variable.
1419 *
1420 * Description:
1421 * If the buf contains the string "selective" then lpfc_selective_reset()
1422 * is called to perform the reset.
1423 *
1424 * Notes:
1425 * Assumes any error from lpfc_selective_reset() will be negative.
1426 * If lpfc_selective_reset() returns zero then the length of the buffer
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02001427 * is returned which indicates success
James Smarte59058c2008-08-24 21:49:00 -04001428 *
1429 * Returns:
1430 * -EINVAL if the buffer does not contain the string "selective"
1431 * length of buf if lpfc-selective_reset() if the call succeeds
1432 * return value of lpfc_selective_reset() if the call fails
1433**/
James Smart40496f02006-07-06 15:50:22 -04001434static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001435lpfc_issue_reset(struct device *dev, struct device_attribute *attr,
1436 const char *buf, size_t count)
James Smart40496f02006-07-06 15:50:22 -04001437{
Tony Jonesee959b02008-02-22 00:13:36 +01001438 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001439 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1440 struct lpfc_hba *phba = vport->phba;
James Smart40496f02006-07-06 15:50:22 -04001441 int status = -EINVAL;
1442
James Smart73d91e52011-10-10 21:32:10 -04001443 if (!phba->cfg_enable_hba_reset)
1444 return -EACCES;
1445
James Smart40496f02006-07-06 15:50:22 -04001446 if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
James Smart7f860592011-03-11 16:05:52 -05001447 status = phba->lpfc_selective_reset(phba);
James Smart40496f02006-07-06 15:50:22 -04001448
1449 if (status == 0)
1450 return strlen(buf);
1451 else
1452 return status;
1453}
1454
James Smarte59058c2008-08-24 21:49:00 -04001455/**
James Smart88a2cfb2011-07-22 18:36:33 -04001456 * lpfc_sli4_pdev_status_reg_wait - Wait for pdev status register for readyness
1457 * @phba: lpfc_hba pointer.
1458 *
1459 * Description:
1460 * SLI4 interface type-2 device to wait on the sliport status register for
1461 * the readyness after performing a firmware reset.
1462 *
1463 * Returns:
Masanari Iida0b1587b2013-07-17 04:37:44 +09001464 * zero for success, -EPERM when port does not have privilege to perform the
James Smart026abb82011-12-13 13:20:45 -05001465 * reset, -EIO when port timeout from recovering from the reset.
1466 *
1467 * Note:
1468 * As the caller will interpret the return code by value, be careful in making
1469 * change or addition to return codes.
James Smart88a2cfb2011-07-22 18:36:33 -04001470 **/
James Smart73d91e52011-10-10 21:32:10 -04001471int
James Smart88a2cfb2011-07-22 18:36:33 -04001472lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba)
1473{
James Smartf7a919b2011-08-21 21:49:16 -04001474 struct lpfc_register portstat_reg = {0};
James Smart88a2cfb2011-07-22 18:36:33 -04001475 int i;
1476
James Smartf7a919b2011-08-21 21:49:16 -04001477 msleep(100);
James Smart88a2cfb2011-07-22 18:36:33 -04001478 lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
1479 &portstat_reg.word0);
1480
Masanari Iida0b1587b2013-07-17 04:37:44 +09001481 /* verify if privileged for the request operation */
James Smartf7a919b2011-08-21 21:49:16 -04001482 if (!bf_get(lpfc_sliport_status_rn, &portstat_reg) &&
1483 !bf_get(lpfc_sliport_status_err, &portstat_reg))
1484 return -EPERM;
1485
James Smart88a2cfb2011-07-22 18:36:33 -04001486 /* wait for the SLI port firmware ready after firmware reset */
1487 for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) {
1488 msleep(10);
1489 lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
1490 &portstat_reg.word0);
1491 if (!bf_get(lpfc_sliport_status_err, &portstat_reg))
1492 continue;
1493 if (!bf_get(lpfc_sliport_status_rn, &portstat_reg))
1494 continue;
1495 if (!bf_get(lpfc_sliport_status_rdy, &portstat_reg))
1496 continue;
1497 break;
1498 }
1499
1500 if (i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT)
1501 return 0;
1502 else
1503 return -EIO;
1504}
1505
1506/**
James Smart52d52442011-05-24 11:42:45 -04001507 * lpfc_sli4_pdev_reg_request - Request physical dev to perform a register acc
James Smartc0c11512011-05-24 11:41:34 -04001508 * @phba: lpfc_hba pointer.
1509 *
1510 * Description:
James Smart52d52442011-05-24 11:42:45 -04001511 * Request SLI4 interface type-2 device to perform a physical register set
1512 * access.
James Smartc0c11512011-05-24 11:41:34 -04001513 *
1514 * Returns:
1515 * zero for success
1516 **/
1517static ssize_t
James Smart52d52442011-05-24 11:42:45 -04001518lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
James Smartc0c11512011-05-24 11:41:34 -04001519{
1520 struct completion online_compl;
James Smartb76f2dc2011-07-22 18:37:42 -04001521 struct pci_dev *pdev = phba->pcidev;
James Smart026abb82011-12-13 13:20:45 -05001522 uint32_t before_fc_flag;
1523 uint32_t sriov_nr_virtfn;
James Smartc0c11512011-05-24 11:41:34 -04001524 uint32_t reg_val;
James Smart026abb82011-12-13 13:20:45 -05001525 int status = 0, rc = 0;
1526 int job_posted = 1, sriov_err;
James Smartc0c11512011-05-24 11:41:34 -04001527
1528 if (!phba->cfg_enable_hba_reset)
James Smartf7a919b2011-08-21 21:49:16 -04001529 return -EACCES;
James Smartc0c11512011-05-24 11:41:34 -04001530
James Smart52d52442011-05-24 11:42:45 -04001531 if ((phba->sli_rev < LPFC_SLI_REV4) ||
James Smart719162b2018-12-10 19:37:01 -08001532 (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
James Smart52d52442011-05-24 11:42:45 -04001533 LPFC_SLI_INTF_IF_TYPE_2))
1534 return -EPERM;
1535
James Smart026abb82011-12-13 13:20:45 -05001536 /* Keep state if we need to restore back */
1537 before_fc_flag = phba->pport->fc_flag;
1538 sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn;
1539
James Smartb76f2dc2011-07-22 18:37:42 -04001540 /* Disable SR-IOV virtual functions if enabled */
1541 if (phba->cfg_sriov_nr_virtfn) {
1542 pci_disable_sriov(pdev);
1543 phba->cfg_sriov_nr_virtfn = 0;
1544 }
James Smart229adb02013-04-17 20:16:51 -04001545
James Smart02936352014-04-04 13:52:12 -04001546 if (opcode == LPFC_FW_DUMP)
1547 phba->hba_flag |= HBA_FW_DUMP_OP;
1548
James Smartc0c11512011-05-24 11:41:34 -04001549 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
1550
James Smart02936352014-04-04 13:52:12 -04001551 if (status != 0) {
1552 phba->hba_flag &= ~HBA_FW_DUMP_OP;
James Smartc0c11512011-05-24 11:41:34 -04001553 return status;
James Smart02936352014-04-04 13:52:12 -04001554 }
James Smartc0c11512011-05-24 11:41:34 -04001555
1556 /* wait for the device to be quiesced before firmware reset */
1557 msleep(100);
1558
1559 reg_val = readl(phba->sli4_hba.conf_regs_memmap_p +
1560 LPFC_CTL_PDEV_CTL_OFFSET);
James Smart52d52442011-05-24 11:42:45 -04001561
1562 if (opcode == LPFC_FW_DUMP)
1563 reg_val |= LPFC_FW_DUMP_REQUEST;
1564 else if (opcode == LPFC_FW_RESET)
1565 reg_val |= LPFC_CTL_PDEV_CTL_FRST;
1566 else if (opcode == LPFC_DV_RESET)
1567 reg_val |= LPFC_CTL_PDEV_CTL_DRST;
1568
James Smartc0c11512011-05-24 11:41:34 -04001569 writel(reg_val, phba->sli4_hba.conf_regs_memmap_p +
1570 LPFC_CTL_PDEV_CTL_OFFSET);
1571 /* flush */
1572 readl(phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET);
1573
1574 /* delay driver action following IF_TYPE_2 reset */
James Smart88a2cfb2011-07-22 18:36:33 -04001575 rc = lpfc_sli4_pdev_status_reg_wait(phba);
1576
James Smart026abb82011-12-13 13:20:45 -05001577 if (rc == -EPERM) {
Masanari Iida0b1587b2013-07-17 04:37:44 +09001578 /* no privilege for reset */
James Smart6b5151f2012-01-18 16:24:06 -05001579 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
Masanari Iida0b1587b2013-07-17 04:37:44 +09001580 "3150 No privilege to perform the requested "
James Smart6b5151f2012-01-18 16:24:06 -05001581 "access: x%x\n", reg_val);
James Smart026abb82011-12-13 13:20:45 -05001582 } else if (rc == -EIO) {
1583 /* reset failed, there is nothing more we can do */
James Smart6b5151f2012-01-18 16:24:06 -05001584 lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
1585 "3153 Fail to perform the requested "
1586 "access: x%x\n", reg_val);
James Smartf7a919b2011-08-21 21:49:16 -04001587 return rc;
James Smart026abb82011-12-13 13:20:45 -05001588 }
1589
1590 /* keep the original port state */
1591 if (before_fc_flag & FC_OFFLINE_MODE)
1592 goto out;
James Smartc0c11512011-05-24 11:41:34 -04001593
1594 init_completion(&online_compl);
James Smart026abb82011-12-13 13:20:45 -05001595 job_posted = lpfc_workq_post_event(phba, &status, &online_compl,
1596 LPFC_EVT_ONLINE);
1597 if (!job_posted)
1598 goto out;
James Smartc0c11512011-05-24 11:41:34 -04001599
1600 wait_for_completion(&online_compl);
1601
James Smart026abb82011-12-13 13:20:45 -05001602out:
1603 /* in any case, restore the virtual functions enabled as before */
1604 if (sriov_nr_virtfn) {
1605 sriov_err =
1606 lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn);
1607 if (!sriov_err)
1608 phba->cfg_sriov_nr_virtfn = sriov_nr_virtfn;
1609 }
James Smartc0c11512011-05-24 11:41:34 -04001610
James Smart026abb82011-12-13 13:20:45 -05001611 /* return proper error code */
1612 if (!rc) {
1613 if (!job_posted)
1614 rc = -ENOMEM;
1615 else if (status)
1616 rc = -EIO;
1617 }
1618 return rc;
James Smartc0c11512011-05-24 11:41:34 -04001619}
1620
1621/**
James Smart3621a712009-04-06 18:47:14 -04001622 * lpfc_nport_evt_cnt_show - Return the number of nport events
James Smarte59058c2008-08-24 21:49:00 -04001623 * @dev: class device that is converted into a Scsi_host.
1624 * @attr: device attribute, not used.
1625 * @buf: on return contains the ascii number of nport events.
1626 *
1627 * Returns: size of formatted string.
1628 **/
dea31012005-04-17 16:05:31 -05001629static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001630lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr,
1631 char *buf)
dea31012005-04-17 16:05:31 -05001632{
Tony Jonesee959b02008-02-22 00:13:36 +01001633 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001634 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1635 struct lpfc_hba *phba = vport->phba;
1636
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001637 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
dea31012005-04-17 16:05:31 -05001638}
1639
Bart Van Assche3999df72019-03-28 11:06:16 -07001640static int
James Smart1dc5ec22018-10-23 13:41:11 -07001641lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out)
1642{
1643 LPFC_MBOXQ_t *mbox = NULL;
1644 unsigned long val = 0;
1645 char *pval = 0;
1646 int rc = 0;
1647
1648 if (!strncmp("enable", buff_out,
1649 strlen("enable"))) {
1650 pval = buff_out + strlen("enable") + 1;
1651 rc = kstrtoul(pval, 0, &val);
1652 if (rc)
1653 return rc; /* Invalid number */
1654 } else if (!strncmp("disable", buff_out,
1655 strlen("disable"))) {
1656 val = 0;
1657 } else {
1658 return -EINVAL; /* Invalid command */
1659 }
1660
1661 switch (val) {
1662 case 0:
1663 val = 0x0; /* Disable */
1664 break;
1665 case 2:
1666 val = 0x1; /* Enable two port trunk */
1667 break;
1668 case 4:
1669 val = 0x2; /* Enable four port trunk */
1670 break;
1671 default:
1672 return -EINVAL;
1673 }
1674
1675 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1676 "0070 Set trunk mode with val %ld ", val);
1677
1678 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1679 if (!mbox)
1680 return -ENOMEM;
1681
1682 lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
1683 LPFC_MBOX_OPCODE_FCOE_FC_SET_TRUNK_MODE,
1684 12, LPFC_SLI4_MBX_EMBED);
1685
1686 bf_set(lpfc_mbx_set_trunk_mode,
1687 &mbox->u.mqe.un.set_trunk_mode,
1688 val);
1689 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
1690 if (rc)
1691 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1692 "0071 Set trunk mode failed with status: %d",
1693 rc);
1694 if (rc != MBX_TIMEOUT)
1695 mempool_free(mbox, phba->mbox_mem_pool);
1696
1697 return 0;
1698}
1699
James Smarte59058c2008-08-24 21:49:00 -04001700/**
James Smart3621a712009-04-06 18:47:14 -04001701 * lpfc_board_mode_show - Return the state of the board
James Smarte59058c2008-08-24 21:49:00 -04001702 * @dev: class device that is converted into a Scsi_host.
1703 * @attr: device attribute, not used.
1704 * @buf: on return contains the state of the adapter.
1705 *
1706 * Returns: size of formatted string.
1707 **/
dea31012005-04-17 16:05:31 -05001708static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001709lpfc_board_mode_show(struct device *dev, struct device_attribute *attr,
1710 char *buf)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001711{
Tony Jonesee959b02008-02-22 00:13:36 +01001712 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001713 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1714 struct lpfc_hba *phba = vport->phba;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001715 char * state;
1716
James Smart2e0fef82007-06-17 19:56:36 -05001717 if (phba->link_state == LPFC_HBA_ERROR)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001718 state = "error";
James Smart2e0fef82007-06-17 19:56:36 -05001719 else if (phba->link_state == LPFC_WARM_START)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001720 state = "warm start";
James Smart2e0fef82007-06-17 19:56:36 -05001721 else if (phba->link_state == LPFC_INIT_START)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001722 state = "offline";
1723 else
1724 state = "online";
1725
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001726 return scnprintf(buf, PAGE_SIZE, "%s\n", state);
Jamie Wellnitz41415862006-02-28 19:25:27 -05001727}
1728
James Smarte59058c2008-08-24 21:49:00 -04001729/**
James Smart3621a712009-04-06 18:47:14 -04001730 * lpfc_board_mode_store - Puts the hba in online, offline, warm or error state
James Smarte59058c2008-08-24 21:49:00 -04001731 * @dev: class device that is converted into a Scsi_host.
1732 * @attr: device attribute, not used.
1733 * @buf: containing one of the strings "online", "offline", "warm" or "error".
1734 * @count: unused variable.
1735 *
1736 * Returns:
1737 * -EACCES if enable hba reset not enabled
1738 * -EINVAL if the buffer does not contain a valid string (see above)
1739 * -EIO if lpfc_workq_post_event() or lpfc_do_offline() fails
1740 * buf length greater than zero indicates success
1741 **/
Jamie Wellnitz41415862006-02-28 19:25:27 -05001742static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001743lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
1744 const char *buf, size_t count)
Jamie Wellnitz41415862006-02-28 19:25:27 -05001745{
Tony Jonesee959b02008-02-22 00:13:36 +01001746 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05001747 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1748 struct lpfc_hba *phba = vport->phba;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001749 struct completion online_compl;
James Smart026abb82011-12-13 13:20:45 -05001750 char *board_mode_str = NULL;
1751 int status = 0;
James Smartfedd3b72011-02-16 12:39:24 -05001752 int rc;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001753
James Smart026abb82011-12-13 13:20:45 -05001754 if (!phba->cfg_enable_hba_reset) {
1755 status = -EACCES;
1756 goto board_mode_out;
1757 }
James Smart88a2cfb2011-07-22 18:36:33 -04001758
1759 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart026abb82011-12-13 13:20:45 -05001760 "3050 lpfc_board_mode set to %s\n", buf);
James Smart88a2cfb2011-07-22 18:36:33 -04001761
Jamie Wellnitz41415862006-02-28 19:25:27 -05001762 init_completion(&online_compl);
1763
James Smart46fa3112007-04-25 09:51:45 -04001764 if(strncmp(buf, "online", sizeof("online") - 1) == 0) {
James Smartfedd3b72011-02-16 12:39:24 -05001765 rc = lpfc_workq_post_event(phba, &status, &online_compl,
Jamie Wellnitz41415862006-02-28 19:25:27 -05001766 LPFC_EVT_ONLINE);
James Smart026abb82011-12-13 13:20:45 -05001767 if (rc == 0) {
1768 status = -ENOMEM;
1769 goto board_mode_out;
1770 }
James Smart46fa3112007-04-25 09:51:45 -04001771 wait_for_completion(&online_compl);
James Smart522dcee2017-06-01 21:07:03 -07001772 if (status)
1773 status = -EIO;
James Smart46fa3112007-04-25 09:51:45 -04001774 } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
1775 status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
Jamie Wellnitz41415862006-02-28 19:25:27 -05001776 else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0)
James Smart6a9c52c2009-10-02 15:16:51 -04001777 if (phba->sli_rev == LPFC_SLI_REV4)
James Smart026abb82011-12-13 13:20:45 -05001778 status = -EINVAL;
James Smart6a9c52c2009-10-02 15:16:51 -04001779 else
1780 status = lpfc_do_offline(phba, LPFC_EVT_WARM_START);
James Smart46fa3112007-04-25 09:51:45 -04001781 else if (strncmp(buf, "error", sizeof("error") - 1) == 0)
James Smart6a9c52c2009-10-02 15:16:51 -04001782 if (phba->sli_rev == LPFC_SLI_REV4)
James Smart026abb82011-12-13 13:20:45 -05001783 status = -EINVAL;
James Smart6a9c52c2009-10-02 15:16:51 -04001784 else
1785 status = lpfc_do_offline(phba, LPFC_EVT_KILL);
James Smartc0c11512011-05-24 11:41:34 -04001786 else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0)
James Smart52d52442011-05-24 11:42:45 -04001787 status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_DUMP);
1788 else if (strncmp(buf, "fw_reset", sizeof("fw_reset") - 1) == 0)
1789 status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_RESET);
1790 else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0)
1791 status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET);
James Smart50212672018-12-13 15:17:57 -08001792 else if (strncmp(buf, "pci_bus_reset", sizeof("pci_bus_reset") - 1)
1793 == 0)
1794 status = lpfc_reset_pci_bus(phba);
James Smart1dc5ec22018-10-23 13:41:11 -07001795 else if (strncmp(buf, "trunk", sizeof("trunk") - 1) == 0)
1796 status = lpfc_set_trunking(phba, (char *)buf + sizeof("trunk"));
Jamie Wellnitz41415862006-02-28 19:25:27 -05001797 else
James Smart026abb82011-12-13 13:20:45 -05001798 status = -EINVAL;
Jamie Wellnitz41415862006-02-28 19:25:27 -05001799
James Smart026abb82011-12-13 13:20:45 -05001800board_mode_out:
Jamie Wellnitz41415862006-02-28 19:25:27 -05001801 if (!status)
1802 return strlen(buf);
James Smart026abb82011-12-13 13:20:45 -05001803 else {
1804 board_mode_str = strchr(buf, '\n');
1805 if (board_mode_str)
1806 *board_mode_str = '\0';
1807 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1808 "3097 Failed \"%s\", status(%d), "
1809 "fc_flag(x%x)\n",
1810 buf, status, phba->pport->fc_flag);
James Smartf7a919b2011-08-21 21:49:16 -04001811 return status;
James Smart026abb82011-12-13 13:20:45 -05001812 }
Jamie Wellnitz41415862006-02-28 19:25:27 -05001813}
1814
James Smarte59058c2008-08-24 21:49:00 -04001815/**
James Smart3621a712009-04-06 18:47:14 -04001816 * lpfc_get_hba_info - Return various bits of informaton about the adapter
James Smarte59058c2008-08-24 21:49:00 -04001817 * @phba: pointer to the adapter structure.
James Smart3621a712009-04-06 18:47:14 -04001818 * @mxri: max xri count.
1819 * @axri: available xri count.
1820 * @mrpi: max rpi count.
1821 * @arpi: available rpi count.
1822 * @mvpi: max vpi count.
1823 * @avpi: available vpi count.
James Smarte59058c2008-08-24 21:49:00 -04001824 *
1825 * Description:
1826 * If an integer pointer for an count is not null then the value for the
1827 * count is returned.
1828 *
1829 * Returns:
1830 * zero on error
1831 * one for success
1832 **/
James Smart311464e2007-08-02 11:10:37 -04001833static int
James Smart858c9f62007-06-17 19:56:39 -05001834lpfc_get_hba_info(struct lpfc_hba *phba,
1835 uint32_t *mxri, uint32_t *axri,
1836 uint32_t *mrpi, uint32_t *arpi,
1837 uint32_t *mvpi, uint32_t *avpi)
James Smart92d7f7b2007-06-17 19:56:38 -05001838{
James Smart04c68492009-05-22 14:52:52 -04001839 struct lpfc_mbx_read_config *rd_config;
James Smart92d7f7b2007-06-17 19:56:38 -05001840 LPFC_MBOXQ_t *pmboxq;
1841 MAILBOX_t *pmb;
1842 int rc = 0;
James Smart15672312010-04-06 14:49:03 -04001843 uint32_t max_vpi;
James Smart92d7f7b2007-06-17 19:56:38 -05001844
1845 /*
1846 * prevent udev from issuing mailbox commands until the port is
1847 * configured.
1848 */
1849 if (phba->link_state < LPFC_LINK_DOWN ||
1850 !phba->mbox_mem_pool ||
James Smartf4b4c682009-05-22 14:53:12 -04001851 (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
James Smart92d7f7b2007-06-17 19:56:38 -05001852 return 0;
1853
1854 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
1855 return 0;
1856
1857 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1858 if (!pmboxq)
1859 return 0;
1860 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
1861
James Smart04c68492009-05-22 14:52:52 -04001862 pmb = &pmboxq->u.mb;
James Smart92d7f7b2007-06-17 19:56:38 -05001863 pmb->mbxCommand = MBX_READ_CONFIG;
1864 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08001865 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05001866
James Smart75baf692010-06-08 18:31:21 -04001867 if (phba->pport->fc_flag & FC_OFFLINE_MODE)
James Smart92d7f7b2007-06-17 19:56:38 -05001868 rc = MBX_NOT_FINISHED;
1869 else
1870 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
1871
1872 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05001873 if (rc != MBX_TIMEOUT)
James Smart92d7f7b2007-06-17 19:56:38 -05001874 mempool_free(pmboxq, phba->mbox_mem_pool);
1875 return 0;
1876 }
1877
James Smartda0436e2009-05-22 14:51:39 -04001878 if (phba->sli_rev == LPFC_SLI_REV4) {
1879 rd_config = &pmboxq->u.mqe.un.rd_config;
1880 if (mrpi)
1881 *mrpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config);
1882 if (arpi)
1883 *arpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config) -
1884 phba->sli4_hba.max_cfg_param.rpi_used;
1885 if (mxri)
1886 *mxri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
1887 if (axri)
1888 *axri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config) -
1889 phba->sli4_hba.max_cfg_param.xri_used;
James Smart15672312010-04-06 14:49:03 -04001890
1891 /* Account for differences with SLI-3. Get vpi count from
1892 * mailbox data and subtract one for max vpi value.
1893 */
1894 max_vpi = (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) > 0) ?
1895 (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) - 1) : 0;
1896
James Smart8b47ae62018-11-29 16:09:33 -08001897 /* Limit the max we support */
1898 if (max_vpi > LPFC_MAX_VPI)
1899 max_vpi = LPFC_MAX_VPI;
James Smartda0436e2009-05-22 14:51:39 -04001900 if (mvpi)
James Smart15672312010-04-06 14:49:03 -04001901 *mvpi = max_vpi;
James Smartda0436e2009-05-22 14:51:39 -04001902 if (avpi)
James Smart15672312010-04-06 14:49:03 -04001903 *avpi = max_vpi - phba->sli4_hba.max_cfg_param.vpi_used;
James Smartda0436e2009-05-22 14:51:39 -04001904 } else {
1905 if (mrpi)
1906 *mrpi = pmb->un.varRdConfig.max_rpi;
1907 if (arpi)
1908 *arpi = pmb->un.varRdConfig.avail_rpi;
1909 if (mxri)
1910 *mxri = pmb->un.varRdConfig.max_xri;
1911 if (axri)
1912 *axri = pmb->un.varRdConfig.avail_xri;
1913 if (mvpi)
1914 *mvpi = pmb->un.varRdConfig.max_vpi;
James Smart8b47ae62018-11-29 16:09:33 -08001915 if (avpi) {
1916 /* avail_vpi is only valid if link is up and ready */
1917 if (phba->link_state == LPFC_HBA_READY)
1918 *avpi = pmb->un.varRdConfig.avail_vpi;
1919 else
1920 *avpi = pmb->un.varRdConfig.max_vpi;
1921 }
James Smartda0436e2009-05-22 14:51:39 -04001922 }
James Smart92d7f7b2007-06-17 19:56:38 -05001923
1924 mempool_free(pmboxq, phba->mbox_mem_pool);
1925 return 1;
1926}
1927
James Smarte59058c2008-08-24 21:49:00 -04001928/**
James Smart3621a712009-04-06 18:47:14 -04001929 * lpfc_max_rpi_show - Return maximum rpi
James Smarte59058c2008-08-24 21:49:00 -04001930 * @dev: class device that is converted into a Scsi_host.
1931 * @attr: device attribute, not used.
1932 * @buf: on return contains the maximum rpi count in decimal or "Unknown".
1933 *
1934 * Description:
1935 * Calls lpfc_get_hba_info() asking for just the mrpi count.
1936 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1937 * to "Unknown" and the buffer length is returned, therefore the caller
1938 * must check for "Unknown" in the buffer to detect a failure.
1939 *
1940 * Returns: size of formatted string.
1941 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001942static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001943lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr,
1944 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001945{
Tony Jonesee959b02008-02-22 00:13:36 +01001946 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05001947 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1948 struct lpfc_hba *phba = vport->phba;
1949 uint32_t cnt;
1950
James Smart858c9f62007-06-17 19:56:39 -05001951 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001952 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
1953 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001954}
1955
James Smarte59058c2008-08-24 21:49:00 -04001956/**
James Smart3621a712009-04-06 18:47:14 -04001957 * lpfc_used_rpi_show - Return maximum rpi minus available rpi
James Smarte59058c2008-08-24 21:49:00 -04001958 * @dev: class device that is converted into a Scsi_host.
1959 * @attr: device attribute, not used.
1960 * @buf: containing the used rpi count in decimal or "Unknown".
1961 *
1962 * Description:
1963 * Calls lpfc_get_hba_info() asking for just the mrpi and arpi counts.
1964 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1965 * to "Unknown" and the buffer length is returned, therefore the caller
1966 * must check for "Unknown" in the buffer to detect a failure.
1967 *
1968 * Returns: size of formatted string.
1969 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001970static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001971lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr,
1972 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05001973{
Tony Jonesee959b02008-02-22 00:13:36 +01001974 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05001975 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
1976 struct lpfc_hba *phba = vport->phba;
1977 uint32_t cnt, acnt;
1978
James Smart858c9f62007-06-17 19:56:39 -05001979 if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07001980 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
1981 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001982}
1983
James Smarte59058c2008-08-24 21:49:00 -04001984/**
James Smart3621a712009-04-06 18:47:14 -04001985 * lpfc_max_xri_show - Return maximum xri
James Smarte59058c2008-08-24 21:49:00 -04001986 * @dev: class device that is converted into a Scsi_host.
1987 * @attr: device attribute, not used.
1988 * @buf: on return contains the maximum xri count in decimal or "Unknown".
1989 *
1990 * Description:
1991 * Calls lpfc_get_hba_info() asking for just the mrpi count.
1992 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
1993 * to "Unknown" and the buffer length is returned, therefore the caller
1994 * must check for "Unknown" in the buffer to detect a failure.
1995 *
1996 * Returns: size of formatted string.
1997 **/
James Smart92d7f7b2007-06-17 19:56:38 -05001998static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01001999lpfc_max_xri_show(struct device *dev, struct device_attribute *attr,
2000 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05002001{
Tony Jonesee959b02008-02-22 00:13:36 +01002002 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05002003 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2004 struct lpfc_hba *phba = vport->phba;
2005 uint32_t cnt;
2006
James Smart858c9f62007-06-17 19:56:39 -05002007 if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002008 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
2009 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002010}
2011
James Smarte59058c2008-08-24 21:49:00 -04002012/**
James Smart3621a712009-04-06 18:47:14 -04002013 * lpfc_used_xri_show - Return maximum xpi minus the available xpi
James Smarte59058c2008-08-24 21:49:00 -04002014 * @dev: class device that is converted into a Scsi_host.
2015 * @attr: device attribute, not used.
2016 * @buf: on return contains the used xri count in decimal or "Unknown".
2017 *
2018 * Description:
2019 * Calls lpfc_get_hba_info() asking for just the mxri and axri counts.
2020 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2021 * to "Unknown" and the buffer length is returned, therefore the caller
2022 * must check for "Unknown" in the buffer to detect a failure.
2023 *
2024 * Returns: size of formatted string.
2025 **/
James Smart92d7f7b2007-06-17 19:56:38 -05002026static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002027lpfc_used_xri_show(struct device *dev, struct device_attribute *attr,
2028 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05002029{
Tony Jonesee959b02008-02-22 00:13:36 +01002030 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05002031 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2032 struct lpfc_hba *phba = vport->phba;
2033 uint32_t cnt, acnt;
2034
James Smart858c9f62007-06-17 19:56:39 -05002035 if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL, NULL, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002036 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
2037 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart858c9f62007-06-17 19:56:39 -05002038}
2039
James Smarte59058c2008-08-24 21:49:00 -04002040/**
James Smart3621a712009-04-06 18:47:14 -04002041 * lpfc_max_vpi_show - Return maximum vpi
James Smarte59058c2008-08-24 21:49:00 -04002042 * @dev: class device that is converted into a Scsi_host.
2043 * @attr: device attribute, not used.
2044 * @buf: on return contains the maximum vpi count in decimal or "Unknown".
2045 *
2046 * Description:
2047 * Calls lpfc_get_hba_info() asking for just the mvpi count.
2048 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2049 * to "Unknown" and the buffer length is returned, therefore the caller
2050 * must check for "Unknown" in the buffer to detect a failure.
2051 *
2052 * Returns: size of formatted string.
2053 **/
James Smart858c9f62007-06-17 19:56:39 -05002054static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002055lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr,
2056 char *buf)
James Smart858c9f62007-06-17 19:56:39 -05002057{
Tony Jonesee959b02008-02-22 00:13:36 +01002058 struct Scsi_Host *shost = class_to_shost(dev);
James Smart858c9f62007-06-17 19:56:39 -05002059 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2060 struct lpfc_hba *phba = vport->phba;
2061 uint32_t cnt;
2062
2063 if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, NULL))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002064 return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
2065 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart858c9f62007-06-17 19:56:39 -05002066}
2067
James Smarte59058c2008-08-24 21:49:00 -04002068/**
James Smart3621a712009-04-06 18:47:14 -04002069 * lpfc_used_vpi_show - Return maximum vpi minus the available vpi
James Smarte59058c2008-08-24 21:49:00 -04002070 * @dev: class device that is converted into a Scsi_host.
2071 * @attr: device attribute, not used.
2072 * @buf: on return contains the used vpi count in decimal or "Unknown".
2073 *
2074 * Description:
2075 * Calls lpfc_get_hba_info() asking for just the mvpi and avpi counts.
2076 * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
2077 * to "Unknown" and the buffer length is returned, therefore the caller
2078 * must check for "Unknown" in the buffer to detect a failure.
2079 *
2080 * Returns: size of formatted string.
2081 **/
James Smart858c9f62007-06-17 19:56:39 -05002082static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002083lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr,
2084 char *buf)
James Smart858c9f62007-06-17 19:56:39 -05002085{
Tony Jonesee959b02008-02-22 00:13:36 +01002086 struct Scsi_Host *shost = class_to_shost(dev);
James Smart858c9f62007-06-17 19:56:39 -05002087 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2088 struct lpfc_hba *phba = vport->phba;
2089 uint32_t cnt, acnt;
2090
2091 if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, &acnt))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002092 return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
2093 return scnprintf(buf, PAGE_SIZE, "Unknown\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002094}
2095
James Smarte59058c2008-08-24 21:49:00 -04002096/**
James Smart3621a712009-04-06 18:47:14 -04002097 * lpfc_npiv_info_show - Return text about NPIV support for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002098 * @dev: class device that is converted into a Scsi_host.
2099 * @attr: device attribute, not used.
2100 * @buf: text that must be interpreted to determine if npiv is supported.
2101 *
2102 * Description:
2103 * Buffer will contain text indicating npiv is not suppoerted on the port,
2104 * the port is an NPIV physical port, or it is an npiv virtual port with
2105 * the id of the vport.
2106 *
2107 * Returns: size of formatted string.
2108 **/
James Smart92d7f7b2007-06-17 19:56:38 -05002109static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002110lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr,
2111 char *buf)
James Smart92d7f7b2007-06-17 19:56:38 -05002112{
Tony Jonesee959b02008-02-22 00:13:36 +01002113 struct Scsi_Host *shost = class_to_shost(dev);
James Smart92d7f7b2007-06-17 19:56:38 -05002114 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2115 struct lpfc_hba *phba = vport->phba;
2116
2117 if (!(phba->max_vpi))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002118 return scnprintf(buf, PAGE_SIZE, "NPIV Not Supported\n");
James Smart92d7f7b2007-06-17 19:56:38 -05002119 if (vport->port_type == LPFC_PHYSICAL_PORT)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002120 return scnprintf(buf, PAGE_SIZE, "NPIV Physical\n");
2121 return scnprintf(buf, PAGE_SIZE, "NPIV Virtual (VPI %d)\n", vport->vpi);
James Smart92d7f7b2007-06-17 19:56:38 -05002122}
2123
James Smarte59058c2008-08-24 21:49:00 -04002124/**
James Smart3621a712009-04-06 18:47:14 -04002125 * lpfc_poll_show - Return text about poll support for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002126 * @dev: class device that is converted into a Scsi_host.
2127 * @attr: device attribute, not used.
2128 * @buf: on return contains the cfg_poll in hex.
2129 *
2130 * Notes:
2131 * cfg_poll should be a lpfc_polling_flags type.
2132 *
2133 * Returns: size of formatted string.
2134 **/
Jamie Wellnitz41415862006-02-28 19:25:27 -05002135static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002136lpfc_poll_show(struct device *dev, struct device_attribute *attr,
2137 char *buf)
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002138{
Tony Jonesee959b02008-02-22 00:13:36 +01002139 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05002140 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2141 struct lpfc_hba *phba = vport->phba;
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002142
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002143 return scnprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002144}
2145
James Smarte59058c2008-08-24 21:49:00 -04002146/**
James Smart3621a712009-04-06 18:47:14 -04002147 * lpfc_poll_store - Set the value of cfg_poll for the adapter
James Smarte59058c2008-08-24 21:49:00 -04002148 * @dev: class device that is converted into a Scsi_host.
2149 * @attr: device attribute, not used.
2150 * @buf: one or more lpfc_polling_flags values.
2151 * @count: not used.
2152 *
2153 * Notes:
2154 * buf contents converted to integer and checked for a valid value.
2155 *
2156 * Returns:
2157 * -EINVAL if the buffer connot be converted or is out of range
2158 * length of the buf on success
2159 **/
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002160static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01002161lpfc_poll_store(struct device *dev, struct device_attribute *attr,
2162 const char *buf, size_t count)
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002163{
Tony Jonesee959b02008-02-22 00:13:36 +01002164 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05002165 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2166 struct lpfc_hba *phba = vport->phba;
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002167 uint32_t creg_val;
2168 uint32_t old_val;
2169 int val=0;
2170
2171 if (!isdigit(buf[0]))
2172 return -EINVAL;
2173
2174 if (sscanf(buf, "%i", &val) != 1)
2175 return -EINVAL;
2176
2177 if ((val & 0x3) != val)
2178 return -EINVAL;
2179
James Smart45ed1192009-10-02 15:17:02 -04002180 if (phba->sli_rev == LPFC_SLI_REV4)
2181 val = 0;
2182
James Smart88a2cfb2011-07-22 18:36:33 -04002183 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
2184 "3051 lpfc_poll changed from %d to %d\n",
2185 phba->cfg_poll, val);
2186
James Smart2e0fef82007-06-17 19:56:36 -05002187 spin_lock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002188
2189 old_val = phba->cfg_poll;
2190
2191 if (val & ENABLE_FCP_RING_POLLING) {
2192 if ((val & DISABLE_FCP_RING_INT) &&
2193 !(old_val & DISABLE_FCP_RING_INT)) {
James Smart9940b972011-03-11 16:06:12 -05002194 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
2195 spin_unlock_irq(&phba->hbalock);
2196 return -EINVAL;
2197 }
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002198 creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
2199 writel(creg_val, phba->HCregaddr);
2200 readl(phba->HCregaddr); /* flush */
2201
2202 lpfc_poll_start_timer(phba);
2203 }
2204 } else if (val != 0x0) {
James Smart2e0fef82007-06-17 19:56:36 -05002205 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002206 return -EINVAL;
2207 }
2208
2209 if (!(val & DISABLE_FCP_RING_INT) &&
2210 (old_val & DISABLE_FCP_RING_INT))
2211 {
James Smart2e0fef82007-06-17 19:56:36 -05002212 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002213 del_timer(&phba->fcp_poll_timer);
James Smart2e0fef82007-06-17 19:56:36 -05002214 spin_lock_irq(&phba->hbalock);
James Smart9940b972011-03-11 16:06:12 -05002215 if (lpfc_readl(phba->HCregaddr, &creg_val)) {
2216 spin_unlock_irq(&phba->hbalock);
2217 return -EINVAL;
2218 }
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002219 creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
2220 writel(creg_val, phba->HCregaddr);
2221 readl(phba->HCregaddr); /* flush */
2222 }
2223
2224 phba->cfg_poll = val;
2225
James Smart2e0fef82007-06-17 19:56:36 -05002226 spin_unlock_irq(&phba->hbalock);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05002227
2228 return strlen(buf);
2229}
dea31012005-04-17 16:05:31 -05002230
James Smarte59058c2008-08-24 21:49:00 -04002231/**
James Smartbc739052010-08-04 16:11:18 -04002232 * lpfc_fips_level_show - Return the current FIPS level for the HBA
2233 * @dev: class unused variable.
2234 * @attr: device attribute, not used.
2235 * @buf: on return contains the module description text.
2236 *
2237 * Returns: size of formatted string.
2238 **/
2239static ssize_t
2240lpfc_fips_level_show(struct device *dev, struct device_attribute *attr,
2241 char *buf)
2242{
2243 struct Scsi_Host *shost = class_to_shost(dev);
2244 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2245 struct lpfc_hba *phba = vport->phba;
2246
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002247 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->fips_level);
James Smartbc739052010-08-04 16:11:18 -04002248}
2249
2250/**
2251 * lpfc_fips_rev_show - Return the FIPS Spec revision for the HBA
2252 * @dev: class unused variable.
2253 * @attr: device attribute, not used.
2254 * @buf: on return contains the module description text.
2255 *
2256 * Returns: size of formatted string.
2257 **/
2258static ssize_t
2259lpfc_fips_rev_show(struct device *dev, struct device_attribute *attr,
2260 char *buf)
2261{
2262 struct Scsi_Host *shost = class_to_shost(dev);
2263 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2264 struct lpfc_hba *phba = vport->phba;
2265
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002266 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->fips_spec_rev);
James Smartbc739052010-08-04 16:11:18 -04002267}
2268
2269/**
James Smartab56dc22011-02-16 12:39:57 -05002270 * lpfc_dss_show - Return the current state of dss and the configured state
2271 * @dev: class converted to a Scsi_host structure.
2272 * @attr: device attribute, not used.
2273 * @buf: on return contains the formatted text.
2274 *
2275 * Returns: size of formatted string.
2276 **/
2277static ssize_t
2278lpfc_dss_show(struct device *dev, struct device_attribute *attr,
2279 char *buf)
2280{
2281 struct Scsi_Host *shost = class_to_shost(dev);
2282 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2283 struct lpfc_hba *phba = vport->phba;
2284
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002285 return scnprintf(buf, PAGE_SIZE, "%s - %sOperational\n",
James Smartab56dc22011-02-16 12:39:57 -05002286 (phba->cfg_enable_dss) ? "Enabled" : "Disabled",
2287 (phba->sli3_options & LPFC_SLI3_DSS_ENABLED) ?
2288 "" : "Not ");
2289}
2290
2291/**
James Smart912e3ac2011-05-24 11:42:11 -04002292 * lpfc_sriov_hw_max_virtfn_show - Return maximum number of virtual functions
2293 * @dev: class converted to a Scsi_host structure.
2294 * @attr: device attribute, not used.
2295 * @buf: on return contains the formatted support level.
2296 *
2297 * Description:
2298 * Returns the maximum number of virtual functions a physical function can
2299 * support, 0 will be returned if called on virtual function.
2300 *
2301 * Returns: size of formatted string.
2302 **/
2303static ssize_t
2304lpfc_sriov_hw_max_virtfn_show(struct device *dev,
2305 struct device_attribute *attr,
2306 char *buf)
2307{
2308 struct Scsi_Host *shost = class_to_shost(dev);
2309 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2310 struct lpfc_hba *phba = vport->phba;
James Smart0a96e972011-07-22 18:37:28 -04002311 uint16_t max_nr_virtfn;
James Smart912e3ac2011-05-24 11:42:11 -04002312
James Smart0a96e972011-07-22 18:37:28 -04002313 max_nr_virtfn = lpfc_sli_sriov_nr_virtfn_get(phba);
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002314 return scnprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn);
James Smart912e3ac2011-05-24 11:42:11 -04002315}
2316
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002317static inline bool lpfc_rangecheck(uint val, uint min, uint max)
2318{
2319 return val >= min && val <= max;
2320}
2321
James Smart912e3ac2011-05-24 11:42:11 -04002322/**
James Smart44fd7fe2017-08-23 16:55:47 -07002323 * lpfc_enable_bbcr_set: Sets an attribute value.
2324 * @phba: pointer the the adapter structure.
2325 * @val: integer attribute value.
2326 *
2327 * Description:
2328 * Validates the min and max values then sets the
2329 * adapter config field if in the valid range. prints error message
2330 * and does not set the parameter if invalid.
2331 *
2332 * Returns:
2333 * zero on success
2334 * -EINVAL if val is invalid
2335 */
2336static ssize_t
2337lpfc_enable_bbcr_set(struct lpfc_hba *phba, uint val)
2338{
2339 if (lpfc_rangecheck(val, 0, 1) && phba->sli_rev == LPFC_SLI_REV4) {
2340 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2341 "3068 %s_enable_bbcr changed from %d to %d\n",
2342 LPFC_DRIVER_NAME, phba->cfg_enable_bbcr, val);
2343 phba->cfg_enable_bbcr = val;
2344 return 0;
2345 }
2346 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2347 "0451 %s_enable_bbcr cannot set to %d, range is 0, 1\n",
2348 LPFC_DRIVER_NAME, val);
2349 return -EINVAL;
2350}
2351
2352/**
James Smart3621a712009-04-06 18:47:14 -04002353 * lpfc_param_show - Return a cfg attribute value in decimal
James Smarte59058c2008-08-24 21:49:00 -04002354 *
2355 * Description:
2356 * Macro that given an attr e.g. hba_queue_depth expands
2357 * into a function with the name lpfc_hba_queue_depth_show.
2358 *
2359 * lpfc_##attr##_show: Return the decimal value of an adapters cfg_xxx field.
2360 * @dev: class device that is converted into a Scsi_host.
2361 * @attr: device attribute, not used.
2362 * @buf: on return contains the attribute value in decimal.
2363 *
2364 * Returns: size of formatted string.
2365 **/
dea31012005-04-17 16:05:31 -05002366#define lpfc_param_show(attr) \
2367static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002368lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2369 char *buf) \
dea31012005-04-17 16:05:31 -05002370{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002371 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002372 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2373 struct lpfc_hba *phba = vport->phba;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002374 return scnprintf(buf, PAGE_SIZE, "%d\n",\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002375 phba->cfg_##attr);\
dea31012005-04-17 16:05:31 -05002376}
2377
James Smarte59058c2008-08-24 21:49:00 -04002378/**
James Smart3621a712009-04-06 18:47:14 -04002379 * lpfc_param_hex_show - Return a cfg attribute value in hex
James Smarte59058c2008-08-24 21:49:00 -04002380 *
2381 * Description:
2382 * Macro that given an attr e.g. hba_queue_depth expands
2383 * into a function with the name lpfc_hba_queue_depth_show
2384 *
2385 * lpfc_##attr##_show: Return the hex value of an adapters cfg_xxx field.
2386 * @dev: class device that is converted into a Scsi_host.
2387 * @attr: device attribute, not used.
James Smart3621a712009-04-06 18:47:14 -04002388 * @buf: on return contains the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002389 *
2390 * Returns: size of formatted string.
2391 **/
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002392#define lpfc_param_hex_show(attr) \
2393static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002394lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2395 char *buf) \
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002396{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002397 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002398 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2399 struct lpfc_hba *phba = vport->phba;\
James Smart84d1b002010-02-12 14:42:33 -05002400 uint val = 0;\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002401 val = phba->cfg_##attr;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002402 return scnprintf(buf, PAGE_SIZE, "%#x\n",\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002403 phba->cfg_##attr);\
2404}
2405
James Smarte59058c2008-08-24 21:49:00 -04002406/**
Uwe Kleine-Königb5950762010-11-01 15:38:34 -04002407 * lpfc_param_init - Initializes a cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002408 *
2409 * Description:
2410 * Macro that given an attr e.g. hba_queue_depth expands
2411 * into a function with the name lpfc_hba_queue_depth_init. The macro also
2412 * takes a default argument, a minimum and maximum argument.
2413 *
2414 * lpfc_##attr##_init: Initializes an attribute.
2415 * @phba: pointer the the adapter structure.
2416 * @val: integer attribute value.
2417 *
2418 * Validates the min and max values then sets the adapter config field
2419 * accordingly, or uses the default if out of range and prints an error message.
2420 *
2421 * Returns:
2422 * zero on success
2423 * -EINVAL if default used
2424 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002425#define lpfc_param_init(attr, default, minval, maxval) \
2426static int \
James Smart84d1b002010-02-12 14:42:33 -05002427lpfc_##attr##_init(struct lpfc_hba *phba, uint val) \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002428{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002429 if (lpfc_rangecheck(val, minval, maxval)) {\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002430 phba->cfg_##attr = val;\
2431 return 0;\
2432 }\
2433 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
James Smarte8b62012007-08-02 11:10:09 -04002434 "0449 lpfc_"#attr" attribute cannot be set to %d, "\
2435 "allowed range is ["#minval", "#maxval"]\n", val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002436 phba->cfg_##attr = default;\
2437 return -EINVAL;\
2438}
2439
James Smarte59058c2008-08-24 21:49:00 -04002440/**
James Smart3621a712009-04-06 18:47:14 -04002441 * lpfc_param_set - Set a cfg attribute value
James Smarte59058c2008-08-24 21:49:00 -04002442 *
2443 * Description:
2444 * Macro that given an attr e.g. hba_queue_depth expands
2445 * into a function with the name lpfc_hba_queue_depth_set
2446 *
2447 * lpfc_##attr##_set: Sets an attribute value.
2448 * @phba: pointer the the adapter structure.
2449 * @val: integer attribute value.
2450 *
2451 * Description:
2452 * Validates the min and max values then sets the
2453 * adapter config field if in the valid range. prints error message
2454 * and does not set the parameter if invalid.
2455 *
2456 * Returns:
2457 * zero on success
2458 * -EINVAL if val is invalid
2459 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002460#define lpfc_param_set(attr, default, minval, maxval) \
2461static int \
James Smart84d1b002010-02-12 14:42:33 -05002462lpfc_##attr##_set(struct lpfc_hba *phba, uint val) \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002463{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002464 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart88a2cfb2011-07-22 18:36:33 -04002465 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
2466 "3052 lpfc_" #attr " changed from %d to %d\n", \
2467 phba->cfg_##attr, val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002468 phba->cfg_##attr = val;\
2469 return 0;\
2470 }\
2471 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
James Smarte8b62012007-08-02 11:10:09 -04002472 "0450 lpfc_"#attr" attribute cannot be set to %d, "\
2473 "allowed range is ["#minval", "#maxval"]\n", val); \
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002474 return -EINVAL;\
2475}
2476
James Smarte59058c2008-08-24 21:49:00 -04002477/**
James Smart3621a712009-04-06 18:47:14 -04002478 * lpfc_param_store - Set a vport attribute value
James Smarte59058c2008-08-24 21:49:00 -04002479 *
2480 * Description:
2481 * Macro that given an attr e.g. hba_queue_depth expands
2482 * into a function with the name lpfc_hba_queue_depth_store.
2483 *
2484 * lpfc_##attr##_store: Set an sttribute value.
2485 * @dev: class device that is converted into a Scsi_host.
2486 * @attr: device attribute, not used.
2487 * @buf: contains the attribute value in ascii.
2488 * @count: not used.
2489 *
2490 * Description:
2491 * Convert the ascii text number to an integer, then
2492 * use the lpfc_##attr##_set function to set the value.
2493 *
2494 * Returns:
2495 * -EINVAL if val is invalid or lpfc_##attr##_set() fails
2496 * length of buffer upon success.
2497 **/
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002498#define lpfc_param_store(attr) \
dea31012005-04-17 16:05:31 -05002499static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002500lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
2501 const char *buf, size_t count) \
dea31012005-04-17 16:05:31 -05002502{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002503 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart2e0fef82007-06-17 19:56:36 -05002504 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
2505 struct lpfc_hba *phba = vport->phba;\
James Smart84d1b002010-02-12 14:42:33 -05002506 uint val = 0;\
James.Smart@Emulex.Com93a20f72005-10-28 20:29:32 -04002507 if (!isdigit(buf[0]))\
2508 return -EINVAL;\
2509 if (sscanf(buf, "%i", &val) != 1)\
2510 return -EINVAL;\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002511 if (lpfc_##attr##_set(phba, val) == 0) \
James.Smart@Emulex.Com755c0d02005-10-28 20:29:06 -04002512 return strlen(buf);\
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04002513 else \
2514 return -EINVAL;\
dea31012005-04-17 16:05:31 -05002515}
2516
James Smarte59058c2008-08-24 21:49:00 -04002517/**
James Smart3621a712009-04-06 18:47:14 -04002518 * lpfc_vport_param_show - Return decimal formatted cfg attribute value
James Smarte59058c2008-08-24 21:49:00 -04002519 *
2520 * Description:
2521 * Macro that given an attr e.g. hba_queue_depth expands
2522 * into a function with the name lpfc_hba_queue_depth_show
2523 *
2524 * lpfc_##attr##_show: prints the attribute value in decimal.
2525 * @dev: class device that is converted into a Scsi_host.
2526 * @attr: device attribute, not used.
2527 * @buf: on return contains the attribute value in decimal.
2528 *
2529 * Returns: length of formatted string.
2530 **/
James Smart3de2a652007-08-02 11:09:59 -04002531#define lpfc_vport_param_show(attr) \
2532static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002533lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2534 char *buf) \
James Smart3de2a652007-08-02 11:09:59 -04002535{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002536 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002537 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002538 return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\
James Smart3de2a652007-08-02 11:09:59 -04002539}
2540
James Smarte59058c2008-08-24 21:49:00 -04002541/**
James Smart3621a712009-04-06 18:47:14 -04002542 * lpfc_vport_param_hex_show - Return hex formatted attribute value
James Smarte59058c2008-08-24 21:49:00 -04002543 *
2544 * Description:
2545 * Macro that given an attr e.g.
2546 * hba_queue_depth expands into a function with the name
2547 * lpfc_hba_queue_depth_show
2548 *
James Smart3621a712009-04-06 18:47:14 -04002549 * lpfc_##attr##_show: prints the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002550 * @dev: class device that is converted into a Scsi_host.
2551 * @attr: device attribute, not used.
James Smart3621a712009-04-06 18:47:14 -04002552 * @buf: on return contains the attribute value in hexadecimal.
James Smarte59058c2008-08-24 21:49:00 -04002553 *
2554 * Returns: length of formatted string.
2555 **/
James Smart3de2a652007-08-02 11:09:59 -04002556#define lpfc_vport_param_hex_show(attr) \
2557static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002558lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
2559 char *buf) \
James Smart3de2a652007-08-02 11:09:59 -04002560{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002561 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002562 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002563 return scnprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\
James Smart3de2a652007-08-02 11:09:59 -04002564}
2565
James Smarte59058c2008-08-24 21:49:00 -04002566/**
James Smart3621a712009-04-06 18:47:14 -04002567 * lpfc_vport_param_init - Initialize a vport cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002568 *
2569 * Description:
2570 * Macro that given an attr e.g. hba_queue_depth expands
2571 * into a function with the name lpfc_hba_queue_depth_init. The macro also
2572 * takes a default argument, a minimum and maximum argument.
2573 *
2574 * lpfc_##attr##_init: validates the min and max values then sets the
2575 * adapter config field accordingly, or uses the default if out of range
2576 * and prints an error message.
2577 * @phba: pointer the the adapter structure.
2578 * @val: integer attribute value.
2579 *
2580 * Returns:
2581 * zero on success
2582 * -EINVAL if default used
2583 **/
James Smart3de2a652007-08-02 11:09:59 -04002584#define lpfc_vport_param_init(attr, default, minval, maxval) \
2585static int \
James Smart84d1b002010-02-12 14:42:33 -05002586lpfc_##attr##_init(struct lpfc_vport *vport, uint val) \
James Smart3de2a652007-08-02 11:09:59 -04002587{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002588 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart3de2a652007-08-02 11:09:59 -04002589 vport->cfg_##attr = val;\
2590 return 0;\
2591 }\
James Smarte8b62012007-08-02 11:10:09 -04002592 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smartd7c255b2008-08-24 21:50:00 -04002593 "0423 lpfc_"#attr" attribute cannot be set to %d, "\
James Smarte8b62012007-08-02 11:10:09 -04002594 "allowed range is ["#minval", "#maxval"]\n", val); \
James Smart3de2a652007-08-02 11:09:59 -04002595 vport->cfg_##attr = default;\
2596 return -EINVAL;\
2597}
2598
James Smarte59058c2008-08-24 21:49:00 -04002599/**
James Smart3621a712009-04-06 18:47:14 -04002600 * lpfc_vport_param_set - Set a vport cfg attribute
James Smarte59058c2008-08-24 21:49:00 -04002601 *
2602 * Description:
2603 * Macro that given an attr e.g. hba_queue_depth expands
2604 * into a function with the name lpfc_hba_queue_depth_set
2605 *
2606 * lpfc_##attr##_set: validates the min and max values then sets the
2607 * adapter config field if in the valid range. prints error message
2608 * and does not set the parameter if invalid.
2609 * @phba: pointer the the adapter structure.
2610 * @val: integer attribute value.
2611 *
2612 * Returns:
2613 * zero on success
2614 * -EINVAL if val is invalid
2615 **/
James Smart3de2a652007-08-02 11:09:59 -04002616#define lpfc_vport_param_set(attr, default, minval, maxval) \
2617static int \
James Smart84d1b002010-02-12 14:42:33 -05002618lpfc_##attr##_set(struct lpfc_vport *vport, uint val) \
James Smart3de2a652007-08-02 11:09:59 -04002619{ \
Arnd Bergmannde8c36b2016-06-15 22:42:17 +02002620 if (lpfc_rangecheck(val, minval, maxval)) {\
James Smart88a2cfb2011-07-22 18:36:33 -04002621 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smart14660f42013-09-06 12:20:20 -04002622 "3053 lpfc_" #attr \
2623 " changed from %d (x%x) to %d (x%x)\n", \
2624 vport->cfg_##attr, vport->cfg_##attr, \
2625 val, val); \
James Smart3de2a652007-08-02 11:09:59 -04002626 vport->cfg_##attr = val;\
2627 return 0;\
2628 }\
James Smarte8b62012007-08-02 11:10:09 -04002629 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
James Smartd7c255b2008-08-24 21:50:00 -04002630 "0424 lpfc_"#attr" attribute cannot be set to %d, "\
James Smarte8b62012007-08-02 11:10:09 -04002631 "allowed range is ["#minval", "#maxval"]\n", val); \
James Smart3de2a652007-08-02 11:09:59 -04002632 return -EINVAL;\
2633}
2634
James Smarte59058c2008-08-24 21:49:00 -04002635/**
James Smart3621a712009-04-06 18:47:14 -04002636 * lpfc_vport_param_store - Set a vport attribute
James Smarte59058c2008-08-24 21:49:00 -04002637 *
2638 * Description:
2639 * Macro that given an attr e.g. hba_queue_depth
2640 * expands into a function with the name lpfc_hba_queue_depth_store
2641 *
2642 * lpfc_##attr##_store: convert the ascii text number to an integer, then
2643 * use the lpfc_##attr##_set function to set the value.
2644 * @cdev: class device that is converted into a Scsi_host.
2645 * @buf: contains the attribute value in decimal.
2646 * @count: not used.
2647 *
2648 * Returns:
2649 * -EINVAL if val is invalid or lpfc_##attr##_set() fails
2650 * length of buffer upon success.
2651 **/
James Smart3de2a652007-08-02 11:09:59 -04002652#define lpfc_vport_param_store(attr) \
2653static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01002654lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
2655 const char *buf, size_t count) \
James Smart3de2a652007-08-02 11:09:59 -04002656{ \
Tony Jonesee959b02008-02-22 00:13:36 +01002657 struct Scsi_Host *shost = class_to_shost(dev);\
James Smart3de2a652007-08-02 11:09:59 -04002658 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
James Smart84d1b002010-02-12 14:42:33 -05002659 uint val = 0;\
James Smart3de2a652007-08-02 11:09:59 -04002660 if (!isdigit(buf[0]))\
2661 return -EINVAL;\
2662 if (sscanf(buf, "%i", &val) != 1)\
2663 return -EINVAL;\
2664 if (lpfc_##attr##_set(vport, val) == 0) \
2665 return strlen(buf);\
2666 else \
2667 return -EINVAL;\
2668}
2669
2670
James Smart895427b2017-02-12 13:52:30 -08002671static DEVICE_ATTR(nvme_info, 0444, lpfc_nvme_info_show, NULL);
James Smart4c47efc2019-01-28 11:14:25 -08002672static DEVICE_ATTR(scsi_stat, 0444, lpfc_scsi_stat_show, NULL);
James Smart81301a92008-12-04 22:39:46 -05002673static DEVICE_ATTR(bg_info, S_IRUGO, lpfc_bg_info_show, NULL);
2674static DEVICE_ATTR(bg_guard_err, S_IRUGO, lpfc_bg_guard_err_show, NULL);
2675static DEVICE_ATTR(bg_apptag_err, S_IRUGO, lpfc_bg_apptag_err_show, NULL);
2676static DEVICE_ATTR(bg_reftag_err, S_IRUGO, lpfc_bg_reftag_err_show, NULL);
Tony Jonesee959b02008-02-22 00:13:36 +01002677static DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
2678static DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
2679static DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
2680static DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL);
2681static DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);
2682static DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL);
2683static DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);
2684static DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);
James Smart84d1b002010-02-12 14:42:33 -05002685static DEVICE_ATTR(link_state, S_IRUGO | S_IWUSR, lpfc_link_state_show,
2686 lpfc_link_state_store);
Tony Jonesee959b02008-02-22 00:13:36 +01002687static DEVICE_ATTR(option_rom_version, S_IRUGO,
2688 lpfc_option_rom_version_show, NULL);
2689static DEVICE_ATTR(num_discovered_ports, S_IRUGO,
2690 lpfc_num_discovered_ports_show, NULL);
James Smart84774a42008-08-24 21:50:06 -04002691static DEVICE_ATTR(menlo_mgmt_mode, S_IRUGO, lpfc_mlomgmt_show, NULL);
Tony Jonesee959b02008-02-22 00:13:36 +01002692static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
Joe Perchesc828a892017-12-19 10:15:08 -08002693static DEVICE_ATTR_RO(lpfc_drvr_version);
2694static DEVICE_ATTR_RO(lpfc_enable_fip);
Tony Jonesee959b02008-02-22 00:13:36 +01002695static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
2696 lpfc_board_mode_show, lpfc_board_mode_store);
2697static DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
2698static DEVICE_ATTR(max_vpi, S_IRUGO, lpfc_max_vpi_show, NULL);
2699static DEVICE_ATTR(used_vpi, S_IRUGO, lpfc_used_vpi_show, NULL);
2700static DEVICE_ATTR(max_rpi, S_IRUGO, lpfc_max_rpi_show, NULL);
2701static DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL);
2702static DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL);
2703static DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL);
2704static DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL);
Joe Perchesc828a892017-12-19 10:15:08 -08002705static DEVICE_ATTR_RO(lpfc_temp_sensor);
2706static DEVICE_ATTR_RO(lpfc_fips_level);
2707static DEVICE_ATTR_RO(lpfc_fips_rev);
2708static DEVICE_ATTR_RO(lpfc_dss);
2709static DEVICE_ATTR_RO(lpfc_sriov_hw_max_virtfn);
James Smart026abb82011-12-13 13:20:45 -05002710static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL);
James Smart1ba981f2014-02-20 09:56:45 -05002711static DEVICE_ATTR(lpfc_xlane_supported, S_IRUGO, lpfc_oas_supported_show,
2712 NULL);
James Smartc3f28af2006-08-18 17:47:18 -04002713
James Smart352e5fd2016-12-30 06:57:47 -08002714static char *lpfc_soft_wwn_key = "C99G71SL8032A";
James Smart1ba981f2014-02-20 09:56:45 -05002715#define WWN_SZ 8
2716/**
2717 * lpfc_wwn_set - Convert string to the 8 byte WWN value.
2718 * @buf: WWN string.
2719 * @cnt: Length of string.
2720 * @wwn: Array to receive converted wwn value.
2721 *
2722 * Returns:
2723 * -EINVAL if the buffer does not contain a valid wwn
2724 * 0 success
2725 **/
2726static size_t
2727lpfc_wwn_set(const char *buf, size_t cnt, char wwn[])
2728{
2729 unsigned int i, j;
James Smartc3f28af2006-08-18 17:47:18 -04002730
James Smart1ba981f2014-02-20 09:56:45 -05002731 /* Count may include a LF at end of string */
2732 if (buf[cnt-1] == '\n')
2733 cnt--;
2734
2735 if ((cnt < 16) || (cnt > 18) || ((cnt == 17) && (*buf++ != 'x')) ||
2736 ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
2737 return -EINVAL;
2738
2739 memset(wwn, 0, WWN_SZ);
2740
2741 /* Validate and store the new name */
2742 for (i = 0, j = 0; i < 16; i++) {
2743 if ((*buf >= 'a') && (*buf <= 'f'))
2744 j = ((j << 4) | ((*buf++ - 'a') + 10));
2745 else if ((*buf >= 'A') && (*buf <= 'F'))
2746 j = ((j << 4) | ((*buf++ - 'A') + 10));
2747 else if ((*buf >= '0') && (*buf <= '9'))
2748 j = ((j << 4) | (*buf++ - '0'));
2749 else
2750 return -EINVAL;
2751 if (i % 2) {
2752 wwn[i/2] = j & 0xff;
2753 j = 0;
2754 }
2755 }
2756 return 0;
2757}
James Smart352e5fd2016-12-30 06:57:47 -08002758/**
2759 * lpfc_soft_wwn_enable_store - Allows setting of the wwn if the key is valid
2760 * @dev: class device that is converted into a Scsi_host.
2761 * @attr: device attribute, not used.
2762 * @buf: containing the string lpfc_soft_wwn_key.
2763 * @count: must be size of lpfc_soft_wwn_key.
2764 *
2765 * Returns:
2766 * -EINVAL if the buffer does not contain lpfc_soft_wwn_key
2767 * length of buf indicates success
2768 **/
2769static ssize_t
2770lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr,
2771 const char *buf, size_t count)
2772{
2773 struct Scsi_Host *shost = class_to_shost(dev);
2774 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2775 struct lpfc_hba *phba = vport->phba;
2776 unsigned int cnt = count;
James Smartaeb3c812017-04-21 16:05:02 -07002777 uint8_t vvvl = vport->fc_sparam.cmn.valid_vendor_ver_level;
2778 u32 *fawwpn_key = (uint32_t *)&vport->fc_sparam.un.vendorVersion[0];
James Smart352e5fd2016-12-30 06:57:47 -08002779
2780 /*
2781 * We're doing a simple sanity check for soft_wwpn setting.
2782 * We require that the user write a specific key to enable
2783 * the soft_wwpn attribute to be settable. Once the attribute
2784 * is written, the enable key resets. If further updates are
2785 * desired, the key must be written again to re-enable the
2786 * attribute.
2787 *
2788 * The "key" is not secret - it is a hardcoded string shown
2789 * here. The intent is to protect against the random user or
2790 * application that is just writing attributes.
2791 */
James Smartaeb3c812017-04-21 16:05:02 -07002792 if (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR) {
2793 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2794 "0051 "LPFC_DRIVER_NAME" soft wwpn can not"
2795 " be enabled: fawwpn is enabled\n");
2796 return -EINVAL;
2797 }
James Smart352e5fd2016-12-30 06:57:47 -08002798
2799 /* count may include a LF at end of string */
2800 if (buf[cnt-1] == '\n')
2801 cnt--;
2802
2803 if ((cnt != strlen(lpfc_soft_wwn_key)) ||
2804 (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0))
2805 return -EINVAL;
2806
2807 phba->soft_wwn_enable = 1;
2808
2809 dev_printk(KERN_WARNING, &phba->pcidev->dev,
2810 "lpfc%d: soft_wwpn assignment has been enabled.\n",
2811 phba->brd_no);
2812 dev_printk(KERN_WARNING, &phba->pcidev->dev,
2813 " The soft_wwpn feature is not supported by Broadcom.");
2814
2815 return count;
2816}
Joe Perches6cbaefb2017-12-19 10:15:09 -08002817static DEVICE_ATTR_WO(lpfc_soft_wwn_enable);
James Smart352e5fd2016-12-30 06:57:47 -08002818
2819/**
2820 * lpfc_soft_wwpn_show - Return the cfg soft ww port name of the adapter
2821 * @dev: class device that is converted into a Scsi_host.
2822 * @attr: device attribute, not used.
2823 * @buf: on return contains the wwpn in hexadecimal.
2824 *
2825 * Returns: size of formatted string.
2826 **/
2827static ssize_t
2828lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr,
2829 char *buf)
2830{
2831 struct Scsi_Host *shost = class_to_shost(dev);
2832 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2833 struct lpfc_hba *phba = vport->phba;
2834
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002835 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart352e5fd2016-12-30 06:57:47 -08002836 (unsigned long long)phba->cfg_soft_wwpn);
2837}
2838
2839/**
2840 * lpfc_soft_wwpn_store - Set the ww port name of the adapter
2841 * @dev class device that is converted into a Scsi_host.
2842 * @attr: device attribute, not used.
2843 * @buf: contains the wwpn in hexadecimal.
2844 * @count: number of wwpn bytes in buf
2845 *
2846 * Returns:
2847 * -EACCES hba reset not enabled, adapter over temp
2848 * -EINVAL soft wwn not enabled, count is invalid, invalid wwpn byte invalid
2849 * -EIO error taking adapter offline or online
2850 * value of count on success
2851 **/
2852static ssize_t
2853lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr,
2854 const char *buf, size_t count)
2855{
2856 struct Scsi_Host *shost = class_to_shost(dev);
2857 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2858 struct lpfc_hba *phba = vport->phba;
2859 struct completion online_compl;
2860 int stat1 = 0, stat2 = 0;
2861 unsigned int cnt = count;
2862 u8 wwpn[WWN_SZ];
2863 int rc;
2864
2865 if (!phba->cfg_enable_hba_reset)
2866 return -EACCES;
2867 spin_lock_irq(&phba->hbalock);
2868 if (phba->over_temp_state == HBA_OVER_TEMP) {
2869 spin_unlock_irq(&phba->hbalock);
2870 return -EACCES;
2871 }
2872 spin_unlock_irq(&phba->hbalock);
2873 /* count may include a LF at end of string */
2874 if (buf[cnt-1] == '\n')
2875 cnt--;
2876
2877 if (!phba->soft_wwn_enable)
2878 return -EINVAL;
2879
2880 /* lock setting wwpn, wwnn down */
2881 phba->soft_wwn_enable = 0;
2882
2883 rc = lpfc_wwn_set(buf, cnt, wwpn);
James Smarte2934ed2017-01-17 12:31:56 -08002884 if (rc) {
James Smart352e5fd2016-12-30 06:57:47 -08002885 /* not able to set wwpn, unlock it */
2886 phba->soft_wwn_enable = 1;
2887 return rc;
2888 }
2889
2890 phba->cfg_soft_wwpn = wwn_to_u64(wwpn);
2891 fc_host_port_name(shost) = phba->cfg_soft_wwpn;
2892 if (phba->cfg_soft_wwnn)
2893 fc_host_node_name(shost) = phba->cfg_soft_wwnn;
2894
2895 dev_printk(KERN_NOTICE, &phba->pcidev->dev,
2896 "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no);
2897
2898 stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
2899 if (stat1)
2900 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2901 "0463 lpfc_soft_wwpn attribute set failed to "
2902 "reinit adapter - %d\n", stat1);
2903 init_completion(&online_compl);
2904 rc = lpfc_workq_post_event(phba, &stat2, &online_compl,
2905 LPFC_EVT_ONLINE);
2906 if (rc == 0)
2907 return -ENOMEM;
2908
2909 wait_for_completion(&online_compl);
2910 if (stat2)
2911 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
2912 "0464 lpfc_soft_wwpn attribute set failed to "
2913 "reinit adapter - %d\n", stat2);
2914 return (stat1 || stat2) ? -EIO : count;
2915}
Joe Perchesb6b996b2017-12-19 10:15:07 -08002916static DEVICE_ATTR_RW(lpfc_soft_wwpn);
James Smart352e5fd2016-12-30 06:57:47 -08002917
2918/**
2919 * lpfc_soft_wwnn_show - Return the cfg soft ww node name for the adapter
2920 * @dev: class device that is converted into a Scsi_host.
2921 * @attr: device attribute, not used.
2922 * @buf: on return contains the wwnn in hexadecimal.
2923 *
2924 * Returns: size of formatted string.
2925 **/
2926static ssize_t
2927lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr,
2928 char *buf)
2929{
2930 struct Scsi_Host *shost = class_to_shost(dev);
2931 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07002932 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart352e5fd2016-12-30 06:57:47 -08002933 (unsigned long long)phba->cfg_soft_wwnn);
2934}
2935
2936/**
2937 * lpfc_soft_wwnn_store - sets the ww node name of the adapter
2938 * @cdev: class device that is converted into a Scsi_host.
2939 * @buf: contains the ww node name in hexadecimal.
2940 * @count: number of wwnn bytes in buf.
2941 *
2942 * Returns:
2943 * -EINVAL soft wwn not enabled, count is invalid, invalid wwnn byte invalid
2944 * value of count on success
2945 **/
2946static ssize_t
2947lpfc_soft_wwnn_store(struct device *dev, struct device_attribute *attr,
2948 const char *buf, size_t count)
2949{
2950 struct Scsi_Host *shost = class_to_shost(dev);
2951 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
2952 unsigned int cnt = count;
2953 u8 wwnn[WWN_SZ];
2954 int rc;
2955
2956 /* count may include a LF at end of string */
2957 if (buf[cnt-1] == '\n')
2958 cnt--;
2959
2960 if (!phba->soft_wwn_enable)
2961 return -EINVAL;
2962
2963 rc = lpfc_wwn_set(buf, cnt, wwnn);
James Smarte2934ed2017-01-17 12:31:56 -08002964 if (rc) {
James Smart352e5fd2016-12-30 06:57:47 -08002965 /* Allow wwnn to be set many times, as long as the enable
2966 * is set. However, once the wwpn is set, everything locks.
2967 */
2968 return rc;
2969 }
2970
2971 phba->cfg_soft_wwnn = wwn_to_u64(wwnn);
2972
2973 dev_printk(KERN_NOTICE, &phba->pcidev->dev,
2974 "lpfc%d: soft_wwnn set. Value will take effect upon "
2975 "setting of the soft_wwpn\n", phba->brd_no);
2976
2977 return count;
2978}
Joe Perchesb6b996b2017-12-19 10:15:07 -08002979static DEVICE_ATTR_RW(lpfc_soft_wwnn);
James Smarta12e07b2006-12-02 13:35:30 -05002980
James Smart1ba981f2014-02-20 09:56:45 -05002981/**
2982 * lpfc_oas_tgt_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_tgt_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, "0x%llx\n",
James Smart1ba981f2014-02-20 09:56:45 -05002999 wwn_to_u64(phba->cfg_oas_tgt_wwpn));
3000}
3001
3002/**
3003 * lpfc_oas_tgt_store - Store wwpn of target whose luns maybe enabled for
3004 * Optimized Access Storage (OAS) operations.
3005 * @dev: class device that is converted into a Scsi_host.
3006 * @attr: device attribute, not used.
3007 * @buf: buffer for passing information.
3008 * @count: Size of the data buffer.
3009 *
3010 * Returns:
3011 * -EINVAL count is invalid, invalid wwpn byte invalid
3012 * -EPERM oas is not supported by hba
3013 * value of count on success
3014 **/
3015static ssize_t
3016lpfc_oas_tgt_store(struct device *dev, struct device_attribute *attr,
3017 const char *buf, size_t count)
3018{
3019 struct Scsi_Host *shost = class_to_shost(dev);
3020 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3021 unsigned int cnt = count;
3022 uint8_t wwpn[WWN_SZ];
3023 int rc;
3024
James Smartf38fa0b2014-04-04 13:52:21 -04003025 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003026 return -EPERM;
3027
3028 /* count may include a LF at end of string */
3029 if (buf[cnt-1] == '\n')
3030 cnt--;
3031
3032 rc = lpfc_wwn_set(buf, cnt, wwpn);
3033 if (rc)
3034 return rc;
3035
3036 memcpy(phba->cfg_oas_tgt_wwpn, wwpn, (8 * sizeof(uint8_t)));
3037 memcpy(phba->sli4_hba.oas_next_tgt_wwpn, wwpn, (8 * sizeof(uint8_t)));
3038 if (wwn_to_u64(wwpn) == 0)
3039 phba->cfg_oas_flags |= OAS_FIND_ANY_TARGET;
3040 else
3041 phba->cfg_oas_flags &= ~OAS_FIND_ANY_TARGET;
3042 phba->cfg_oas_flags &= ~OAS_LUN_VALID;
3043 phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
3044 return count;
3045}
3046static DEVICE_ATTR(lpfc_xlane_tgt, S_IRUGO | S_IWUSR,
3047 lpfc_oas_tgt_show, lpfc_oas_tgt_store);
3048
3049/**
James Smartc92c8412016-07-06 12:36:05 -07003050 * lpfc_oas_priority_show - Return wwpn of target whose luns maybe enabled for
3051 * Optimized Access Storage (OAS) operations.
3052 * @dev: class device that is converted into a Scsi_host.
3053 * @attr: device attribute, not used.
3054 * @buf: buffer for passing information.
3055 *
3056 * Returns:
3057 * value of count
3058 **/
3059static ssize_t
3060lpfc_oas_priority_show(struct device *dev, struct device_attribute *attr,
3061 char *buf)
3062{
3063 struct Scsi_Host *shost = class_to_shost(dev);
3064 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3065
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003066 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_priority);
James Smartc92c8412016-07-06 12:36:05 -07003067}
3068
3069/**
3070 * lpfc_oas_priority_store - Store wwpn of target whose luns maybe enabled for
3071 * Optimized Access Storage (OAS) operations.
3072 * @dev: class device that is converted into a Scsi_host.
3073 * @attr: device attribute, not used.
3074 * @buf: buffer for passing information.
3075 * @count: Size of the data buffer.
3076 *
3077 * Returns:
3078 * -EINVAL count is invalid, invalid wwpn byte invalid
3079 * -EPERM oas is not supported by hba
3080 * value of count on success
3081 **/
3082static ssize_t
3083lpfc_oas_priority_store(struct device *dev, struct device_attribute *attr,
3084 const char *buf, size_t count)
3085{
3086 struct Scsi_Host *shost = class_to_shost(dev);
3087 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3088 unsigned int cnt = count;
3089 unsigned long val;
3090 int ret;
3091
3092 if (!phba->cfg_fof)
3093 return -EPERM;
3094
3095 /* count may include a LF at end of string */
3096 if (buf[cnt-1] == '\n')
3097 cnt--;
3098
3099 ret = kstrtoul(buf, 0, &val);
3100 if (ret || (val > 0x7f))
3101 return -EINVAL;
3102
3103 if (val)
3104 phba->cfg_oas_priority = (uint8_t)val;
3105 else
3106 phba->cfg_oas_priority = phba->cfg_XLanePriority;
3107 return count;
3108}
3109static DEVICE_ATTR(lpfc_xlane_priority, S_IRUGO | S_IWUSR,
3110 lpfc_oas_priority_show, lpfc_oas_priority_store);
3111
3112/**
James Smart1ba981f2014-02-20 09:56:45 -05003113 * lpfc_oas_vpt_show - Return wwpn of vport whose targets maybe enabled
3114 * for Optimized Access Storage (OAS) operations.
3115 * @dev: class device that is converted into a Scsi_host.
3116 * @attr: device attribute, not used.
3117 * @buf: buffer for passing information.
3118 *
3119 * Returns:
3120 * value of count on success
3121 **/
3122static ssize_t
3123lpfc_oas_vpt_show(struct device *dev, struct device_attribute *attr,
3124 char *buf)
3125{
3126 struct Scsi_Host *shost = class_to_shost(dev);
3127 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3128
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003129 return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
James Smart1ba981f2014-02-20 09:56:45 -05003130 wwn_to_u64(phba->cfg_oas_vpt_wwpn));
3131}
3132
3133/**
3134 * lpfc_oas_vpt_store - Store wwpn of vport whose targets maybe enabled
3135 * for Optimized Access Storage (OAS) operations.
3136 * @dev: class device that is converted into a Scsi_host.
3137 * @attr: device attribute, not used.
3138 * @buf: buffer for passing information.
3139 * @count: Size of the data buffer.
3140 *
3141 * Returns:
3142 * -EINVAL count is invalid, invalid wwpn byte invalid
3143 * -EPERM oas is not supported by hba
3144 * value of count on success
3145 **/
3146static ssize_t
3147lpfc_oas_vpt_store(struct device *dev, struct device_attribute *attr,
3148 const char *buf, size_t count)
3149{
3150 struct Scsi_Host *shost = class_to_shost(dev);
3151 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3152 unsigned int cnt = count;
3153 uint8_t wwpn[WWN_SZ];
3154 int rc;
3155
James Smartf38fa0b2014-04-04 13:52:21 -04003156 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003157 return -EPERM;
3158
3159 /* count may include a LF at end of string */
3160 if (buf[cnt-1] == '\n')
3161 cnt--;
3162
3163 rc = lpfc_wwn_set(buf, cnt, wwpn);
3164 if (rc)
3165 return rc;
3166
3167 memcpy(phba->cfg_oas_vpt_wwpn, wwpn, (8 * sizeof(uint8_t)));
3168 memcpy(phba->sli4_hba.oas_next_vpt_wwpn, wwpn, (8 * sizeof(uint8_t)));
3169 if (wwn_to_u64(wwpn) == 0)
3170 phba->cfg_oas_flags |= OAS_FIND_ANY_VPORT;
3171 else
3172 phba->cfg_oas_flags &= ~OAS_FIND_ANY_VPORT;
3173 phba->cfg_oas_flags &= ~OAS_LUN_VALID;
James Smartb5749fe2016-12-19 15:07:26 -08003174 if (phba->cfg_oas_priority == 0)
3175 phba->cfg_oas_priority = phba->cfg_XLanePriority;
James Smart1ba981f2014-02-20 09:56:45 -05003176 phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
3177 return count;
3178}
3179static DEVICE_ATTR(lpfc_xlane_vpt, S_IRUGO | S_IWUSR,
3180 lpfc_oas_vpt_show, lpfc_oas_vpt_store);
3181
3182/**
3183 * lpfc_oas_lun_state_show - Return the current state (enabled or disabled)
3184 * of whether luns will be enabled or disabled
3185 * for Optimized Access Storage (OAS) operations.
3186 * @dev: class device that is converted into a Scsi_host.
3187 * @attr: device attribute, not used.
3188 * @buf: buffer for passing information.
3189 *
3190 * Returns:
3191 * size of formatted string.
3192 **/
3193static ssize_t
3194lpfc_oas_lun_state_show(struct device *dev, struct device_attribute *attr,
3195 char *buf)
3196{
3197 struct Scsi_Host *shost = class_to_shost(dev);
3198 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3199
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003200 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_state);
James Smart1ba981f2014-02-20 09:56:45 -05003201}
3202
3203/**
3204 * lpfc_oas_lun_state_store - Store the state (enabled or disabled)
3205 * of whether luns will be enabled or disabled
3206 * for Optimized Access Storage (OAS) operations.
3207 * @dev: class device that is converted into a Scsi_host.
3208 * @attr: device attribute, not used.
3209 * @buf: buffer for passing information.
3210 * @count: Size of the data buffer.
3211 *
3212 * Returns:
3213 * -EINVAL count is invalid, invalid wwpn byte invalid
3214 * -EPERM oas is not supported by hba
3215 * value of count on success
3216 **/
3217static ssize_t
3218lpfc_oas_lun_state_store(struct device *dev, struct device_attribute *attr,
3219 const char *buf, size_t count)
3220{
3221 struct Scsi_Host *shost = class_to_shost(dev);
3222 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3223 int val = 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 (!isdigit(buf[0]))
3229 return -EINVAL;
3230
3231 if (sscanf(buf, "%i", &val) != 1)
3232 return -EINVAL;
3233
3234 if ((val != 0) && (val != 1))
3235 return -EINVAL;
3236
3237 phba->cfg_oas_lun_state = val;
James Smart1ba981f2014-02-20 09:56:45 -05003238 return strlen(buf);
3239}
3240static DEVICE_ATTR(lpfc_xlane_lun_state, S_IRUGO | S_IWUSR,
3241 lpfc_oas_lun_state_show, lpfc_oas_lun_state_store);
3242
3243/**
3244 * lpfc_oas_lun_status_show - Return the status of the Optimized Access
3245 * Storage (OAS) lun returned by the
3246 * lpfc_oas_lun_show function.
3247 * @dev: class device that is converted into a Scsi_host.
3248 * @attr: device attribute, not used.
3249 * @buf: buffer for passing information.
3250 *
3251 * Returns:
3252 * size of formatted string.
3253 **/
3254static ssize_t
3255lpfc_oas_lun_status_show(struct device *dev, struct device_attribute *attr,
3256 char *buf)
3257{
3258 struct Scsi_Host *shost = class_to_shost(dev);
3259 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3260
3261 if (!(phba->cfg_oas_flags & OAS_LUN_VALID))
3262 return -EFAULT;
3263
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003264 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_status);
James Smart1ba981f2014-02-20 09:56:45 -05003265}
3266static DEVICE_ATTR(lpfc_xlane_lun_status, S_IRUGO,
3267 lpfc_oas_lun_status_show, NULL);
3268
3269
3270/**
3271 * lpfc_oas_lun_state_set - enable or disable a lun for Optimized Access Storage
3272 * (OAS) operations.
3273 * @phba: lpfc_hba pointer.
3274 * @ndlp: pointer to fcp target node.
3275 * @lun: the fc lun for setting oas state.
3276 * @oas_state: the oas state to be set to the lun.
3277 *
3278 * Returns:
3279 * SUCCESS : 0
3280 * -EPERM OAS is not enabled or not supported by this port.
3281 *
3282 */
3283static size_t
3284lpfc_oas_lun_state_set(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
James Smartc92c8412016-07-06 12:36:05 -07003285 uint8_t tgt_wwpn[], uint64_t lun,
3286 uint32_t oas_state, uint8_t pri)
James Smart1ba981f2014-02-20 09:56:45 -05003287{
3288
3289 int rc = 0;
3290
James Smartf38fa0b2014-04-04 13:52:21 -04003291 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003292 return -EPERM;
3293
3294 if (oas_state) {
3295 if (!lpfc_enable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
James Smartc92c8412016-07-06 12:36:05 -07003296 (struct lpfc_name *)tgt_wwpn,
3297 lun, pri))
James Smart1ba981f2014-02-20 09:56:45 -05003298 rc = -ENOMEM;
3299 } else {
3300 lpfc_disable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003301 (struct lpfc_name *)tgt_wwpn, lun, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003302 }
3303 return rc;
3304
3305}
3306
3307/**
3308 * lpfc_oas_lun_get_next - get the next lun that has been enabled for Optimized
3309 * Access Storage (OAS) operations.
3310 * @phba: lpfc_hba pointer.
3311 * @vpt_wwpn: wwpn of the vport associated with the returned lun
3312 * @tgt_wwpn: wwpn of the target associated with the returned lun
3313 * @lun_status: status of the lun returned lun
3314 *
3315 * Returns the first or next lun enabled for OAS operations for the vport/target
3316 * specified. If a lun is found, its vport wwpn, target wwpn and status is
3317 * returned. If the lun is not found, NOT_OAS_ENABLED_LUN is returned.
3318 *
3319 * Return:
3320 * lun that is OAS enabled for the vport/target
3321 * NOT_OAS_ENABLED_LUN when no oas enabled lun found.
3322 */
3323static uint64_t
3324lpfc_oas_lun_get_next(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
James Smartb5749fe2016-12-19 15:07:26 -08003325 uint8_t tgt_wwpn[], uint32_t *lun_status,
3326 uint32_t *lun_pri)
James Smart1ba981f2014-02-20 09:56:45 -05003327{
3328 uint64_t found_lun;
3329
3330 if (unlikely(!phba) || !vpt_wwpn || !tgt_wwpn)
3331 return NOT_OAS_ENABLED_LUN;
3332 if (lpfc_find_next_oas_lun(phba, (struct lpfc_name *)
3333 phba->sli4_hba.oas_next_vpt_wwpn,
3334 (struct lpfc_name *)
3335 phba->sli4_hba.oas_next_tgt_wwpn,
3336 &phba->sli4_hba.oas_next_lun,
3337 (struct lpfc_name *)vpt_wwpn,
3338 (struct lpfc_name *)tgt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003339 &found_lun, lun_status, lun_pri))
James Smart1ba981f2014-02-20 09:56:45 -05003340 return found_lun;
3341 else
3342 return NOT_OAS_ENABLED_LUN;
3343}
3344
3345/**
3346 * lpfc_oas_lun_state_change - enable/disable a lun for OAS operations
3347 * @phba: lpfc_hba pointer.
3348 * @vpt_wwpn: vport wwpn by reference.
3349 * @tgt_wwpn: target wwpn by reference.
3350 * @lun: the fc lun for setting oas state.
3351 * @oas_state: the oas state to be set to the oas_lun.
3352 *
3353 * This routine enables (OAS_LUN_ENABLE) or disables (OAS_LUN_DISABLE)
3354 * a lun for OAS operations.
3355 *
3356 * Return:
3357 * SUCCESS: 0
3358 * -ENOMEM: failed to enable an lun for OAS operations
3359 * -EPERM: OAS is not enabled
3360 */
3361static ssize_t
3362lpfc_oas_lun_state_change(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
3363 uint8_t tgt_wwpn[], uint64_t lun,
James Smartc92c8412016-07-06 12:36:05 -07003364 uint32_t oas_state, uint8_t pri)
James Smart1ba981f2014-02-20 09:56:45 -05003365{
3366
3367 int rc;
3368
3369 rc = lpfc_oas_lun_state_set(phba, vpt_wwpn, tgt_wwpn, lun,
James Smartc92c8412016-07-06 12:36:05 -07003370 oas_state, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003371 return rc;
3372}
3373
3374/**
3375 * lpfc_oas_lun_show - Return oas enabled luns from a chosen target
3376 * @dev: class device that is converted into a Scsi_host.
3377 * @attr: device attribute, not used.
3378 * @buf: buffer for passing information.
3379 *
3380 * This routine returns a lun enabled for OAS each time the function
3381 * is called.
3382 *
3383 * Returns:
3384 * SUCCESS: size of formatted string.
3385 * -EFAULT: target or vport wwpn was not set properly.
3386 * -EPERM: oas is not enabled.
3387 **/
3388static ssize_t
3389lpfc_oas_lun_show(struct device *dev, struct device_attribute *attr,
3390 char *buf)
3391{
3392 struct Scsi_Host *shost = class_to_shost(dev);
3393 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3394
3395 uint64_t oas_lun;
3396 int len = 0;
3397
James Smartf38fa0b2014-04-04 13:52:21 -04003398 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003399 return -EPERM;
3400
3401 if (wwn_to_u64(phba->cfg_oas_vpt_wwpn) == 0)
3402 if (!(phba->cfg_oas_flags & OAS_FIND_ANY_VPORT))
3403 return -EFAULT;
3404
3405 if (wwn_to_u64(phba->cfg_oas_tgt_wwpn) == 0)
3406 if (!(phba->cfg_oas_flags & OAS_FIND_ANY_TARGET))
3407 return -EFAULT;
3408
3409 oas_lun = lpfc_oas_lun_get_next(phba, phba->cfg_oas_vpt_wwpn,
3410 phba->cfg_oas_tgt_wwpn,
James Smartb5749fe2016-12-19 15:07:26 -08003411 &phba->cfg_oas_lun_status,
3412 &phba->cfg_oas_priority);
James Smart1ba981f2014-02-20 09:56:45 -05003413 if (oas_lun != NOT_OAS_ENABLED_LUN)
3414 phba->cfg_oas_flags |= OAS_LUN_VALID;
3415
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003416 len += scnprintf(buf + len, PAGE_SIZE-len, "0x%llx", oas_lun);
James Smart1ba981f2014-02-20 09:56:45 -05003417
3418 return len;
3419}
3420
3421/**
3422 * lpfc_oas_lun_store - Sets the OAS state for lun
3423 * @dev: class device that is converted into a Scsi_host.
3424 * @attr: device attribute, not used.
3425 * @buf: buffer for passing information.
3426 *
3427 * This function sets the OAS state for lun. Before this function is called,
3428 * the vport wwpn, target wwpn, and oas state need to be set.
3429 *
3430 * Returns:
3431 * SUCCESS: size of formatted string.
3432 * -EFAULT: target or vport wwpn was not set properly.
3433 * -EPERM: oas is not enabled.
3434 * size of formatted string.
3435 **/
3436static ssize_t
3437lpfc_oas_lun_store(struct device *dev, struct device_attribute *attr,
3438 const char *buf, size_t count)
3439{
3440 struct Scsi_Host *shost = class_to_shost(dev);
3441 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
3442 uint64_t scsi_lun;
James Smartb5749fe2016-12-19 15:07:26 -08003443 uint32_t pri;
James Smart1ba981f2014-02-20 09:56:45 -05003444 ssize_t rc;
3445
James Smartf38fa0b2014-04-04 13:52:21 -04003446 if (!phba->cfg_fof)
James Smart1ba981f2014-02-20 09:56:45 -05003447 return -EPERM;
3448
3449 if (wwn_to_u64(phba->cfg_oas_vpt_wwpn) == 0)
3450 return -EFAULT;
3451
3452 if (wwn_to_u64(phba->cfg_oas_tgt_wwpn) == 0)
3453 return -EFAULT;
3454
3455 if (!isdigit(buf[0]))
3456 return -EINVAL;
3457
3458 if (sscanf(buf, "0x%llx", &scsi_lun) != 1)
3459 return -EINVAL;
3460
James Smartb5749fe2016-12-19 15:07:26 -08003461 pri = phba->cfg_oas_priority;
3462 if (pri == 0)
3463 pri = phba->cfg_XLanePriority;
3464
James Smart1ba981f2014-02-20 09:56:45 -05003465 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
James Smartc92c8412016-07-06 12:36:05 -07003466 "3372 Try to set vport 0x%llx target 0x%llx lun:0x%llx "
3467 "priority 0x%x with oas state %d\n",
James Smart1ba981f2014-02-20 09:56:45 -05003468 wwn_to_u64(phba->cfg_oas_vpt_wwpn),
3469 wwn_to_u64(phba->cfg_oas_tgt_wwpn), scsi_lun,
James Smartb5749fe2016-12-19 15:07:26 -08003470 pri, phba->cfg_oas_lun_state);
James Smart1ba981f2014-02-20 09:56:45 -05003471
3472 rc = lpfc_oas_lun_state_change(phba, phba->cfg_oas_vpt_wwpn,
James Smartc92c8412016-07-06 12:36:05 -07003473 phba->cfg_oas_tgt_wwpn, scsi_lun,
James Smartb5749fe2016-12-19 15:07:26 -08003474 phba->cfg_oas_lun_state, pri);
James Smart1ba981f2014-02-20 09:56:45 -05003475 if (rc)
3476 return rc;
3477
3478 return count;
3479}
3480static DEVICE_ATTR(lpfc_xlane_lun, S_IRUGO | S_IWUSR,
3481 lpfc_oas_lun_show, lpfc_oas_lun_store);
James Smartc3f28af2006-08-18 17:47:18 -04003482
James Smartf358dd02017-02-12 13:52:34 -08003483int lpfc_enable_nvmet_cnt;
3484unsigned long long lpfc_enable_nvmet[LPFC_NVMET_MAX_PORTS] = {
3485 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3486 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
3487module_param_array(lpfc_enable_nvmet, ullong, &lpfc_enable_nvmet_cnt, 0444);
3488MODULE_PARM_DESC(lpfc_enable_nvmet, "Enable HBA port(s) WWPN as a NVME Target");
3489
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05003490static int lpfc_poll = 0;
James Smartab56dc22011-02-16 12:39:57 -05003491module_param(lpfc_poll, int, S_IRUGO);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05003492MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
3493 " 0 - none,"
3494 " 1 - poll with interrupts enabled"
3495 " 3 - poll and disable FCP ring interrupts");
3496
Joe Perchesb6b996b2017-12-19 10:15:07 -08003497static DEVICE_ATTR_RW(lpfc_poll);
dea31012005-04-17 16:05:31 -05003498
James Smart96418b52017-03-04 09:30:31 -08003499int lpfc_no_hba_reset_cnt;
3500unsigned long lpfc_no_hba_reset[MAX_HBAS_NO_RESET] = {
3501 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
3502module_param_array(lpfc_no_hba_reset, ulong, &lpfc_no_hba_reset_cnt, 0444);
3503MODULE_PARM_DESC(lpfc_no_hba_reset, "WWPN of HBAs that should not be reset");
3504
James Smart12247e82016-07-06 12:36:09 -07003505LPFC_ATTR(sli_mode, 0, 0, 3,
3506 "SLI mode selector:"
3507 " 0 - auto (SLI-3 if supported),"
3508 " 2 - select SLI-2 even on SLI-3 capable HBAs,"
3509 " 3 - select SLI-3");
James Smart92d7f7b2007-06-17 19:56:38 -05003510
James Smart458c0832016-07-06 12:36:07 -07003511LPFC_ATTR_R(enable_npiv, 1, 0, 1,
3512 "Enable NPIV functionality");
James Smart92d7f7b2007-06-17 19:56:38 -05003513
James Smart7d791df2011-07-22 18:37:52 -04003514LPFC_ATTR_R(fcf_failover_policy, 1, 1, 2,
3515 "FCF Fast failover=1 Priority failover=2");
3516
James Smarte5771b42013-03-01 16:37:14 -05003517/*
3518# lpfc_enable_rrq: Track XRI/OXID reuse after IO failures
3519# 0x0 = disabled, XRI/OXID use not tracked.
3520# 0x1 = XRI/OXID reuse is timed with ratov, RRQ sent.
3521# 0x2 = XRI/OXID reuse is timed with ratov, No RRQ sent.
3522*/
James Smart31202b02016-10-13 15:06:08 -07003523LPFC_ATTR_R(enable_rrq, 2, 0, 2,
3524 "Enable RRQ functionality");
James Smart19ca7602010-11-20 23:11:55 -05003525
dea31012005-04-17 16:05:31 -05003526/*
James Smart84d1b002010-02-12 14:42:33 -05003527# lpfc_suppress_link_up: Bring link up at initialization
3528# 0x0 = bring link up (issue MBX_INIT_LINK)
3529# 0x1 = do NOT bring link up at initialization(MBX_INIT_LINK)
3530# 0x2 = never bring up link
3531# Default value is 0.
3532*/
James Smarte40a02c2010-02-26 14:13:54 -05003533LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK,
3534 LPFC_DELAY_INIT_LINK_INDEFINITELY,
3535 "Suppress Link Up at initialization");
James Smart2a9bf3d2010-06-07 15:24:45 -04003536/*
3537# lpfc_cnt: Number of IOCBs allocated for ELS, CT, and ABTS
3538# 1 - (1024)
3539# 2 - (2048)
3540# 3 - (3072)
3541# 4 - (4096)
3542# 5 - (5120)
3543*/
3544static ssize_t
3545lpfc_iocb_hw_show(struct device *dev, struct device_attribute *attr, char *buf)
3546{
3547 struct Scsi_Host *shost = class_to_shost(dev);
3548 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
3549
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003550 return scnprintf(buf, PAGE_SIZE, "%d\n", phba->iocb_max);
James Smart2a9bf3d2010-06-07 15:24:45 -04003551}
3552
3553static DEVICE_ATTR(iocb_hw, S_IRUGO,
3554 lpfc_iocb_hw_show, NULL);
3555static ssize_t
3556lpfc_txq_hw_show(struct device *dev, struct device_attribute *attr, char *buf)
3557{
3558 struct Scsi_Host *shost = class_to_shost(dev);
3559 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
James Smart895427b2017-02-12 13:52:30 -08003560 struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
James Smart2a9bf3d2010-06-07 15:24:45 -04003561
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003562 return scnprintf(buf, PAGE_SIZE, "%d\n",
Dick Kennedy1234a6d2017-09-29 17:34:29 -07003563 pring ? pring->txq_max : 0);
James Smart2a9bf3d2010-06-07 15:24:45 -04003564}
3565
3566static DEVICE_ATTR(txq_hw, S_IRUGO,
3567 lpfc_txq_hw_show, NULL);
3568static ssize_t
3569lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr,
3570 char *buf)
3571{
3572 struct Scsi_Host *shost = class_to_shost(dev);
3573 struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
James Smart895427b2017-02-12 13:52:30 -08003574 struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
James Smart2a9bf3d2010-06-07 15:24:45 -04003575
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003576 return scnprintf(buf, PAGE_SIZE, "%d\n",
Dick Kennedy1234a6d2017-09-29 17:34:29 -07003577 pring ? pring->txcmplq_max : 0);
James Smart2a9bf3d2010-06-07 15:24:45 -04003578}
3579
3580static DEVICE_ATTR(txcmplq_hw, S_IRUGO,
3581 lpfc_txcmplq_hw_show, NULL);
3582
James Smart0d8c8ba2016-10-13 15:06:07 -07003583LPFC_ATTR_R(iocb_cnt, 2, 1, 5,
James Smart2a9bf3d2010-06-07 15:24:45 -04003584 "Number of IOCBs alloc for ELS, CT, and ABTS: 1k to 5k IOCBs");
James Smart84d1b002010-02-12 14:42:33 -05003585
3586/*
James Smartc01f3202006-08-18 17:47:08 -04003587# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
3588# until the timer expires. Value range is [0,255]. Default value is 30.
3589*/
3590static int lpfc_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
3591static int lpfc_devloss_tmo = LPFC_DEF_DEVLOSS_TMO;
3592module_param(lpfc_nodev_tmo, int, 0);
3593MODULE_PARM_DESC(lpfc_nodev_tmo,
3594 "Seconds driver will hold I/O waiting "
3595 "for a device to come back");
James Smarte59058c2008-08-24 21:49:00 -04003596
3597/**
James Smart3621a712009-04-06 18:47:14 -04003598 * lpfc_nodev_tmo_show - Return the hba dev loss timeout value
James Smarte59058c2008-08-24 21:49:00 -04003599 * @dev: class converted to a Scsi_host structure.
3600 * @attr: device attribute, not used.
3601 * @buf: on return contains the dev loss timeout in decimal.
3602 *
3603 * Returns: size of formatted string.
3604 **/
James Smartc01f3202006-08-18 17:47:08 -04003605static ssize_t
Tony Jonesee959b02008-02-22 00:13:36 +01003606lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr,
3607 char *buf)
James Smartc01f3202006-08-18 17:47:08 -04003608{
Tony Jonesee959b02008-02-22 00:13:36 +01003609 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05003610 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
James Smarte40a02c2010-02-26 14:13:54 -05003611
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07003612 return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003613}
3614
James Smarte59058c2008-08-24 21:49:00 -04003615/**
James Smart3621a712009-04-06 18:47:14 -04003616 * lpfc_nodev_tmo_init - Set the hba nodev timeout value
James Smarte59058c2008-08-24 21:49:00 -04003617 * @vport: lpfc vport structure pointer.
3618 * @val: contains the nodev timeout value.
3619 *
3620 * Description:
3621 * If the devloss tmo is already set then nodev tmo is set to devloss tmo,
3622 * a kernel error message is printed and zero is returned.
3623 * Else if val is in range then nodev tmo and devloss tmo are set to val.
3624 * Otherwise nodev tmo is set to the default value.
3625 *
3626 * Returns:
3627 * zero if already set or if val is in range
3628 * -EINVAL val out of range
3629 **/
James Smartc01f3202006-08-18 17:47:08 -04003630static int
James Smart3de2a652007-08-02 11:09:59 -04003631lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003632{
James Smart3de2a652007-08-02 11:09:59 -04003633 if (vport->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) {
3634 vport->cfg_nodev_tmo = vport->cfg_devloss_tmo;
3635 if (val != LPFC_DEF_DEVLOSS_TMO)
James Smarte8b62012007-08-02 11:10:09 -04003636 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003637 "0407 Ignoring lpfc_nodev_tmo module "
3638 "parameter because lpfc_devloss_tmo "
3639 "is set.\n");
James Smartc01f3202006-08-18 17:47:08 -04003640 return 0;
3641 }
3642
3643 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003644 vport->cfg_nodev_tmo = val;
3645 vport->cfg_devloss_tmo = val;
James Smartc01f3202006-08-18 17:47:08 -04003646 return 0;
3647 }
James Smarte8b62012007-08-02 11:10:09 -04003648 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3649 "0400 lpfc_nodev_tmo attribute cannot be set to"
3650 " %d, allowed range is [%d, %d]\n",
3651 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smart3de2a652007-08-02 11:09:59 -04003652 vport->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
James Smartc01f3202006-08-18 17:47:08 -04003653 return -EINVAL;
3654}
3655
James Smarte59058c2008-08-24 21:49:00 -04003656/**
James Smart3621a712009-04-06 18:47:14 -04003657 * lpfc_update_rport_devloss_tmo - Update dev loss tmo value
James Smarte59058c2008-08-24 21:49:00 -04003658 * @vport: lpfc vport structure pointer.
3659 *
3660 * Description:
3661 * Update all the ndlp's dev loss tmo with the vport devloss tmo value.
3662 **/
James Smart7054a602007-04-25 09:52:34 -04003663static void
James Smart3de2a652007-08-02 11:09:59 -04003664lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
James Smart7054a602007-04-25 09:52:34 -04003665{
James Smart858c9f62007-06-17 19:56:39 -05003666 struct Scsi_Host *shost;
James Smart7054a602007-04-25 09:52:34 -04003667 struct lpfc_nodelist *ndlp;
James Smart01466022018-04-09 14:24:27 -07003668#if (IS_ENABLED(CONFIG_NVME_FC))
3669 struct lpfc_nvme_rport *rport;
James Smart9e210172018-09-13 15:41:10 -07003670 struct nvme_fc_remote_port *remoteport = NULL;
James Smart01466022018-04-09 14:24:27 -07003671#endif
James Smart7054a602007-04-25 09:52:34 -04003672
James Smart51ef4c22007-08-02 11:10:31 -04003673 shost = lpfc_shost_from_vport(vport);
3674 spin_lock_irq(shost->host_lock);
James Smart7a06dcd2017-06-01 21:06:55 -07003675 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
3676 if (!NLP_CHK_NODE_ACT(ndlp))
3677 continue;
3678 if (ndlp->rport)
James Smart51ef4c22007-08-02 11:10:31 -04003679 ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
James Smart6ddcf0a2017-11-03 09:33:30 -07003680#if (IS_ENABLED(CONFIG_NVME_FC))
James Smart9e210172018-09-13 15:41:10 -07003681 spin_lock(&vport->phba->hbalock);
James Smart01466022018-04-09 14:24:27 -07003682 rport = lpfc_ndlp_get_nrport(ndlp);
3683 if (rport)
James Smart9e210172018-09-13 15:41:10 -07003684 remoteport = rport->remoteport;
3685 spin_unlock(&vport->phba->hbalock);
James Smart07f50992019-08-14 16:56:45 -07003686 if (rport && remoteport)
3687 nvme_fc_set_remoteport_devloss(remoteport,
James Smart6ddcf0a2017-11-03 09:33:30 -07003688 vport->cfg_devloss_tmo);
3689#endif
James Smart7a06dcd2017-06-01 21:06:55 -07003690 }
James Smart51ef4c22007-08-02 11:10:31 -04003691 spin_unlock_irq(shost->host_lock);
James Smart7054a602007-04-25 09:52:34 -04003692}
3693
James Smarte59058c2008-08-24 21:49:00 -04003694/**
James Smart3621a712009-04-06 18:47:14 -04003695 * lpfc_nodev_tmo_set - Set the vport nodev tmo and devloss tmo values
James Smarte59058c2008-08-24 21:49:00 -04003696 * @vport: lpfc vport structure pointer.
3697 * @val: contains the tmo value.
3698 *
3699 * Description:
3700 * If the devloss tmo is already set or the vport dev loss tmo has changed
3701 * then a kernel error message is printed and zero is returned.
3702 * Else if val is in range then nodev tmo and devloss tmo are set to val.
3703 * Otherwise nodev tmo is set to the default value.
3704 *
3705 * Returns:
3706 * zero if already set or if val is in range
3707 * -EINVAL val out of range
3708 **/
James Smartc01f3202006-08-18 17:47:08 -04003709static int
James Smart3de2a652007-08-02 11:09:59 -04003710lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003711{
James Smart3de2a652007-08-02 11:09:59 -04003712 if (vport->dev_loss_tmo_changed ||
3713 (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
James Smarte8b62012007-08-02 11:10:09 -04003714 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003715 "0401 Ignoring change to lpfc_nodev_tmo "
3716 "because lpfc_devloss_tmo is set.\n");
James Smartc01f3202006-08-18 17:47:08 -04003717 return 0;
3718 }
James Smartc01f3202006-08-18 17:47:08 -04003719 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003720 vport->cfg_nodev_tmo = val;
3721 vport->cfg_devloss_tmo = val;
Mike Christie0af5d702010-09-15 16:52:31 -05003722 /*
3723 * For compat: set the fc_host dev loss so new rports
3724 * will get the value.
3725 */
3726 fc_host_dev_loss_tmo(lpfc_shost_from_vport(vport)) = val;
James Smart3de2a652007-08-02 11:09:59 -04003727 lpfc_update_rport_devloss_tmo(vport);
James Smartc01f3202006-08-18 17:47:08 -04003728 return 0;
3729 }
James Smarte8b62012007-08-02 11:10:09 -04003730 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003731 "0403 lpfc_nodev_tmo attribute cannot be set to "
James Smarte8b62012007-08-02 11:10:09 -04003732 "%d, allowed range is [%d, %d]\n",
3733 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smartc01f3202006-08-18 17:47:08 -04003734 return -EINVAL;
3735}
3736
James Smart3de2a652007-08-02 11:09:59 -04003737lpfc_vport_param_store(nodev_tmo)
James Smartc01f3202006-08-18 17:47:08 -04003738
Joe Perchesb6b996b2017-12-19 10:15:07 -08003739static DEVICE_ATTR_RW(lpfc_nodev_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003740
3741/*
3742# lpfc_devloss_tmo: If set, it will hold all I/O errors on devices that
3743# disappear until the timer expires. Value range is [0,255]. Default
3744# value is 30.
3745*/
James Smartab56dc22011-02-16 12:39:57 -05003746module_param(lpfc_devloss_tmo, int, S_IRUGO);
James Smartc01f3202006-08-18 17:47:08 -04003747MODULE_PARM_DESC(lpfc_devloss_tmo,
3748 "Seconds driver will hold I/O waiting "
3749 "for a device to come back");
James Smart3de2a652007-08-02 11:09:59 -04003750lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
3751 LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
3752lpfc_vport_param_show(devloss_tmo)
James Smarte59058c2008-08-24 21:49:00 -04003753
3754/**
James Smart3621a712009-04-06 18:47:14 -04003755 * lpfc_devloss_tmo_set - Sets vport nodev tmo, devloss tmo values, changed bit
James Smarte59058c2008-08-24 21:49:00 -04003756 * @vport: lpfc vport structure pointer.
3757 * @val: contains the tmo value.
3758 *
3759 * Description:
3760 * If val is in a valid range then set the vport nodev tmo,
3761 * devloss tmo, also set the vport dev loss tmo changed flag.
3762 * Else a kernel error message is printed.
3763 *
3764 * Returns:
3765 * zero if val is in range
3766 * -EINVAL val out of range
3767 **/
James Smartc01f3202006-08-18 17:47:08 -04003768static int
James Smart3de2a652007-08-02 11:09:59 -04003769lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val)
James Smartc01f3202006-08-18 17:47:08 -04003770{
3771 if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
James Smart3de2a652007-08-02 11:09:59 -04003772 vport->cfg_nodev_tmo = val;
3773 vport->cfg_devloss_tmo = val;
3774 vport->dev_loss_tmo_changed = 1;
Mike Christie0af5d702010-09-15 16:52:31 -05003775 fc_host_dev_loss_tmo(lpfc_shost_from_vport(vport)) = val;
James Smart3de2a652007-08-02 11:09:59 -04003776 lpfc_update_rport_devloss_tmo(vport);
James Smartc01f3202006-08-18 17:47:08 -04003777 return 0;
3778 }
3779
James Smarte8b62012007-08-02 11:10:09 -04003780 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07003781 "0404 lpfc_devloss_tmo attribute cannot be set to "
3782 "%d, allowed range is [%d, %d]\n",
James Smarte8b62012007-08-02 11:10:09 -04003783 val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
James Smartc01f3202006-08-18 17:47:08 -04003784 return -EINVAL;
3785}
3786
James Smart3de2a652007-08-02 11:09:59 -04003787lpfc_vport_param_store(devloss_tmo)
Joe Perchesb6b996b2017-12-19 10:15:07 -08003788static DEVICE_ATTR_RW(lpfc_devloss_tmo);
James Smartc01f3202006-08-18 17:47:08 -04003789
3790/*
James Smartf358dd02017-02-12 13:52:34 -08003791 * lpfc_suppress_rsp: Enable suppress rsp feature is firmware supports it
3792 * lpfc_suppress_rsp = 0 Disable
3793 * lpfc_suppress_rsp = 1 Enable (default)
3794 *
3795 */
3796LPFC_ATTR_R(suppress_rsp, 1, 0, 1,
3797 "Enable suppress rsp feature is firmware supports it");
3798
3799/*
James Smart2d7dbc42017-02-12 13:52:35 -08003800 * lpfc_nvmet_mrq: Specify number of RQ pairs for processing NVMET cmds
James Smartbcb24f62017-11-20 16:00:36 -08003801 * lpfc_nvmet_mrq = 0 driver will calcualte optimal number of RQ pairs
James Smart2d7dbc42017-02-12 13:52:35 -08003802 * lpfc_nvmet_mrq = 1 use a single RQ pair
3803 * lpfc_nvmet_mrq >= 2 use specified RQ pairs for MRQ
3804 *
3805 */
3806LPFC_ATTR_R(nvmet_mrq,
James Smartbcb24f62017-11-20 16:00:36 -08003807 LPFC_NVMET_MRQ_AUTO, LPFC_NVMET_MRQ_AUTO, LPFC_NVMET_MRQ_MAX,
James Smart2d7dbc42017-02-12 13:52:35 -08003808 "Specify number of RQ pairs for processing NVMET cmds");
3809
3810/*
James Smart2448e482018-04-09 14:24:24 -07003811 * lpfc_nvmet_mrq_post: Specify number of RQ buffer to initially post
3812 * to each NVMET RQ. Range 64 to 2048, default is 512.
3813 */
3814LPFC_ATTR_R(nvmet_mrq_post,
3815 LPFC_NVMET_RQE_DEF_POST, LPFC_NVMET_RQE_MIN_POST,
3816 LPFC_NVMET_RQE_DEF_COUNT,
3817 "Specify number of RQ buffers to initially post");
3818
3819/*
James Smart895427b2017-02-12 13:52:30 -08003820 * lpfc_enable_fc4_type: Defines what FC4 types are supported.
3821 * Supported Values: 1 - register just FCP
3822 * 3 - register both FCP and NVME
James Smartb1684a02019-01-28 11:14:36 -08003823 * Supported values are [1,3]. Default value is 3
James Smart895427b2017-02-12 13:52:30 -08003824 */
James Smartb1684a02019-01-28 11:14:36 -08003825LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_BOTH,
James Smart895427b2017-02-12 13:52:30 -08003826 LPFC_ENABLE_FCP, LPFC_ENABLE_BOTH,
Dick Kennedycf4c8c82017-09-29 17:34:38 -07003827 "Enable FC4 Protocol support - FCP / NVME");
James Smart895427b2017-02-12 13:52:30 -08003828
3829/*
dea31012005-04-17 16:05:31 -05003830# lpfc_log_verbose: Only turn this flag on if you are willing to risk being
3831# deluged with LOTS of information.
3832# You can set a bit mask to record specific types of verbose messages:
James Smartf4b4c682009-05-22 14:53:12 -04003833# See lpfc_logmsh.h for definitions.
dea31012005-04-17 16:05:31 -05003834*/
James Smartf4b4c682009-05-22 14:53:12 -04003835LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffffffff,
James Smarte8b62012007-08-02 11:10:09 -04003836 "Verbose logging bit-mask");
dea31012005-04-17 16:05:31 -05003837
3838/*
James Smart7ee5d432007-10-27 13:37:17 -04003839# lpfc_enable_da_id: This turns on the DA_ID CT command that deregisters
3840# objects that have been registered with the nameserver after login.
3841*/
James Smartcf971242012-03-01 22:37:32 -05003842LPFC_VPORT_ATTR_R(enable_da_id, 1, 0, 1,
James Smart7ee5d432007-10-27 13:37:17 -04003843 "Deregister nameserver objects before LOGO");
3844
3845/*
dea31012005-04-17 16:05:31 -05003846# lun_queue_depth: This parameter is used to limit the number of outstanding
James Smart572709e2013-07-15 18:32:43 -04003847# commands per FCP LUN. Value range is [1,512]. Default value is 30.
3848# If this parameter value is greater than 1/8th the maximum number of exchanges
3849# supported by the HBA port, then the lun queue depth will be reduced to
3850# 1/8th the maximum number of exchanges.
dea31012005-04-17 16:05:31 -05003851*/
James Smart572709e2013-07-15 18:32:43 -04003852LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 512,
James Smart3de2a652007-08-02 11:09:59 -04003853 "Max number of FCP commands we can queue to a specific LUN");
dea31012005-04-17 16:05:31 -05003854
3855/*
James Smart7dc517d2010-07-14 15:32:10 -04003856# tgt_queue_depth: This parameter is used to limit the number of outstanding
3857# commands per target port. Value range is [10,65535]. Default value is 65535.
3858*/
James Smartf91bc592018-04-09 14:24:22 -07003859static uint lpfc_tgt_queue_depth = LPFC_MAX_TGT_QDEPTH;
3860module_param(lpfc_tgt_queue_depth, uint, 0444);
3861MODULE_PARM_DESC(lpfc_tgt_queue_depth, "Set max Target queue depth");
3862lpfc_vport_param_show(tgt_queue_depth);
3863lpfc_vport_param_init(tgt_queue_depth, LPFC_MAX_TGT_QDEPTH,
3864 LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH);
3865
3866/**
3867 * lpfc_tgt_queue_depth_store: Sets an attribute value.
3868 * @phba: pointer the the adapter structure.
3869 * @val: integer attribute value.
3870 *
3871 * Description: Sets the parameter to the new value.
3872 *
3873 * Returns:
3874 * zero on success
3875 * -EINVAL if val is invalid
3876 */
3877static int
3878lpfc_tgt_queue_depth_set(struct lpfc_vport *vport, uint val)
3879{
3880 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3881 struct lpfc_nodelist *ndlp;
3882
3883 if (!lpfc_rangecheck(val, LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH))
3884 return -EINVAL;
3885
3886 if (val == vport->cfg_tgt_queue_depth)
3887 return 0;
3888
3889 spin_lock_irq(shost->host_lock);
3890 vport->cfg_tgt_queue_depth = val;
3891
3892 /* Next loop thru nodelist and change cmd_qdepth */
3893 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp)
3894 ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
3895
3896 spin_unlock_irq(shost->host_lock);
3897 return 0;
3898}
3899
3900lpfc_vport_param_store(tgt_queue_depth);
3901static DEVICE_ATTR_RW(lpfc_tgt_queue_depth);
James Smart7dc517d2010-07-14 15:32:10 -04003902
3903/*
Jamie Wellnitzb28485a2006-02-28 19:25:21 -05003904# hba_queue_depth: This parameter is used to limit the number of outstanding
3905# commands per lpfc HBA. Value range is [32,8192]. If this parameter
3906# value is greater than the maximum number of exchanges supported by the HBA,
3907# then maximum number of exchanges supported by the HBA is used to determine
3908# the hba_queue_depth.
3909*/
3910LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192,
3911 "Max number of FCP commands we can queue to a lpfc HBA");
3912
3913/*
James Smart92d7f7b2007-06-17 19:56:38 -05003914# peer_port_login: This parameter allows/prevents logins
3915# between peer ports hosted on the same physical port.
3916# When this parameter is set 0 peer ports of same physical port
3917# are not allowed to login to each other.
3918# When this parameter is set 1 peer ports of same physical port
3919# are allowed to login to each other.
3920# Default value of this parameter is 0.
3921*/
James Smart3de2a652007-08-02 11:09:59 -04003922LPFC_VPORT_ATTR_R(peer_port_login, 0, 0, 1,
3923 "Allow peer ports on the same physical port to login to each "
3924 "other.");
James Smart92d7f7b2007-06-17 19:56:38 -05003925
3926/*
James Smart3de2a652007-08-02 11:09:59 -04003927# restrict_login: This parameter allows/prevents logins
James Smart92d7f7b2007-06-17 19:56:38 -05003928# between Virtual Ports and remote initiators.
3929# When this parameter is not set (0) Virtual Ports will accept PLOGIs from
3930# other initiators and will attempt to PLOGI all remote ports.
3931# When this parameter is set (1) Virtual Ports will reject PLOGIs from
3932# remote ports and will not attempt to PLOGI to other initiators.
3933# This parameter does not restrict to the physical port.
3934# This parameter does not restrict logins to Fabric resident remote ports.
3935# Default value of this parameter is 1.
3936*/
James Smart3de2a652007-08-02 11:09:59 -04003937static int lpfc_restrict_login = 1;
James Smartab56dc22011-02-16 12:39:57 -05003938module_param(lpfc_restrict_login, int, S_IRUGO);
James Smart3de2a652007-08-02 11:09:59 -04003939MODULE_PARM_DESC(lpfc_restrict_login,
3940 "Restrict virtual ports login to remote initiators.");
3941lpfc_vport_param_show(restrict_login);
3942
James Smarte59058c2008-08-24 21:49:00 -04003943/**
James Smart3621a712009-04-06 18:47:14 -04003944 * lpfc_restrict_login_init - Set the vport restrict login flag
James Smarte59058c2008-08-24 21:49:00 -04003945 * @vport: lpfc vport structure pointer.
3946 * @val: contains the restrict login value.
3947 *
3948 * Description:
3949 * If val is not in a valid range then log a kernel error message and set
3950 * the vport restrict login to one.
3951 * If the port type is physical clear the restrict login flag and return.
3952 * Else set the restrict login flag to val.
3953 *
3954 * Returns:
3955 * zero if val is in range
3956 * -EINVAL val out of range
3957 **/
James Smart3de2a652007-08-02 11:09:59 -04003958static int
3959lpfc_restrict_login_init(struct lpfc_vport *vport, int val)
3960{
3961 if (val < 0 || val > 1) {
James Smarte8b62012007-08-02 11:10:09 -04003962 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartd7c255b2008-08-24 21:50:00 -04003963 "0422 lpfc_restrict_login attribute cannot "
James Smarte8b62012007-08-02 11:10:09 -04003964 "be set to %d, allowed range is [0, 1]\n",
3965 val);
James Smart3de2a652007-08-02 11:09:59 -04003966 vport->cfg_restrict_login = 1;
3967 return -EINVAL;
3968 }
3969 if (vport->port_type == LPFC_PHYSICAL_PORT) {
3970 vport->cfg_restrict_login = 0;
3971 return 0;
3972 }
3973 vport->cfg_restrict_login = val;
3974 return 0;
3975}
3976
James Smarte59058c2008-08-24 21:49:00 -04003977/**
James Smart3621a712009-04-06 18:47:14 -04003978 * lpfc_restrict_login_set - Set the vport restrict login flag
James Smarte59058c2008-08-24 21:49:00 -04003979 * @vport: lpfc vport structure pointer.
3980 * @val: contains the restrict login value.
3981 *
3982 * Description:
3983 * If val is not in a valid range then log a kernel error message and set
3984 * the vport restrict login to one.
3985 * If the port type is physical and the val is not zero log a kernel
3986 * error message, clear the restrict login flag and return zero.
3987 * Else set the restrict login flag to val.
3988 *
3989 * Returns:
3990 * zero if val is in range
3991 * -EINVAL val out of range
3992 **/
James Smart3de2a652007-08-02 11:09:59 -04003993static int
3994lpfc_restrict_login_set(struct lpfc_vport *vport, int val)
3995{
3996 if (val < 0 || val > 1) {
James Smarte8b62012007-08-02 11:10:09 -04003997 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartd7c255b2008-08-24 21:50:00 -04003998 "0425 lpfc_restrict_login attribute cannot "
James Smarte8b62012007-08-02 11:10:09 -04003999 "be set to %d, allowed range is [0, 1]\n",
4000 val);
James Smart3de2a652007-08-02 11:09:59 -04004001 vport->cfg_restrict_login = 1;
4002 return -EINVAL;
4003 }
4004 if (vport->port_type == LPFC_PHYSICAL_PORT && val != 0) {
James Smarte8b62012007-08-02 11:10:09 -04004005 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4006 "0468 lpfc_restrict_login must be 0 for "
4007 "Physical ports.\n");
James Smart3de2a652007-08-02 11:09:59 -04004008 vport->cfg_restrict_login = 0;
4009 return 0;
4010 }
4011 vport->cfg_restrict_login = val;
4012 return 0;
4013}
4014lpfc_vport_param_store(restrict_login);
Joe Perchesb6b996b2017-12-19 10:15:07 -08004015static DEVICE_ATTR_RW(lpfc_restrict_login);
James Smart92d7f7b2007-06-17 19:56:38 -05004016
4017/*
dea31012005-04-17 16:05:31 -05004018# Some disk devices have a "select ID" or "select Target" capability.
4019# From a protocol standpoint "select ID" usually means select the
4020# Fibre channel "ALPA". In the FC-AL Profile there is an "informative
4021# annex" which contains a table that maps a "select ID" (a number
4022# between 0 and 7F) to an ALPA. By default, for compatibility with
4023# older drivers, the lpfc driver scans this table from low ALPA to high
4024# ALPA.
4025#
4026# Turning on the scan-down variable (on = 1, off = 0) will
4027# cause the lpfc driver to use an inverted table, effectively
4028# scanning ALPAs from high to low. Value range is [0,1]. Default value is 1.
4029#
4030# (Note: This "select ID" functionality is a LOOP ONLY characteristic
4031# and will not work across a fabric. Also this parameter will take
4032# effect only in the case when ALPA map is not available.)
4033*/
James Smart3de2a652007-08-02 11:09:59 -04004034LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1,
4035 "Start scanning for devices from highest ALPA to lowest");
dea31012005-04-17 16:05:31 -05004036
4037/*
dea31012005-04-17 16:05:31 -05004038# lpfc_topology: link topology for init link
4039# 0x0 = attempt loop mode then point-to-point
Jamie Wellnitz367c2712006-02-28 19:25:32 -05004040# 0x01 = internal loopback mode
dea31012005-04-17 16:05:31 -05004041# 0x02 = attempt point-to-point mode only
4042# 0x04 = attempt loop mode only
4043# 0x06 = attempt point-to-point mode then loop
4044# Set point-to-point mode if you want to run as an N_Port.
4045# Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
4046# Default value is 0.
4047*/
James Smart0a035432016-10-13 15:06:10 -07004048LPFC_ATTR(topology, 0, 0, 6,
4049 "Select Fibre Channel topology");
James Smarte59058c2008-08-24 21:49:00 -04004050
4051/**
James Smart3621a712009-04-06 18:47:14 -04004052 * lpfc_topology_set - Set the adapters topology field
James Smarte59058c2008-08-24 21:49:00 -04004053 * @phba: lpfc_hba pointer.
4054 * @val: topology value.
4055 *
4056 * Description:
4057 * If val is in a valid range then set the adapter's topology field and
4058 * issue a lip; if the lip fails reset the topology to the old value.
4059 *
4060 * If the value is not in range log a kernel error message and return an error.
4061 *
4062 * Returns:
4063 * zero if val is in range and lip okay
4064 * non-zero return value from lpfc_issue_lip()
4065 * -EINVAL val out of range
4066 **/
James Smarta257bf92009-04-06 18:48:10 -04004067static ssize_t
4068lpfc_topology_store(struct device *dev, struct device_attribute *attr,
4069 const char *buf, size_t count)
James Smart83108bd2008-01-11 01:53:09 -05004070{
James Smarta257bf92009-04-06 18:48:10 -04004071 struct Scsi_Host *shost = class_to_shost(dev);
4072 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4073 struct lpfc_hba *phba = vport->phba;
4074 int val = 0;
4075 int nolip = 0;
4076 const char *val_buf = buf;
James Smart83108bd2008-01-11 01:53:09 -05004077 int err;
4078 uint32_t prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004079
4080 if (!strncmp(buf, "nolip ", strlen("nolip "))) {
4081 nolip = 1;
4082 val_buf = &buf[strlen("nolip ")];
4083 }
4084
4085 if (!isdigit(val_buf[0]))
4086 return -EINVAL;
4087 if (sscanf(val_buf, "%i", &val) != 1)
4088 return -EINVAL;
4089
James Smart83108bd2008-01-11 01:53:09 -05004090 if (val >= 0 && val <= 6) {
4091 prev_val = phba->cfg_topology;
James Smartff78d8f2011-12-13 13:21:35 -05004092 if (phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G &&
4093 val == 4) {
4094 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4095 "3113 Loop mode not supported at speed %d\n",
James Smartd38dd522015-08-31 16:48:17 -04004096 val);
James Smartff78d8f2011-12-13 13:21:35 -05004097 return -EINVAL;
4098 }
James Smart76558b22018-11-29 16:09:38 -08004099 if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC ||
4100 phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) &&
James Smartf6978f42019-05-21 17:48:57 -07004101 val == 4) {
James Smartd38dd522015-08-31 16:48:17 -04004102 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
James Smartf6978f42019-05-21 17:48:57 -07004103 "3114 Loop mode not supported\n");
James Smartd38dd522015-08-31 16:48:17 -04004104 return -EINVAL;
4105 }
4106 phba->cfg_topology = val;
James Smarta257bf92009-04-06 18:48:10 -04004107 if (nolip)
4108 return strlen(buf);
4109
James Smart88a2cfb2011-07-22 18:36:33 -04004110 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4111 "3054 lpfc_topology changed from %d to %d\n",
4112 prev_val, val);
James Smarte74c03c2013-04-17 20:15:19 -04004113 if (prev_val != val && phba->sli_rev == LPFC_SLI_REV4)
4114 phba->fc_topology_changed = 1;
James Smart83108bd2008-01-11 01:53:09 -05004115 err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
James Smarta257bf92009-04-06 18:48:10 -04004116 if (err) {
James Smart83108bd2008-01-11 01:53:09 -05004117 phba->cfg_topology = prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004118 return -EINVAL;
4119 } else
4120 return strlen(buf);
James Smart83108bd2008-01-11 01:53:09 -05004121 }
4122 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4123 "%d:0467 lpfc_topology attribute cannot be set to %d, "
4124 "allowed range is [0, 6]\n",
4125 phba->brd_no, val);
4126 return -EINVAL;
4127}
James Smart0a035432016-10-13 15:06:10 -07004128
James Smart83108bd2008-01-11 01:53:09 -05004129lpfc_param_show(topology)
Joe Perchesb6b996b2017-12-19 10:15:07 -08004130static DEVICE_ATTR_RW(lpfc_topology);
dea31012005-04-17 16:05:31 -05004131
James Smart21e9a0a2009-05-22 14:53:21 -04004132/**
4133 * lpfc_static_vport_show: Read callback function for
4134 * lpfc_static_vport sysfs file.
4135 * @dev: Pointer to class device object.
4136 * @attr: device attribute structure.
4137 * @buf: Data buffer.
4138 *
4139 * This function is the read call back function for
4140 * lpfc_static_vport sysfs file. The lpfc_static_vport
4141 * sysfs file report the mageability of the vport.
4142 **/
4143static ssize_t
4144lpfc_static_vport_show(struct device *dev, struct device_attribute *attr,
4145 char *buf)
4146{
4147 struct Scsi_Host *shost = class_to_shost(dev);
4148 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4149 if (vport->vport_flag & STATIC_VPORT)
4150 sprintf(buf, "1\n");
4151 else
4152 sprintf(buf, "0\n");
4153
4154 return strlen(buf);
4155}
4156
4157/*
4158 * Sysfs attribute to control the statistical data collection.
4159 */
Joe Perchesc828a892017-12-19 10:15:08 -08004160static DEVICE_ATTR_RO(lpfc_static_vport);
James Smartea2151b2008-09-07 11:52:10 -04004161
4162/**
James Smart3621a712009-04-06 18:47:14 -04004163 * lpfc_stat_data_ctrl_store - write call back for lpfc_stat_data_ctrl sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004164 * @dev: Pointer to class device.
4165 * @buf: Data buffer.
4166 * @count: Size of the data buffer.
4167 *
Masahiro Yamada9332ef92017-02-27 14:28:47 -08004168 * This function get called when a user write to the lpfc_stat_data_ctrl
James Smartea2151b2008-09-07 11:52:10 -04004169 * sysfs file. This function parse the command written to the sysfs file
4170 * and take appropriate action. These commands are used for controlling
4171 * driver statistical data collection.
4172 * Following are the command this function handles.
4173 *
4174 * setbucket <bucket_type> <base> <step>
4175 * = Set the latency buckets.
4176 * destroybucket = destroy all the buckets.
4177 * start = start data collection
4178 * stop = stop data collection
4179 * reset = reset the collected data
4180 **/
4181static ssize_t
4182lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
4183 const char *buf, size_t count)
4184{
4185 struct Scsi_Host *shost = class_to_shost(dev);
4186 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4187 struct lpfc_hba *phba = vport->phba;
4188#define LPFC_MAX_DATA_CTRL_LEN 1024
4189 static char bucket_data[LPFC_MAX_DATA_CTRL_LEN];
4190 unsigned long i;
4191 char *str_ptr, *token;
4192 struct lpfc_vport **vports;
4193 struct Scsi_Host *v_shost;
4194 char *bucket_type_str, *base_str, *step_str;
4195 unsigned long base, step, bucket_type;
4196
4197 if (!strncmp(buf, "setbucket", strlen("setbucket"))) {
James Smarta257bf92009-04-06 18:48:10 -04004198 if (strlen(buf) > (LPFC_MAX_DATA_CTRL_LEN - 1))
James Smartea2151b2008-09-07 11:52:10 -04004199 return -EINVAL;
4200
James Smarteb016562014-09-03 12:58:06 -04004201 strncpy(bucket_data, buf, LPFC_MAX_DATA_CTRL_LEN);
James Smartea2151b2008-09-07 11:52:10 -04004202 str_ptr = &bucket_data[0];
4203 /* Ignore this token - this is command token */
4204 token = strsep(&str_ptr, "\t ");
4205 if (!token)
4206 return -EINVAL;
4207
4208 bucket_type_str = strsep(&str_ptr, "\t ");
4209 if (!bucket_type_str)
4210 return -EINVAL;
4211
4212 if (!strncmp(bucket_type_str, "linear", strlen("linear")))
4213 bucket_type = LPFC_LINEAR_BUCKET;
4214 else if (!strncmp(bucket_type_str, "power2", strlen("power2")))
4215 bucket_type = LPFC_POWER2_BUCKET;
4216 else
4217 return -EINVAL;
4218
4219 base_str = strsep(&str_ptr, "\t ");
4220 if (!base_str)
4221 return -EINVAL;
4222 base = simple_strtoul(base_str, NULL, 0);
4223
4224 step_str = strsep(&str_ptr, "\t ");
4225 if (!step_str)
4226 return -EINVAL;
4227 step = simple_strtoul(step_str, NULL, 0);
4228 if (!step)
4229 return -EINVAL;
4230
4231 /* Block the data collection for every vport */
4232 vports = lpfc_create_vport_work_array(phba);
4233 if (vports == NULL)
4234 return -ENOMEM;
4235
James Smartf4b4c682009-05-22 14:53:12 -04004236 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004237 v_shost = lpfc_shost_from_vport(vports[i]);
4238 spin_lock_irq(v_shost->host_lock);
4239 /* Block and reset data collection */
4240 vports[i]->stat_data_blocked = 1;
4241 if (vports[i]->stat_data_enabled)
4242 lpfc_vport_reset_stat_data(vports[i]);
4243 spin_unlock_irq(v_shost->host_lock);
4244 }
4245
4246 /* Set the bucket attributes */
4247 phba->bucket_type = bucket_type;
4248 phba->bucket_base = base;
4249 phba->bucket_step = step;
4250
James Smartf4b4c682009-05-22 14:53:12 -04004251 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004252 v_shost = lpfc_shost_from_vport(vports[i]);
4253
4254 /* Unblock data collection */
4255 spin_lock_irq(v_shost->host_lock);
4256 vports[i]->stat_data_blocked = 0;
4257 spin_unlock_irq(v_shost->host_lock);
4258 }
4259 lpfc_destroy_vport_work_array(phba, vports);
4260 return strlen(buf);
4261 }
4262
4263 if (!strncmp(buf, "destroybucket", strlen("destroybucket"))) {
4264 vports = lpfc_create_vport_work_array(phba);
4265 if (vports == NULL)
4266 return -ENOMEM;
4267
James Smartf4b4c682009-05-22 14:53:12 -04004268 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
James Smartea2151b2008-09-07 11:52:10 -04004269 v_shost = lpfc_shost_from_vport(vports[i]);
4270 spin_lock_irq(shost->host_lock);
4271 vports[i]->stat_data_blocked = 1;
4272 lpfc_free_bucket(vport);
4273 vport->stat_data_enabled = 0;
4274 vports[i]->stat_data_blocked = 0;
4275 spin_unlock_irq(shost->host_lock);
4276 }
4277 lpfc_destroy_vport_work_array(phba, vports);
4278 phba->bucket_type = LPFC_NO_BUCKET;
4279 phba->bucket_base = 0;
4280 phba->bucket_step = 0;
4281 return strlen(buf);
4282 }
4283
4284 if (!strncmp(buf, "start", strlen("start"))) {
4285 /* If no buckets configured return error */
4286 if (phba->bucket_type == LPFC_NO_BUCKET)
4287 return -EINVAL;
4288 spin_lock_irq(shost->host_lock);
4289 if (vport->stat_data_enabled) {
4290 spin_unlock_irq(shost->host_lock);
4291 return strlen(buf);
4292 }
4293 lpfc_alloc_bucket(vport);
4294 vport->stat_data_enabled = 1;
4295 spin_unlock_irq(shost->host_lock);
4296 return strlen(buf);
4297 }
4298
4299 if (!strncmp(buf, "stop", strlen("stop"))) {
4300 spin_lock_irq(shost->host_lock);
4301 if (vport->stat_data_enabled == 0) {
4302 spin_unlock_irq(shost->host_lock);
4303 return strlen(buf);
4304 }
4305 lpfc_free_bucket(vport);
4306 vport->stat_data_enabled = 0;
4307 spin_unlock_irq(shost->host_lock);
4308 return strlen(buf);
4309 }
4310
4311 if (!strncmp(buf, "reset", strlen("reset"))) {
4312 if ((phba->bucket_type == LPFC_NO_BUCKET)
4313 || !vport->stat_data_enabled)
4314 return strlen(buf);
4315 spin_lock_irq(shost->host_lock);
4316 vport->stat_data_blocked = 1;
4317 lpfc_vport_reset_stat_data(vport);
4318 vport->stat_data_blocked = 0;
4319 spin_unlock_irq(shost->host_lock);
4320 return strlen(buf);
4321 }
4322 return -EINVAL;
4323}
4324
4325
4326/**
James Smart3621a712009-04-06 18:47:14 -04004327 * lpfc_stat_data_ctrl_show - Read function for lpfc_stat_data_ctrl sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004328 * @dev: Pointer to class device object.
4329 * @buf: Data buffer.
4330 *
4331 * This function is the read call back function for
4332 * lpfc_stat_data_ctrl sysfs file. This function report the
4333 * current statistical data collection state.
4334 **/
4335static ssize_t
4336lpfc_stat_data_ctrl_show(struct device *dev, struct device_attribute *attr,
4337 char *buf)
4338{
4339 struct Scsi_Host *shost = class_to_shost(dev);
4340 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4341 struct lpfc_hba *phba = vport->phba;
4342 int index = 0;
4343 int i;
4344 char *bucket_type;
4345 unsigned long bucket_value;
4346
4347 switch (phba->bucket_type) {
4348 case LPFC_LINEAR_BUCKET:
4349 bucket_type = "linear";
4350 break;
4351 case LPFC_POWER2_BUCKET:
4352 bucket_type = "power2";
4353 break;
4354 default:
4355 bucket_type = "No Bucket";
4356 break;
4357 }
4358
4359 sprintf(&buf[index], "Statistical Data enabled :%d, "
4360 "blocked :%d, Bucket type :%s, Bucket base :%d,"
4361 " Bucket step :%d\nLatency Ranges :",
4362 vport->stat_data_enabled, vport->stat_data_blocked,
4363 bucket_type, phba->bucket_base, phba->bucket_step);
4364 index = strlen(buf);
4365 if (phba->bucket_type != LPFC_NO_BUCKET) {
4366 for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
4367 if (phba->bucket_type == LPFC_LINEAR_BUCKET)
4368 bucket_value = phba->bucket_base +
4369 phba->bucket_step * i;
4370 else
4371 bucket_value = phba->bucket_base +
4372 (1 << i) * phba->bucket_step;
4373
4374 if (index + 10 > PAGE_SIZE)
4375 break;
4376 sprintf(&buf[index], "%08ld ", bucket_value);
4377 index = strlen(buf);
4378 }
4379 }
4380 sprintf(&buf[index], "\n");
4381 return strlen(buf);
4382}
4383
4384/*
4385 * Sysfs attribute to control the statistical data collection.
4386 */
Joe Perchesb6b996b2017-12-19 10:15:07 -08004387static DEVICE_ATTR_RW(lpfc_stat_data_ctrl);
James Smartea2151b2008-09-07 11:52:10 -04004388
4389/*
4390 * lpfc_drvr_stat_data: sysfs attr to get driver statistical data.
4391 */
4392
4393/*
4394 * Each Bucket takes 11 characters and 1 new line + 17 bytes WWN
4395 * for each target.
4396 */
4397#define STAT_DATA_SIZE_PER_TARGET(NUM_BUCKETS) ((NUM_BUCKETS) * 11 + 18)
4398#define MAX_STAT_DATA_SIZE_PER_TARGET \
4399 STAT_DATA_SIZE_PER_TARGET(LPFC_MAX_BUCKET_COUNT)
4400
4401
4402/**
James Smart3621a712009-04-06 18:47:14 -04004403 * sysfs_drvr_stat_data_read - Read function for lpfc_drvr_stat_data attribute
Chris Wright2c3c8be2010-05-12 18:28:57 -07004404 * @filp: sysfs file
James Smartea2151b2008-09-07 11:52:10 -04004405 * @kobj: Pointer to the kernel object
4406 * @bin_attr: Attribute object
4407 * @buff: Buffer pointer
4408 * @off: File offset
4409 * @count: Buffer size
4410 *
4411 * This function is the read call back function for lpfc_drvr_stat_data
4412 * sysfs file. This function export the statistical data to user
4413 * applications.
4414 **/
4415static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07004416sysfs_drvr_stat_data_read(struct file *filp, struct kobject *kobj,
4417 struct bin_attribute *bin_attr,
James Smartea2151b2008-09-07 11:52:10 -04004418 char *buf, loff_t off, size_t count)
4419{
4420 struct device *dev = container_of(kobj, struct device,
4421 kobj);
4422 struct Scsi_Host *shost = class_to_shost(dev);
4423 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4424 struct lpfc_hba *phba = vport->phba;
4425 int i = 0, index = 0;
4426 unsigned long nport_index;
4427 struct lpfc_nodelist *ndlp = NULL;
4428 nport_index = (unsigned long)off /
4429 MAX_STAT_DATA_SIZE_PER_TARGET;
4430
4431 if (!vport->stat_data_enabled || vport->stat_data_blocked
4432 || (phba->bucket_type == LPFC_NO_BUCKET))
4433 return 0;
4434
4435 spin_lock_irq(shost->host_lock);
4436 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
4437 if (!NLP_CHK_NODE_ACT(ndlp) || !ndlp->lat_data)
4438 continue;
4439
4440 if (nport_index > 0) {
4441 nport_index--;
4442 continue;
4443 }
4444
4445 if ((index + MAX_STAT_DATA_SIZE_PER_TARGET)
4446 > count)
4447 break;
4448
4449 if (!ndlp->lat_data)
4450 continue;
4451
4452 /* Print the WWN */
4453 sprintf(&buf[index], "%02x%02x%02x%02x%02x%02x%02x%02x:",
4454 ndlp->nlp_portname.u.wwn[0],
4455 ndlp->nlp_portname.u.wwn[1],
4456 ndlp->nlp_portname.u.wwn[2],
4457 ndlp->nlp_portname.u.wwn[3],
4458 ndlp->nlp_portname.u.wwn[4],
4459 ndlp->nlp_portname.u.wwn[5],
4460 ndlp->nlp_portname.u.wwn[6],
4461 ndlp->nlp_portname.u.wwn[7]);
4462
4463 index = strlen(buf);
4464
4465 for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
4466 sprintf(&buf[index], "%010u,",
4467 ndlp->lat_data[i].cmd_count);
4468 index = strlen(buf);
4469 }
4470 sprintf(&buf[index], "\n");
4471 index = strlen(buf);
4472 }
4473 spin_unlock_irq(shost->host_lock);
4474 return index;
4475}
4476
4477static struct bin_attribute sysfs_drvr_stat_data_attr = {
4478 .attr = {
4479 .name = "lpfc_drvr_stat_data",
4480 .mode = S_IRUSR,
James Smartea2151b2008-09-07 11:52:10 -04004481 },
4482 .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET,
4483 .read = sysfs_drvr_stat_data_read,
4484 .write = NULL,
4485};
4486
dea31012005-04-17 16:05:31 -05004487/*
4488# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
4489# connection.
James Smart76a95d72010-11-20 23:11:48 -05004490# Value range is [0,16]. Default value is 0.
dea31012005-04-17 16:05:31 -05004491*/
James Smarte59058c2008-08-24 21:49:00 -04004492/**
James Smart3621a712009-04-06 18:47:14 -04004493 * lpfc_link_speed_set - Set the adapters link speed
James Smarte59058c2008-08-24 21:49:00 -04004494 * @phba: lpfc_hba pointer.
4495 * @val: link speed value.
4496 *
4497 * Description:
4498 * If val is in a valid range then set the adapter's link speed field and
4499 * issue a lip; if the lip fails reset the link speed to the old value.
4500 *
4501 * Notes:
4502 * If the value is not in range log a kernel error message and return an error.
4503 *
4504 * Returns:
4505 * zero if val is in range and lip okay.
4506 * non-zero return value from lpfc_issue_lip()
4507 * -EINVAL val out of range
4508 **/
James Smarta257bf92009-04-06 18:48:10 -04004509static ssize_t
4510lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
4511 const char *buf, size_t count)
James Smart83108bd2008-01-11 01:53:09 -05004512{
James Smarta257bf92009-04-06 18:48:10 -04004513 struct Scsi_Host *shost = class_to_shost(dev);
4514 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4515 struct lpfc_hba *phba = vport->phba;
James Smart76a95d72010-11-20 23:11:48 -05004516 int val = LPFC_USER_LINK_SPEED_AUTO;
James Smarta257bf92009-04-06 18:48:10 -04004517 int nolip = 0;
4518 const char *val_buf = buf;
James Smart83108bd2008-01-11 01:53:09 -05004519 int err;
James Smartc6918162016-10-13 15:06:16 -07004520 uint32_t prev_val, if_type;
4521
4522 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
James Smart719162b2018-12-10 19:37:01 -08004523 if (if_type >= LPFC_SLI_INTF_IF_TYPE_2 &&
James Smartc6918162016-10-13 15:06:16 -07004524 phba->hba_flag & HBA_FORCED_LINK_SPEED)
4525 return -EPERM;
James Smart83108bd2008-01-11 01:53:09 -05004526
James Smarta257bf92009-04-06 18:48:10 -04004527 if (!strncmp(buf, "nolip ", strlen("nolip "))) {
4528 nolip = 1;
4529 val_buf = &buf[strlen("nolip ")];
4530 }
4531
4532 if (!isdigit(val_buf[0]))
4533 return -EINVAL;
4534 if (sscanf(val_buf, "%i", &val) != 1)
4535 return -EINVAL;
4536
James Smart88a2cfb2011-07-22 18:36:33 -04004537 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4538 "3055 lpfc_link_speed changed from %d to %d %s\n",
4539 phba->cfg_link_speed, val, nolip ? "(nolip)" : "(lip)");
4540
James Smart76a95d72010-11-20 23:11:48 -05004541 if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
4542 ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
4543 ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
4544 ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
4545 ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
James Smartd38dd522015-08-31 16:48:17 -04004546 ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
James Smartfbd8a6b2018-02-22 08:18:45 -08004547 ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
4548 ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
James Smart76a95d72010-11-20 23:11:48 -05004549 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4550 "2879 lpfc_link_speed attribute cannot be set "
4551 "to %d. Speed is not supported by this port.\n",
4552 val);
James Smart83108bd2008-01-11 01:53:09 -05004553 return -EINVAL;
James Smart76a95d72010-11-20 23:11:48 -05004554 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004555 if (val >= LPFC_USER_LINK_SPEED_16G &&
4556 phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smartff78d8f2011-12-13 13:21:35 -05004557 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4558 "3112 lpfc_link_speed attribute cannot be set "
4559 "to %d. Speed is not supported in loop mode.\n",
4560 val);
4561 return -EINVAL;
4562 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004563
4564 switch (val) {
4565 case LPFC_USER_LINK_SPEED_AUTO:
4566 case LPFC_USER_LINK_SPEED_1G:
4567 case LPFC_USER_LINK_SPEED_2G:
4568 case LPFC_USER_LINK_SPEED_4G:
4569 case LPFC_USER_LINK_SPEED_8G:
4570 case LPFC_USER_LINK_SPEED_16G:
4571 case LPFC_USER_LINK_SPEED_32G:
4572 case LPFC_USER_LINK_SPEED_64G:
James Smart83108bd2008-01-11 01:53:09 -05004573 prev_val = phba->cfg_link_speed;
4574 phba->cfg_link_speed = val;
James Smarta257bf92009-04-06 18:48:10 -04004575 if (nolip)
4576 return strlen(buf);
4577
James Smart83108bd2008-01-11 01:53:09 -05004578 err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
James Smarta257bf92009-04-06 18:48:10 -04004579 if (err) {
James Smart83108bd2008-01-11 01:53:09 -05004580 phba->cfg_link_speed = prev_val;
James Smarta257bf92009-04-06 18:48:10 -04004581 return -EINVAL;
James Smartfbd8a6b2018-02-22 08:18:45 -08004582 }
4583 return strlen(buf);
4584 default:
4585 break;
James Smart83108bd2008-01-11 01:53:09 -05004586 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004587
James Smart83108bd2008-01-11 01:53:09 -05004588 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smartfbd8a6b2018-02-22 08:18:45 -08004589 "0469 lpfc_link_speed attribute cannot be set to %d, "
4590 "allowed values are [%s]\n",
4591 val, LPFC_LINK_SPEED_STRING);
James Smart83108bd2008-01-11 01:53:09 -05004592 return -EINVAL;
James Smartfbd8a6b2018-02-22 08:18:45 -08004593
James Smart83108bd2008-01-11 01:53:09 -05004594}
4595
4596static int lpfc_link_speed = 0;
James Smartab56dc22011-02-16 12:39:57 -05004597module_param(lpfc_link_speed, int, S_IRUGO);
James Smart83108bd2008-01-11 01:53:09 -05004598MODULE_PARM_DESC(lpfc_link_speed, "Select link speed");
4599lpfc_param_show(link_speed)
James Smarte59058c2008-08-24 21:49:00 -04004600
4601/**
James Smart3621a712009-04-06 18:47:14 -04004602 * lpfc_link_speed_init - Set the adapters link speed
James Smarte59058c2008-08-24 21:49:00 -04004603 * @phba: lpfc_hba pointer.
4604 * @val: link speed value.
4605 *
4606 * Description:
4607 * If val is in a valid range then set the adapter's link speed field.
4608 *
4609 * Notes:
4610 * If the value is not in range log a kernel error message, clear the link
4611 * speed and return an error.
4612 *
4613 * Returns:
4614 * zero if val saved.
4615 * -EINVAL val out of range
4616 **/
James Smart83108bd2008-01-11 01:53:09 -05004617static int
4618lpfc_link_speed_init(struct lpfc_hba *phba, int val)
4619{
James Smartfbd8a6b2018-02-22 08:18:45 -08004620 if (val >= LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) {
James Smartff78d8f2011-12-13 13:21:35 -05004621 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4622 "3111 lpfc_link_speed of %d cannot "
4623 "support loop mode, setting topology to default.\n",
4624 val);
4625 phba->cfg_topology = 0;
4626 }
James Smartfbd8a6b2018-02-22 08:18:45 -08004627
4628 switch (val) {
4629 case LPFC_USER_LINK_SPEED_AUTO:
4630 case LPFC_USER_LINK_SPEED_1G:
4631 case LPFC_USER_LINK_SPEED_2G:
4632 case LPFC_USER_LINK_SPEED_4G:
4633 case LPFC_USER_LINK_SPEED_8G:
4634 case LPFC_USER_LINK_SPEED_16G:
4635 case LPFC_USER_LINK_SPEED_32G:
4636 case LPFC_USER_LINK_SPEED_64G:
James Smart83108bd2008-01-11 01:53:09 -05004637 phba->cfg_link_speed = val;
4638 return 0;
James Smartfbd8a6b2018-02-22 08:18:45 -08004639 default:
4640 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4641 "0405 lpfc_link_speed attribute cannot "
4642 "be set to %d, allowed values are "
4643 "["LPFC_LINK_SPEED_STRING"]\n", val);
4644 phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
4645 return -EINVAL;
James Smart83108bd2008-01-11 01:53:09 -05004646 }
James Smart83108bd2008-01-11 01:53:09 -05004647}
4648
Joe Perchesb6b996b2017-12-19 10:15:07 -08004649static DEVICE_ATTR_RW(lpfc_link_speed);
dea31012005-04-17 16:05:31 -05004650
4651/*
James Smart0d878412009-10-02 15:16:56 -04004652# lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
4653# 0 = aer disabled or not supported
4654# 1 = aer supported and enabled (default)
4655# Value range is [0,1]. Default value is 1.
4656*/
James Smart506139a2016-10-13 15:06:09 -07004657LPFC_ATTR(aer_support, 1, 0, 1,
4658 "Enable PCIe device AER support");
4659lpfc_param_show(aer_support)
James Smart0d878412009-10-02 15:16:56 -04004660
4661/**
4662 * lpfc_aer_support_store - Set the adapter for aer support
4663 *
4664 * @dev: class device that is converted into a Scsi_host.
4665 * @attr: device attribute, not used.
James Smart912e3ac2011-05-24 11:42:11 -04004666 * @buf: containing enable or disable aer flag.
James Smart0d878412009-10-02 15:16:56 -04004667 * @count: unused variable.
4668 *
4669 * Description:
4670 * If the val is 1 and currently the device's AER capability was not
4671 * enabled, invoke the kernel's enable AER helper routine, trying to
4672 * enable the device's AER capability. If the helper routine enabling
4673 * AER returns success, update the device's cfg_aer_support flag to
4674 * indicate AER is supported by the device; otherwise, if the device
4675 * AER capability is already enabled to support AER, then do nothing.
4676 *
4677 * If the val is 0 and currently the device's AER support was enabled,
4678 * invoke the kernel's disable AER helper routine. After that, update
4679 * the device's cfg_aer_support flag to indicate AER is not supported
4680 * by the device; otherwise, if the device AER capability is already
4681 * disabled from supporting AER, then do nothing.
4682 *
4683 * Returns:
4684 * length of the buf on success if val is in range the intended mode
4685 * is supported.
4686 * -EINVAL if val out of range or intended mode is not supported.
4687 **/
4688static ssize_t
4689lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
4690 const char *buf, size_t count)
4691{
4692 struct Scsi_Host *shost = class_to_shost(dev);
4693 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4694 struct lpfc_hba *phba = vport->phba;
4695 int val = 0, rc = -EINVAL;
4696
4697 if (!isdigit(buf[0]))
4698 return -EINVAL;
4699 if (sscanf(buf, "%i", &val) != 1)
4700 return -EINVAL;
4701
4702 switch (val) {
4703 case 0:
4704 if (phba->hba_flag & HBA_AER_ENABLED) {
4705 rc = pci_disable_pcie_error_reporting(phba->pcidev);
4706 if (!rc) {
4707 spin_lock_irq(&phba->hbalock);
4708 phba->hba_flag &= ~HBA_AER_ENABLED;
4709 spin_unlock_irq(&phba->hbalock);
4710 phba->cfg_aer_support = 0;
4711 rc = strlen(buf);
4712 } else
James Smart891478a2009-11-18 15:40:23 -05004713 rc = -EPERM;
4714 } else {
James Smart0d878412009-10-02 15:16:56 -04004715 phba->cfg_aer_support = 0;
James Smart891478a2009-11-18 15:40:23 -05004716 rc = strlen(buf);
4717 }
James Smart0d878412009-10-02 15:16:56 -04004718 break;
4719 case 1:
4720 if (!(phba->hba_flag & HBA_AER_ENABLED)) {
4721 rc = pci_enable_pcie_error_reporting(phba->pcidev);
4722 if (!rc) {
4723 spin_lock_irq(&phba->hbalock);
4724 phba->hba_flag |= HBA_AER_ENABLED;
4725 spin_unlock_irq(&phba->hbalock);
4726 phba->cfg_aer_support = 1;
4727 rc = strlen(buf);
4728 } else
James Smart891478a2009-11-18 15:40:23 -05004729 rc = -EPERM;
4730 } else {
James Smart0d878412009-10-02 15:16:56 -04004731 phba->cfg_aer_support = 1;
James Smart891478a2009-11-18 15:40:23 -05004732 rc = strlen(buf);
4733 }
James Smart0d878412009-10-02 15:16:56 -04004734 break;
4735 default:
4736 rc = -EINVAL;
4737 break;
4738 }
4739 return rc;
4740}
4741
Joe Perchesb6b996b2017-12-19 10:15:07 -08004742static DEVICE_ATTR_RW(lpfc_aer_support);
James Smart0d878412009-10-02 15:16:56 -04004743
4744/**
4745 * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device
4746 * @dev: class device that is converted into a Scsi_host.
4747 * @attr: device attribute, not used.
James Smart912e3ac2011-05-24 11:42:11 -04004748 * @buf: containing flag 1 for aer cleanup state.
James Smart0d878412009-10-02 15:16:56 -04004749 * @count: unused variable.
4750 *
4751 * Description:
4752 * If the @buf contains 1 and the device currently has the AER support
4753 * enabled, then invokes the kernel AER helper routine
4754 * pci_cleanup_aer_uncorrect_error_status to clean up the uncorrectable
4755 * error status register.
4756 *
4757 * Notes:
4758 *
4759 * Returns:
4760 * -EINVAL if the buf does not contain the 1 or the device is not currently
4761 * enabled with the AER support.
4762 **/
4763static ssize_t
4764lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr,
4765 const char *buf, size_t count)
4766{
4767 struct Scsi_Host *shost = class_to_shost(dev);
4768 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4769 struct lpfc_hba *phba = vport->phba;
4770 int val, rc = -1;
4771
4772 if (!isdigit(buf[0]))
4773 return -EINVAL;
4774 if (sscanf(buf, "%i", &val) != 1)
4775 return -EINVAL;
James Smart891478a2009-11-18 15:40:23 -05004776 if (val != 1)
4777 return -EINVAL;
James Smart0d878412009-10-02 15:16:56 -04004778
James Smart891478a2009-11-18 15:40:23 -05004779 if (phba->hba_flag & HBA_AER_ENABLED)
James Smart0d878412009-10-02 15:16:56 -04004780 rc = pci_cleanup_aer_uncorrect_error_status(phba->pcidev);
4781
4782 if (rc == 0)
4783 return strlen(buf);
4784 else
James Smart891478a2009-11-18 15:40:23 -05004785 return -EPERM;
James Smart0d878412009-10-02 15:16:56 -04004786}
4787
4788static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
4789 lpfc_aer_cleanup_state);
4790
James Smart912e3ac2011-05-24 11:42:11 -04004791/**
4792 * lpfc_sriov_nr_virtfn_store - Enable the adapter for sr-iov virtual functions
4793 *
4794 * @dev: class device that is converted into a Scsi_host.
4795 * @attr: device attribute, not used.
4796 * @buf: containing the string the number of vfs to be enabled.
4797 * @count: unused variable.
4798 *
4799 * Description:
4800 * When this api is called either through user sysfs, the driver shall
4801 * try to enable or disable SR-IOV virtual functions according to the
4802 * following:
4803 *
4804 * If zero virtual function has been enabled to the physical function,
4805 * the driver shall invoke the pci enable virtual function api trying
4806 * to enable the virtual functions. If the nr_vfn provided is greater
4807 * than the maximum supported, the maximum virtual function number will
4808 * be used for invoking the api; otherwise, the nr_vfn provided shall
4809 * be used for invoking the api. If the api call returned success, the
4810 * actual number of virtual functions enabled will be set to the driver
4811 * cfg_sriov_nr_virtfn; otherwise, -EINVAL shall be returned and driver
4812 * cfg_sriov_nr_virtfn remains zero.
4813 *
4814 * If none-zero virtual functions have already been enabled to the
4815 * physical function, as reflected by the driver's cfg_sriov_nr_virtfn,
4816 * -EINVAL will be returned and the driver does nothing;
4817 *
4818 * If the nr_vfn provided is zero and none-zero virtual functions have
4819 * been enabled, as indicated by the driver's cfg_sriov_nr_virtfn, the
4820 * disabling virtual function api shall be invoded to disable all the
4821 * virtual functions and driver's cfg_sriov_nr_virtfn shall be set to
4822 * zero. Otherwise, if zero virtual function has been enabled, do
4823 * nothing.
4824 *
4825 * Returns:
4826 * length of the buf on success if val is in range the intended mode
4827 * is supported.
4828 * -EINVAL if val out of range or intended mode is not supported.
4829 **/
4830static ssize_t
4831lpfc_sriov_nr_virtfn_store(struct device *dev, struct device_attribute *attr,
4832 const char *buf, size_t count)
4833{
4834 struct Scsi_Host *shost = class_to_shost(dev);
4835 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4836 struct lpfc_hba *phba = vport->phba;
4837 struct pci_dev *pdev = phba->pcidev;
4838 int val = 0, rc = -EINVAL;
4839
4840 /* Sanity check on user data */
4841 if (!isdigit(buf[0]))
4842 return -EINVAL;
4843 if (sscanf(buf, "%i", &val) != 1)
4844 return -EINVAL;
4845 if (val < 0)
4846 return -EINVAL;
4847
4848 /* Request disabling virtual functions */
4849 if (val == 0) {
4850 if (phba->cfg_sriov_nr_virtfn > 0) {
4851 pci_disable_sriov(pdev);
4852 phba->cfg_sriov_nr_virtfn = 0;
4853 }
4854 return strlen(buf);
4855 }
4856
4857 /* Request enabling virtual functions */
4858 if (phba->cfg_sriov_nr_virtfn > 0) {
4859 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4860 "3018 There are %d virtual functions "
4861 "enabled on physical function.\n",
4862 phba->cfg_sriov_nr_virtfn);
4863 return -EEXIST;
4864 }
4865
4866 if (val <= LPFC_MAX_VFN_PER_PFN)
4867 phba->cfg_sriov_nr_virtfn = val;
4868 else {
4869 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
4870 "3019 Enabling %d virtual functions is not "
4871 "allowed.\n", val);
4872 return -EINVAL;
4873 }
4874
4875 rc = lpfc_sli_probe_sriov_nr_virtfn(phba, phba->cfg_sriov_nr_virtfn);
4876 if (rc) {
4877 phba->cfg_sriov_nr_virtfn = 0;
4878 rc = -EPERM;
4879 } else
4880 rc = strlen(buf);
4881
4882 return rc;
4883}
4884
James Smart0cfbbf22016-10-13 15:06:12 -07004885LPFC_ATTR(sriov_nr_virtfn, LPFC_DEF_VFN_PER_PFN, 0, LPFC_MAX_VFN_PER_PFN,
4886 "Enable PCIe device SR-IOV virtual fn");
4887
James Smart912e3ac2011-05-24 11:42:11 -04004888lpfc_param_show(sriov_nr_virtfn)
Joe Perchesb6b996b2017-12-19 10:15:07 -08004889static DEVICE_ATTR_RW(lpfc_sriov_nr_virtfn);
James Smart912e3ac2011-05-24 11:42:11 -04004890
James Smart173edbb2012-06-12 13:54:50 -04004891/**
James Smartc71ab862012-10-31 14:44:33 -04004892 * lpfc_request_firmware_store - Request for Linux generic firmware upgrade
4893 *
4894 * @dev: class device that is converted into a Scsi_host.
4895 * @attr: device attribute, not used.
4896 * @buf: containing the string the number of vfs to be enabled.
4897 * @count: unused variable.
4898 *
4899 * Description:
4900 *
4901 * Returns:
4902 * length of the buf on success if val is in range the intended mode
4903 * is supported.
4904 * -EINVAL if val out of range or intended mode is not supported.
4905 **/
4906static ssize_t
4907lpfc_request_firmware_upgrade_store(struct device *dev,
4908 struct device_attribute *attr,
4909 const char *buf, size_t count)
4910{
4911 struct Scsi_Host *shost = class_to_shost(dev);
4912 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4913 struct lpfc_hba *phba = vport->phba;
4914 int val = 0, rc = -EINVAL;
4915
4916 /* Sanity check on user data */
4917 if (!isdigit(buf[0]))
4918 return -EINVAL;
4919 if (sscanf(buf, "%i", &val) != 1)
4920 return -EINVAL;
4921 if (val != 1)
4922 return -EINVAL;
4923
4924 rc = lpfc_sli4_request_firmware_update(phba, RUN_FW_UPGRADE);
4925 if (rc)
4926 rc = -EPERM;
4927 else
4928 rc = strlen(buf);
4929 return rc;
4930}
4931
4932static int lpfc_req_fw_upgrade;
4933module_param(lpfc_req_fw_upgrade, int, S_IRUGO|S_IWUSR);
4934MODULE_PARM_DESC(lpfc_req_fw_upgrade, "Enable Linux generic firmware upgrade");
4935lpfc_param_show(request_firmware_upgrade)
4936
4937/**
4938 * lpfc_request_firmware_upgrade_init - Enable initial linux generic fw upgrade
4939 * @phba: lpfc_hba pointer.
4940 * @val: 0 or 1.
4941 *
4942 * Description:
4943 * Set the initial Linux generic firmware upgrade enable or disable flag.
4944 *
4945 * Returns:
4946 * zero if val saved.
4947 * -EINVAL val out of range
4948 **/
4949static int
4950lpfc_request_firmware_upgrade_init(struct lpfc_hba *phba, int val)
4951{
4952 if (val >= 0 && val <= 1) {
4953 phba->cfg_request_firmware_upgrade = val;
4954 return 0;
4955 }
4956 return -EINVAL;
4957}
4958static DEVICE_ATTR(lpfc_req_fw_upgrade, S_IRUGO | S_IWUSR,
4959 lpfc_request_firmware_upgrade_show,
4960 lpfc_request_firmware_upgrade_store);
4961
4962/**
James Smart41b194b2019-05-14 14:58:08 -07004963 * lpfc_force_rscn_store
4964 *
4965 * @dev: class device that is converted into a Scsi_host.
4966 * @attr: device attribute, not used.
4967 * @buf: unused string
4968 * @count: unused variable.
4969 *
4970 * Description:
4971 * Force the switch to send a RSCN to all other NPorts in our zone
4972 * If we are direct connect pt2pt, build the RSCN command ourself
4973 * and send to the other NPort. Not supported for private loop.
4974 *
4975 * Returns:
4976 * 0 - on success
4977 * -EIO - if command is not sent
4978 **/
4979static ssize_t
4980lpfc_force_rscn_store(struct device *dev, struct device_attribute *attr,
4981 const char *buf, size_t count)
4982{
4983 struct Scsi_Host *shost = class_to_shost(dev);
4984 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
4985 int i;
4986
4987 i = lpfc_issue_els_rscn(vport, 0);
4988 if (i)
4989 return -EIO;
4990 return strlen(buf);
4991}
4992
4993/*
4994 * lpfc_force_rscn: Force an RSCN to be sent to all remote NPorts
4995 * connected to the HBA.
4996 *
4997 * Value range is any ascii value
4998 */
4999static int lpfc_force_rscn;
5000module_param(lpfc_force_rscn, int, 0644);
5001MODULE_PARM_DESC(lpfc_force_rscn,
5002 "Force an RSCN to be sent to all remote NPorts");
5003lpfc_param_show(force_rscn)
5004
5005/**
5006 * lpfc_force_rscn_init - Force an RSCN to be sent to all remote NPorts
5007 * @phba: lpfc_hba pointer.
5008 * @val: unused value.
5009 *
5010 * Returns:
5011 * zero if val saved.
5012 **/
5013static int
5014lpfc_force_rscn_init(struct lpfc_hba *phba, int val)
5015{
5016 return 0;
5017}
5018static DEVICE_ATTR_RW(lpfc_force_rscn);
5019
5020/**
James Smart173edbb2012-06-12 13:54:50 -04005021 * lpfc_fcp_imax_store
5022 *
5023 * @dev: class device that is converted into a Scsi_host.
5024 * @attr: device attribute, not used.
5025 * @buf: string with the number of fast-path FCP interrupts per second.
5026 * @count: unused variable.
5027 *
5028 * Description:
5029 * If val is in a valid range [636,651042], then set the adapter's
5030 * maximum number of fast-path FCP interrupts per second.
5031 *
5032 * Returns:
5033 * length of the buf on success if val is in range the intended mode
5034 * is supported.
5035 * -EINVAL if val out of range or intended mode is not supported.
5036 **/
5037static ssize_t
5038lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr,
5039 const char *buf, size_t count)
5040{
5041 struct Scsi_Host *shost = class_to_shost(dev);
5042 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5043 struct lpfc_hba *phba = vport->phba;
James Smart32517fc2019-01-28 11:14:33 -08005044 struct lpfc_eq_intr_info *eqi;
James Smartcb733e32019-01-28 11:14:32 -08005045 uint32_t usdelay;
James Smart173edbb2012-06-12 13:54:50 -04005046 int val = 0, i;
5047
James Smartbf8dae82012-08-03 12:36:24 -04005048 /* fcp_imax is only valid for SLI4 */
5049 if (phba->sli_rev != LPFC_SLI_REV4)
5050 return -EINVAL;
5051
James Smart173edbb2012-06-12 13:54:50 -04005052 /* Sanity check on user data */
5053 if (!isdigit(buf[0]))
5054 return -EINVAL;
5055 if (sscanf(buf, "%i", &val) != 1)
5056 return -EINVAL;
5057
James Smartbf8dae82012-08-03 12:36:24 -04005058 /*
5059 * Value range for the HBA is [5000,5000000]
5060 * The value for each EQ depends on how many EQs are configured.
James Smart895427b2017-02-12 13:52:30 -08005061 * Allow value == 0
James Smartbf8dae82012-08-03 12:36:24 -04005062 */
James Smart895427b2017-02-12 13:52:30 -08005063 if (val && (val < LPFC_MIN_IMAX || val > LPFC_MAX_IMAX))
James Smart173edbb2012-06-12 13:54:50 -04005064 return -EINVAL;
5065
James Smart32517fc2019-01-28 11:14:33 -08005066 phba->cfg_auto_imax = (val) ? 0 : 1;
5067 if (phba->cfg_fcp_imax && !val) {
5068 queue_delayed_work(phba->wq, &phba->eq_delay_work,
5069 msecs_to_jiffies(LPFC_EQ_DELAY_MSECS));
5070
5071 for_each_present_cpu(i) {
5072 eqi = per_cpu_ptr(phba->sli4_hba.eq_info, i);
5073 eqi->icnt = 0;
5074 }
5075 }
5076
James Smart173edbb2012-06-12 13:54:50 -04005077 phba->cfg_fcp_imax = (uint32_t)val;
James Smart43140ca2017-03-04 09:30:34 -08005078
James Smartcb733e32019-01-28 11:14:32 -08005079 if (phba->cfg_fcp_imax)
5080 usdelay = LPFC_SEC_TO_USEC / phba->cfg_fcp_imax;
5081 else
5082 usdelay = 0;
5083
James Smart6a828b02019-01-28 11:14:31 -08005084 for (i = 0; i < phba->cfg_irq_chann; i += LPFC_MAX_EQ_DELAY_EQID_CNT)
James Smart0cf07f842017-06-01 21:07:10 -07005085 lpfc_modify_hba_eq_delay(phba, i, LPFC_MAX_EQ_DELAY_EQID_CNT,
James Smartcb733e32019-01-28 11:14:32 -08005086 usdelay);
James Smart173edbb2012-06-12 13:54:50 -04005087
5088 return strlen(buf);
5089}
5090
5091/*
5092# lpfc_fcp_imax: The maximum number of fast-path FCP interrupts per second
James Smartbf8dae82012-08-03 12:36:24 -04005093# for the HBA.
James Smart173edbb2012-06-12 13:54:50 -04005094#
James Smartbf8dae82012-08-03 12:36:24 -04005095# Value range is [5,000 to 5,000,000]. Default value is 50,000.
James Smart173edbb2012-06-12 13:54:50 -04005096*/
James Smartbf8dae82012-08-03 12:36:24 -04005097static int lpfc_fcp_imax = LPFC_DEF_IMAX;
James Smart173edbb2012-06-12 13:54:50 -04005098module_param(lpfc_fcp_imax, int, S_IRUGO|S_IWUSR);
5099MODULE_PARM_DESC(lpfc_fcp_imax,
James Smartbf8dae82012-08-03 12:36:24 -04005100 "Set the maximum number of FCP interrupts per second per HBA");
James Smart173edbb2012-06-12 13:54:50 -04005101lpfc_param_show(fcp_imax)
5102
5103/**
5104 * lpfc_fcp_imax_init - Set the initial sr-iov virtual function enable
5105 * @phba: lpfc_hba pointer.
5106 * @val: link speed value.
5107 *
5108 * Description:
5109 * If val is in a valid range [636,651042], then initialize the adapter's
5110 * maximum number of fast-path FCP interrupts per second.
5111 *
5112 * Returns:
5113 * zero if val saved.
5114 * -EINVAL val out of range
5115 **/
5116static int
5117lpfc_fcp_imax_init(struct lpfc_hba *phba, int val)
5118{
James Smartbf8dae82012-08-03 12:36:24 -04005119 if (phba->sli_rev != LPFC_SLI_REV4) {
5120 phba->cfg_fcp_imax = 0;
5121 return 0;
5122 }
5123
James Smart895427b2017-02-12 13:52:30 -08005124 if ((val >= LPFC_MIN_IMAX && val <= LPFC_MAX_IMAX) ||
5125 (val == 0)) {
James Smart173edbb2012-06-12 13:54:50 -04005126 phba->cfg_fcp_imax = val;
5127 return 0;
5128 }
5129
5130 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07005131 "3016 lpfc_fcp_imax: %d out of range, using default\n",
5132 val);
James Smartbf8dae82012-08-03 12:36:24 -04005133 phba->cfg_fcp_imax = LPFC_DEF_IMAX;
James Smart173edbb2012-06-12 13:54:50 -04005134
5135 return 0;
5136}
5137
Joe Perchesb6b996b2017-12-19 10:15:07 -08005138static DEVICE_ATTR_RW(lpfc_fcp_imax);
James Smart173edbb2012-06-12 13:54:50 -04005139
James Smart32517fc2019-01-28 11:14:33 -08005140/**
5141 * lpfc_cq_max_proc_limit_store
5142 *
5143 * @dev: class device that is converted into a Scsi_host.
5144 * @attr: device attribute, not used.
5145 * @buf: string with the cq max processing limit of cqes
5146 * @count: unused variable.
5147 *
5148 * Description:
5149 * If val is in a valid range, then set value on each cq
5150 *
5151 * Returns:
5152 * The length of the buf: if successful
5153 * -ERANGE: if val is not in the valid range
5154 * -EINVAL: if bad value format or intended mode is not supported.
5155 **/
5156static ssize_t
5157lpfc_cq_max_proc_limit_store(struct device *dev, struct device_attribute *attr,
5158 const char *buf, size_t count)
5159{
5160 struct Scsi_Host *shost = class_to_shost(dev);
5161 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5162 struct lpfc_hba *phba = vport->phba;
5163 struct lpfc_queue *eq, *cq;
5164 unsigned long val;
5165 int i;
5166
5167 /* cq_max_proc_limit is only valid for SLI4 */
5168 if (phba->sli_rev != LPFC_SLI_REV4)
5169 return -EINVAL;
5170
5171 /* Sanity check on user data */
5172 if (!isdigit(buf[0]))
5173 return -EINVAL;
5174 if (kstrtoul(buf, 0, &val))
5175 return -EINVAL;
5176
5177 if (val < LPFC_CQ_MIN_PROC_LIMIT || val > LPFC_CQ_MAX_PROC_LIMIT)
5178 return -ERANGE;
5179
5180 phba->cfg_cq_max_proc_limit = (uint32_t)val;
5181
5182 /* set the values on the cq's */
5183 for (i = 0; i < phba->cfg_irq_chann; i++) {
James Smart657add42019-05-21 17:49:06 -07005184 /* Get the EQ corresponding to the IRQ vector */
5185 eq = phba->sli4_hba.hba_eq_hdl[i].eq;
James Smart32517fc2019-01-28 11:14:33 -08005186 if (!eq)
5187 continue;
5188
5189 list_for_each_entry(cq, &eq->child_list, list)
5190 cq->max_proc_limit = min(phba->cfg_cq_max_proc_limit,
5191 cq->entry_count);
5192 }
5193
5194 return strlen(buf);
5195}
5196
James Smart0cf07f842017-06-01 21:07:10 -07005197/*
James Smart32517fc2019-01-28 11:14:33 -08005198 * lpfc_cq_max_proc_limit: The maximum number CQE entries processed in an
5199 * itteration of CQ processing.
James Smart0cf07f842017-06-01 21:07:10 -07005200 */
James Smart32517fc2019-01-28 11:14:33 -08005201static int lpfc_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
5202module_param(lpfc_cq_max_proc_limit, int, 0644);
5203MODULE_PARM_DESC(lpfc_cq_max_proc_limit,
5204 "Set the maximum number CQEs processed in an iteration of "
5205 "CQ processing");
5206lpfc_param_show(cq_max_proc_limit)
5207
5208/*
5209 * lpfc_cq_poll_threshold: Set the threshold of CQE completions in a
5210 * single handler call which should request a polled completion rather
5211 * than re-enabling interrupts.
5212 */
5213LPFC_ATTR_RW(cq_poll_threshold, LPFC_CQ_DEF_THRESHOLD_TO_POLL,
5214 LPFC_CQ_MIN_THRESHOLD_TO_POLL,
5215 LPFC_CQ_MAX_THRESHOLD_TO_POLL,
5216 "CQE Processing Threshold to enable Polling");
5217
5218/**
5219 * lpfc_cq_max_proc_limit_init - Set the initial cq max_proc_limit
5220 * @phba: lpfc_hba pointer.
5221 * @val: entry limit
5222 *
5223 * Description:
5224 * If val is in a valid range, then initialize the adapter's maximum
5225 * value.
5226 *
5227 * Returns:
5228 * Always returns 0 for success, even if value not always set to
5229 * requested value. If value out of range or not supported, will fall
5230 * back to default.
5231 **/
5232static int
5233lpfc_cq_max_proc_limit_init(struct lpfc_hba *phba, int val)
5234{
5235 phba->cfg_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
5236
5237 if (phba->sli_rev != LPFC_SLI_REV4)
5238 return 0;
5239
5240 if (val >= LPFC_CQ_MIN_PROC_LIMIT && val <= LPFC_CQ_MAX_PROC_LIMIT) {
5241 phba->cfg_cq_max_proc_limit = val;
5242 return 0;
5243 }
5244
5245 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
5246 "0371 "LPFC_DRIVER_NAME"_cq_max_proc_limit: "
5247 "%d out of range, using default\n",
5248 phba->cfg_cq_max_proc_limit);
5249
5250 return 0;
5251}
5252
5253static DEVICE_ATTR_RW(lpfc_cq_max_proc_limit);
James Smart0cf07f842017-06-01 21:07:10 -07005254
James Smart7bb03bb2013-04-17 20:19:16 -04005255/**
5256 * lpfc_state_show - Display current driver CPU affinity
5257 * @dev: class converted to a Scsi_host structure.
5258 * @attr: device attribute, not used.
5259 * @buf: on return contains text describing the state of the link.
5260 *
5261 * Returns: size of formatted string.
5262 **/
5263static ssize_t
5264lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr,
5265 char *buf)
5266{
5267 struct Scsi_Host *shost = class_to_shost(dev);
5268 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5269 struct lpfc_hba *phba = vport->phba;
5270 struct lpfc_vector_map_info *cpup;
James Smart76fd07a2014-02-20 09:57:18 -05005271 int len = 0;
James Smart7bb03bb2013-04-17 20:19:16 -04005272
5273 if ((phba->sli_rev != LPFC_SLI_REV4) ||
5274 (phba->intr_type != MSIX))
5275 return len;
5276
5277 switch (phba->cfg_fcp_cpu_map) {
5278 case 0:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005279 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart7bb03bb2013-04-17 20:19:16 -04005280 "fcp_cpu_map: No mapping (%d)\n",
5281 phba->cfg_fcp_cpu_map);
5282 return len;
5283 case 1:
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005284 len += scnprintf(buf + len, PAGE_SIZE-len,
James Smart7bb03bb2013-04-17 20:19:16 -04005285 "fcp_cpu_map: HBA centric mapping (%d): "
James Smart222e9232019-01-28 11:14:35 -08005286 "%d of %d CPUs online from %d possible CPUs\n",
5287 phba->cfg_fcp_cpu_map, num_online_cpus(),
5288 num_present_cpus(),
5289 phba->sli4_hba.num_possible_cpu);
James Smart7bb03bb2013-04-17 20:19:16 -04005290 break;
James Smart7bb03bb2013-04-17 20:19:16 -04005291 }
5292
James Smart222e9232019-01-28 11:14:35 -08005293 while (phba->sli4_hba.curr_disp_cpu <
5294 phba->sli4_hba.num_possible_cpu) {
James Smart76fd07a2014-02-20 09:57:18 -05005295 cpup = &phba->sli4_hba.cpu_map[phba->sli4_hba.curr_disp_cpu];
5296
James Smart222e9232019-01-28 11:14:35 -08005297 if (!cpu_present(phba->sli4_hba.curr_disp_cpu))
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005298 len += scnprintf(buf + len, PAGE_SIZE - len,
James Smart222e9232019-01-28 11:14:35 -08005299 "CPU %02d not present\n",
5300 phba->sli4_hba.curr_disp_cpu);
5301 else if (cpup->irq == LPFC_VECTOR_MAP_EMPTY) {
James Smartb3295c22019-01-28 11:14:30 -08005302 if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005303 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005304 buf + len, PAGE_SIZE - len,
5305 "CPU %02d hdwq None "
James Smartd9954a22019-05-21 17:49:05 -07005306 "physid %d coreid %d ht %d ua %d\n",
James Smart76fd07a2014-02-20 09:57:18 -05005307 phba->sli4_hba.curr_disp_cpu,
James Smartd9954a22019-05-21 17:49:05 -07005308 cpup->phys_id, cpup->core_id,
5309 (cpup->flag & LPFC_CPU_MAP_HYPER),
5310 (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
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\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 Smartb3295c22019-01-28 11:14:30 -08005321 } else {
5322 if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005323 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005324 buf + len, PAGE_SIZE - len,
5325 "CPU %02d hdwq None "
James Smartd9954a22019-05-21 17:49:05 -07005326 "physid %d coreid %d ht %d ua %d IRQ %d\n",
James Smart76fd07a2014-02-20 09:57:18 -05005327 phba->sli4_hba.curr_disp_cpu,
James Smartb3295c22019-01-28 11:14:30 -08005328 cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005329 cpup->core_id,
5330 (cpup->flag & LPFC_CPU_MAP_HYPER),
5331 (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
5332 cpup->irq);
James Smartb3295c22019-01-28 11:14:30 -08005333 else
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005334 len += scnprintf(
James Smartb3295c22019-01-28 11:14:30 -08005335 buf + len, PAGE_SIZE - len,
James Smart6a828b02019-01-28 11:14:31 -08005336 "CPU %02d EQ %04d hdwq %04d "
James Smartd9954a22019-05-21 17:49:05 -07005337 "physid %d coreid %d ht %d ua %d IRQ %d\n",
James Smartb3295c22019-01-28 11:14:30 -08005338 phba->sli4_hba.curr_disp_cpu,
James Smart6a828b02019-01-28 11:14:31 -08005339 cpup->eq, cpup->hdwq, cpup->phys_id,
James Smartd9954a22019-05-21 17:49:05 -07005340 cpup->core_id,
5341 (cpup->flag & LPFC_CPU_MAP_HYPER),
5342 (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
5343 cpup->irq);
James Smartb3295c22019-01-28 11:14:30 -08005344 }
James Smart7bb03bb2013-04-17 20:19:16 -04005345
James Smart76fd07a2014-02-20 09:57:18 -05005346 phba->sli4_hba.curr_disp_cpu++;
5347
5348 /* display max number of CPUs keeping some margin */
5349 if (phba->sli4_hba.curr_disp_cpu <
James Smart222e9232019-01-28 11:14:35 -08005350 phba->sli4_hba.num_possible_cpu &&
James Smart76fd07a2014-02-20 09:57:18 -05005351 (len >= (PAGE_SIZE - 64))) {
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005352 len += scnprintf(buf + len,
James Smart222e9232019-01-28 11:14:35 -08005353 PAGE_SIZE - len, "more...\n");
James Smart76fd07a2014-02-20 09:57:18 -05005354 break;
5355 }
James Smart7bb03bb2013-04-17 20:19:16 -04005356 }
James Smart76fd07a2014-02-20 09:57:18 -05005357
James Smart222e9232019-01-28 11:14:35 -08005358 if (phba->sli4_hba.curr_disp_cpu == phba->sli4_hba.num_possible_cpu)
James Smart76fd07a2014-02-20 09:57:18 -05005359 phba->sli4_hba.curr_disp_cpu = 0;
5360
James Smart7bb03bb2013-04-17 20:19:16 -04005361 return len;
5362}
5363
5364/**
5365 * lpfc_fcp_cpu_map_store - Change CPU affinity of driver vectors
5366 * @dev: class device that is converted into a Scsi_host.
5367 * @attr: device attribute, not used.
5368 * @buf: one or more lpfc_polling_flags values.
5369 * @count: not used.
5370 *
5371 * Returns:
5372 * -EINVAL - Not implemented yet.
5373 **/
5374static ssize_t
5375lpfc_fcp_cpu_map_store(struct device *dev, struct device_attribute *attr,
5376 const char *buf, size_t count)
5377{
5378 int status = -EINVAL;
5379 return status;
5380}
5381
5382/*
5383# lpfc_fcp_cpu_map: Defines how to map CPUs to IRQ vectors
5384# for the HBA.
5385#
James Smart6a828b02019-01-28 11:14:31 -08005386# Value range is [0 to 1]. Default value is LPFC_HBA_CPU_MAP (1).
James Smart7bb03bb2013-04-17 20:19:16 -04005387# 0 - Do not affinitze IRQ vectors
5388# 1 - Affintize HBA vectors with respect to each HBA
5389# (start with CPU0 for each HBA)
James Smart6a828b02019-01-28 11:14:31 -08005390# This also defines how Hardware Queues are mapped to specific CPUs.
James Smart7bb03bb2013-04-17 20:19:16 -04005391*/
James Smart6a828b02019-01-28 11:14:31 -08005392static int lpfc_fcp_cpu_map = LPFC_HBA_CPU_MAP;
James Smart7bb03bb2013-04-17 20:19:16 -04005393module_param(lpfc_fcp_cpu_map, int, S_IRUGO|S_IWUSR);
5394MODULE_PARM_DESC(lpfc_fcp_cpu_map,
5395 "Defines how to map CPUs to IRQ vectors per HBA");
5396
5397/**
5398 * lpfc_fcp_cpu_map_init - Set the initial sr-iov virtual function enable
5399 * @phba: lpfc_hba pointer.
5400 * @val: link speed value.
5401 *
5402 * Description:
5403 * If val is in a valid range [0-2], then affinitze the adapter's
5404 * MSIX vectors.
5405 *
5406 * Returns:
5407 * zero if val saved.
5408 * -EINVAL val out of range
5409 **/
5410static int
5411lpfc_fcp_cpu_map_init(struct lpfc_hba *phba, int val)
5412{
5413 if (phba->sli_rev != LPFC_SLI_REV4) {
5414 phba->cfg_fcp_cpu_map = 0;
5415 return 0;
5416 }
5417
5418 if (val >= LPFC_MIN_CPU_MAP && val <= LPFC_MAX_CPU_MAP) {
5419 phba->cfg_fcp_cpu_map = val;
5420 return 0;
5421 }
5422
5423 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
James Smart6c860682016-10-13 15:06:13 -07005424 "3326 lpfc_fcp_cpu_map: %d out of range, using "
5425 "default\n", val);
James Smart6a828b02019-01-28 11:14:31 -08005426 phba->cfg_fcp_cpu_map = LPFC_HBA_CPU_MAP;
James Smart7bb03bb2013-04-17 20:19:16 -04005427
5428 return 0;
5429}
5430
Joe Perchesb6b996b2017-12-19 10:15:07 -08005431static DEVICE_ATTR_RW(lpfc_fcp_cpu_map);
James Smart7bb03bb2013-04-17 20:19:16 -04005432
James Smart0d878412009-10-02 15:16:56 -04005433/*
dea31012005-04-17 16:05:31 -05005434# lpfc_fcp_class: Determines FC class to use for the FCP protocol.
5435# Value range is [2,3]. Default value is 3.
5436*/
James Smart3de2a652007-08-02 11:09:59 -04005437LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3,
5438 "Select Fibre Channel class of service for FCP sequences");
dea31012005-04-17 16:05:31 -05005439
5440/*
5441# lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
5442# is [0,1]. Default value is 0.
5443*/
James Smart3de2a652007-08-02 11:09:59 -04005444LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1,
5445 "Use ADISC on rediscovery to authenticate FCP devices");
dea31012005-04-17 16:05:31 -05005446
5447/*
James Smart3cb01c52013-07-15 18:35:04 -04005448# lpfc_first_burst_size: First burst size to use on the NPorts
5449# that support first burst.
5450# Value range is [0,65536]. Default value is 0.
5451*/
5452LPFC_VPORT_ATTR_RW(first_burst_size, 0, 0, 65536,
5453 "First burst size for Targets that support first burst");
5454
5455/*
James Smart2d7dbc42017-02-12 13:52:35 -08005456* lpfc_nvmet_fb_size: NVME Target mode supported first burst size.
5457* When the driver is configured as an NVME target, this value is
5458* communicated to the NVME initiator in the PRLI response. It is
5459* used only when the lpfc_nvme_enable_fb and lpfc_nvmet_support
5460* parameters are set and the target is sending the PRLI RSP.
James Smart895427b2017-02-12 13:52:30 -08005461* Parameter supported on physical port only - no NPIV support.
James Smart2d7dbc42017-02-12 13:52:35 -08005462* Value range is [0,65536]. Default value is 0.
James Smart895427b2017-02-12 13:52:30 -08005463*/
James Smart2d7dbc42017-02-12 13:52:35 -08005464LPFC_ATTR_RW(nvmet_fb_size, 0, 0, 65536,
5465 "NVME Target mode first burst size in 512B increments.");
5466
5467/*
5468 * lpfc_nvme_enable_fb: Enable NVME first burst on I and T functions.
5469 * For the Initiator (I), enabling this parameter means that an NVMET
5470 * PRLI response with FBA enabled and an FB_SIZE set to a nonzero value will be
James Smartdb197bc2019-08-14 16:57:03 -07005471 * processed by the initiator for subsequent NVME FCP IO.
5472 * Currently, this feature is not supported on the NVME target
James Smart2d7dbc42017-02-12 13:52:35 -08005473 * Value range is [0,1]. Default value is 0 (disabled).
5474 */
James Smart895427b2017-02-12 13:52:30 -08005475LPFC_ATTR_RW(nvme_enable_fb, 0, 0, 1,
James Smartdb197bc2019-08-14 16:57:03 -07005476 "Enable First Burst feature for NVME Initiator.");
James Smart895427b2017-02-12 13:52:30 -08005477
5478/*
James Smart977b5a02008-09-07 11:52:04 -04005479# lpfc_max_scsicmpl_time: Use scsi command completion time to control I/O queue
5480# depth. Default value is 0. When the value of this parameter is zero the
5481# SCSI command completion time is not used for controlling I/O queue depth. When
5482# the parameter is set to a non-zero value, the I/O queue depth is controlled
5483# to limit the I/O completion time to the parameter value.
5484# The value is set in milliseconds.
5485*/
James Smarted5b1522016-10-13 15:06:11 -07005486LPFC_VPORT_ATTR(max_scsicmpl_time, 0, 0, 60000,
James Smart977b5a02008-09-07 11:52:04 -04005487 "Use command completion time to control queue depth");
James Smarted5b1522016-10-13 15:06:11 -07005488
James Smart977b5a02008-09-07 11:52:04 -04005489lpfc_vport_param_show(max_scsicmpl_time);
James Smart977b5a02008-09-07 11:52:04 -04005490static int
5491lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val)
5492{
5493 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5494 struct lpfc_nodelist *ndlp, *next_ndlp;
5495
5496 if (val == vport->cfg_max_scsicmpl_time)
5497 return 0;
5498 if ((val < 0) || (val > 60000))
5499 return -EINVAL;
5500 vport->cfg_max_scsicmpl_time = val;
5501
5502 spin_lock_irq(shost->host_lock);
5503 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
5504 if (!NLP_CHK_NODE_ACT(ndlp))
5505 continue;
5506 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
5507 continue;
James Smart7dc517d2010-07-14 15:32:10 -04005508 ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
James Smart977b5a02008-09-07 11:52:04 -04005509 }
5510 spin_unlock_irq(shost->host_lock);
5511 return 0;
5512}
5513lpfc_vport_param_store(max_scsicmpl_time);
Joe Perchesb6b996b2017-12-19 10:15:07 -08005514static DEVICE_ATTR_RW(lpfc_max_scsicmpl_time);
James Smart977b5a02008-09-07 11:52:04 -04005515
5516/*
dea31012005-04-17 16:05:31 -05005517# lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
5518# range is [0,1]. Default value is 0.
5519*/
5520LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
5521
5522/*
James Smartc4908502019-01-28 11:14:28 -08005523# lpfc_xri_rebalancing: enable or disable XRI rebalancing feature
5524# range is [0,1]. Default value is 1.
5525*/
5526LPFC_ATTR_R(xri_rebalancing, 1, 0, 1, "Enable/Disable XRI rebalancing");
5527
5528/*
James Smart895427b2017-02-12 13:52:30 -08005529 * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds
5530 * range is [0,1]. Default value is 0.
James Smart45aa3122019-01-28 11:14:29 -08005531 * For [0], FCP commands are issued to Work Queues based on upper layer
5532 * hardware queue index.
James Smart895427b2017-02-12 13:52:30 -08005533 * For [1], FCP commands are issued to a Work Queue associated with the
5534 * current CPU.
5535 *
James Smart45aa3122019-01-28 11:14:29 -08005536 * LPFC_FCP_SCHED_BY_HDWQ == 0
James Smart895427b2017-02-12 13:52:30 -08005537 * LPFC_FCP_SCHED_BY_CPU == 1
5538 *
5539 * The driver dynamically sets this to 1 (BY_CPU) if it's able to set up cpu
5540 * affinity for FCP/NVME I/Os through Work Queues associated with the current
5541 * CPU. Otherwise, the default 0 (Round Robin) scheduling of FCP/NVME I/Os
5542 * through WQs will be used.
5543 */
James Smart6a828b02019-01-28 11:14:31 -08005544LPFC_ATTR_RW(fcp_io_sched, LPFC_FCP_SCHED_BY_CPU,
James Smart45aa3122019-01-28 11:14:29 -08005545 LPFC_FCP_SCHED_BY_HDWQ,
James Smart895427b2017-02-12 13:52:30 -08005546 LPFC_FCP_SCHED_BY_CPU,
5547 "Determine scheduling algorithm for "
James Smart45aa3122019-01-28 11:14:29 -08005548 "issuing commands [0] - Hardware Queue, [1] - Current CPU");
James Smart49aa1432012-08-03 12:36:42 -04005549
5550/*
James Smart7ea92eb2018-10-23 13:41:10 -07005551 * lpfc_ns_query: Determine algrithmn for NameServer queries after RSCN
5552 * range is [0,1]. Default value is 0.
5553 * For [0], GID_FT is used for NameServer queries after RSCN (default)
5554 * For [1], GID_PT is used for NameServer queries after RSCN
5555 *
5556 */
5557LPFC_ATTR_RW(ns_query, LPFC_NS_QUERY_GID_FT,
5558 LPFC_NS_QUERY_GID_FT, LPFC_NS_QUERY_GID_PT,
5559 "Determine algorithm NameServer queries after RSCN "
5560 "[0] - GID_FT, [1] - GID_PT");
5561
5562/*
James Smarta6571c62012-10-31 14:44:42 -04005563# lpfc_fcp2_no_tgt_reset: Determine bus reset behavior
5564# range is [0,1]. Default value is 0.
5565# For [0], bus reset issues target reset to ALL devices
5566# For [1], bus reset issues target reset to non-FCP2 devices
5567*/
5568LPFC_ATTR_RW(fcp2_no_tgt_reset, 0, 0, 1, "Determine bus reset behavior for "
5569 "FCP2 devices [0] - issue tgt reset, [1] - no tgt reset");
5570
5571
5572/*
dea31012005-04-17 16:05:31 -05005573# lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
5574# cr_delay (msec) or cr_count outstanding commands. cr_delay can take
James Smart7054a602007-04-25 09:52:34 -04005575# value [0,63]. cr_count can take value [1,255]. Default value of cr_delay
dea31012005-04-17 16:05:31 -05005576# is 0. Default value of cr_count is 1. The cr_count feature is disabled if
5577# cr_delay is set to 0.
5578*/
Jamie Wellnitz8189fd12006-02-28 19:25:35 -05005579LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an "
dea31012005-04-17 16:05:31 -05005580 "interrupt response is generated");
5581
Jamie Wellnitz8189fd12006-02-28 19:25:35 -05005582LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "
dea31012005-04-17 16:05:31 -05005583 "interrupt response is generated");
5584
5585/*
Jamie Wellnitzcf5bf972006-02-28 22:33:08 -05005586# lpfc_multi_ring_support: Determines how many rings to spread available
5587# cmd/rsp IOCB entries across.
5588# Value range is [1,2]. Default value is 1.
5589*/
5590LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
5591 "SLI rings to spread IOCB entries across");
5592
5593/*
James Smarta4bc3372006-12-02 13:34:16 -05005594# lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this
5595# identifies what rctl value to configure the additional ring for.
5596# Value range is [1,0xff]. Default value is 4 (Unsolicated Data).
5597*/
James Smart6a9c52c2009-10-02 15:16:51 -04005598LPFC_ATTR_R(multi_ring_rctl, FC_RCTL_DD_UNSOL_DATA, 1,
James Smarta4bc3372006-12-02 13:34:16 -05005599 255, "Identifies RCTL for additional ring configuration");
5600
5601/*
5602# lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this
5603# identifies what type value to configure the additional ring for.
5604# Value range is [1,0xff]. Default value is 5 (LLC/SNAP).
5605*/
James Smart6a9c52c2009-10-02 15:16:51 -04005606LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP, 1,
James Smarta4bc3372006-12-02 13:34:16 -05005607 255, "Identifies TYPE for additional ring configuration");
5608
5609/*
James Smart4258e982015-12-16 18:11:58 -05005610# lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN
5611# 0 = SmartSAN functionality disabled (default)
5612# 1 = SmartSAN functionality enabled
5613# This parameter will override the value of lpfc_fdmi_on module parameter.
5614# Value range is [0,1]. Default value is 0.
dea31012005-04-17 16:05:31 -05005615*/
James Smart4258e982015-12-16 18:11:58 -05005616LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality");
5617
5618/*
5619# lpfc_fdmi_on: Controls FDMI support.
James Smart9abd9992018-08-14 12:55:05 -07005620# 0 No FDMI support
5621# 1 Traditional FDMI support (default)
James Smart8663cbb2016-03-31 14:12:33 -07005622# Traditional FDMI support means the driver will assume FDMI-2 support;
5623# however, if that fails, it will fallback to FDMI-1.
5624# If lpfc_enable_SmartSAN is set to 1, the driver ignores lpfc_fdmi_on.
5625# If lpfc_enable_SmartSAN is set 0, the driver uses the current value of
5626# lpfc_fdmi_on.
James Smart9abd9992018-08-14 12:55:05 -07005627# Value range [0,1]. Default value is 1.
James Smart4258e982015-12-16 18:11:58 -05005628*/
James Smart9abd9992018-08-14 12:55:05 -07005629LPFC_ATTR_R(fdmi_on, 1, 0, 1, "Enable FDMI support");
dea31012005-04-17 16:05:31 -05005630
5631/*
5632# Specifies the maximum number of ELS cmds we can have outstanding (for
5633# discovery). Value range is [1,64]. Default value = 32.
5634*/
James Smart3de2a652007-08-02 11:09:59 -04005635LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
dea31012005-04-17 16:05:31 -05005636 "during discovery");
5637
5638/*
James Smartc4a7c922013-05-31 17:04:59 -04005639# lpfc_max_luns: maximum allowed LUN ID. This is the highest LUN ID that
5640# will be scanned by the SCSI midlayer when sequential scanning is
5641# used; and is also the highest LUN ID allowed when the SCSI midlayer
5642# parses REPORT_LUN responses. The lpfc driver has no LUN count or
5643# LUN ID limit, but the SCSI midlayer requires this field for the uses
5644# above. The lpfc driver limits the default value to 255 for two reasons.
5645# As it bounds the sequential scan loop, scanning for thousands of luns
5646# on a target can take minutes of wall clock time. Additionally,
5647# there are FC targets, such as JBODs, that only recognize 8-bits of
5648# LUN ID. When they receive a value greater than 8 bits, they chop off
5649# the high order bits. In other words, they see LUN IDs 0, 256, 512,
5650# and so on all as LUN ID 0. This causes the linux kernel, which sees
5651# valid responses at each of the LUN IDs, to believe there are multiple
5652# devices present, when in fact, there is only 1.
5653# A customer that is aware of their target behaviors, and the results as
5654# indicated above, is welcome to increase the lpfc_max_luns value.
5655# As mentioned, this value is not used by the lpfc driver, only the
5656# SCSI midlayer.
James Smart65a29c12006-07-06 15:50:50 -04005657# Value range is [0,65535]. Default value is 255.
5658# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
dea31012005-04-17 16:05:31 -05005659*/
Hannes Reinecke1abf6352014-06-25 15:27:38 +02005660LPFC_VPORT_ULL_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN ID");
dea31012005-04-17 16:05:31 -05005661
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05005662/*
5663# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
5664# Value range is [1,255], default value is 10.
5665*/
5666LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
5667 "Milliseconds driver will wait between polling FCP ring");
5668
James Smart4ff43242006-12-02 13:34:56 -05005669/*
James Smart0c411222013-09-06 12:22:46 -04005670# lpfc_task_mgmt_tmo: Maximum time to wait for task management commands
5671# to complete in seconds. Value range is [5,180], default value is 60.
5672*/
5673LPFC_ATTR_RW(task_mgmt_tmo, 60, 5, 180,
5674 "Maximum time to wait for task management commands to complete");
5675/*
James Smart4ff43242006-12-02 13:34:56 -05005676# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
5677# support this feature
George Kadianakis8605c462010-01-17 21:19:31 +02005678# 0 = MSI disabled
James Smart4ff43242006-12-02 13:34:56 -05005679# 1 = MSI enabled
George Kadianakis8605c462010-01-17 21:19:31 +02005680# 2 = MSI-X enabled (default)
5681# Value range is [0,2]. Default value is 2.
James Smart4ff43242006-12-02 13:34:56 -05005682*/
George Kadianakis8605c462010-01-17 21:19:31 +02005683LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
James Smartdb2378e2008-02-08 18:49:51 -05005684 "MSI-X (2), if possible");
James Smart4ff43242006-12-02 13:34:56 -05005685
James Smart13815c82008-01-11 01:52:48 -05005686/*
James Smartf358dd02017-02-12 13:52:34 -08005687 * lpfc_nvme_oas: Use the oas bit when sending NVME/NVMET IOs
James Smart895427b2017-02-12 13:52:30 -08005688 *
5689 * 0 = NVME OAS disabled
5690 * 1 = NVME OAS enabled
5691 *
5692 * Value range is [0,1]. Default value is 0.
5693 */
5694LPFC_ATTR_RW(nvme_oas, 0, 0, 1,
5695 "Use OAS bit on NVME IOs");
5696
5697/*
James Smart4e565cf2018-02-22 08:18:50 -08005698 * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
5699 *
5700 * 0 = Put NVME Command in SGL
5701 * 1 = Embed NVME Command in WQE (unless G7)
5702 * 2 = Embed NVME Command in WQE (force)
5703 *
5704 * Value range is [0,2]. Default value is 1.
5705 */
5706LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
5707 "Embed NVME Command in WQE");
5708
5709/*
James Smart6a828b02019-01-28 11:14:31 -08005710 * lpfc_hdw_queue: Set the number of Hardware Queues the driver
James Smartcdb42be2019-01-28 11:14:21 -08005711 * will advertise it supports to the NVME and SCSI layers. This also
James Smart6a828b02019-01-28 11:14:31 -08005712 * will map to the number of CQ/WQ pairs the driver will create.
James Smart895427b2017-02-12 13:52:30 -08005713 *
5714 * The NVME Layer will try to create this many, plus 1 administrative
5715 * hardware queue. The administrative queue will always map to WQ 0
James Smart6a828b02019-01-28 11:14:31 -08005716 * A hardware IO queue maps (qidx) to a specific driver CQ/WQ.
James Smart895427b2017-02-12 13:52:30 -08005717 *
James Smartcdb42be2019-01-28 11:14:21 -08005718 * 0 = Configure the number of hdw queues to the number of active CPUs.
James Smart6a828b02019-01-28 11:14:31 -08005719 * 1,128 = Manually specify how many hdw queues to use.
James Smart895427b2017-02-12 13:52:30 -08005720 *
James Smart6a828b02019-01-28 11:14:31 -08005721 * Value range is [0,128]. Default value is 0.
James Smart895427b2017-02-12 13:52:30 -08005722 */
James Smartcdb42be2019-01-28 11:14:21 -08005723LPFC_ATTR_R(hdw_queue,
5724 LPFC_HBA_HDWQ_DEF,
5725 LPFC_HBA_HDWQ_MIN, LPFC_HBA_HDWQ_MAX,
5726 "Set the number of I/O Hardware Queues");
James Smart895427b2017-02-12 13:52:30 -08005727
5728/*
James Smart6a828b02019-01-28 11:14:31 -08005729 * lpfc_irq_chann: Set the number of IRQ vectors that are available
5730 * for Hardware Queues to utilize. This also will map to the number
5731 * of EQ / MSI-X vectors the driver will create. This should never be
5732 * more than the number of Hardware Queues
5733 *
5734 * 0 = Configure number of IRQ Channels to the number of active CPUs.
5735 * 1,128 = Manually specify how many IRQ Channels to use.
5736 *
5737 * Value range is [0,128]. Default value is 0.
5738 */
5739LPFC_ATTR_R(irq_chann,
5740 LPFC_HBA_HDWQ_DEF,
5741 LPFC_HBA_HDWQ_MIN, LPFC_HBA_HDWQ_MAX,
5742 "Set the number of I/O IRQ Channels");
5743
5744/*
James Smart13815c82008-01-11 01:52:48 -05005745# lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware.
5746# 0 = HBA resets disabled
5747# 1 = HBA resets enabled (default)
James Smart50212672018-12-13 15:17:57 -08005748# 2 = HBA reset via PCI bus reset enabled
5749# Value range is [0,2]. Default value is 1.
James Smart13815c82008-01-11 01:52:48 -05005750*/
James Smart50212672018-12-13 15:17:57 -08005751LPFC_ATTR_RW(enable_hba_reset, 1, 0, 2, "Enable HBA resets from the driver.");
James Smartc3f28af2006-08-18 17:47:18 -04005752
James Smart13815c82008-01-11 01:52:48 -05005753/*
James Smarteb7a3392010-11-20 23:12:02 -05005754# lpfc_enable_hba_heartbeat: Disable HBA heartbeat timer..
James Smart13815c82008-01-11 01:52:48 -05005755# 0 = HBA Heartbeat disabled
5756# 1 = HBA Heartbeat enabled (default)
5757# Value range is [0,1]. Default value is 1.
5758*/
James Smarteb7a3392010-11-20 23:12:02 -05005759LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat.");
James Smart92d7f7b2007-06-17 19:56:38 -05005760
James Smart83108bd2008-01-11 01:53:09 -05005761/*
James Smart1ba981f2014-02-20 09:56:45 -05005762# lpfc_EnableXLane: Enable Express Lane Feature
5763# 0x0 Express Lane Feature disabled
5764# 0x1 Express Lane Feature enabled
5765# Value range is [0,1]. Default value is 0.
5766*/
5767LPFC_ATTR_R(EnableXLane, 0, 0, 1, "Enable Express Lane Feature.");
5768
5769/*
5770# lpfc_XLanePriority: Define CS_CTL priority for Express Lane Feature
5771# 0x0 - 0x7f = CS_CTL field in FC header (high 7 bits)
5772# Value range is [0x0,0x7f]. Default value is 0
5773*/
James Smart28d7f3d2014-05-21 08:05:28 -04005774LPFC_ATTR_RW(XLanePriority, 0, 0x0, 0x7f, "CS_CTL for Express Lane Feature.");
James Smart1ba981f2014-02-20 09:56:45 -05005775
5776/*
James Smart81301a92008-12-04 22:39:46 -05005777# lpfc_enable_bg: Enable BlockGuard (Emulex's Implementation of T10-DIF)
5778# 0 = BlockGuard disabled (default)
5779# 1 = BlockGuard enabled
5780# Value range is [0,1]. Default value is 0.
5781*/
5782LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
5783
James Smart6fb120a2009-05-22 14:52:59 -04005784/*
James Smart81301a92008-12-04 22:39:46 -05005785# lpfc_prot_mask: i
5786# - Bit mask of host protection capabilities used to register with the
5787# SCSI mid-layer
5788# - Only meaningful if BG is turned on (lpfc_enable_bg=1).
5789# - Allows you to ultimately specify which profiles to use
5790# - Default will result in registering capabilities for all profiles.
James Smart005ffa72012-09-29 11:29:17 -04005791# - SHOST_DIF_TYPE1_PROTECTION 1
5792# HBA supports T10 DIF Type 1: HBA to Target Type 1 Protection
5793# - SHOST_DIX_TYPE0_PROTECTION 8
5794# HBA supports DIX Type 0: Host to HBA protection only
5795# - SHOST_DIX_TYPE1_PROTECTION 16
5796# HBA supports DIX Type 1: Host to HBA Type 1 protection
James Smart81301a92008-12-04 22:39:46 -05005797#
5798*/
James Smartb3b98b72016-10-13 15:06:06 -07005799LPFC_ATTR(prot_mask,
5800 (SHOST_DIF_TYPE1_PROTECTION |
5801 SHOST_DIX_TYPE0_PROTECTION |
5802 SHOST_DIX_TYPE1_PROTECTION),
5803 0,
5804 (SHOST_DIF_TYPE1_PROTECTION |
5805 SHOST_DIX_TYPE0_PROTECTION |
5806 SHOST_DIX_TYPE1_PROTECTION),
5807 "T10-DIF host protection capabilities mask");
James Smart81301a92008-12-04 22:39:46 -05005808
5809/*
5810# lpfc_prot_guard: i
5811# - Bit mask of protection guard types to register with the SCSI mid-layer
James Smart005ffa72012-09-29 11:29:17 -04005812# - Guard types are currently either 1) T10-DIF CRC 2) IP checksum
James Smart81301a92008-12-04 22:39:46 -05005813# - Allows you to ultimately specify which profiles to use
5814# - Default will result in registering capabilities for all guard types
5815#
5816*/
James Smartb3b98b72016-10-13 15:06:06 -07005817LPFC_ATTR(prot_guard,
5818 SHOST_DIX_GUARD_IP, SHOST_DIX_GUARD_CRC, SHOST_DIX_GUARD_IP,
5819 "T10-DIF host protection guard type");
James Smart81301a92008-12-04 22:39:46 -05005820
James Smart92494142011-02-16 12:39:44 -05005821/*
5822 * Delay initial NPort discovery when Clean Address bit is cleared in
5823 * FLOGI/FDISC accept and FCID/Fabric name/Fabric portname is changed.
5824 * This parameter can have value 0 or 1.
5825 * When this parameter is set to 0, no delay is added to the initial
5826 * discovery.
5827 * When this parameter is set to non-zero value, initial Nport discovery is
5828 * delayed by ra_tov seconds when Clean Address bit is cleared in FLOGI/FDISC
5829 * accept and FCID/Fabric name/Fabric portname is changed.
5830 * Driver always delay Nport discovery for subsequent FLOGI/FDISC completion
5831 * when Clean Address bit is cleared in FLOGI/FDISC
5832 * accept and FCID/Fabric name/Fabric portname is changed.
5833 * Default value is 0.
5834 */
James Smart8eb8b962016-07-06 12:36:08 -07005835LPFC_ATTR(delay_discovery, 0, 0, 1,
5836 "Delay NPort discovery when Clean Address bit is cleared.");
James Smart81301a92008-12-04 22:39:46 -05005837
5838/*
James Smart3621a712009-04-06 18:47:14 -04005839 * lpfc_sg_seg_cnt - Initial Maximum DMA Segment Count
James Smart5b9e70b2018-09-10 10:30:42 -07005840 * This value can be set to values between 64 and 4096. The default value
5841 * is 64, but may be increased to allow for larger Max I/O sizes. The scsi
5842 * and nvme layers will allow I/O sizes up to (MAX_SEG_COUNT * SEG_SIZE).
James Smart96f70772013-04-17 20:16:15 -04005843 * Because of the additional overhead involved in setting up T10-DIF,
5844 * this parameter will be limited to 128 if BlockGuard is enabled under SLI4
5845 * and will be limited to 512 if BlockGuard is enabled under SLI3.
James Smart83108bd2008-01-11 01:53:09 -05005846 */
James Smart5b9e70b2018-09-10 10:30:42 -07005847static uint lpfc_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
5848module_param(lpfc_sg_seg_cnt, uint, 0444);
5849MODULE_PARM_DESC(lpfc_sg_seg_cnt, "Max Scatter Gather Segment Count");
5850
5851/**
5852 * lpfc_sg_seg_cnt_show - Display the scatter/gather list sizes
5853 * configured for the adapter
5854 * @dev: class converted to a Scsi_host structure.
5855 * @attr: device attribute, not used.
5856 * @buf: on return contains a string with the list sizes
5857 *
5858 * Returns: size of formatted string.
5859 **/
5860static ssize_t
5861lpfc_sg_seg_cnt_show(struct device *dev, struct device_attribute *attr,
5862 char *buf)
5863{
5864 struct Scsi_Host *shost = class_to_shost(dev);
5865 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
5866 struct lpfc_hba *phba = vport->phba;
5867 int len;
5868
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005869 len = scnprintf(buf, PAGE_SIZE, "SGL sz: %d total SGEs: %d\n",
James Smart5b9e70b2018-09-10 10:30:42 -07005870 phba->cfg_sg_dma_buf_size, phba->cfg_total_seg_cnt);
5871
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07005872 len += scnprintf(buf + len, PAGE_SIZE, "Cfg: %d SCSI: %d NVME: %d\n",
James Smart5b9e70b2018-09-10 10:30:42 -07005873 phba->cfg_sg_seg_cnt, phba->cfg_scsi_seg_cnt,
5874 phba->cfg_nvme_seg_cnt);
5875 return len;
5876}
5877
5878static DEVICE_ATTR_RO(lpfc_sg_seg_cnt);
5879
5880/**
5881 * lpfc_sg_seg_cnt_init - Set the hba sg_seg_cnt initial value
5882 * @phba: lpfc_hba pointer.
5883 * @val: contains the initial value
5884 *
5885 * Description:
5886 * Validates the initial value is within range and assigns it to the
5887 * adapter. If not in range, an error message is posted and the
5888 * default value is assigned.
5889 *
5890 * Returns:
5891 * zero if value is in range and is set
5892 * -EINVAL if value was out of range
5893 **/
5894static int
5895lpfc_sg_seg_cnt_init(struct lpfc_hba *phba, int val)
5896{
5897 if (val >= LPFC_MIN_SG_SEG_CNT && val <= LPFC_MAX_SG_SEG_CNT) {
5898 phba->cfg_sg_seg_cnt = val;
5899 return 0;
5900 }
5901 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
5902 "0409 "LPFC_DRIVER_NAME"_sg_seg_cnt attribute cannot "
5903 "be set to %d, allowed range is [%d, %d]\n",
5904 val, LPFC_MIN_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT);
5905 phba->cfg_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
5906 return -EINVAL;
5907}
James Smart83108bd2008-01-11 01:53:09 -05005908
James Smart96f70772013-04-17 20:16:15 -04005909/*
James Smart7bdedb32016-07-06 12:36:00 -07005910 * lpfc_enable_mds_diags: Enable MDS Diagnostics
5911 * 0 = MDS Diagnostics disabled (default)
5912 * 1 = MDS Diagnostics enabled
5913 * Value range is [0,1]. Default value is 0.
5914 */
5915LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");
5916
James Smart44fd7fe2017-08-23 16:55:47 -07005917/*
James Smartd2cc9bc2018-09-10 10:30:50 -07005918 * lpfc_ras_fwlog_buffsize: Firmware logging host buffer size
5919 * 0 = Disable firmware logging (default)
5920 * [1-4] = Multiple of 1/4th Mb of host memory for FW logging
5921 * Value range [0..4]. Default value is 0
5922 */
5923LPFC_ATTR_RW(ras_fwlog_buffsize, 0, 0, 4, "Host memory for FW logging");
5924
5925/*
5926 * lpfc_ras_fwlog_level: Firmware logging verbosity level
5927 * Valid only if firmware logging is enabled
5928 * 0(Least Verbosity) 4 (most verbosity)
5929 * Value range is [0..4]. Default value is 0
5930 */
5931LPFC_ATTR_RW(ras_fwlog_level, 0, 0, 4, "Firmware Logging Level");
5932
5933/*
5934 * lpfc_ras_fwlog_func: Firmware logging enabled on function number
5935 * Default function which has RAS support : 0
5936 * Value Range is [0..7].
5937 * FW logging is a global action and enablement is via a specific
5938 * port.
5939 */
5940LPFC_ATTR_RW(ras_fwlog_func, 0, 0, 7, "Firmware Logging Enabled on Function");
5941
5942/*
James Smart44fd7fe2017-08-23 16:55:47 -07005943 * lpfc_enable_bbcr: Enable BB Credit Recovery
5944 * 0 = BB Credit Recovery disabled
5945 * 1 = BB Credit Recovery enabled (default)
5946 * Value range is [0,1]. Default value is 1.
5947 */
5948LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
5949
James Smart1351e692018-02-22 08:18:43 -08005950/*
5951 * lpfc_enable_dpp: Enable DPP on G7
5952 * 0 = DPP on G7 disabled
5953 * 1 = DPP on G7 enabled (default)
5954 * Value range is [0,1]. Default value is 1.
5955 */
5956LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
5957
Tony Jonesee959b02008-02-22 00:13:36 +01005958struct device_attribute *lpfc_hba_attrs[] = {
James Smart895427b2017-02-12 13:52:30 -08005959 &dev_attr_nvme_info,
James Smart4c47efc2019-01-28 11:14:25 -08005960 &dev_attr_scsi_stat,
James Smart81301a92008-12-04 22:39:46 -05005961 &dev_attr_bg_info,
5962 &dev_attr_bg_guard_err,
5963 &dev_attr_bg_apptag_err,
5964 &dev_attr_bg_reftag_err,
Tony Jonesee959b02008-02-22 00:13:36 +01005965 &dev_attr_info,
5966 &dev_attr_serialnum,
5967 &dev_attr_modeldesc,
5968 &dev_attr_modelname,
5969 &dev_attr_programtype,
5970 &dev_attr_portnum,
5971 &dev_attr_fwrev,
5972 &dev_attr_hdw,
5973 &dev_attr_option_rom_version,
Hannes Reineckebbd1ae42008-03-18 14:32:28 +01005974 &dev_attr_link_state,
Tony Jonesee959b02008-02-22 00:13:36 +01005975 &dev_attr_num_discovered_ports,
James Smart84774a42008-08-24 21:50:06 -04005976 &dev_attr_menlo_mgmt_mode,
Tony Jonesee959b02008-02-22 00:13:36 +01005977 &dev_attr_lpfc_drvr_version,
James Smart45ed1192009-10-02 15:17:02 -04005978 &dev_attr_lpfc_enable_fip,
Tony Jonesee959b02008-02-22 00:13:36 +01005979 &dev_attr_lpfc_temp_sensor,
5980 &dev_attr_lpfc_log_verbose,
5981 &dev_attr_lpfc_lun_queue_depth,
James Smart7dc517d2010-07-14 15:32:10 -04005982 &dev_attr_lpfc_tgt_queue_depth,
Tony Jonesee959b02008-02-22 00:13:36 +01005983 &dev_attr_lpfc_hba_queue_depth,
5984 &dev_attr_lpfc_peer_port_login,
5985 &dev_attr_lpfc_nodev_tmo,
5986 &dev_attr_lpfc_devloss_tmo,
James Smart895427b2017-02-12 13:52:30 -08005987 &dev_attr_lpfc_enable_fc4_type,
Tony Jonesee959b02008-02-22 00:13:36 +01005988 &dev_attr_lpfc_fcp_class,
5989 &dev_attr_lpfc_use_adisc,
James Smart3cb01c52013-07-15 18:35:04 -04005990 &dev_attr_lpfc_first_burst_size,
Tony Jonesee959b02008-02-22 00:13:36 +01005991 &dev_attr_lpfc_ack0,
James Smartc4908502019-01-28 11:14:28 -08005992 &dev_attr_lpfc_xri_rebalancing,
Tony Jonesee959b02008-02-22 00:13:36 +01005993 &dev_attr_lpfc_topology,
5994 &dev_attr_lpfc_scan_down,
5995 &dev_attr_lpfc_link_speed,
James Smart49aa1432012-08-03 12:36:42 -04005996 &dev_attr_lpfc_fcp_io_sched,
James Smart7ea92eb2018-10-23 13:41:10 -07005997 &dev_attr_lpfc_ns_query,
James Smarta6571c62012-10-31 14:44:42 -04005998 &dev_attr_lpfc_fcp2_no_tgt_reset,
Tony Jonesee959b02008-02-22 00:13:36 +01005999 &dev_attr_lpfc_cr_delay,
6000 &dev_attr_lpfc_cr_count,
6001 &dev_attr_lpfc_multi_ring_support,
6002 &dev_attr_lpfc_multi_ring_rctl,
6003 &dev_attr_lpfc_multi_ring_type,
6004 &dev_attr_lpfc_fdmi_on,
James Smart4258e982015-12-16 18:11:58 -05006005 &dev_attr_lpfc_enable_SmartSAN,
Tony Jonesee959b02008-02-22 00:13:36 +01006006 &dev_attr_lpfc_max_luns,
6007 &dev_attr_lpfc_enable_npiv,
James Smart7d791df2011-07-22 18:37:52 -04006008 &dev_attr_lpfc_fcf_failover_policy,
James Smart19ca7602010-11-20 23:11:55 -05006009 &dev_attr_lpfc_enable_rrq,
Tony Jonesee959b02008-02-22 00:13:36 +01006010 &dev_attr_nport_evt_cnt,
6011 &dev_attr_board_mode,
6012 &dev_attr_max_vpi,
6013 &dev_attr_used_vpi,
6014 &dev_attr_max_rpi,
6015 &dev_attr_used_rpi,
6016 &dev_attr_max_xri,
6017 &dev_attr_used_xri,
6018 &dev_attr_npiv_info,
6019 &dev_attr_issue_reset,
6020 &dev_attr_lpfc_poll,
6021 &dev_attr_lpfc_poll_tmo,
James Smart0c411222013-09-06 12:22:46 -04006022 &dev_attr_lpfc_task_mgmt_tmo,
Tony Jonesee959b02008-02-22 00:13:36 +01006023 &dev_attr_lpfc_use_msi,
James Smart895427b2017-02-12 13:52:30 -08006024 &dev_attr_lpfc_nvme_oas,
James Smart4e565cf2018-02-22 08:18:50 -08006025 &dev_attr_lpfc_nvme_embed_cmd,
James Smartda0436e2009-05-22 14:51:39 -04006026 &dev_attr_lpfc_fcp_imax,
James Smart41b194b2019-05-14 14:58:08 -07006027 &dev_attr_lpfc_force_rscn,
James Smart32517fc2019-01-28 11:14:33 -08006028 &dev_attr_lpfc_cq_poll_threshold,
6029 &dev_attr_lpfc_cq_max_proc_limit,
James Smart7bb03bb2013-04-17 20:19:16 -04006030 &dev_attr_lpfc_fcp_cpu_map,
James Smartcdb42be2019-01-28 11:14:21 -08006031 &dev_attr_lpfc_hdw_queue,
James Smart6a828b02019-01-28 11:14:31 -08006032 &dev_attr_lpfc_irq_chann,
James Smartf358dd02017-02-12 13:52:34 -08006033 &dev_attr_lpfc_suppress_rsp,
James Smart2d7dbc42017-02-12 13:52:35 -08006034 &dev_attr_lpfc_nvmet_mrq,
James Smart2448e482018-04-09 14:24:24 -07006035 &dev_attr_lpfc_nvmet_mrq_post,
James Smart895427b2017-02-12 13:52:30 -08006036 &dev_attr_lpfc_nvme_enable_fb,
James Smart2d7dbc42017-02-12 13:52:35 -08006037 &dev_attr_lpfc_nvmet_fb_size,
James Smart81301a92008-12-04 22:39:46 -05006038 &dev_attr_lpfc_enable_bg,
James Smart352e5fd2016-12-30 06:57:47 -08006039 &dev_attr_lpfc_soft_wwnn,
6040 &dev_attr_lpfc_soft_wwpn,
6041 &dev_attr_lpfc_soft_wwn_enable,
Tony Jonesee959b02008-02-22 00:13:36 +01006042 &dev_attr_lpfc_enable_hba_reset,
6043 &dev_attr_lpfc_enable_hba_heartbeat,
James Smart1ba981f2014-02-20 09:56:45 -05006044 &dev_attr_lpfc_EnableXLane,
6045 &dev_attr_lpfc_XLanePriority,
6046 &dev_attr_lpfc_xlane_lun,
6047 &dev_attr_lpfc_xlane_tgt,
6048 &dev_attr_lpfc_xlane_vpt,
6049 &dev_attr_lpfc_xlane_lun_state,
6050 &dev_attr_lpfc_xlane_lun_status,
James Smartc92c8412016-07-06 12:36:05 -07006051 &dev_attr_lpfc_xlane_priority,
Tony Jonesee959b02008-02-22 00:13:36 +01006052 &dev_attr_lpfc_sg_seg_cnt,
James Smart977b5a02008-09-07 11:52:04 -04006053 &dev_attr_lpfc_max_scsicmpl_time,
James Smartea2151b2008-09-07 11:52:10 -04006054 &dev_attr_lpfc_stat_data_ctrl,
James Smart0d878412009-10-02 15:16:56 -04006055 &dev_attr_lpfc_aer_support,
6056 &dev_attr_lpfc_aer_state_cleanup,
James Smart912e3ac2011-05-24 11:42:11 -04006057 &dev_attr_lpfc_sriov_nr_virtfn,
James Smartc71ab862012-10-31 14:44:33 -04006058 &dev_attr_lpfc_req_fw_upgrade,
James Smart84d1b002010-02-12 14:42:33 -05006059 &dev_attr_lpfc_suppress_link_up,
James Smart2a9bf3d2010-06-07 15:24:45 -04006060 &dev_attr_lpfc_iocb_cnt,
6061 &dev_attr_iocb_hw,
6062 &dev_attr_txq_hw,
6063 &dev_attr_txcmplq_hw,
James Smartbc739052010-08-04 16:11:18 -04006064 &dev_attr_lpfc_fips_level,
6065 &dev_attr_lpfc_fips_rev,
James Smartab56dc22011-02-16 12:39:57 -05006066 &dev_attr_lpfc_dss,
James Smart912e3ac2011-05-24 11:42:11 -04006067 &dev_attr_lpfc_sriov_hw_max_virtfn,
James Smart026abb82011-12-13 13:20:45 -05006068 &dev_attr_protocol,
James Smart1ba981f2014-02-20 09:56:45 -05006069 &dev_attr_lpfc_xlane_supported,
James Smart7bdedb32016-07-06 12:36:00 -07006070 &dev_attr_lpfc_enable_mds_diags,
James Smartd2cc9bc2018-09-10 10:30:50 -07006071 &dev_attr_lpfc_ras_fwlog_buffsize,
6072 &dev_attr_lpfc_ras_fwlog_level,
6073 &dev_attr_lpfc_ras_fwlog_func,
James Smart44fd7fe2017-08-23 16:55:47 -07006074 &dev_attr_lpfc_enable_bbcr,
James Smart1351e692018-02-22 08:18:43 -08006075 &dev_attr_lpfc_enable_dpp,
dea31012005-04-17 16:05:31 -05006076 NULL,
6077};
6078
Tony Jonesee959b02008-02-22 00:13:36 +01006079struct device_attribute *lpfc_vport_attrs[] = {
6080 &dev_attr_info,
Hannes Reineckebbd1ae42008-03-18 14:32:28 +01006081 &dev_attr_link_state,
Tony Jonesee959b02008-02-22 00:13:36 +01006082 &dev_attr_num_discovered_ports,
6083 &dev_attr_lpfc_drvr_version,
6084 &dev_attr_lpfc_log_verbose,
6085 &dev_attr_lpfc_lun_queue_depth,
James Smart7dc517d2010-07-14 15:32:10 -04006086 &dev_attr_lpfc_tgt_queue_depth,
Tony Jonesee959b02008-02-22 00:13:36 +01006087 &dev_attr_lpfc_nodev_tmo,
6088 &dev_attr_lpfc_devloss_tmo,
6089 &dev_attr_lpfc_hba_queue_depth,
6090 &dev_attr_lpfc_peer_port_login,
6091 &dev_attr_lpfc_restrict_login,
6092 &dev_attr_lpfc_fcp_class,
6093 &dev_attr_lpfc_use_adisc,
James Smart3cb01c52013-07-15 18:35:04 -04006094 &dev_attr_lpfc_first_burst_size,
Tony Jonesee959b02008-02-22 00:13:36 +01006095 &dev_attr_lpfc_max_luns,
6096 &dev_attr_nport_evt_cnt,
6097 &dev_attr_npiv_info,
6098 &dev_attr_lpfc_enable_da_id,
James Smartea2151b2008-09-07 11:52:10 -04006099 &dev_attr_lpfc_max_scsicmpl_time,
6100 &dev_attr_lpfc_stat_data_ctrl,
James Smart21e9a0a2009-05-22 14:53:21 -04006101 &dev_attr_lpfc_static_vport,
James Smartbc739052010-08-04 16:11:18 -04006102 &dev_attr_lpfc_fips_level,
6103 &dev_attr_lpfc_fips_rev,
James Smart3de2a652007-08-02 11:09:59 -04006104 NULL,
6105};
6106
James Smarte59058c2008-08-24 21:49:00 -04006107/**
James Smart3621a712009-04-06 18:47:14 -04006108 * sysfs_ctlreg_write - Write method for writing to ctlreg
Chris Wright2c3c8be2010-05-12 18:28:57 -07006109 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006110 * @kobj: kernel kobject that contains the kernel class device.
6111 * @bin_attr: kernel attributes passed to us.
6112 * @buf: contains the data to be written to the adapter IOREG space.
6113 * @off: offset into buffer to beginning of data.
6114 * @count: bytes to transfer.
6115 *
6116 * Description:
6117 * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
6118 * Uses the adapter io control registers to send buf contents to the adapter.
6119 *
6120 * Returns:
6121 * -ERANGE off and count combo out of range
6122 * -EINVAL off, count or buff address invalid
6123 * -EPERM adapter is offline
6124 * value of count, buf contents written
6125 **/
dea31012005-04-17 16:05:31 -05006126static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006127sysfs_ctlreg_write(struct file *filp, struct kobject *kobj,
6128 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006129 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006130{
6131 size_t buf_off;
Tony Jonesee959b02008-02-22 00:13:36 +01006132 struct device *dev = container_of(kobj, struct device, kobj);
6133 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05006134 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6135 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006136
James Smartf1126682009-06-10 17:22:44 -04006137 if (phba->sli_rev >= LPFC_SLI_REV4)
6138 return -EPERM;
6139
dea31012005-04-17 16:05:31 -05006140 if ((off + count) > FF_REG_AREA_SIZE)
6141 return -ERANGE;
6142
James Smartf7a919b2011-08-21 21:49:16 -04006143 if (count <= LPFC_REG_WRITE_KEY_SIZE)
6144 return 0;
dea31012005-04-17 16:05:31 -05006145
6146 if (off % 4 || count % 4 || (unsigned long)buf % 4)
6147 return -EINVAL;
6148
James Smartf7a919b2011-08-21 21:49:16 -04006149 /* This is to protect HBA registers from accidental writes. */
6150 if (memcmp(buf, LPFC_REG_WRITE_KEY, LPFC_REG_WRITE_KEY_SIZE))
6151 return -EINVAL;
6152
6153 if (!(vport->fc_flag & FC_OFFLINE_MODE))
dea31012005-04-17 16:05:31 -05006154 return -EPERM;
dea31012005-04-17 16:05:31 -05006155
James Smart2e0fef82007-06-17 19:56:36 -05006156 spin_lock_irq(&phba->hbalock);
James Smartf7a919b2011-08-21 21:49:16 -04006157 for (buf_off = 0; buf_off < count - LPFC_REG_WRITE_KEY_SIZE;
6158 buf_off += sizeof(uint32_t))
6159 writel(*((uint32_t *)(buf + buf_off + LPFC_REG_WRITE_KEY_SIZE)),
dea31012005-04-17 16:05:31 -05006160 phba->ctrl_regs_memmap_p + off + buf_off);
6161
James Smart2e0fef82007-06-17 19:56:36 -05006162 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006163
6164 return count;
6165}
6166
James Smarte59058c2008-08-24 21:49:00 -04006167/**
James Smart3621a712009-04-06 18:47:14 -04006168 * sysfs_ctlreg_read - Read method for reading from ctlreg
Chris Wright2c3c8be2010-05-12 18:28:57 -07006169 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006170 * @kobj: kernel kobject that contains the kernel class device.
6171 * @bin_attr: kernel attributes passed to us.
André Goddard Rosaaf901ca2009-11-14 13:09:05 -02006172 * @buf: if successful contains the data from the adapter IOREG space.
James Smarte59058c2008-08-24 21:49:00 -04006173 * @off: offset into buffer to beginning of data.
6174 * @count: bytes to transfer.
6175 *
6176 * Description:
6177 * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
6178 * Uses the adapter io control registers to read data into buf.
6179 *
6180 * Returns:
6181 * -ERANGE off and count combo out of range
6182 * -EINVAL off, count or buff address invalid
6183 * value of count, buf contents read
6184 **/
dea31012005-04-17 16:05:31 -05006185static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006186sysfs_ctlreg_read(struct file *filp, struct kobject *kobj,
6187 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006188 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006189{
6190 size_t buf_off;
6191 uint32_t * tmp_ptr;
Tony Jonesee959b02008-02-22 00:13:36 +01006192 struct device *dev = container_of(kobj, struct device, kobj);
6193 struct Scsi_Host *shost = class_to_shost(dev);
James Smart2e0fef82007-06-17 19:56:36 -05006194 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6195 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006196
James Smartf1126682009-06-10 17:22:44 -04006197 if (phba->sli_rev >= LPFC_SLI_REV4)
6198 return -EPERM;
6199
dea31012005-04-17 16:05:31 -05006200 if (off > FF_REG_AREA_SIZE)
6201 return -ERANGE;
6202
6203 if ((off + count) > FF_REG_AREA_SIZE)
6204 count = FF_REG_AREA_SIZE - off;
6205
6206 if (count == 0) return 0;
6207
6208 if (off % 4 || count % 4 || (unsigned long)buf % 4)
6209 return -EINVAL;
6210
James Smart2e0fef82007-06-17 19:56:36 -05006211 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006212
6213 for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {
6214 tmp_ptr = (uint32_t *)(buf + buf_off);
6215 *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);
6216 }
6217
James Smart2e0fef82007-06-17 19:56:36 -05006218 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05006219
6220 return count;
6221}
6222
6223static struct bin_attribute sysfs_ctlreg_attr = {
6224 .attr = {
6225 .name = "ctlreg",
6226 .mode = S_IRUSR | S_IWUSR,
dea31012005-04-17 16:05:31 -05006227 },
6228 .size = 256,
6229 .read = sysfs_ctlreg_read,
6230 .write = sysfs_ctlreg_write,
6231};
6232
James Smarte59058c2008-08-24 21:49:00 -04006233/**
James Smart3621a712009-04-06 18:47:14 -04006234 * sysfs_mbox_write - Write method for writing information via mbox
Chris Wright2c3c8be2010-05-12 18:28:57 -07006235 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006236 * @kobj: kernel kobject that contains the kernel class device.
6237 * @bin_attr: kernel attributes passed to us.
6238 * @buf: contains the data to be written to sysfs mbox.
6239 * @off: offset into buffer to beginning of data.
6240 * @count: bytes to transfer.
6241 *
6242 * Description:
James Smart026abb82011-12-13 13:20:45 -05006243 * Deprecated function. All mailbox access from user space is performed via the
6244 * bsg interface.
James Smarte59058c2008-08-24 21:49:00 -04006245 *
6246 * Returns:
James Smart026abb82011-12-13 13:20:45 -05006247 * -EPERM operation not permitted
James Smarte59058c2008-08-24 21:49:00 -04006248 **/
dea31012005-04-17 16:05:31 -05006249static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006250sysfs_mbox_write(struct file *filp, struct kobject *kobj,
6251 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006252 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006253{
James Smart026abb82011-12-13 13:20:45 -05006254 return -EPERM;
dea31012005-04-17 16:05:31 -05006255}
6256
James Smarte59058c2008-08-24 21:49:00 -04006257/**
James Smart3621a712009-04-06 18:47:14 -04006258 * sysfs_mbox_read - Read method for reading information via mbox
Chris Wright2c3c8be2010-05-12 18:28:57 -07006259 * @filp: open sysfs file
James Smarte59058c2008-08-24 21:49:00 -04006260 * @kobj: kernel kobject that contains the kernel class device.
6261 * @bin_attr: kernel attributes passed to us.
6262 * @buf: contains the data to be read from sysfs mbox.
6263 * @off: offset into buffer to beginning of data.
6264 * @count: bytes to transfer.
6265 *
6266 * Description:
James Smart026abb82011-12-13 13:20:45 -05006267 * Deprecated function. All mailbox access from user space is performed via the
6268 * bsg interface.
James Smarte59058c2008-08-24 21:49:00 -04006269 *
6270 * Returns:
James Smart026abb82011-12-13 13:20:45 -05006271 * -EPERM operation not permitted
James Smarte59058c2008-08-24 21:49:00 -04006272 **/
dea31012005-04-17 16:05:31 -05006273static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -07006274sysfs_mbox_read(struct file *filp, struct kobject *kobj,
6275 struct bin_attribute *bin_attr,
Zhang Rui91a69022007-06-09 13:57:22 +08006276 char *buf, loff_t off, size_t count)
dea31012005-04-17 16:05:31 -05006277{
James Smart026abb82011-12-13 13:20:45 -05006278 return -EPERM;
dea31012005-04-17 16:05:31 -05006279}
6280
6281static struct bin_attribute sysfs_mbox_attr = {
6282 .attr = {
6283 .name = "mbox",
6284 .mode = S_IRUSR | S_IWUSR,
dea31012005-04-17 16:05:31 -05006285 },
James Smartc0c11512011-05-24 11:41:34 -04006286 .size = MAILBOX_SYSFS_MAX,
dea31012005-04-17 16:05:31 -05006287 .read = sysfs_mbox_read,
6288 .write = sysfs_mbox_write,
6289};
6290
James Smarte59058c2008-08-24 21:49:00 -04006291/**
James Smart3621a712009-04-06 18:47:14 -04006292 * lpfc_alloc_sysfs_attr - Creates the ctlreg and mbox entries
James Smarte59058c2008-08-24 21:49:00 -04006293 * @vport: address of lpfc vport structure.
6294 *
6295 * Return codes:
6296 * zero on success
6297 * error return code from sysfs_create_bin_file()
6298 **/
dea31012005-04-17 16:05:31 -05006299int
James Smart2e0fef82007-06-17 19:56:36 -05006300lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05006301{
James Smart2e0fef82007-06-17 19:56:36 -05006302 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05006303 int error;
6304
Tony Jonesee959b02008-02-22 00:13:36 +01006305 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smarteada2722008-12-04 22:39:13 -05006306 &sysfs_drvr_stat_data_attr);
6307
6308 /* Virtual ports do not need ctrl_reg and mbox */
6309 if (error || vport->port_type == LPFC_NPIV_PORT)
6310 goto out;
6311
6312 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smart92d7f7b2007-06-17 19:56:38 -05006313 &sysfs_ctlreg_attr);
dea31012005-04-17 16:05:31 -05006314 if (error)
James Smarteada2722008-12-04 22:39:13 -05006315 goto out_remove_stat_attr;
dea31012005-04-17 16:05:31 -05006316
Tony Jonesee959b02008-02-22 00:13:36 +01006317 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
James Smart92d7f7b2007-06-17 19:56:38 -05006318 &sysfs_mbox_attr);
dea31012005-04-17 16:05:31 -05006319 if (error)
6320 goto out_remove_ctlreg_attr;
6321
6322 return 0;
6323out_remove_ctlreg_attr:
Tony Jonesee959b02008-02-22 00:13:36 +01006324 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
James Smarteada2722008-12-04 22:39:13 -05006325out_remove_stat_attr:
6326 sysfs_remove_bin_file(&shost->shost_dev.kobj,
6327 &sysfs_drvr_stat_data_attr);
dea31012005-04-17 16:05:31 -05006328out:
6329 return error;
6330}
6331
James Smarte59058c2008-08-24 21:49:00 -04006332/**
James Smart3621a712009-04-06 18:47:14 -04006333 * lpfc_free_sysfs_attr - Removes the ctlreg and mbox entries
James Smarte59058c2008-08-24 21:49:00 -04006334 * @vport: address of lpfc vport structure.
6335 **/
dea31012005-04-17 16:05:31 -05006336void
James Smart2e0fef82007-06-17 19:56:36 -05006337lpfc_free_sysfs_attr(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05006338{
James Smart2e0fef82007-06-17 19:56:36 -05006339 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smartea2151b2008-09-07 11:52:10 -04006340 sysfs_remove_bin_file(&shost->shost_dev.kobj,
6341 &sysfs_drvr_stat_data_attr);
James Smarteada2722008-12-04 22:39:13 -05006342 /* Virtual ports do not need ctrl_reg and mbox */
6343 if (vport->port_type == LPFC_NPIV_PORT)
6344 return;
Tony Jonesee959b02008-02-22 00:13:36 +01006345 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
6346 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
dea31012005-04-17 16:05:31 -05006347}
6348
dea31012005-04-17 16:05:31 -05006349/*
6350 * Dynamic FC Host Attributes Support
6351 */
6352
James Smarte59058c2008-08-24 21:49:00 -04006353/**
James Smart6c9231f2016-12-19 15:07:24 -08006354 * lpfc_get_host_symbolic_name - Copy symbolic name into the scsi host
6355 * @shost: kernel scsi host pointer.
6356 **/
6357static void
6358lpfc_get_host_symbolic_name(struct Scsi_Host *shost)
6359{
6360 struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
6361
6362 lpfc_vport_symbolic_node_name(vport, fc_host_symbolic_name(shost),
6363 sizeof fc_host_symbolic_name(shost));
6364}
6365
6366/**
James Smart3621a712009-04-06 18:47:14 -04006367 * lpfc_get_host_port_id - Copy the vport DID into the scsi host port id
James Smarte59058c2008-08-24 21:49:00 -04006368 * @shost: kernel scsi host pointer.
6369 **/
dea31012005-04-17 16:05:31 -05006370static void
6371lpfc_get_host_port_id(struct Scsi_Host *shost)
6372{
James Smart2e0fef82007-06-17 19:56:36 -05006373 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6374
dea31012005-04-17 16:05:31 -05006375 /* note: fc_myDID already in cpu endianness */
James Smart2e0fef82007-06-17 19:56:36 -05006376 fc_host_port_id(shost) = vport->fc_myDID;
dea31012005-04-17 16:05:31 -05006377}
6378
James Smarte59058c2008-08-24 21:49:00 -04006379/**
James Smart3621a712009-04-06 18:47:14 -04006380 * lpfc_get_host_port_type - Set the value of the scsi host port type
James Smarte59058c2008-08-24 21:49:00 -04006381 * @shost: kernel scsi host pointer.
6382 **/
dea31012005-04-17 16:05:31 -05006383static void
6384lpfc_get_host_port_type(struct Scsi_Host *shost)
6385{
James Smart2e0fef82007-06-17 19:56:36 -05006386 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6387 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006388
6389 spin_lock_irq(shost->host_lock);
6390
James Smart92d7f7b2007-06-17 19:56:38 -05006391 if (vport->port_type == LPFC_NPIV_PORT) {
6392 fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
6393 } else if (lpfc_is_link_up(phba)) {
James Smart76a95d72010-11-20 23:11:48 -05006394 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
James Smart2e0fef82007-06-17 19:56:36 -05006395 if (vport->fc_flag & FC_PUBLIC_LOOP)
dea31012005-04-17 16:05:31 -05006396 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
6397 else
6398 fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
6399 } else {
James Smart2e0fef82007-06-17 19:56:36 -05006400 if (vport->fc_flag & FC_FABRIC)
dea31012005-04-17 16:05:31 -05006401 fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
6402 else
6403 fc_host_port_type(shost) = FC_PORTTYPE_PTP;
6404 }
6405 } else
6406 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
6407
6408 spin_unlock_irq(shost->host_lock);
6409}
6410
James Smarte59058c2008-08-24 21:49:00 -04006411/**
James Smart3621a712009-04-06 18:47:14 -04006412 * lpfc_get_host_port_state - Set the value of the scsi host port state
James Smarte59058c2008-08-24 21:49:00 -04006413 * @shost: kernel scsi host pointer.
6414 **/
dea31012005-04-17 16:05:31 -05006415static void
6416lpfc_get_host_port_state(struct Scsi_Host *shost)
6417{
James Smart2e0fef82007-06-17 19:56:36 -05006418 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6419 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006420
6421 spin_lock_irq(shost->host_lock);
6422
James Smart2e0fef82007-06-17 19:56:36 -05006423 if (vport->fc_flag & FC_OFFLINE_MODE)
dea31012005-04-17 16:05:31 -05006424 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
6425 else {
James Smart2e0fef82007-06-17 19:56:36 -05006426 switch (phba->link_state) {
6427 case LPFC_LINK_UNKNOWN:
dea31012005-04-17 16:05:31 -05006428 case LPFC_LINK_DOWN:
6429 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
6430 break;
6431 case LPFC_LINK_UP:
dea31012005-04-17 16:05:31 -05006432 case LPFC_CLEAR_LA:
6433 case LPFC_HBA_READY:
James Smart026abb82011-12-13 13:20:45 -05006434 /* Links up, reports port state accordingly */
6435 if (vport->port_state < LPFC_VPORT_READY)
6436 fc_host_port_state(shost) =
6437 FC_PORTSTATE_BYPASSED;
6438 else
6439 fc_host_port_state(shost) =
6440 FC_PORTSTATE_ONLINE;
dea31012005-04-17 16:05:31 -05006441 break;
6442 case LPFC_HBA_ERROR:
6443 fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
6444 break;
6445 default:
6446 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
6447 break;
6448 }
6449 }
6450
6451 spin_unlock_irq(shost->host_lock);
6452}
6453
James Smarte59058c2008-08-24 21:49:00 -04006454/**
James Smart3621a712009-04-06 18:47:14 -04006455 * lpfc_get_host_speed - Set the value of the scsi host speed
James Smarte59058c2008-08-24 21:49:00 -04006456 * @shost: kernel scsi host pointer.
6457 **/
dea31012005-04-17 16:05:31 -05006458static void
6459lpfc_get_host_speed(struct Scsi_Host *shost)
6460{
James Smart2e0fef82007-06-17 19:56:36 -05006461 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6462 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05006463
6464 spin_lock_irq(shost->host_lock);
6465
James Smarta085e872015-12-16 18:12:02 -05006466 if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) {
dea31012005-04-17 16:05:31 -05006467 switch(phba->fc_linkspeed) {
James Smart76a95d72010-11-20 23:11:48 -05006468 case LPFC_LINK_SPEED_1GHZ:
6469 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
dea31012005-04-17 16:05:31 -05006470 break;
James Smart76a95d72010-11-20 23:11:48 -05006471 case LPFC_LINK_SPEED_2GHZ:
6472 fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
dea31012005-04-17 16:05:31 -05006473 break;
James Smart76a95d72010-11-20 23:11:48 -05006474 case LPFC_LINK_SPEED_4GHZ:
6475 fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
dea31012005-04-17 16:05:31 -05006476 break;
James Smart76a95d72010-11-20 23:11:48 -05006477 case LPFC_LINK_SPEED_8GHZ:
6478 fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
James Smartb87eab32007-04-25 09:53:28 -04006479 break;
James Smart76a95d72010-11-20 23:11:48 -05006480 case LPFC_LINK_SPEED_10GHZ:
6481 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
James Smartf4b4c682009-05-22 14:53:12 -04006482 break;
James Smart76a95d72010-11-20 23:11:48 -05006483 case LPFC_LINK_SPEED_16GHZ:
6484 fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
6485 break;
James Smartd38dd522015-08-31 16:48:17 -04006486 case LPFC_LINK_SPEED_32GHZ:
6487 fc_host_speed(shost) = FC_PORTSPEED_32GBIT;
6488 break;
James Smartfbd8a6b2018-02-22 08:18:45 -08006489 case LPFC_LINK_SPEED_64GHZ:
6490 fc_host_speed(shost) = FC_PORTSPEED_64GBIT;
6491 break;
James Smart1dc5ec22018-10-23 13:41:11 -07006492 case LPFC_LINK_SPEED_128GHZ:
6493 fc_host_speed(shost) = FC_PORTSPEED_128GBIT;
6494 break;
James Smart76a95d72010-11-20 23:11:48 -05006495 default:
6496 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
dea31012005-04-17 16:05:31 -05006497 break;
6498 }
James Smartb615a202018-07-31 17:23:19 -07006499 } else if (lpfc_is_link_up(phba) && (phba->hba_flag & HBA_FCOE_MODE)) {
6500 switch (phba->fc_linkspeed) {
6501 case LPFC_ASYNC_LINK_SPEED_10GBPS:
6502 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
6503 break;
6504 case LPFC_ASYNC_LINK_SPEED_25GBPS:
6505 fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
6506 break;
6507 case LPFC_ASYNC_LINK_SPEED_40GBPS:
6508 fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
6509 break;
6510 case LPFC_ASYNC_LINK_SPEED_100GBPS:
6511 fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
6512 break;
6513 default:
6514 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
6515 break;
6516 }
James Smart09372822008-01-11 01:52:54 -05006517 } else
6518 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
dea31012005-04-17 16:05:31 -05006519
6520 spin_unlock_irq(shost->host_lock);
6521}
6522
James Smarte59058c2008-08-24 21:49:00 -04006523/**
James Smart3621a712009-04-06 18:47:14 -04006524 * lpfc_get_host_fabric_name - Set the value of the scsi host fabric name
James Smarte59058c2008-08-24 21:49:00 -04006525 * @shost: kernel scsi host pointer.
6526 **/
dea31012005-04-17 16:05:31 -05006527static void
6528lpfc_get_host_fabric_name (struct Scsi_Host *shost)
6529{
James Smart2e0fef82007-06-17 19:56:36 -05006530 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6531 struct lpfc_hba *phba = vport->phba;
Andrew Vasquezf631b4b2005-08-31 15:23:12 -07006532 u64 node_name;
dea31012005-04-17 16:05:31 -05006533
6534 spin_lock_irq(shost->host_lock);
6535
James Smart73d91e52011-10-10 21:32:10 -04006536 if ((vport->port_state > LPFC_FLOGI) &&
6537 ((vport->fc_flag & FC_FABRIC) ||
6538 ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
6539 (vport->fc_flag & FC_PUBLIC_LOOP))))
Andrew Morton68ce1eb2005-09-21 09:46:54 -07006540 node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
dea31012005-04-17 16:05:31 -05006541 else
6542 /* fabric is local port if there is no F/FL_Port */
James Smart09372822008-01-11 01:52:54 -05006543 node_name = 0;
dea31012005-04-17 16:05:31 -05006544
6545 spin_unlock_irq(shost->host_lock);
6546
Andrew Vasquezf631b4b2005-08-31 15:23:12 -07006547 fc_host_fabric_name(shost) = node_name;
dea31012005-04-17 16:05:31 -05006548}
6549
James Smarte59058c2008-08-24 21:49:00 -04006550/**
James Smart3621a712009-04-06 18:47:14 -04006551 * lpfc_get_stats - Return statistical information about the adapter
James Smarte59058c2008-08-24 21:49:00 -04006552 * @shost: kernel scsi host pointer.
6553 *
6554 * Notes:
6555 * NULL on error for link down, no mbox pool, sli2 active,
6556 * management not allowed, memory allocation error, or mbox error.
6557 *
6558 * Returns:
6559 * NULL for error
6560 * address of the adapter host statistics
6561 **/
dea31012005-04-17 16:05:31 -05006562static struct fc_host_statistics *
6563lpfc_get_stats(struct Scsi_Host *shost)
6564{
James Smart2e0fef82007-06-17 19:56:36 -05006565 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6566 struct lpfc_hba *phba = vport->phba;
6567 struct lpfc_sli *psli = &phba->sli;
James.Smart@Emulex.Comf888ba32005-08-10 15:03:01 -04006568 struct fc_host_statistics *hs = &phba->link_stats;
James Smart64ba8812006-08-02 15:24:34 -04006569 struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
dea31012005-04-17 16:05:31 -05006570 LPFC_MBOXQ_t *pmboxq;
6571 MAILBOX_t *pmb;
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006572 int rc = 0;
dea31012005-04-17 16:05:31 -05006573
James Smart92d7f7b2007-06-17 19:56:38 -05006574 /*
6575 * prevent udev from issuing mailbox commands until the port is
6576 * configured.
6577 */
James Smart2e0fef82007-06-17 19:56:36 -05006578 if (phba->link_state < LPFC_LINK_DOWN ||
6579 !phba->mbox_mem_pool ||
James Smartf4b4c682009-05-22 14:53:12 -04006580 (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
James Smart92d7f7b2007-06-17 19:56:38 -05006581 return NULL;
James Smart2e0fef82007-06-17 19:56:36 -05006582
6583 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
James Smart46fa3112007-04-25 09:51:45 -04006584 return NULL;
6585
dea31012005-04-17 16:05:31 -05006586 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
6587 if (!pmboxq)
6588 return NULL;
6589 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
6590
James Smart04c68492009-05-22 14:52:52 -04006591 pmb = &pmboxq->u.mb;
dea31012005-04-17 16:05:31 -05006592 pmb->mbxCommand = MBX_READ_STATUS;
6593 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006594 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006595 pmboxq->vport = vport;
dea31012005-04-17 16:05:31 -05006596
James Smart75baf692010-06-08 18:31:21 -04006597 if (vport->fc_flag & FC_OFFLINE_MODE)
dea31012005-04-17 16:05:31 -05006598 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006599 else
dea31012005-04-17 16:05:31 -05006600 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6601
6602 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05006603 if (rc != MBX_TIMEOUT)
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006604 mempool_free(pmboxq, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05006605 return NULL;
6606 }
6607
James.Smart@Emulex.Comf888ba32005-08-10 15:03:01 -04006608 memset(hs, 0, sizeof (struct fc_host_statistics));
6609
dea31012005-04-17 16:05:31 -05006610 hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
James Smart73d91e52011-10-10 21:32:10 -04006611 /*
6612 * The MBX_READ_STATUS returns tx_k_bytes which has to
6613 * converted to words
6614 */
6615 hs->tx_words = (uint64_t)
6616 ((uint64_t)pmb->un.varRdStatus.xmitByteCnt
6617 * (uint64_t)256);
dea31012005-04-17 16:05:31 -05006618 hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
James Smart73d91e52011-10-10 21:32:10 -04006619 hs->rx_words = (uint64_t)
6620 ((uint64_t)pmb->un.varRdStatus.rcvByteCnt
6621 * (uint64_t)256);
dea31012005-04-17 16:05:31 -05006622
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006623 memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
dea31012005-04-17 16:05:31 -05006624 pmb->mbxCommand = MBX_READ_LNK_STAT;
6625 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006626 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006627 pmboxq->vport = vport;
dea31012005-04-17 16:05:31 -05006628
James Smart75baf692010-06-08 18:31:21 -04006629 if (vport->fc_flag & FC_OFFLINE_MODE)
dea31012005-04-17 16:05:31 -05006630 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
James.Smart@Emulex.Com433c3572005-10-28 20:28:56 -04006631 else
dea31012005-04-17 16:05:31 -05006632 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6633
6634 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05006635 if (rc != MBX_TIMEOUT)
James Smart92d7f7b2007-06-17 19:56:38 -05006636 mempool_free(pmboxq, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05006637 return NULL;
6638 }
6639
6640 hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
6641 hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
6642 hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
6643 hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
6644 hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
6645 hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
6646 hs->error_frames = pmb->un.varRdLnk.crcCnt;
6647
James Smart64ba8812006-08-02 15:24:34 -04006648 hs->link_failure_count -= lso->link_failure_count;
6649 hs->loss_of_sync_count -= lso->loss_of_sync_count;
6650 hs->loss_of_signal_count -= lso->loss_of_signal_count;
6651 hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count;
6652 hs->invalid_tx_word_count -= lso->invalid_tx_word_count;
6653 hs->invalid_crc_count -= lso->invalid_crc_count;
6654 hs->error_frames -= lso->error_frames;
6655
James Smart76a95d72010-11-20 23:11:48 -05006656 if (phba->hba_flag & HBA_FCOE_MODE) {
James Smart4d9ab992009-10-02 15:16:39 -04006657 hs->lip_count = -1;
6658 hs->nos_count = (phba->link_events >> 1);
6659 hs->nos_count -= lso->link_events;
James Smart76a95d72010-11-20 23:11:48 -05006660 } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
dea31012005-04-17 16:05:31 -05006661 hs->lip_count = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006662 hs->lip_count -= lso->link_events;
dea31012005-04-17 16:05:31 -05006663 hs->nos_count = -1;
6664 } else {
6665 hs->lip_count = -1;
6666 hs->nos_count = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006667 hs->nos_count -= lso->link_events;
dea31012005-04-17 16:05:31 -05006668 }
6669
6670 hs->dumped_frames = -1;
6671
Arnd Bergmannc4d6204d2018-06-18 17:28:23 +02006672 hs->seconds_since_last_reset = ktime_get_seconds() - psli->stats_start;
dea31012005-04-17 16:05:31 -05006673
James Smart1dcb58e2007-04-25 09:51:30 -04006674 mempool_free(pmboxq, phba->mbox_mem_pool);
6675
dea31012005-04-17 16:05:31 -05006676 return hs;
6677}
6678
James Smarte59058c2008-08-24 21:49:00 -04006679/**
James Smart3621a712009-04-06 18:47:14 -04006680 * lpfc_reset_stats - Copy the adapter link stats information
James Smarte59058c2008-08-24 21:49:00 -04006681 * @shost: kernel scsi host pointer.
6682 **/
James Smart64ba8812006-08-02 15:24:34 -04006683static void
6684lpfc_reset_stats(struct Scsi_Host *shost)
6685{
James Smart2e0fef82007-06-17 19:56:36 -05006686 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
6687 struct lpfc_hba *phba = vport->phba;
6688 struct lpfc_sli *psli = &phba->sli;
6689 struct lpfc_lnk_stat *lso = &psli->lnk_stat_offsets;
James Smart64ba8812006-08-02 15:24:34 -04006690 LPFC_MBOXQ_t *pmboxq;
6691 MAILBOX_t *pmb;
6692 int rc = 0;
6693
James Smart2e0fef82007-06-17 19:56:36 -05006694 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
James Smart46fa3112007-04-25 09:51:45 -04006695 return;
6696
James Smart64ba8812006-08-02 15:24:34 -04006697 pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
6698 if (!pmboxq)
6699 return;
6700 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
6701
James Smart04c68492009-05-22 14:52:52 -04006702 pmb = &pmboxq->u.mb;
James Smart64ba8812006-08-02 15:24:34 -04006703 pmb->mbxCommand = MBX_READ_STATUS;
6704 pmb->mbxOwner = OWN_HOST;
6705 pmb->un.varWords[0] = 0x1; /* reset request */
James Smart3e1f0712018-11-29 16:09:29 -08006706 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006707 pmboxq->vport = vport;
James Smart64ba8812006-08-02 15:24:34 -04006708
James Smart2e0fef82007-06-17 19:56:36 -05006709 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smartf4b4c682009-05-22 14:53:12 -04006710 (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
James Smart64ba8812006-08-02 15:24:34 -04006711 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
6712 else
6713 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6714
6715 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05006716 if (rc != MBX_TIMEOUT)
James Smart64ba8812006-08-02 15:24:34 -04006717 mempool_free(pmboxq, phba->mbox_mem_pool);
6718 return;
6719 }
6720
6721 memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
6722 pmb->mbxCommand = MBX_READ_LNK_STAT;
6723 pmb->mbxOwner = OWN_HOST;
James Smart3e1f0712018-11-29 16:09:29 -08006724 pmboxq->ctx_buf = NULL;
James Smart92d7f7b2007-06-17 19:56:38 -05006725 pmboxq->vport = vport;
James Smart64ba8812006-08-02 15:24:34 -04006726
James Smart2e0fef82007-06-17 19:56:36 -05006727 if ((vport->fc_flag & FC_OFFLINE_MODE) ||
James Smartf4b4c682009-05-22 14:53:12 -04006728 (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
James Smart64ba8812006-08-02 15:24:34 -04006729 rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
6730 else
6731 rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
6732
6733 if (rc != MBX_SUCCESS) {
James Smart858c9f62007-06-17 19:56:39 -05006734 if (rc != MBX_TIMEOUT)
James Smart64ba8812006-08-02 15:24:34 -04006735 mempool_free( pmboxq, phba->mbox_mem_pool);
6736 return;
6737 }
6738
6739 lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
6740 lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
6741 lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
6742 lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
6743 lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
6744 lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
6745 lso->error_frames = pmb->un.varRdLnk.crcCnt;
James Smart76a95d72010-11-20 23:11:48 -05006746 if (phba->hba_flag & HBA_FCOE_MODE)
James Smart4d9ab992009-10-02 15:16:39 -04006747 lso->link_events = (phba->link_events >> 1);
6748 else
6749 lso->link_events = (phba->fc_eventTag >> 1);
James Smart64ba8812006-08-02 15:24:34 -04006750
Arnd Bergmannc4d6204d2018-06-18 17:28:23 +02006751 psli->stats_start = ktime_get_seconds();
James Smart64ba8812006-08-02 15:24:34 -04006752
James Smart1dcb58e2007-04-25 09:51:30 -04006753 mempool_free(pmboxq, phba->mbox_mem_pool);
6754
James Smart64ba8812006-08-02 15:24:34 -04006755 return;
6756}
dea31012005-04-17 16:05:31 -05006757
6758/*
6759 * The LPFC driver treats linkdown handling as target loss events so there
6760 * are no sysfs handlers for link_down_tmo.
6761 */
James Smart685f0bf2007-04-25 09:53:08 -04006762
James Smarte59058c2008-08-24 21:49:00 -04006763/**
James Smart3621a712009-04-06 18:47:14 -04006764 * lpfc_get_node_by_target - Return the nodelist for a target
James Smarte59058c2008-08-24 21:49:00 -04006765 * @starget: kernel scsi target pointer.
6766 *
6767 * Returns:
6768 * address of the node list if found
6769 * NULL target not found
6770 **/
James Smart685f0bf2007-04-25 09:53:08 -04006771static struct lpfc_nodelist *
6772lpfc_get_node_by_target(struct scsi_target *starget)
dea31012005-04-17 16:05:31 -05006773{
James Smart2e0fef82007-06-17 19:56:36 -05006774 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
6775 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
James Smart685f0bf2007-04-25 09:53:08 -04006776 struct lpfc_nodelist *ndlp;
dea31012005-04-17 16:05:31 -05006777
6778 spin_lock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04006779 /* Search for this, mapped, target ID */
James Smart2e0fef82007-06-17 19:56:36 -05006780 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smarte47c9092008-02-08 18:49:26 -05006781 if (NLP_CHK_NODE_ACT(ndlp) &&
6782 ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
James Smart685f0bf2007-04-25 09:53:08 -04006783 starget->id == ndlp->nlp_sid) {
6784 spin_unlock_irq(shost->host_lock);
6785 return ndlp;
dea31012005-04-17 16:05:31 -05006786 }
6787 }
6788 spin_unlock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04006789 return NULL;
6790}
dea31012005-04-17 16:05:31 -05006791
James Smarte59058c2008-08-24 21:49:00 -04006792/**
James Smart3621a712009-04-06 18:47:14 -04006793 * lpfc_get_starget_port_id - Set the target port id to the ndlp DID or -1
James Smarte59058c2008-08-24 21:49:00 -04006794 * @starget: kernel scsi target pointer.
6795 **/
James Smart685f0bf2007-04-25 09:53:08 -04006796static void
6797lpfc_get_starget_port_id(struct scsi_target *starget)
6798{
6799 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
6800
6801 fc_starget_port_id(starget) = ndlp ? ndlp->nlp_DID : -1;
dea31012005-04-17 16:05:31 -05006802}
6803
James Smarte59058c2008-08-24 21:49:00 -04006804/**
James Smart3621a712009-04-06 18:47:14 -04006805 * lpfc_get_starget_node_name - Set the target node name
James Smarte59058c2008-08-24 21:49:00 -04006806 * @starget: kernel scsi target pointer.
6807 *
6808 * Description: Set the target node name to the ndlp node name wwn or zero.
6809 **/
dea31012005-04-17 16:05:31 -05006810static void
6811lpfc_get_starget_node_name(struct scsi_target *starget)
6812{
James Smart685f0bf2007-04-25 09:53:08 -04006813 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
dea31012005-04-17 16:05:31 -05006814
James Smart685f0bf2007-04-25 09:53:08 -04006815 fc_starget_node_name(starget) =
6816 ndlp ? wwn_to_u64(ndlp->nlp_nodename.u.wwn) : 0;
dea31012005-04-17 16:05:31 -05006817}
6818
James Smarte59058c2008-08-24 21:49:00 -04006819/**
James Smart3621a712009-04-06 18:47:14 -04006820 * lpfc_get_starget_port_name - Set the target port name
James Smarte59058c2008-08-24 21:49:00 -04006821 * @starget: kernel scsi target pointer.
6822 *
6823 * Description: set the target port name to the ndlp port name wwn or zero.
6824 **/
dea31012005-04-17 16:05:31 -05006825static void
6826lpfc_get_starget_port_name(struct scsi_target *starget)
6827{
James Smart685f0bf2007-04-25 09:53:08 -04006828 struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
dea31012005-04-17 16:05:31 -05006829
James Smart685f0bf2007-04-25 09:53:08 -04006830 fc_starget_port_name(starget) =
6831 ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0;
dea31012005-04-17 16:05:31 -05006832}
6833
James Smarte59058c2008-08-24 21:49:00 -04006834/**
James Smart3621a712009-04-06 18:47:14 -04006835 * lpfc_set_rport_loss_tmo - Set the rport dev loss tmo
James Smarte59058c2008-08-24 21:49:00 -04006836 * @rport: fc rport address.
6837 * @timeout: new value for dev loss tmo.
6838 *
6839 * Description:
6840 * If timeout is non zero set the dev_loss_tmo to timeout, else set
6841 * dev_loss_tmo to one.
6842 **/
dea31012005-04-17 16:05:31 -05006843static void
dea31012005-04-17 16:05:31 -05006844lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
6845{
James Smarta643c6d2019-08-14 16:56:48 -07006846 struct lpfc_rport_data *rdata = rport->dd_data;
6847 struct lpfc_nodelist *ndlp = rdata->pnode;
6848#if (IS_ENABLED(CONFIG_NVME_FC))
6849 struct lpfc_nvme_rport *nrport = NULL;
6850#endif
6851
dea31012005-04-17 16:05:31 -05006852 if (timeout)
James Smartc01f3202006-08-18 17:47:08 -04006853 rport->dev_loss_tmo = timeout;
dea31012005-04-17 16:05:31 -05006854 else
James Smartc01f3202006-08-18 17:47:08 -04006855 rport->dev_loss_tmo = 1;
James Smarta643c6d2019-08-14 16:56:48 -07006856
6857 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
6858 dev_info(&rport->dev, "Cannot find remote node to "
6859 "set rport dev loss tmo, port_id x%x\n",
6860 rport->port_id);
6861 return;
6862 }
6863
6864#if (IS_ENABLED(CONFIG_NVME_FC))
6865 nrport = lpfc_ndlp_get_nrport(ndlp);
6866
6867 if (nrport && nrport->remoteport)
6868 nvme_fc_set_remoteport_devloss(nrport->remoteport,
6869 rport->dev_loss_tmo);
6870#endif
dea31012005-04-17 16:05:31 -05006871}
6872
James Smarte59058c2008-08-24 21:49:00 -04006873/**
James Smart3621a712009-04-06 18:47:14 -04006874 * lpfc_rport_show_function - Return rport target information
James Smarte59058c2008-08-24 21:49:00 -04006875 *
6876 * Description:
6877 * Macro that uses field to generate a function with the name lpfc_show_rport_
6878 *
6879 * lpfc_show_rport_##field: returns the bytes formatted in buf
6880 * @cdev: class converted to an fc_rport.
6881 * @buf: on return contains the target_field or zero.
6882 *
6883 * Returns: size of formatted string.
6884 **/
dea31012005-04-17 16:05:31 -05006885#define lpfc_rport_show_function(field, format_string, sz, cast) \
6886static ssize_t \
Tony Jonesee959b02008-02-22 00:13:36 +01006887lpfc_show_rport_##field (struct device *dev, \
6888 struct device_attribute *attr, \
6889 char *buf) \
dea31012005-04-17 16:05:31 -05006890{ \
Tony Jonesee959b02008-02-22 00:13:36 +01006891 struct fc_rport *rport = transport_class_to_rport(dev); \
dea31012005-04-17 16:05:31 -05006892 struct lpfc_rport_data *rdata = rport->hostdata; \
Silvio Cesaree7f7b6f2019-03-21 09:44:32 -07006893 return scnprintf(buf, sz, format_string, \
dea31012005-04-17 16:05:31 -05006894 (rdata->target) ? cast rdata->target->field : 0); \
6895}
6896
6897#define lpfc_rport_rd_attr(field, format_string, sz) \
6898 lpfc_rport_show_function(field, format_string, sz, ) \
6899static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
6900
James Smarteada2722008-12-04 22:39:13 -05006901/**
James Smart3621a712009-04-06 18:47:14 -04006902 * lpfc_set_vport_symbolic_name - Set the vport's symbolic name
James Smarteada2722008-12-04 22:39:13 -05006903 * @fc_vport: The fc_vport who's symbolic name has been changed.
6904 *
6905 * Description:
6906 * This function is called by the transport after the @fc_vport's symbolic name
6907 * has been changed. This function re-registers the symbolic name with the
Lucas De Marchi25985ed2011-03-30 22:57:33 -03006908 * switch to propagate the change into the fabric if the vport is active.
James Smarteada2722008-12-04 22:39:13 -05006909 **/
6910static void
6911lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport)
6912{
6913 struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
6914
6915 if (vport->port_state == LPFC_VPORT_READY)
6916 lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
6917}
dea31012005-04-17 16:05:31 -05006918
James Smartf4b4c682009-05-22 14:53:12 -04006919/**
6920 * lpfc_hba_log_verbose_init - Set hba's log verbose level
6921 * @phba: Pointer to lpfc_hba struct.
6922 *
6923 * This function is called by the lpfc_get_cfgparam() routine to set the
6924 * module lpfc_log_verbose into the @phba cfg_log_verbose for use with
Justin P. Mattock70f23fd2011-05-10 10:16:21 +02006925 * log message according to the module's lpfc_log_verbose parameter setting
James Smartf4b4c682009-05-22 14:53:12 -04006926 * before hba port or vport created.
6927 **/
6928static void
6929lpfc_hba_log_verbose_init(struct lpfc_hba *phba, uint32_t verbose)
6930{
6931 phba->cfg_log_verbose = verbose;
6932}
6933
dea31012005-04-17 16:05:31 -05006934struct fc_function_template lpfc_transport_functions = {
6935 /* fixed attributes the driver supports */
6936 .show_host_node_name = 1,
6937 .show_host_port_name = 1,
6938 .show_host_supported_classes = 1,
6939 .show_host_supported_fc4s = 1,
dea31012005-04-17 16:05:31 -05006940 .show_host_supported_speeds = 1,
6941 .show_host_maxframe_size = 1,
James Smart6c9231f2016-12-19 15:07:24 -08006942
6943 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
James Smarteada2722008-12-04 22:39:13 -05006944 .show_host_symbolic_name = 1,
dea31012005-04-17 16:05:31 -05006945
6946 /* dynamic attributes the driver supports */
6947 .get_host_port_id = lpfc_get_host_port_id,
6948 .show_host_port_id = 1,
6949
6950 .get_host_port_type = lpfc_get_host_port_type,
6951 .show_host_port_type = 1,
6952
6953 .get_host_port_state = lpfc_get_host_port_state,
6954 .show_host_port_state = 1,
6955
6956 /* active_fc4s is shown but doesn't change (thus no get function) */
6957 .show_host_active_fc4s = 1,
6958
6959 .get_host_speed = lpfc_get_host_speed,
6960 .show_host_speed = 1,
6961
6962 .get_host_fabric_name = lpfc_get_host_fabric_name,
6963 .show_host_fabric_name = 1,
6964
6965 /*
6966 * The LPFC driver treats linkdown handling as target loss events
6967 * so there are no sysfs handlers for link_down_tmo.
6968 */
6969
6970 .get_fc_host_stats = lpfc_get_stats,
James Smart64ba8812006-08-02 15:24:34 -04006971 .reset_fc_host_stats = lpfc_reset_stats,
dea31012005-04-17 16:05:31 -05006972
6973 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
6974 .show_rport_maxframe_size = 1,
6975 .show_rport_supported_classes = 1,
6976
dea31012005-04-17 16:05:31 -05006977 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
6978 .show_rport_dev_loss_tmo = 1,
6979
6980 .get_starget_port_id = lpfc_get_starget_port_id,
6981 .show_starget_port_id = 1,
6982
6983 .get_starget_node_name = lpfc_get_starget_node_name,
6984 .show_starget_node_name = 1,
6985
6986 .get_starget_port_name = lpfc_get_starget_port_name,
6987 .show_starget_port_name = 1,
Andrew Vasquez91ca7b02005-10-27 16:03:37 -07006988
6989 .issue_fc_host_lip = lpfc_issue_lip,
James Smartc01f3202006-08-18 17:47:08 -04006990 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
6991 .terminate_rport_io = lpfc_terminate_rport_io,
James Smart92d7f7b2007-06-17 19:56:38 -05006992
James Smart92d7f7b2007-06-17 19:56:38 -05006993 .dd_fcvport_size = sizeof(struct lpfc_vport *),
James Smarteada2722008-12-04 22:39:13 -05006994
6995 .vport_disable = lpfc_vport_disable,
6996
6997 .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
James Smartf1c3b0f2009-07-19 10:01:32 -04006998
6999 .bsg_request = lpfc_bsg_request,
7000 .bsg_timeout = lpfc_bsg_timeout,
James Smart92d7f7b2007-06-17 19:56:38 -05007001};
7002
James Smart98c9ea52007-10-27 13:37:33 -04007003struct fc_function_template lpfc_vport_transport_functions = {
7004 /* fixed attributes the driver supports */
7005 .show_host_node_name = 1,
7006 .show_host_port_name = 1,
7007 .show_host_supported_classes = 1,
7008 .show_host_supported_fc4s = 1,
7009 .show_host_supported_speeds = 1,
7010 .show_host_maxframe_size = 1,
James Smart6c9231f2016-12-19 15:07:24 -08007011
7012 .get_host_symbolic_name = lpfc_get_host_symbolic_name,
James Smarteada2722008-12-04 22:39:13 -05007013 .show_host_symbolic_name = 1,
James Smart98c9ea52007-10-27 13:37:33 -04007014
7015 /* dynamic attributes the driver supports */
7016 .get_host_port_id = lpfc_get_host_port_id,
7017 .show_host_port_id = 1,
7018
7019 .get_host_port_type = lpfc_get_host_port_type,
7020 .show_host_port_type = 1,
7021
7022 .get_host_port_state = lpfc_get_host_port_state,
7023 .show_host_port_state = 1,
7024
7025 /* active_fc4s is shown but doesn't change (thus no get function) */
7026 .show_host_active_fc4s = 1,
7027
7028 .get_host_speed = lpfc_get_host_speed,
7029 .show_host_speed = 1,
7030
7031 .get_host_fabric_name = lpfc_get_host_fabric_name,
7032 .show_host_fabric_name = 1,
7033
7034 /*
7035 * The LPFC driver treats linkdown handling as target loss events
7036 * so there are no sysfs handlers for link_down_tmo.
7037 */
7038
7039 .get_fc_host_stats = lpfc_get_stats,
7040 .reset_fc_host_stats = lpfc_reset_stats,
7041
7042 .dd_fcrport_size = sizeof(struct lpfc_rport_data),
7043 .show_rport_maxframe_size = 1,
7044 .show_rport_supported_classes = 1,
7045
7046 .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
7047 .show_rport_dev_loss_tmo = 1,
7048
7049 .get_starget_port_id = lpfc_get_starget_port_id,
7050 .show_starget_port_id = 1,
7051
7052 .get_starget_node_name = lpfc_get_starget_node_name,
7053 .show_starget_node_name = 1,
7054
7055 .get_starget_port_name = lpfc_get_starget_port_name,
7056 .show_starget_port_name = 1,
7057
7058 .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
7059 .terminate_rport_io = lpfc_terminate_rport_io,
7060
7061 .vport_disable = lpfc_vport_disable,
James Smarteada2722008-12-04 22:39:13 -05007062
7063 .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
James Smart98c9ea52007-10-27 13:37:33 -04007064};
7065
James Smarte59058c2008-08-24 21:49:00 -04007066/**
James Smart4945c0f2019-08-14 16:57:02 -07007067 * lpfc_get_hba_function_mode - Used to determine the HBA function in FCoE
7068 * Mode
7069 * @phba: lpfc_hba pointer.
7070 **/
7071static void
7072lpfc_get_hba_function_mode(struct lpfc_hba *phba)
7073{
7074 /* If it's a SkyHawk FCoE adapter */
7075 if (phba->pcidev->device == PCI_DEVICE_ID_SKYHAWK)
7076 phba->hba_flag |= HBA_FCOE_MODE;
7077 else
7078 phba->hba_flag &= ~HBA_FCOE_MODE;
7079}
7080
7081/**
James Smart3621a712009-04-06 18:47:14 -04007082 * lpfc_get_cfgparam - Used during probe_one to init the adapter structure
James Smarte59058c2008-08-24 21:49:00 -04007083 * @phba: lpfc_hba pointer.
7084 **/
dea31012005-04-17 16:05:31 -05007085void
7086lpfc_get_cfgparam(struct lpfc_hba *phba)
7087{
James Smart49aa1432012-08-03 12:36:42 -04007088 lpfc_fcp_io_sched_init(phba, lpfc_fcp_io_sched);
James Smart7ea92eb2018-10-23 13:41:10 -07007089 lpfc_ns_query_init(phba, lpfc_ns_query);
James Smarta6571c62012-10-31 14:44:42 -04007090 lpfc_fcp2_no_tgt_reset_init(phba, lpfc_fcp2_no_tgt_reset);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007091 lpfc_cr_delay_init(phba, lpfc_cr_delay);
7092 lpfc_cr_count_init(phba, lpfc_cr_count);
Jamie Wellnitzcf5bf972006-02-28 22:33:08 -05007093 lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
James Smarta4bc3372006-12-02 13:34:16 -05007094 lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
7095 lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007096 lpfc_ack0_init(phba, lpfc_ack0);
James Smartc4908502019-01-28 11:14:28 -08007097 lpfc_xri_rebalancing_init(phba, lpfc_xri_rebalancing);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007098 lpfc_topology_init(phba, lpfc_topology);
James.Smart@Emulex.Com7bcbb752005-10-28 20:29:13 -04007099 lpfc_link_speed_init(phba, lpfc_link_speed);
James.Smart@Emulex.Com875fbdf2005-11-29 16:32:13 -05007100 lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
James Smart0c411222013-09-06 12:22:46 -04007101 lpfc_task_mgmt_tmo_init(phba, lpfc_task_mgmt_tmo);
James Smart78b2d852007-08-02 11:10:21 -04007102 lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
James Smart7d791df2011-07-22 18:37:52 -04007103 lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy);
James Smart19ca7602010-11-20 23:11:55 -05007104 lpfc_enable_rrq_init(phba, lpfc_enable_rrq);
James Smart4258e982015-12-16 18:11:58 -05007105 lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
7106 lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
James Smart4ff43242006-12-02 13:34:56 -05007107 lpfc_use_msi_init(phba, lpfc_use_msi);
James Smart895427b2017-02-12 13:52:30 -08007108 lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
James Smart4e565cf2018-02-22 08:18:50 -08007109 lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
James Smartda0436e2009-05-22 14:51:39 -04007110 lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
James Smart41b194b2019-05-14 14:58:08 -07007111 lpfc_force_rscn_init(phba, lpfc_force_rscn);
James Smart32517fc2019-01-28 11:14:33 -08007112 lpfc_cq_poll_threshold_init(phba, lpfc_cq_poll_threshold);
7113 lpfc_cq_max_proc_limit_init(phba, lpfc_cq_max_proc_limit);
James Smart7bb03bb2013-04-17 20:19:16 -04007114 lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
James Smart13815c82008-01-11 01:52:48 -05007115 lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
7116 lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
James Smart2ea259e2017-02-12 13:52:27 -08007117
James Smart1ba981f2014-02-20 09:56:45 -05007118 lpfc_EnableXLane_init(phba, lpfc_EnableXLane);
7119 if (phba->sli_rev != LPFC_SLI_REV4)
7120 phba->cfg_EnableXLane = 0;
7121 lpfc_XLanePriority_init(phba, lpfc_XLanePriority);
James Smart2ea259e2017-02-12 13:52:27 -08007122
James Smart1ba981f2014-02-20 09:56:45 -05007123 memset(phba->cfg_oas_tgt_wwpn, 0, (8 * sizeof(uint8_t)));
7124 memset(phba->cfg_oas_vpt_wwpn, 0, (8 * sizeof(uint8_t)));
7125 phba->cfg_oas_lun_state = 0;
7126 phba->cfg_oas_lun_status = 0;
7127 phba->cfg_oas_flags = 0;
James Smartc92c8412016-07-06 12:36:05 -07007128 phba->cfg_oas_priority = 0;
James Smart81301a92008-12-04 22:39:46 -05007129 lpfc_enable_bg_init(phba, lpfc_enable_bg);
James Smartb3b98b72016-10-13 15:06:06 -07007130 lpfc_prot_mask_init(phba, lpfc_prot_mask);
7131 lpfc_prot_guard_init(phba, lpfc_prot_guard);
James Smart45ed1192009-10-02 15:17:02 -04007132 if (phba->sli_rev == LPFC_SLI_REV4)
7133 phba->cfg_poll = 0;
7134 else
James Smart1ba981f2014-02-20 09:56:45 -05007135 phba->cfg_poll = lpfc_poll;
James Smartf44ac122018-03-05 12:04:08 -08007136
James Smart4945c0f2019-08-14 16:57:02 -07007137 /* Get the function mode */
7138 lpfc_get_hba_function_mode(phba);
7139
7140 /* BlockGuard allowed for FC only. */
7141 if (phba->cfg_enable_bg && phba->hba_flag & HBA_FCOE_MODE) {
7142 lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
7143 "0581 BlockGuard feature not supported\n");
7144 /* If set, clear the BlockGuard support param */
7145 phba->cfg_enable_bg = 0;
7146 } else if (phba->cfg_enable_bg) {
James Smartf44ac122018-03-05 12:04:08 -08007147 phba->sli3_options |= LPFC_SLI3_BG_ENABLED;
James Smart4945c0f2019-08-14 16:57:02 -07007148 }
James Smartf44ac122018-03-05 12:04:08 -08007149
James Smartf358dd02017-02-12 13:52:34 -08007150 lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp);
James Smart4258e982015-12-16 18:11:58 -05007151
James Smart895427b2017-02-12 13:52:30 -08007152 lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type);
James Smart2d7dbc42017-02-12 13:52:35 -08007153 lpfc_nvmet_mrq_init(phba, lpfc_nvmet_mrq);
James Smart2448e482018-04-09 14:24:24 -07007154 lpfc_nvmet_mrq_post_init(phba, lpfc_nvmet_mrq_post);
James Smart895427b2017-02-12 13:52:30 -08007155
7156 /* Initialize first burst. Target vs Initiator are different. */
7157 lpfc_nvme_enable_fb_init(phba, lpfc_nvme_enable_fb);
James Smart2d7dbc42017-02-12 13:52:35 -08007158 lpfc_nvmet_fb_size_init(phba, lpfc_nvmet_fb_size);
James Smartcdb42be2019-01-28 11:14:21 -08007159 lpfc_hdw_queue_init(phba, lpfc_hdw_queue);
James Smart6a828b02019-01-28 11:14:31 -08007160 lpfc_irq_chann_init(phba, lpfc_irq_chann);
James Smart44fd7fe2017-08-23 16:55:47 -07007161 lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
James Smart1351e692018-02-22 08:18:43 -08007162 lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
James Smart895427b2017-02-12 13:52:30 -08007163
7164 if (phba->sli_rev != LPFC_SLI_REV4) {
7165 /* NVME only supported on SLI4 */
7166 phba->nvmet_support = 0;
James Smart982ab122019-03-12 16:30:10 -07007167 phba->cfg_nvmet_mrq = 0;
James Smart895427b2017-02-12 13:52:30 -08007168 phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
James Smart44fd7fe2017-08-23 16:55:47 -07007169 phba->cfg_enable_bbcr = 0;
James Smartc4908502019-01-28 11:14:28 -08007170 phba->cfg_xri_rebalancing = 0;
James Smart895427b2017-02-12 13:52:30 -08007171 } else {
7172 /* We MUST have FCP support */
7173 if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
7174 phba->cfg_enable_fc4_type |= LPFC_ENABLE_FCP;
7175 }
7176
James Smart32517fc2019-01-28 11:14:33 -08007177 phba->cfg_auto_imax = (phba->cfg_fcp_imax) ? 0 : 1;
James Smart0cf07f842017-06-01 21:07:10 -07007178
James Smart06b6fa382018-07-31 17:23:24 -07007179 phba->cfg_enable_pbde = 0;
7180
James Smart895427b2017-02-12 13:52:30 -08007181 /* A value of 0 means use the number of CPUs found in the system */
James Smartcdb42be2019-01-28 11:14:21 -08007182 if (phba->cfg_hdw_queue == 0)
7183 phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
James Smart6a828b02019-01-28 11:14:31 -08007184 if (phba->cfg_irq_chann == 0)
7185 phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
7186 if (phba->cfg_irq_chann > phba->cfg_hdw_queue)
7187 phba->cfg_irq_chann = phba->cfg_hdw_queue;
James Smart4258e982015-12-16 18:11:58 -05007188
James Smart352e5fd2016-12-30 06:57:47 -08007189 phba->cfg_soft_wwnn = 0L;
7190 phba->cfg_soft_wwpn = 0L;
James Smart83108bd2008-01-11 01:53:09 -05007191 lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
James Smart7054a602007-04-25 09:52:34 -04007192 lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
James Smart6fb120a2009-05-22 14:52:59 -04007193 lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
James Smart0d878412009-10-02 15:16:56 -04007194 lpfc_aer_support_init(phba, lpfc_aer_support);
James Smart912e3ac2011-05-24 11:42:11 -04007195 lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn);
James Smartc71ab862012-10-31 14:44:33 -04007196 lpfc_request_firmware_upgrade_init(phba, lpfc_req_fw_upgrade);
James Smart84d1b002010-02-12 14:42:33 -05007197 lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up);
James Smart2a9bf3d2010-06-07 15:24:45 -04007198 lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt);
James Smart8eb8b962016-07-06 12:36:08 -07007199 lpfc_delay_discovery_init(phba, lpfc_delay_discovery);
James Smart12247e82016-07-06 12:36:09 -07007200 lpfc_sli_mode_init(phba, lpfc_sli_mode);
James Smartab56dc22011-02-16 12:39:57 -05007201 phba->cfg_enable_dss = 1;
James Smart7bdedb32016-07-06 12:36:00 -07007202 lpfc_enable_mds_diags_init(phba, lpfc_enable_mds_diags);
James Smartd2cc9bc2018-09-10 10:30:50 -07007203 lpfc_ras_fwlog_buffsize_init(phba, lpfc_ras_fwlog_buffsize);
7204 lpfc_ras_fwlog_level_init(phba, lpfc_ras_fwlog_level);
7205 lpfc_ras_fwlog_func_init(phba, lpfc_ras_fwlog_func);
7206
James Smart3de2a652007-08-02 11:09:59 -04007207 return;
7208}
Jamie Wellnitzb28485a2006-02-28 19:25:21 -05007209
James Smarte59058c2008-08-24 21:49:00 -04007210/**
James Smart895427b2017-02-12 13:52:30 -08007211 * lpfc_nvme_mod_param_dep - Adjust module parameter value based on
7212 * dependencies between protocols and roles.
7213 * @phba: lpfc_hba pointer.
7214 **/
7215void
7216lpfc_nvme_mod_param_dep(struct lpfc_hba *phba)
7217{
James Smartcdb42be2019-01-28 11:14:21 -08007218 if (phba->cfg_hdw_queue > phba->sli4_hba.num_present_cpu)
7219 phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
James Smart6a828b02019-01-28 11:14:31 -08007220 if (phba->cfg_irq_chann > phba->sli4_hba.num_present_cpu)
7221 phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
7222 if (phba->cfg_irq_chann > phba->cfg_hdw_queue)
7223 phba->cfg_irq_chann = phba->cfg_hdw_queue;
James Smart895427b2017-02-12 13:52:30 -08007224
James Smartf358dd02017-02-12 13:52:34 -08007225 if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME &&
7226 phba->nvmet_support) {
7227 phba->cfg_enable_fc4_type &= ~LPFC_ENABLE_FCP;
James Smart2d7dbc42017-02-12 13:52:35 -08007228
7229 lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
7230 "6013 %s x%x fb_size x%x, fb_max x%x\n",
7231 "NVME Target PRLI ACC enable_fb ",
7232 phba->cfg_nvme_enable_fb,
7233 phba->cfg_nvmet_fb_size,
7234 LPFC_NVMET_FB_SZ_MAX);
7235
7236 if (phba->cfg_nvme_enable_fb == 0)
7237 phba->cfg_nvmet_fb_size = 0;
7238 else {
7239 if (phba->cfg_nvmet_fb_size > LPFC_NVMET_FB_SZ_MAX)
7240 phba->cfg_nvmet_fb_size = LPFC_NVMET_FB_SZ_MAX;
7241 }
7242
James Smartbcb24f62017-11-20 16:00:36 -08007243 if (!phba->cfg_nvmet_mrq)
James Smart6a828b02019-01-28 11:14:31 -08007244 phba->cfg_nvmet_mrq = phba->cfg_irq_chann;
James Smartbcb24f62017-11-20 16:00:36 -08007245
James Smart2d7dbc42017-02-12 13:52:35 -08007246 /* Adjust lpfc_nvmet_mrq to avoid running out of WQE slots */
James Smart6a828b02019-01-28 11:14:31 -08007247 if (phba->cfg_nvmet_mrq > phba->cfg_irq_chann) {
7248 phba->cfg_nvmet_mrq = phba->cfg_irq_chann;
James Smart2d7dbc42017-02-12 13:52:35 -08007249 lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC,
7250 "6018 Adjust lpfc_nvmet_mrq to %d\n",
7251 phba->cfg_nvmet_mrq);
7252 }
James Smartbcb24f62017-11-20 16:00:36 -08007253 if (phba->cfg_nvmet_mrq > LPFC_NVMET_MRQ_MAX)
7254 phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_MAX;
7255
James Smart2d7dbc42017-02-12 13:52:35 -08007256 } else {
James Smartf358dd02017-02-12 13:52:34 -08007257 /* Not NVME Target mode. Turn off Target parameters. */
7258 phba->nvmet_support = 0;
James Smart982ab122019-03-12 16:30:10 -07007259 phba->cfg_nvmet_mrq = 0;
James Smart2d7dbc42017-02-12 13:52:35 -08007260 phba->cfg_nvmet_fb_size = 0;
7261 }
James Smart895427b2017-02-12 13:52:30 -08007262}
7263
7264/**
James Smart3621a712009-04-06 18:47:14 -04007265 * lpfc_get_vport_cfgparam - Used during port create, init the vport structure
James Smarte59058c2008-08-24 21:49:00 -04007266 * @vport: lpfc_vport pointer.
7267 **/
James Smart3de2a652007-08-02 11:09:59 -04007268void
7269lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
7270{
James Smarte8b62012007-08-02 11:10:09 -04007271 lpfc_log_verbose_init(vport, lpfc_log_verbose);
James Smart3de2a652007-08-02 11:09:59 -04007272 lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth);
James Smart7dc517d2010-07-14 15:32:10 -04007273 lpfc_tgt_queue_depth_init(vport, lpfc_tgt_queue_depth);
James Smart3de2a652007-08-02 11:09:59 -04007274 lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo);
7275 lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo);
7276 lpfc_peer_port_login_init(vport, lpfc_peer_port_login);
7277 lpfc_restrict_login_init(vport, lpfc_restrict_login);
7278 lpfc_fcp_class_init(vport, lpfc_fcp_class);
7279 lpfc_use_adisc_init(vport, lpfc_use_adisc);
James Smart3cb01c52013-07-15 18:35:04 -04007280 lpfc_first_burst_size_init(vport, lpfc_first_burst_size);
James Smart977b5a02008-09-07 11:52:04 -04007281 lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time);
James Smart3de2a652007-08-02 11:09:59 -04007282 lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
7283 lpfc_max_luns_init(vport, lpfc_max_luns);
7284 lpfc_scan_down_init(vport, lpfc_scan_down);
James Smart7ee5d432007-10-27 13:37:17 -04007285 lpfc_enable_da_id_init(vport, lpfc_enable_da_id);
dea31012005-04-17 16:05:31 -05007286 return;
7287}