^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*******************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is part of the Emulex Linux Device Driver for *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Fibre Channel Host Bus Adapters. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2004-2016 Emulex. All rights reserved. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * EMULEX and SLI are trademarks of Emulex. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * www.broadcom.com *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Portions Copyright (C) 2004-2005 Christoph Hellwig *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * This program is free software; you can redistribute it and/or *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * modify it under the terms of version 2 of the GNU General *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Public License as published by the Free Software Foundation. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * This program is distributed in the hope that it will be useful. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * TO BE LEGALLY INVALID. See the GNU General Public License for *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * more details, a copy of which can be found in the file COPYING *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * included with this package. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *******************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/aer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <scsi/scsi_transport_fc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <scsi/fc/fc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "lpfc_hw4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "lpfc_hw.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "lpfc_sli.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "lpfc_sli4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "lpfc_nl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "lpfc_disc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include "lpfc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "lpfc_scsi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include "lpfc_nvme.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include "lpfc_logmsg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include "lpfc_version.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include "lpfc_compat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include "lpfc_crtn.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include "lpfc_vport.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include "lpfc_attr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define LPFC_DEF_DEVLOSS_TMO 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define LPFC_MIN_DEVLOSS_TMO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define LPFC_MAX_DEVLOSS_TMO 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define LPFC_DEF_MRQ_POST 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define LPFC_MIN_MRQ_POST 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define LPFC_MAX_MRQ_POST 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * Write key size should be multiple of 4. If write key is changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * make sure that library write key is also changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define LPFC_REG_WRITE_KEY_SIZE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define LPFC_REG_WRITE_KEY "EMLX"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) const char *const trunk_errmsg[] = { /* map errcode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) "", /* There is no such error code at index 0*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) "link negotiated speed does not match existing"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) " trunk - link was \"low\" speed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) "link negotiated speed does not match"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) " existing trunk - link was \"middle\" speed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) "link negotiated speed does not match existing"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) " trunk - link was \"high\" speed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) "Attached to non-trunking port - F_Port",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) "Attached to non-trunking port - N_Port",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) "FLOGI response timeout",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) "non-FLOGI frame received",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) "Invalid FLOGI response",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) "Trunking initialization protocol",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) "Trunk peer device mismatch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @incr: integer to convert.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @hdw: ascii string holding converted integer plus a string terminator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * JEDEC Joint Electron Device Engineering Council.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * Convert a 32 bit integer composed of 8 nibbles into an 8 byte ascii
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * character string. The string is then terminated with a NULL in byte 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Hex 0-9 becomes ascii '0' to '9'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Hex a-f becomes ascii '=' to 'B' capital B.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * Coded for 32 bit integers only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) lpfc_jedec_to_ascii(int incr, char hdw[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) j = (incr & 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (j <= 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) hdw[7 - i] = 0x30 + j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) hdw[7 - i] = 0x61 + j - 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) incr = (incr >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) hdw[8] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * lpfc_drvr_version_show - Return the Emulex driver string with version number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * @dev: class unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @buf: on return contains the module description text.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return scnprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * lpfc_enable_fip_show - Return the fip mode of the HBA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @dev: class unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @buf: on return contains the module description text.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) lpfc_enable_fip_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (phba->hba_flag & HBA_FIP_SUPPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return scnprintf(buf, PAGE_SIZE, "1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return scnprintf(buf, PAGE_SIZE, "0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct lpfc_vport *vport = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct lpfc_nvmet_tgtport *tgtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct nvme_fc_local_port *localport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct lpfc_nvme_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct lpfc_nvme_rport *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct nvme_fc_remote_port *nrport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct lpfc_fc4_ctrl_stat *cstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) uint64_t data1, data2, data3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) uint64_t totin, totout, tot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) char *statep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) char tmp[LPFC_MAX_NVME_INFO_TMP_LEN] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (phba->nvmet_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (!phba->targetport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) len = scnprintf(buf, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) "NVME Target: x%llx is not allocated\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) wwn_to_u64(vport->fc_portname.u.wwn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* Port state is only one of two values for now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (phba->targetport->port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) statep = "REGISTERED";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) statep = "INIT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) "NVME Target Enabled State %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) statep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) "%s%d WWPN x%llx WWNN x%llx DID x%06x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) "NVME Target: lpfc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) phba->brd_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) wwn_to_u64(vport->fc_portname.u.wwn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) wwn_to_u64(vport->fc_nodename.u.wwn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) phba->targetport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (strlcat(buf, "\nNVME Target: Statistics\n", PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) "LS: Rcv %08x Drop %08x Abort %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) atomic_read(&tgtp->rcv_ls_req_in),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) atomic_read(&tgtp->rcv_ls_req_drop),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) atomic_read(&tgtp->xmt_ls_abort));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (atomic_read(&tgtp->rcv_ls_req_in) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) atomic_read(&tgtp->rcv_ls_req_out)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) "Rcv LS: in %08x != out %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) atomic_read(&tgtp->rcv_ls_req_in),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) atomic_read(&tgtp->rcv_ls_req_out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) "LS: Xmt %08x Drop %08x Cmpl %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) atomic_read(&tgtp->xmt_ls_rsp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) atomic_read(&tgtp->xmt_ls_drop),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) atomic_read(&tgtp->xmt_ls_rsp_cmpl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) "LS: RSP Abort %08x xb %08x Err %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) atomic_read(&tgtp->xmt_ls_rsp_aborted),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) atomic_read(&tgtp->xmt_ls_rsp_xb_set),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) atomic_read(&tgtp->xmt_ls_rsp_error));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) "FCP: Rcv %08x Defer %08x Release %08x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) "Drop %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) atomic_read(&tgtp->rcv_fcp_cmd_in),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) atomic_read(&tgtp->rcv_fcp_cmd_defer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) atomic_read(&tgtp->xmt_fcp_release),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) atomic_read(&tgtp->rcv_fcp_cmd_drop));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (atomic_read(&tgtp->rcv_fcp_cmd_in) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) atomic_read(&tgtp->rcv_fcp_cmd_out)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) "Rcv FCP: in %08x != out %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) atomic_read(&tgtp->rcv_fcp_cmd_in),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) atomic_read(&tgtp->rcv_fcp_cmd_out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) "FCP Rsp: RD %08x rsp %08x WR %08x rsp %08x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) "drop %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) atomic_read(&tgtp->xmt_fcp_read),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) atomic_read(&tgtp->xmt_fcp_read_rsp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) atomic_read(&tgtp->xmt_fcp_write),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) atomic_read(&tgtp->xmt_fcp_rsp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) atomic_read(&tgtp->xmt_fcp_drop));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) "FCP Rsp Cmpl: %08x err %08x drop %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) atomic_read(&tgtp->xmt_fcp_rsp_cmpl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) atomic_read(&tgtp->xmt_fcp_rsp_error),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) atomic_read(&tgtp->xmt_fcp_rsp_drop));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) "FCP Rsp Abort: %08x xb %08x xricqe %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) atomic_read(&tgtp->xmt_fcp_rsp_aborted),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) atomic_read(&tgtp->xmt_fcp_rsp_xb_set),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) atomic_read(&tgtp->xmt_fcp_xri_abort_cqe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) "ABORT: Xmt %08x Cmpl %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) atomic_read(&tgtp->xmt_fcp_abort),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) atomic_read(&tgtp->xmt_fcp_abort_cmpl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) atomic_read(&tgtp->xmt_abort_sol),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) atomic_read(&tgtp->xmt_abort_unsol),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) atomic_read(&tgtp->xmt_abort_rsp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) atomic_read(&tgtp->xmt_abort_rsp_error));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) "DELAY: ctx %08x fod %08x wqfull %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) atomic_read(&tgtp->defer_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) atomic_read(&tgtp->defer_fod),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) atomic_read(&tgtp->defer_wqfull));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* Calculate outstanding IOs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) tot = atomic_read(&tgtp->rcv_fcp_cmd_drop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) tot += atomic_read(&tgtp->xmt_fcp_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) "IO_CTX: %08x WAIT: cur %08x tot %08x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) "CTX Outstanding %08llx\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) phba->sli4_hba.nvmet_xri_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) phba->sli4_hba.nvmet_io_wait_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) phba->sli4_hba.nvmet_io_wait_total,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) tot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) strlcat(buf, tmp, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) localport = vport->localport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (!localport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) len = scnprintf(buf, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) "NVME Initiator x%llx is not allocated\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) wwn_to_u64(vport->fc_portname.u.wwn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) lport = (struct lpfc_nvme_lport *)localport->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (strlcat(buf, "\nNVME Initiator Enabled\n", PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) "XRI Dist lpfc%d Total %d IO %d ELS %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) phba->brd_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) phba->sli4_hba.max_cfg_param.max_xri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) phba->sli4_hba.io_xri_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) lpfc_sli4_get_els_iocb_cnt(phba));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Port state is only one of two values for now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (localport->port_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) statep = "ONLINE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) statep = "UNKNOWN ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) "%s%d WWPN x%llx WWNN x%llx DID x%06x %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) "NVME LPORT lpfc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) phba->brd_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) wwn_to_u64(vport->fc_portname.u.wwn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) wwn_to_u64(vport->fc_nodename.u.wwn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) localport->port_id, statep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) nrport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) spin_lock(&vport->phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) rport = lpfc_ndlp_get_nrport(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (rport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) nrport = rport->remoteport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) spin_unlock(&vport->phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (!nrport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Port state is only one of two values for now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) switch (nrport->port_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case FC_OBJSTATE_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) statep = "ONLINE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) case FC_OBJSTATE_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) statep = "UNKNOWN ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) statep = "UNSUPPORTED";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* Tab in to show lport ownership. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) goto unlock_buf_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (phba->brd_no >= 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) goto unlock_buf_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) scnprintf(tmp, sizeof(tmp), "WWPN x%llx ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) nrport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) goto unlock_buf_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) scnprintf(tmp, sizeof(tmp), "WWNN x%llx ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) nrport->node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) goto unlock_buf_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) scnprintf(tmp, sizeof(tmp), "DID x%06x ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) nrport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) goto unlock_buf_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* An NVME rport can have multiple roles. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) goto unlock_buf_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) goto unlock_buf_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) goto unlock_buf_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) FC_PORT_ROLE_NVME_TARGET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) FC_PORT_ROLE_NVME_DISCOVERY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) nrport->port_role);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) goto unlock_buf_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) scnprintf(tmp, sizeof(tmp), "%s\n", statep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) goto unlock_buf_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (!lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (strlcat(buf, "\nNVME Statistics\n", PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) "LS: Xmt %010x Cmpl %010x Abort %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) atomic_read(&lport->fc4NvmeLsRequests),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) atomic_read(&lport->fc4NvmeLsCmpls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) atomic_read(&lport->xmt_ls_abort));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) "LS XMIT: Err %08x CMPL: xb %08x Err %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) atomic_read(&lport->xmt_ls_err),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) atomic_read(&lport->cmpl_ls_xb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) atomic_read(&lport->cmpl_ls_err));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) totin = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) totout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) for (i = 0; i < phba->cfg_hdw_queue; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) cstat = &phba->sli4_hba.hdwq[i].nvme_cstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) tot = cstat->io_cmpls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) totin += tot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) data1 = cstat->input_requests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) data2 = cstat->output_requests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) data3 = cstat->control_requests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) totout += (data1 + data2 + data3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) "Total FCP Cmpl %016llx Issue %016llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) "OutIO %016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) totin, totout, totout - totin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) "\tabort %08x noxri %08x nondlp %08x qdepth %08x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) "wqerr %08x err %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) atomic_read(&lport->xmt_fcp_abort),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) atomic_read(&lport->xmt_fcp_noxri),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) atomic_read(&lport->xmt_fcp_bad_ndlp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) atomic_read(&lport->xmt_fcp_qdepth),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) atomic_read(&lport->xmt_fcp_err),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) atomic_read(&lport->xmt_fcp_wqerr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) scnprintf(tmp, sizeof(tmp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) "FCP CMPL: xb %08x Err %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) atomic_read(&lport->cmpl_fcp_xb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) atomic_read(&lport->cmpl_fcp_err));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) strlcat(buf, tmp, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* host_lock is already unlocked. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) unlock_buf_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) buffer_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) len = strnlen(buf, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (unlikely(len >= (PAGE_SIZE - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) lpfc_printf_log(phba, KERN_INFO, LOG_NVME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) "6314 Catching potential buffer "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) "overflow > PAGE_SIZE = %lu bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) strscpy(buf + PAGE_SIZE - 1 - sizeof(LPFC_NVME_INFO_MORE_STR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) LPFC_NVME_INFO_MORE_STR, sizeof(LPFC_NVME_INFO_MORE_STR) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) lpfc_scsi_stat_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct lpfc_vport *vport = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct lpfc_fc4_ctrl_stat *cstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) u64 data1, data2, data3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) u64 tot, totin, totout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) (phba->sli_rev != LPFC_SLI_REV4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) scnprintf(buf, PAGE_SIZE, "SCSI HDWQ Statistics\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) totin = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) totout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) for (i = 0; i < phba->cfg_hdw_queue; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) cstat = &phba->sli4_hba.hdwq[i].scsi_cstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) tot = cstat->io_cmpls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) totin += tot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) data1 = cstat->input_requests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) data2 = cstat->output_requests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) data3 = cstat->control_requests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) totout += (data1 + data2 + data3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) "IO %016llx ", i, data1, data2, data3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) tot, ((data1 + data2 + data3) - tot));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) goto buffer_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) "OutIO %016llx\n", totin, totout, totout - totin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) strlcat(buf, tmp, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) buffer_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) len = strnlen(buf, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) lpfc_bg_info_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (phba->cfg_enable_bg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (phba->sli3_options & LPFC_SLI3_BG_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return scnprintf(buf, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) "BlockGuard Enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return scnprintf(buf, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) "BlockGuard Not Supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return scnprintf(buf, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) "BlockGuard Disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) lpfc_bg_guard_err_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return scnprintf(buf, PAGE_SIZE, "%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) (unsigned long long)phba->bg_guard_err_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) lpfc_bg_apptag_err_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return scnprintf(buf, PAGE_SIZE, "%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) (unsigned long long)phba->bg_apptag_err_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) lpfc_bg_reftag_err_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return scnprintf(buf, PAGE_SIZE, "%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) (unsigned long long)phba->bg_reftag_err_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * lpfc_info_show - Return some pci info about the host in ascii
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * @buf: on return contains the formatted text from lpfc_info().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) lpfc_info_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return scnprintf(buf, PAGE_SIZE, "%s\n", lpfc_info(host));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * lpfc_serialnum_show - Return the hba serial number in ascii
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * @buf: on return contains the formatted text serial number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) lpfc_serialnum_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return scnprintf(buf, PAGE_SIZE, "%s\n", phba->SerialNumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * lpfc_temp_sensor_show - Return the temperature sensor level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * @buf: on return contains the formatted support level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * Returns a number indicating the temperature sensor level currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * supported, zero or one in ascii.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return scnprintf(buf, PAGE_SIZE, "%d\n", phba->temp_sensor_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * lpfc_modeldesc_show - Return the model description of the hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * @buf: on return contains the scsi vpd model description.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ModelDesc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * lpfc_modelname_show - Return the model name of the hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * @buf: on return contains the scsi vpd model name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) lpfc_modelname_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ModelName);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * lpfc_programtype_show - Return the program type of the hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * @buf: on return contains the scsi vpd program type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) lpfc_programtype_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return scnprintf(buf, PAGE_SIZE, "%s\n", phba->ProgramType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * lpfc_mlomgmt_show - Return the Menlo Maintenance sli flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * @buf: on return contains the Menlo Maintenance sli flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) lpfc_mlomgmt_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return scnprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) (phba->sli.sli_flag & LPFC_MENLO_MAINT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * lpfc_vportnum_show - Return the port number in ascii of the hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * @buf: on return contains scsi vpd program type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) lpfc_vportnum_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return scnprintf(buf, PAGE_SIZE, "%s\n", phba->Port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * lpfc_fwrev_show - Return the firmware rev running in the hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * @buf: on return contains the scsi vpd program type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) lpfc_fwrev_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) uint32_t if_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) uint8_t sli_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) char fwrev[FW_REV_STR_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) lpfc_decode_firmware_rev(phba, fwrev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if_type = phba->sli4_hba.pc_sli4_params.if_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) sli_family = phba->sli4_hba.pc_sli4_params.sli_family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (phba->sli_rev < LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) len = scnprintf(buf, PAGE_SIZE, "%s, sli-%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) fwrev, phba->sli_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) len = scnprintf(buf, PAGE_SIZE, "%s, sli-%d:%d:%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) fwrev, phba->sli_rev, if_type, sli_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) * lpfc_hdw_show - Return the jedec information about the hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * @buf: on return contains the scsi vpd program type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) char hdw[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) lpfc_vpd_t *vp = &phba->vpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return scnprintf(buf, PAGE_SIZE, "%s %08x %08x\n", hdw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) vp->rev.smRev, vp->rev.smFwRev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * lpfc_option_rom_version_show - Return the adapter ROM FCode version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * @buf: on return contains the ROM and FCode ascii strings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) char fwrev[FW_REV_STR_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (phba->sli_rev < LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return scnprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) phba->OptionROMVersion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) lpfc_decode_firmware_rev(phba, fwrev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return scnprintf(buf, PAGE_SIZE, "%s\n", fwrev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * lpfc_state_show - Return the link state of the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * @buf: on return contains text describing the state of the link.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * The switch statement has no default so zero will be returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) switch (phba->link_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) case LPFC_LINK_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) case LPFC_WARM_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) case LPFC_INIT_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) case LPFC_INIT_MBX_CMDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) case LPFC_LINK_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) case LPFC_HBA_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (phba->hba_flag & LINK_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) len += scnprintf(buf + len, PAGE_SIZE-len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) "Link Down - User disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) len += scnprintf(buf + len, PAGE_SIZE-len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) "Link Down\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) case LPFC_LINK_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) case LPFC_CLEAR_LA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) case LPFC_HBA_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) len += scnprintf(buf + len, PAGE_SIZE-len, "Link Up - ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) switch (vport->port_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) case LPFC_LOCAL_CFG_LINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) len += scnprintf(buf + len, PAGE_SIZE-len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) "Configuring Link\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) case LPFC_FDISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) case LPFC_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) case LPFC_FABRIC_CFG_LINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) case LPFC_NS_REG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) case LPFC_NS_QRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) case LPFC_BUILD_DISC_LIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) case LPFC_DISC_AUTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) "Discovery\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) case LPFC_VPORT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) "Ready\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) case LPFC_VPORT_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) "Failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) case LPFC_VPORT_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) "Unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (phba->sli.sli_flag & LPFC_MENLO_MAINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) len += scnprintf(buf + len, PAGE_SIZE-len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) " Menlo Maint Mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (vport->fc_flag & FC_PUBLIC_LOOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) len += scnprintf(buf + len, PAGE_SIZE-len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) " Public Loop\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) len += scnprintf(buf + len, PAGE_SIZE-len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) " Private Loop\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (vport->fc_flag & FC_FABRIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) len += scnprintf(buf + len, PAGE_SIZE-len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) " Fabric\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) len += scnprintf(buf + len, PAGE_SIZE-len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) " Point-2-Point\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if ((phba->sli_rev == LPFC_SLI_REV4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) ((bf_get(lpfc_sli_intf_if_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) &phba->sli4_hba.sli_intf) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) LPFC_SLI_INTF_IF_TYPE_6))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct lpfc_trunk_link link = phba->trunk_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (bf_get(lpfc_conf_trunk_port0, &phba->sli4_hba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) "Trunk port 0: Link %s %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) (link.link0.state == LPFC_LINK_UP) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) "Up" : "Down. ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) trunk_errmsg[link.link0.fault]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (bf_get(lpfc_conf_trunk_port1, &phba->sli4_hba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) "Trunk port 1: Link %s %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) (link.link1.state == LPFC_LINK_UP) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) "Up" : "Down. ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) trunk_errmsg[link.link1.fault]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (bf_get(lpfc_conf_trunk_port2, &phba->sli4_hba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) "Trunk port 2: Link %s %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) (link.link2.state == LPFC_LINK_UP) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) "Up" : "Down. ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) trunk_errmsg[link.link2.fault]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (bf_get(lpfc_conf_trunk_port3, &phba->sli4_hba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) "Trunk port 3: Link %s %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) (link.link3.state == LPFC_LINK_UP) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) "Up" : "Down. ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) trunk_errmsg[link.link3.fault]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * lpfc_sli4_protocol_show - Return the fip mode of the HBA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * @dev: class unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * @buf: on return contains the module description text.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) lpfc_sli4_protocol_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (phba->sli_rev < LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return scnprintf(buf, PAGE_SIZE, "fc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (phba->sli4_hba.lnk_info.lnk_dv == LPFC_LNK_DAT_VAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_GE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return scnprintf(buf, PAGE_SIZE, "fcoe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return scnprintf(buf, PAGE_SIZE, "fc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return scnprintf(buf, PAGE_SIZE, "unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * lpfc_oas_supported_show - Return whether or not Optimized Access Storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * (OAS) is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) * @dev: class unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * @buf: on return contains the module description text.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) lpfc_oas_supported_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return scnprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) phba->sli4_hba.pc_sli4_params.oas_supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * lpfc_link_state_store - Transition the link_state on an HBA port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * @buf: one or more lpfc_polling_flags values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * @count: not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * -EINVAL if the buffer is not "up" or "down"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) * return from link state change function if non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * length of the buf on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) lpfc_link_state_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) int status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if ((strncmp(buf, "up", sizeof("up") - 1) == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) (phba->link_state == LPFC_LINK_DOWN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) status = phba->lpfc_hba_init_link(phba, MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) else if ((strncmp(buf, "down", sizeof("down") - 1) == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) (phba->link_state >= LPFC_LINK_UP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) status = phba->lpfc_hba_down_link(phba, MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * lpfc_num_discovered_ports_show - Return sum of mapped and unmapped vports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) * @buf: on return contains the sum of fc mapped and unmapped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * Returns the ascii text number of the sum of the fc mapped and unmapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) * vport counts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) lpfc_num_discovered_ports_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return scnprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) vport->fc_map_cnt + vport->fc_unmap_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * lpfc_issue_lip - Misnomer, name carried over from long ago
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * @shost: Scsi_Host pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * Bring the link down gracefully then re-init the link. The firmware will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) * re-init the fiber channel interface as required. Does not issue a LIP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * -EPERM port offline or management commands are being blocked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) * -ENOMEM cannot allocate memory for the mailbox command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * -EIO error sending the mailbox command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) * zero for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) lpfc_issue_lip(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) LPFC_MBOXQ_t *pmboxq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) int mbxstatus = MBXERR_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * If the link is offline, disabled or BLOCK_MGMT_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * it doesn't make any sense to allow issue_lip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if ((vport->fc_flag & FC_OFFLINE_MODE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) (phba->hba_flag & LINK_DISABLED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (!pmboxq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) pmboxq->u.mb.mbxOwner = OWN_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if ((vport->fc_flag & FC_PT2PT) && (vport->fc_flag & FC_PT2PT_NO_NVME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) vport->fc_flag &= ~FC_PT2PT_NO_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if ((mbxstatus == MBX_SUCCESS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) (pmboxq->u.mb.mbxStatus == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) pmboxq->u.mb.mbxStatus == MBXERR_LINK_DOWN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) lpfc_init_link(phba, pmboxq, phba->cfg_topology,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) phba->cfg_link_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) phba->fc_ratov * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if ((mbxstatus == MBX_SUCCESS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) (pmboxq->u.mb.mbxStatus == MBXERR_SEC_NO_PERMISSION))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) "2859 SLI authentication is required "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) "for INIT_LINK but has not done yet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) lpfc_set_loopback_flag(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (mbxstatus != MBX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (mbxstatus == MBXERR_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) lpfc_emptyq_wait(struct lpfc_hba *phba, struct list_head *q, spinlock_t *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) int cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) spin_lock_irq(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) while (!list_empty(q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) spin_unlock_irq(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (cnt++ > 250) { /* 5 secs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) "0466 %s %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) "Outstanding IO when ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) "bringing Adapter offline\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) spin_lock_irq(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) spin_unlock_irq(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * lpfc_do_offline - Issues a mailbox command to bring the link down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * @type: LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * Assumes any error from lpfc_do_offline() will be negative.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) * Can wait up to 5 seconds for the port ring buffers count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) * to reach zero, prints a warning if it is not zero and continues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) * lpfc_workq_post_event() returns a non-zero return code if call fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * -EIO error posting the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * zero for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) lpfc_do_offline(struct lpfc_hba *phba, uint32_t type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) struct completion online_compl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) struct lpfc_queue *qp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) struct lpfc_sli_ring *pring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) struct lpfc_sli *psli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) init_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) rc = lpfc_workq_post_event(phba, &status, &online_compl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) LPFC_EVT_OFFLINE_PREP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) wait_for_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) psli = &phba->sli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) * If freeing the queues have already started, don't access them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * Otherwise set FREE_WAIT to indicate that queues are being used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * to hold the freeing process until we finish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (!(psli->sli_flag & LPFC_QUEUE_FREE_INIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) psli->sli_flag |= LPFC_QUEUE_FREE_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) goto skip_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) /* Wait a little for things to settle down, but not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) * long enough for dev loss timeout to expire.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (phba->sli_rev != LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) for (i = 0; i < psli->num_rings; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) pring = &psli->sli3_ring[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (!lpfc_emptyq_wait(phba, &pring->txcmplq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) &phba->hbalock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) list_for_each_entry(qp, &phba->sli4_hba.lpfc_wq_list, wq_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) pring = qp->pring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (!pring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (!lpfc_emptyq_wait(phba, &pring->txcmplq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) &pring->ring_lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) psli->sli_flag &= ~LPFC_QUEUE_FREE_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) skip_wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) init_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) rc = lpfc_workq_post_event(phba, &status, &online_compl, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) wait_for_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) * lpfc_reset_pci_bus - resets PCI bridge controller's secondary bus of an HBA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) * Issues a PCI secondary bus reset for the phba->pcidev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * First walks the bus_list to ensure only PCI devices with Emulex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * vendor id, device ids that support hot reset, only one occurrence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * of function 0, and all ports on the bus are in offline mode to ensure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * hot reset only affects one valid HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) * -ENOTSUPP, cfg_enable_hba_reset must be of value 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) * -ENODEV, NULL ptr to pcidev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) * -EBADSLT, detected invalid device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) * -EBUSY, port is not in offline state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) * 0, successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) lpfc_reset_pci_bus(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) struct pci_dev *pdev = phba->pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) struct Scsi_Host *shost = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) struct lpfc_hba *phba_other = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) struct pci_dev *ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (phba->cfg_enable_hba_reset != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "8345 pdev NULL!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) res = lpfc_check_pci_resettable(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) /* Walk the list of devices on the pci_dev's bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) list_for_each_entry(ptr, &pdev->bus->devices, bus_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) /* Check port is offline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) shost = pci_get_drvdata(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) if (shost) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) phba_other =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (!(phba_other->pport->fc_flag & FC_OFFLINE_MODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) lpfc_printf_log(phba_other, KERN_INFO, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) "8349 WWPN = 0x%02x%02x%02x%02x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) "%02x%02x%02x%02x is not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) "offline!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) phba_other->wwpn[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) phba_other->wwpn[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) phba_other->wwpn[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) phba_other->wwpn[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) phba_other->wwpn[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) phba_other->wwpn[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) phba_other->wwpn[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) phba_other->wwpn[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) /* Issue PCI bus reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) res = pci_reset_bus(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) "8350 PCI reset bus failed: %d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) * lpfc_selective_reset - Offline then onlines the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * If the port is configured to allow a reset then the hba is brought
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) * offline then online.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) * Assumes any error from lpfc_do_offline() will be negative.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) * Do not make this function static.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) * lpfc_do_offline() return code if not zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) * -EIO reset not configured or error posting the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) * zero for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) lpfc_selective_reset(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) struct completion online_compl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) if (!phba->cfg_enable_hba_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (!(phba->pport->fc_flag & FC_OFFLINE_MODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) init_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) rc = lpfc_workq_post_event(phba, &status, &online_compl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) LPFC_EVT_ONLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) wait_for_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) * lpfc_issue_reset - Selectively resets an adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) * @buf: containing the string "selective".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) * @count: unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) * If the buf contains the string "selective" then lpfc_selective_reset()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) * is called to perform the reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) * Assumes any error from lpfc_selective_reset() will be negative.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) * If lpfc_selective_reset() returns zero then the length of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) * is returned which indicates success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) * -EINVAL if the buffer does not contain the string "selective"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) * length of buf if lpfc-selective_reset() if the call succeeds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) * return value of lpfc_selective_reset() if the call fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) lpfc_issue_reset(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) int status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (!phba->cfg_enable_hba_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (strncmp(buf, "selective", sizeof("selective") - 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) status = phba->lpfc_selective_reset(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * lpfc_sli4_pdev_status_reg_wait - Wait for pdev status register for readyness
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) * SLI4 interface type-2 device to wait on the sliport status register for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * the readyness after performing a firmware reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) * zero for success, -EPERM when port does not have privilege to perform the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) * reset, -EIO when port timeout from recovering from the reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) * Note:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) * As the caller will interpret the return code by value, be careful in making
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * change or addition to return codes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) struct lpfc_register portstat_reg = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) &portstat_reg.word0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) /* verify if privileged for the request operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (!bf_get(lpfc_sliport_status_rn, &portstat_reg) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) !bf_get(lpfc_sliport_status_err, &portstat_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) /* wait for the SLI port firmware ready after firmware reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) &portstat_reg.word0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) if (!bf_get(lpfc_sliport_status_err, &portstat_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (!bf_get(lpfc_sliport_status_rn, &portstat_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) if (!bf_get(lpfc_sliport_status_rdy, &portstat_reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * lpfc_sli4_pdev_reg_request - Request physical dev to perform a register acc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) * Request SLI4 interface type-2 device to perform a physical register set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * access.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) * zero for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) struct completion online_compl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) struct pci_dev *pdev = phba->pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) uint32_t before_fc_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) uint32_t sriov_nr_virtfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) uint32_t reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) int status = 0, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) int job_posted = 1, sriov_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) if (!phba->cfg_enable_hba_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if ((phba->sli_rev < LPFC_SLI_REV4) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) LPFC_SLI_INTF_IF_TYPE_2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) /* Keep state if we need to restore back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) before_fc_flag = phba->pport->fc_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) if (opcode == LPFC_FW_DUMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) init_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) phba->fw_dump_cmpl = &online_compl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) /* Disable SR-IOV virtual functions if enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (phba->cfg_sriov_nr_virtfn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) pci_disable_sriov(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) phba->cfg_sriov_nr_virtfn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) /* wait for the device to be quiesced before firmware reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) reg_val = readl(phba->sli4_hba.conf_regs_memmap_p +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) LPFC_CTL_PDEV_CTL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (opcode == LPFC_FW_DUMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) reg_val |= LPFC_FW_DUMP_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) else if (opcode == LPFC_FW_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) reg_val |= LPFC_CTL_PDEV_CTL_FRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) else if (opcode == LPFC_DV_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) reg_val |= LPFC_CTL_PDEV_CTL_DRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) writel(reg_val, phba->sli4_hba.conf_regs_memmap_p +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) LPFC_CTL_PDEV_CTL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) readl(phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) /* delay driver action following IF_TYPE_2 reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) rc = lpfc_sli4_pdev_status_reg_wait(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (rc == -EPERM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) /* no privilege for reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) "3150 No privilege to perform the requested "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) "access: x%x\n", reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) } else if (rc == -EIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) /* reset failed, there is nothing more we can do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) "3153 Fail to perform the requested "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) "access: x%x\n", reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) if (phba->fw_dump_cmpl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) phba->fw_dump_cmpl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /* keep the original port state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) if (before_fc_flag & FC_OFFLINE_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) if (phba->fw_dump_cmpl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) phba->fw_dump_cmpl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* Firmware dump will trigger an HA_ERATT event, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) * lpfc_handle_eratt_s4 routine already handles bringing the port back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) * online.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) if (opcode == LPFC_FW_DUMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) wait_for_completion(phba->fw_dump_cmpl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) init_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) job_posted = lpfc_workq_post_event(phba, &status, &online_compl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) LPFC_EVT_ONLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (!job_posted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) wait_for_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) /* in any case, restore the virtual functions enabled as before */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) if (sriov_nr_virtfn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) /* If fw_dump was performed, first disable to clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (opcode == LPFC_FW_DUMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) pci_disable_sriov(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) phba->cfg_sriov_nr_virtfn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) sriov_err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (!sriov_err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) phba->cfg_sriov_nr_virtfn = sriov_nr_virtfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /* return proper error code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if (!job_posted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) else if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) * lpfc_nport_evt_cnt_show - Return the number of nport events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) * @buf: on return contains the ascii number of nport events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) return scnprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) LPFC_MBOXQ_t *mbox = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) unsigned long val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) char *pval = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) if (!strncmp("enable", buff_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) strlen("enable"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) pval = buff_out + strlen("enable") + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) rc = kstrtoul(pval, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) return rc; /* Invalid number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) } else if (!strncmp("disable", buff_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) strlen("disable"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) return -EINVAL; /* Invalid command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) val = 0x0; /* Disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) val = 0x1; /* Enable two port trunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) val = 0x2; /* Enable four port trunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) "0070 Set trunk mode with val %ld ", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) if (!mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) LPFC_MBOX_OPCODE_FCOE_FC_SET_TRUNK_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 12, LPFC_SLI4_MBX_EMBED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) bf_set(lpfc_mbx_set_trunk_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) &mbox->u.mqe.un.set_trunk_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) "0071 Set trunk mode failed with status: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) * lpfc_board_mode_show - Return the state of the board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) * @buf: on return contains the state of the adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) lpfc_board_mode_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) char * state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (phba->link_state == LPFC_HBA_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) state = "error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) else if (phba->link_state == LPFC_WARM_START)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) state = "warm start";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) else if (phba->link_state == LPFC_INIT_START)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) state = "offline";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) state = "online";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) return scnprintf(buf, PAGE_SIZE, "%s\n", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) * lpfc_board_mode_store - Puts the hba in online, offline, warm or error state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) * @buf: containing one of the strings "online", "offline", "warm" or "error".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) * @count: unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) * -EACCES if enable hba reset not enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) * -EINVAL if the buffer does not contain a valid string (see above)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) * -EIO if lpfc_workq_post_event() or lpfc_do_offline() fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) * buf length greater than zero indicates success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) struct completion online_compl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) char *board_mode_str = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) if (!phba->cfg_enable_hba_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) status = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) goto board_mode_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) "3050 lpfc_board_mode set to %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) init_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) if(strncmp(buf, "online", sizeof("online") - 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) rc = lpfc_workq_post_event(phba, &status, &online_compl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) LPFC_EVT_ONLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) goto board_mode_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) wait_for_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) status = lpfc_do_offline(phba, LPFC_EVT_WARM_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) else if (strncmp(buf, "error", sizeof("error") - 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) status = lpfc_do_offline(phba, LPFC_EVT_KILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_DUMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) else if (strncmp(buf, "fw_reset", sizeof("fw_reset") - 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) else if (strncmp(buf, "pci_bus_reset", sizeof("pci_bus_reset") - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) status = lpfc_reset_pci_bus(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) else if (strncmp(buf, "trunk", sizeof("trunk") - 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) status = lpfc_set_trunking(phba, (char *)buf + sizeof("trunk"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) board_mode_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (!status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) board_mode_str = strchr(buf, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) if (board_mode_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) *board_mode_str = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) "3097 Failed \"%s\", status(%d), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) "fc_flag(x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) buf, status, phba->pport->fc_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) * lpfc_get_hba_info - Return various bits of informaton about the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) * @phba: pointer to the adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) * @mxri: max xri count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) * @axri: available xri count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) * @mrpi: max rpi count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) * @arpi: available rpi count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) * @mvpi: max vpi count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) * @avpi: available vpi count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) * If an integer pointer for an count is not null then the value for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) * count is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) * zero on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) * one for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) lpfc_get_hba_info(struct lpfc_hba *phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) uint32_t *mxri, uint32_t *axri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) uint32_t *mrpi, uint32_t *arpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) uint32_t *mvpi, uint32_t *avpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) struct lpfc_mbx_read_config *rd_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) LPFC_MBOXQ_t *pmboxq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) MAILBOX_t *pmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) uint32_t max_vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) * prevent udev from issuing mailbox commands until the port is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) * configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (phba->link_state < LPFC_LINK_DOWN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) !phba->mbox_mem_pool ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (!pmboxq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) pmb = &pmboxq->u.mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) pmb->mbxCommand = MBX_READ_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) pmb->mbxOwner = OWN_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) pmboxq->ctx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) if (phba->pport->fc_flag & FC_OFFLINE_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) rc = MBX_NOT_FINISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) if (rc != MBX_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) if (rc != MBX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) if (phba->sli_rev == LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) rd_config = &pmboxq->u.mqe.un.rd_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) if (mrpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) *mrpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) if (arpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) *arpi = bf_get(lpfc_mbx_rd_conf_rpi_count, rd_config) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) phba->sli4_hba.max_cfg_param.rpi_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) if (mxri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) *mxri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if (axri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) *axri = bf_get(lpfc_mbx_rd_conf_xri_count, rd_config) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) phba->sli4_hba.max_cfg_param.xri_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) /* Account for differences with SLI-3. Get vpi count from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) * mailbox data and subtract one for max vpi value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) max_vpi = (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) > 0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) (bf_get(lpfc_mbx_rd_conf_vpi_count, rd_config) - 1) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) /* Limit the max we support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) if (max_vpi > LPFC_MAX_VPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) max_vpi = LPFC_MAX_VPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) if (mvpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) *mvpi = max_vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) if (avpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) *avpi = max_vpi - phba->sli4_hba.max_cfg_param.vpi_used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) if (mrpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) *mrpi = pmb->un.varRdConfig.max_rpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (arpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) *arpi = pmb->un.varRdConfig.avail_rpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) if (mxri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) *mxri = pmb->un.varRdConfig.max_xri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) if (axri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) *axri = pmb->un.varRdConfig.avail_xri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) if (mvpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) *mvpi = pmb->un.varRdConfig.max_vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) if (avpi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) /* avail_vpi is only valid if link is up and ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) if (phba->link_state == LPFC_HBA_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) *avpi = pmb->un.varRdConfig.avail_vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) *avpi = pmb->un.varRdConfig.max_vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) * lpfc_max_rpi_show - Return maximum rpi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) * @buf: on return contains the maximum rpi count in decimal or "Unknown".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * Calls lpfc_get_hba_info() asking for just the mrpi count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) * to "Unknown" and the buffer length is returned, therefore the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) * must check for "Unknown" in the buffer to detect a failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) uint32_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, NULL, NULL, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) return scnprintf(buf, PAGE_SIZE, "Unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) * lpfc_used_rpi_show - Return maximum rpi minus available rpi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) * @buf: containing the used rpi count in decimal or "Unknown".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) * Calls lpfc_get_hba_info() asking for just the mrpi and arpi counts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) * to "Unknown" and the buffer length is returned, therefore the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) * must check for "Unknown" in the buffer to detect a failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) uint32_t cnt, acnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (lpfc_get_hba_info(phba, NULL, NULL, &cnt, &acnt, NULL, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) return scnprintf(buf, PAGE_SIZE, "Unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) * lpfc_max_xri_show - Return maximum xri
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) * @buf: on return contains the maximum xri count in decimal or "Unknown".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) * Calls lpfc_get_hba_info() asking for just the mrpi count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) * to "Unknown" and the buffer length is returned, therefore the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) * must check for "Unknown" in the buffer to detect a failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) lpfc_max_xri_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) uint32_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) if (lpfc_get_hba_info(phba, &cnt, NULL, NULL, NULL, NULL, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) return scnprintf(buf, PAGE_SIZE, "Unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) * lpfc_used_xri_show - Return maximum xpi minus the available xpi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) * @buf: on return contains the used xri count in decimal or "Unknown".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) * Calls lpfc_get_hba_info() asking for just the mxri and axri counts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) * to "Unknown" and the buffer length is returned, therefore the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) * must check for "Unknown" in the buffer to detect a failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) lpfc_used_xri_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) uint32_t cnt, acnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) if (lpfc_get_hba_info(phba, &cnt, &acnt, NULL, NULL, NULL, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) return scnprintf(buf, PAGE_SIZE, "Unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * lpfc_max_vpi_show - Return maximum vpi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * @buf: on return contains the maximum vpi count in decimal or "Unknown".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) * Calls lpfc_get_hba_info() asking for just the mvpi count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) * to "Unknown" and the buffer length is returned, therefore the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) * must check for "Unknown" in the buffer to detect a failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) uint32_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) return scnprintf(buf, PAGE_SIZE, "%d\n", cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) return scnprintf(buf, PAGE_SIZE, "Unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) * lpfc_used_vpi_show - Return maximum vpi minus the available vpi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) * @buf: on return contains the used vpi count in decimal or "Unknown".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) * Calls lpfc_get_hba_info() asking for just the mvpi and avpi counts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) * to "Unknown" and the buffer length is returned, therefore the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) * must check for "Unknown" in the buffer to detect a failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) uint32_t cnt, acnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) if (lpfc_get_hba_info(phba, NULL, NULL, NULL, NULL, &cnt, &acnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) return scnprintf(buf, PAGE_SIZE, "%d\n", (cnt - acnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) return scnprintf(buf, PAGE_SIZE, "Unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) * lpfc_npiv_info_show - Return text about NPIV support for the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) * @buf: text that must be interpreted to determine if npiv is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) * Buffer will contain text indicating npiv is not suppoerted on the port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) * the port is an NPIV physical port, or it is an npiv virtual port with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) * the id of the vport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) if (!(phba->max_vpi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) return scnprintf(buf, PAGE_SIZE, "NPIV Not Supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) if (vport->port_type == LPFC_PHYSICAL_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) return scnprintf(buf, PAGE_SIZE, "NPIV Physical\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) return scnprintf(buf, PAGE_SIZE, "NPIV Virtual (VPI %d)\n", vport->vpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) * lpfc_poll_show - Return text about poll support for the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) * @buf: on return contains the cfg_poll in hex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) * cfg_poll should be a lpfc_polling_flags type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) lpfc_poll_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) return scnprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) * lpfc_poll_store - Set the value of cfg_poll for the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) * @buf: one or more lpfc_polling_flags values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) * @count: not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) * buf contents converted to integer and checked for a valid value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) * -EINVAL if the buffer connot be converted or is out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) * length of the buf on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) lpfc_poll_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) uint32_t creg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) uint32_t old_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) int val=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) if (!isdigit(buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) if (sscanf(buf, "%i", &val) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) if ((val & 0x3) != val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) "3051 lpfc_poll changed from %d to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) phba->cfg_poll, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) old_val = phba->cfg_poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) if (val & ENABLE_FCP_RING_POLLING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if ((val & DISABLE_FCP_RING_INT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) !(old_val & DISABLE_FCP_RING_INT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (lpfc_readl(phba->HCregaddr, &creg_val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) writel(creg_val, phba->HCregaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) readl(phba->HCregaddr); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) lpfc_poll_start_timer(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) } else if (val != 0x0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) if (!(val & DISABLE_FCP_RING_INT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) (old_val & DISABLE_FCP_RING_INT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) del_timer(&phba->fcp_poll_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) if (lpfc_readl(phba->HCregaddr, &creg_val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) writel(creg_val, phba->HCregaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) readl(phba->HCregaddr); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) phba->cfg_poll = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) * lpfc_sriov_hw_max_virtfn_show - Return maximum number of virtual functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) * @buf: on return contains the formatted support level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) * Returns the maximum number of virtual functions a physical function can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) * support, 0 will be returned if called on virtual function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) lpfc_sriov_hw_max_virtfn_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) uint16_t max_nr_virtfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) max_nr_virtfn = lpfc_sli_sriov_nr_virtfn_get(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) return scnprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) static inline bool lpfc_rangecheck(uint val, uint min, uint max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) return val >= min && val <= max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) * lpfc_enable_bbcr_set: Sets an attribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) * @phba: pointer the the adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) * @val: integer attribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) * Validates the min and max values then sets the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) * adapter config field if in the valid range. prints error message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) * and does not set the parameter if invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) * zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) * -EINVAL if val is invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) lpfc_enable_bbcr_set(struct lpfc_hba *phba, uint val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) if (lpfc_rangecheck(val, 0, 1) && phba->sli_rev == LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) "3068 %s_enable_bbcr changed from %d to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) LPFC_DRIVER_NAME, phba->cfg_enable_bbcr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) phba->cfg_enable_bbcr = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) "0451 %s_enable_bbcr cannot set to %d, range is 0, 1\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) LPFC_DRIVER_NAME, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) * lpfc_param_show - Return a cfg attribute value in decimal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) * Macro that given an attr e.g. hba_queue_depth expands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) * into a function with the name lpfc_hba_queue_depth_show.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) * lpfc_##attr##_show: Return the decimal value of an adapters cfg_xxx field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) * @buf: on return contains the attribute value in decimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) #define lpfc_param_show(attr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) struct Scsi_Host *shost = class_to_shost(dev);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) struct lpfc_hba *phba = vport->phba;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) return scnprintf(buf, PAGE_SIZE, "%d\n",\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) phba->cfg_##attr);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) * lpfc_param_hex_show - Return a cfg attribute value in hex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) * Macro that given an attr e.g. hba_queue_depth expands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) * into a function with the name lpfc_hba_queue_depth_show
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) * lpfc_##attr##_show: Return the hex value of an adapters cfg_xxx field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) * @buf: on return contains the attribute value in hexadecimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) #define lpfc_param_hex_show(attr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) struct Scsi_Host *shost = class_to_shost(dev);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) struct lpfc_hba *phba = vport->phba;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) uint val = 0;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) val = phba->cfg_##attr;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) return scnprintf(buf, PAGE_SIZE, "%#x\n",\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) phba->cfg_##attr);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) * lpfc_param_init - Initializes a cfg attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) * Macro that given an attr e.g. hba_queue_depth expands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) * into a function with the name lpfc_hba_queue_depth_init. The macro also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) * takes a default argument, a minimum and maximum argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) * lpfc_##attr##_init: Initializes an attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) * @phba: pointer the the adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) * @val: integer attribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) * Validates the min and max values then sets the adapter config field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) * accordingly, or uses the default if out of range and prints an error message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) * zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) * -EINVAL if default used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) #define lpfc_param_init(attr, default, minval, maxval) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) static int \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) lpfc_##attr##_init(struct lpfc_hba *phba, uint val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) if (lpfc_rangecheck(val, minval, maxval)) {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) phba->cfg_##attr = val;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) return 0;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) }\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) "0449 lpfc_"#attr" attribute cannot be set to %d, "\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) "allowed range is ["#minval", "#maxval"]\n", val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) phba->cfg_##attr = default;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) return -EINVAL;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) * lpfc_param_set - Set a cfg attribute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) * Macro that given an attr e.g. hba_queue_depth expands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) * into a function with the name lpfc_hba_queue_depth_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) * lpfc_##attr##_set: Sets an attribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) * @phba: pointer the the adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) * @val: integer attribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) * Validates the min and max values then sets the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) * adapter config field if in the valid range. prints error message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) * and does not set the parameter if invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) * zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) * -EINVAL if val is invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) #define lpfc_param_set(attr, default, minval, maxval) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) static int \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) lpfc_##attr##_set(struct lpfc_hba *phba, uint val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) if (lpfc_rangecheck(val, minval, maxval)) {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) "3052 lpfc_" #attr " changed from %d to %d\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) phba->cfg_##attr, val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) phba->cfg_##attr = val;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) return 0;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) }\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) "0450 lpfc_"#attr" attribute cannot be set to %d, "\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) "allowed range is ["#minval", "#maxval"]\n", val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) return -EINVAL;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) * lpfc_param_store - Set a vport attribute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) * Macro that given an attr e.g. hba_queue_depth expands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) * into a function with the name lpfc_hba_queue_depth_store.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) * lpfc_##attr##_store: Set an sttribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) * @buf: contains the attribute value in ascii.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) * @count: not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) * Convert the ascii text number to an integer, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) * use the lpfc_##attr##_set function to set the value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) * -EINVAL if val is invalid or lpfc_##attr##_set() fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) * length of buffer upon success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) #define lpfc_param_store(attr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) const char *buf, size_t count) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) struct Scsi_Host *shost = class_to_shost(dev);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) struct lpfc_hba *phba = vport->phba;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) uint val = 0;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) if (!isdigit(buf[0]))\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) return -EINVAL;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) if (sscanf(buf, "%i", &val) != 1)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) return -EINVAL;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) if (lpfc_##attr##_set(phba, val) == 0) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) return strlen(buf);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) return -EINVAL;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) * lpfc_vport_param_show - Return decimal formatted cfg attribute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) * Macro that given an attr e.g. hba_queue_depth expands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) * into a function with the name lpfc_hba_queue_depth_show
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) * lpfc_##attr##_show: prints the attribute value in decimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) * @buf: on return contains the attribute value in decimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) * Returns: length of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) #define lpfc_vport_param_show(attr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) struct Scsi_Host *shost = class_to_shost(dev);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) * lpfc_vport_param_hex_show - Return hex formatted attribute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) * Macro that given an attr e.g.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) * hba_queue_depth expands into a function with the name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) * lpfc_hba_queue_depth_show
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) * lpfc_##attr##_show: prints the attribute value in hexadecimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) * @buf: on return contains the attribute value in hexadecimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) * Returns: length of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) #define lpfc_vport_param_hex_show(attr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) struct Scsi_Host *shost = class_to_shost(dev);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) return scnprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) * lpfc_vport_param_init - Initialize a vport cfg attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) * Macro that given an attr e.g. hba_queue_depth expands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) * into a function with the name lpfc_hba_queue_depth_init. The macro also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) * takes a default argument, a minimum and maximum argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) * lpfc_##attr##_init: validates the min and max values then sets the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) * adapter config field accordingly, or uses the default if out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) * and prints an error message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) * @phba: pointer the the adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) * @val: integer attribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) * zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) * -EINVAL if default used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) #define lpfc_vport_param_init(attr, default, minval, maxval) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) static int \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) lpfc_##attr##_init(struct lpfc_vport *vport, uint val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) if (lpfc_rangecheck(val, minval, maxval)) {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) vport->cfg_##attr = val;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) return 0;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) }\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) "0423 lpfc_"#attr" attribute cannot be set to %d, "\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) "allowed range is ["#minval", "#maxval"]\n", val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) vport->cfg_##attr = default;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) return -EINVAL;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) * lpfc_vport_param_set - Set a vport cfg attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) * Macro that given an attr e.g. hba_queue_depth expands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) * into a function with the name lpfc_hba_queue_depth_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) * lpfc_##attr##_set: validates the min and max values then sets the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) * adapter config field if in the valid range. prints error message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) * and does not set the parameter if invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) * @phba: pointer the the adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) * @val: integer attribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) * zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) * -EINVAL if val is invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) #define lpfc_vport_param_set(attr, default, minval, maxval) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) static int \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) lpfc_##attr##_set(struct lpfc_vport *vport, uint val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) if (lpfc_rangecheck(val, minval, maxval)) {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) "3053 lpfc_" #attr \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) " changed from %d (x%x) to %d (x%x)\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) vport->cfg_##attr, vport->cfg_##attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) val, val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) vport->cfg_##attr = val;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) return 0;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) }\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) "0424 lpfc_"#attr" attribute cannot be set to %d, "\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) "allowed range is ["#minval", "#maxval"]\n", val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) return -EINVAL;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) * lpfc_vport_param_store - Set a vport attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) * Macro that given an attr e.g. hba_queue_depth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) * expands into a function with the name lpfc_hba_queue_depth_store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) * lpfc_##attr##_store: convert the ascii text number to an integer, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) * use the lpfc_##attr##_set function to set the value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) * @cdev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) * @buf: contains the attribute value in decimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) * @count: not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) * -EINVAL if val is invalid or lpfc_##attr##_set() fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) * length of buffer upon success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) #define lpfc_vport_param_store(attr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) const char *buf, size_t count) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) struct Scsi_Host *shost = class_to_shost(dev);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) uint val = 0;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) if (!isdigit(buf[0]))\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) return -EINVAL;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) if (sscanf(buf, "%i", &val) != 1)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) return -EINVAL;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) if (lpfc_##attr##_set(vport, val) == 0) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) return strlen(buf);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) return -EINVAL;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) static DEVICE_ATTR(nvme_info, 0444, lpfc_nvme_info_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) static DEVICE_ATTR(scsi_stat, 0444, lpfc_scsi_stat_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) static DEVICE_ATTR(bg_info, S_IRUGO, lpfc_bg_info_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) static DEVICE_ATTR(bg_guard_err, S_IRUGO, lpfc_bg_guard_err_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) static DEVICE_ATTR(bg_apptag_err, S_IRUGO, lpfc_bg_apptag_err_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) static DEVICE_ATTR(bg_reftag_err, S_IRUGO, lpfc_bg_reftag_err_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) static DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) static DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) static DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) static DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) static DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) static DEVICE_ATTR(portnum, S_IRUGO, lpfc_vportnum_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) static DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) static DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) static DEVICE_ATTR(link_state, S_IRUGO | S_IWUSR, lpfc_link_state_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) lpfc_link_state_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) static DEVICE_ATTR(option_rom_version, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) lpfc_option_rom_version_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) static DEVICE_ATTR(num_discovered_ports, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) lpfc_num_discovered_ports_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) static DEVICE_ATTR(menlo_mgmt_mode, S_IRUGO, lpfc_mlomgmt_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) static DEVICE_ATTR_RO(lpfc_drvr_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) static DEVICE_ATTR_RO(lpfc_enable_fip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) lpfc_board_mode_show, lpfc_board_mode_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) static DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) static DEVICE_ATTR(max_vpi, S_IRUGO, lpfc_max_vpi_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) static DEVICE_ATTR(used_vpi, S_IRUGO, lpfc_used_vpi_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) static DEVICE_ATTR(max_rpi, S_IRUGO, lpfc_max_rpi_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) static DEVICE_ATTR(used_rpi, S_IRUGO, lpfc_used_rpi_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) static DEVICE_ATTR(max_xri, S_IRUGO, lpfc_max_xri_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) static DEVICE_ATTR(used_xri, S_IRUGO, lpfc_used_xri_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) static DEVICE_ATTR(npiv_info, S_IRUGO, lpfc_npiv_info_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) static DEVICE_ATTR_RO(lpfc_temp_sensor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) static DEVICE_ATTR_RO(lpfc_sriov_hw_max_virtfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) static DEVICE_ATTR(lpfc_xlane_supported, S_IRUGO, lpfc_oas_supported_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) static char *lpfc_soft_wwn_key = "C99G71SL8032A";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) #define WWN_SZ 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) * lpfc_wwn_set - Convert string to the 8 byte WWN value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) * @buf: WWN string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) * @cnt: Length of string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) * @wwn: Array to receive converted wwn value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) * -EINVAL if the buffer does not contain a valid wwn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) * 0 success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) static size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) lpfc_wwn_set(const char *buf, size_t cnt, char wwn[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) /* Count may include a LF at end of string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) if (buf[cnt-1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) if ((cnt < 16) || (cnt > 18) || ((cnt == 17) && (*buf++ != 'x')) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x'))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) memset(wwn, 0, WWN_SZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) /* Validate and store the new name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) for (i = 0, j = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) if ((*buf >= 'a') && (*buf <= 'f'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) j = ((j << 4) | ((*buf++ - 'a') + 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) else if ((*buf >= 'A') && (*buf <= 'F'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) j = ((j << 4) | ((*buf++ - 'A') + 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) else if ((*buf >= '0') && (*buf <= '9'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) j = ((j << 4) | (*buf++ - '0'));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) if (i % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) wwn[i/2] = j & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) * lpfc_soft_wwn_enable_store - Allows setting of the wwn if the key is valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) * @buf: containing the string lpfc_soft_wwn_key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) * @count: must be size of lpfc_soft_wwn_key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) * -EINVAL if the buffer does not contain lpfc_soft_wwn_key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) * length of buf indicates success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) unsigned int cnt = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) uint8_t vvvl = vport->fc_sparam.cmn.valid_vendor_ver_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) u32 *fawwpn_key = (uint32_t *)&vport->fc_sparam.un.vendorVersion[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) * We're doing a simple sanity check for soft_wwpn setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) * We require that the user write a specific key to enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) * the soft_wwpn attribute to be settable. Once the attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) * is written, the enable key resets. If further updates are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) * desired, the key must be written again to re-enable the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) * attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) * The "key" is not secret - it is a hardcoded string shown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) * here. The intent is to protect against the random user or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) * application that is just writing attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) if (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) "0051 "LPFC_DRIVER_NAME" soft wwpn can not"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) " be enabled: fawwpn is enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) /* count may include a LF at end of string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) if (buf[cnt-1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) if ((cnt != strlen(lpfc_soft_wwn_key)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) phba->soft_wwn_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) dev_printk(KERN_WARNING, &phba->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) "lpfc%d: soft_wwpn assignment has been enabled.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) phba->brd_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) dev_printk(KERN_WARNING, &phba->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) " The soft_wwpn feature is not supported by Broadcom.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) static DEVICE_ATTR_WO(lpfc_soft_wwn_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) * lpfc_soft_wwpn_show - Return the cfg soft ww port name of the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) * @buf: on return contains the wwpn in hexadecimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) (unsigned long long)phba->cfg_soft_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) * lpfc_soft_wwpn_store - Set the ww port name of the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) * @dev class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) * @buf: contains the wwpn in hexadecimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) * @count: number of wwpn bytes in buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) * -EACCES hba reset not enabled, adapter over temp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) * -EINVAL soft wwn not enabled, count is invalid, invalid wwpn byte invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) * -EIO error taking adapter offline or online
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) * value of count on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) struct completion online_compl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) int stat1 = 0, stat2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) unsigned int cnt = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) u8 wwpn[WWN_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) if (!phba->cfg_enable_hba_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) if (phba->over_temp_state == HBA_OVER_TEMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) /* count may include a LF at end of string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) if (buf[cnt-1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) if (!phba->soft_wwn_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) /* lock setting wwpn, wwnn down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) phba->soft_wwn_enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) rc = lpfc_wwn_set(buf, cnt, wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) /* not able to set wwpn, unlock it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) phba->soft_wwn_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) phba->cfg_soft_wwpn = wwn_to_u64(wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) fc_host_port_name(shost) = phba->cfg_soft_wwpn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) if (phba->cfg_soft_wwnn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) fc_host_node_name(shost) = phba->cfg_soft_wwnn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) dev_printk(KERN_NOTICE, &phba->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) if (stat1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) "0463 lpfc_soft_wwpn attribute set failed to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) "reinit adapter - %d\n", stat1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) init_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) rc = lpfc_workq_post_event(phba, &stat2, &online_compl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) LPFC_EVT_ONLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) wait_for_completion(&online_compl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) if (stat2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) "0464 lpfc_soft_wwpn attribute set failed to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) "reinit adapter - %d\n", stat2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) return (stat1 || stat2) ? -EIO : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) static DEVICE_ATTR_RW(lpfc_soft_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) * lpfc_soft_wwnn_show - Return the cfg soft ww node name for the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) * @buf: on return contains the wwnn in hexadecimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) (unsigned long long)phba->cfg_soft_wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) * lpfc_soft_wwnn_store - sets the ww node name of the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) * @cdev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) * @buf: contains the ww node name in hexadecimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) * @count: number of wwnn bytes in buf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) * -EINVAL soft wwn not enabled, count is invalid, invalid wwnn byte invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) * value of count on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) lpfc_soft_wwnn_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) unsigned int cnt = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) u8 wwnn[WWN_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) /* count may include a LF at end of string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) if (buf[cnt-1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) if (!phba->soft_wwn_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) rc = lpfc_wwn_set(buf, cnt, wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) /* Allow wwnn to be set many times, as long as the enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) * is set. However, once the wwpn is set, everything locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) phba->cfg_soft_wwnn = wwn_to_u64(wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) dev_printk(KERN_NOTICE, &phba->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) "lpfc%d: soft_wwnn set. Value will take effect upon "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) "setting of the soft_wwpn\n", phba->brd_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) static DEVICE_ATTR_RW(lpfc_soft_wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) * lpfc_oas_tgt_show - Return wwpn of target whose luns maybe enabled for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) * Optimized Access Storage (OAS) operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) * value of count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) lpfc_oas_tgt_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) wwn_to_u64(phba->cfg_oas_tgt_wwpn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) * lpfc_oas_tgt_store - Store wwpn of target whose luns maybe enabled for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) * Optimized Access Storage (OAS) operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) * @count: Size of the data buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) * -EINVAL count is invalid, invalid wwpn byte invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) * -EPERM oas is not supported by hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) * value of count on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) lpfc_oas_tgt_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) unsigned int cnt = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) uint8_t wwpn[WWN_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) if (!phba->cfg_fof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) /* count may include a LF at end of string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) if (buf[cnt-1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) rc = lpfc_wwn_set(buf, cnt, wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) memcpy(phba->cfg_oas_tgt_wwpn, wwpn, (8 * sizeof(uint8_t)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) memcpy(phba->sli4_hba.oas_next_tgt_wwpn, wwpn, (8 * sizeof(uint8_t)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) if (wwn_to_u64(wwpn) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) phba->cfg_oas_flags |= OAS_FIND_ANY_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) phba->cfg_oas_flags &= ~OAS_FIND_ANY_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) phba->cfg_oas_flags &= ~OAS_LUN_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) static DEVICE_ATTR(lpfc_xlane_tgt, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) lpfc_oas_tgt_show, lpfc_oas_tgt_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) * lpfc_oas_priority_show - Return wwpn of target whose luns maybe enabled for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) * Optimized Access Storage (OAS) operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) * value of count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) lpfc_oas_priority_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) * lpfc_oas_priority_store - Store wwpn of target whose luns maybe enabled for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) * Optimized Access Storage (OAS) operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) * @count: Size of the data buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) * -EINVAL count is invalid, invalid wwpn byte invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) * -EPERM oas is not supported by hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) * value of count on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) lpfc_oas_priority_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) unsigned int cnt = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) if (!phba->cfg_fof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) /* count may include a LF at end of string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) if (buf[cnt-1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) ret = kstrtoul(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) if (ret || (val > 0x7f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) phba->cfg_oas_priority = (uint8_t)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) phba->cfg_oas_priority = phba->cfg_XLanePriority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) static DEVICE_ATTR(lpfc_xlane_priority, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) lpfc_oas_priority_show, lpfc_oas_priority_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) * lpfc_oas_vpt_show - Return wwpn of vport whose targets maybe enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) * for Optimized Access Storage (OAS) operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) * value of count on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) lpfc_oas_vpt_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) return scnprintf(buf, PAGE_SIZE, "0x%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) wwn_to_u64(phba->cfg_oas_vpt_wwpn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) * lpfc_oas_vpt_store - Store wwpn of vport whose targets maybe enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) * for Optimized Access Storage (OAS) operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) * @count: Size of the data buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) * -EINVAL count is invalid, invalid wwpn byte invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) * -EPERM oas is not supported by hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) * value of count on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) lpfc_oas_vpt_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) unsigned int cnt = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) uint8_t wwpn[WWN_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) if (!phba->cfg_fof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) /* count may include a LF at end of string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) if (buf[cnt-1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) rc = lpfc_wwn_set(buf, cnt, wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) memcpy(phba->cfg_oas_vpt_wwpn, wwpn, (8 * sizeof(uint8_t)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) memcpy(phba->sli4_hba.oas_next_vpt_wwpn, wwpn, (8 * sizeof(uint8_t)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) if (wwn_to_u64(wwpn) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) phba->cfg_oas_flags |= OAS_FIND_ANY_VPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) phba->cfg_oas_flags &= ~OAS_FIND_ANY_VPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) phba->cfg_oas_flags &= ~OAS_LUN_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) if (phba->cfg_oas_priority == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) phba->cfg_oas_priority = phba->cfg_XLanePriority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) phba->sli4_hba.oas_next_lun = FIND_FIRST_OAS_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) static DEVICE_ATTR(lpfc_xlane_vpt, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) lpfc_oas_vpt_show, lpfc_oas_vpt_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) * lpfc_oas_lun_state_show - Return the current state (enabled or disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) * of whether luns will be enabled or disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) * for Optimized Access Storage (OAS) operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) * size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) lpfc_oas_lun_state_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) * lpfc_oas_lun_state_store - Store the state (enabled or disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) * of whether luns will be enabled or disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) * for Optimized Access Storage (OAS) operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) * @count: Size of the data buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) * -EINVAL count is invalid, invalid wwpn byte invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) * -EPERM oas is not supported by hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) * value of count on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) lpfc_oas_lun_state_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) if (!phba->cfg_fof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) if (!isdigit(buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) if (sscanf(buf, "%i", &val) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) if ((val != 0) && (val != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) phba->cfg_oas_lun_state = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) static DEVICE_ATTR(lpfc_xlane_lun_state, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) lpfc_oas_lun_state_show, lpfc_oas_lun_state_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) * lpfc_oas_lun_status_show - Return the status of the Optimized Access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) * Storage (OAS) lun returned by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) * lpfc_oas_lun_show function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) * size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) lpfc_oas_lun_status_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) if (!(phba->cfg_oas_flags & OAS_LUN_VALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) return scnprintf(buf, PAGE_SIZE, "%d\n", phba->cfg_oas_lun_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) static DEVICE_ATTR(lpfc_xlane_lun_status, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) lpfc_oas_lun_status_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) * lpfc_oas_lun_state_set - enable or disable a lun for Optimized Access Storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) * (OAS) operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) * @ndlp: pointer to fcp target node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) * @lun: the fc lun for setting oas state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) * @oas_state: the oas state to be set to the lun.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) * SUCCESS : 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) * -EPERM OAS is not enabled or not supported by this port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) static size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) lpfc_oas_lun_state_set(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) uint8_t tgt_wwpn[], uint64_t lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) uint32_t oas_state, uint8_t pri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) if (!phba->cfg_fof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) if (oas_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) if (!lpfc_enable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) (struct lpfc_name *)tgt_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) lun, pri))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) lpfc_disable_oas_lun(phba, (struct lpfc_name *)vpt_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) (struct lpfc_name *)tgt_wwpn, lun, pri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) * lpfc_oas_lun_get_next - get the next lun that has been enabled for Optimized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) * Access Storage (OAS) operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) * @vpt_wwpn: wwpn of the vport associated with the returned lun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) * @tgt_wwpn: wwpn of the target associated with the returned lun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) * @lun_status: status of the lun returned lun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) * Returns the first or next lun enabled for OAS operations for the vport/target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) * specified. If a lun is found, its vport wwpn, target wwpn and status is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) * returned. If the lun is not found, NOT_OAS_ENABLED_LUN is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) * lun that is OAS enabled for the vport/target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) * NOT_OAS_ENABLED_LUN when no oas enabled lun found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) static uint64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) lpfc_oas_lun_get_next(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) uint8_t tgt_wwpn[], uint32_t *lun_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) uint32_t *lun_pri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) uint64_t found_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) if (unlikely(!phba) || !vpt_wwpn || !tgt_wwpn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) return NOT_OAS_ENABLED_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) if (lpfc_find_next_oas_lun(phba, (struct lpfc_name *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) phba->sli4_hba.oas_next_vpt_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) (struct lpfc_name *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) phba->sli4_hba.oas_next_tgt_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) &phba->sli4_hba.oas_next_lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) (struct lpfc_name *)vpt_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) (struct lpfc_name *)tgt_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) &found_lun, lun_status, lun_pri))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) return found_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) return NOT_OAS_ENABLED_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) * lpfc_oas_lun_state_change - enable/disable a lun for OAS operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) * @vpt_wwpn: vport wwpn by reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) * @tgt_wwpn: target wwpn by reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) * @lun: the fc lun for setting oas state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) * @oas_state: the oas state to be set to the oas_lun.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) * This routine enables (OAS_LUN_ENABLE) or disables (OAS_LUN_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) * a lun for OAS operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) * SUCCESS: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) * -ENOMEM: failed to enable an lun for OAS operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) * -EPERM: OAS is not enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) lpfc_oas_lun_state_change(struct lpfc_hba *phba, uint8_t vpt_wwpn[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) uint8_t tgt_wwpn[], uint64_t lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) uint32_t oas_state, uint8_t pri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) rc = lpfc_oas_lun_state_set(phba, vpt_wwpn, tgt_wwpn, lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) oas_state, pri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) * lpfc_oas_lun_show - Return oas enabled luns from a chosen target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) * This routine returns a lun enabled for OAS each time the function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) * is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) * SUCCESS: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) * -EFAULT: target or vport wwpn was not set properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) * -EPERM: oas is not enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) lpfc_oas_lun_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) uint64_t oas_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) if (!phba->cfg_fof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) if (wwn_to_u64(phba->cfg_oas_vpt_wwpn) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) if (!(phba->cfg_oas_flags & OAS_FIND_ANY_VPORT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) if (wwn_to_u64(phba->cfg_oas_tgt_wwpn) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) if (!(phba->cfg_oas_flags & OAS_FIND_ANY_TARGET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) oas_lun = lpfc_oas_lun_get_next(phba, phba->cfg_oas_vpt_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) phba->cfg_oas_tgt_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) &phba->cfg_oas_lun_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) &phba->cfg_oas_priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) if (oas_lun != NOT_OAS_ENABLED_LUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) phba->cfg_oas_flags |= OAS_LUN_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) len += scnprintf(buf + len, PAGE_SIZE-len, "0x%llx", oas_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) * lpfc_oas_lun_store - Sets the OAS state for lun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) * @buf: buffer for passing information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) * This function sets the OAS state for lun. Before this function is called,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) * the vport wwpn, target wwpn, and oas state need to be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) * SUCCESS: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) * -EFAULT: target or vport wwpn was not set properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) * -EPERM: oas is not enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) * size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) lpfc_oas_lun_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) uint64_t scsi_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) uint32_t pri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) ssize_t rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) if (!phba->cfg_fof)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) if (wwn_to_u64(phba->cfg_oas_vpt_wwpn) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) if (wwn_to_u64(phba->cfg_oas_tgt_wwpn) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) if (!isdigit(buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) if (sscanf(buf, "0x%llx", &scsi_lun) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) pri = phba->cfg_oas_priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) if (pri == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) pri = phba->cfg_XLanePriority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) "3372 Try to set vport 0x%llx target 0x%llx lun:0x%llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) "priority 0x%x with oas state %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) wwn_to_u64(phba->cfg_oas_vpt_wwpn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) wwn_to_u64(phba->cfg_oas_tgt_wwpn), scsi_lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) pri, phba->cfg_oas_lun_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) rc = lpfc_oas_lun_state_change(phba, phba->cfg_oas_vpt_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) phba->cfg_oas_tgt_wwpn, scsi_lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) phba->cfg_oas_lun_state, pri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) static DEVICE_ATTR(lpfc_xlane_lun, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) lpfc_oas_lun_show, lpfc_oas_lun_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) int lpfc_enable_nvmet_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) unsigned long long lpfc_enable_nvmet[LPFC_NVMET_MAX_PORTS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) module_param_array(lpfc_enable_nvmet, ullong, &lpfc_enable_nvmet_cnt, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) MODULE_PARM_DESC(lpfc_enable_nvmet, "Enable HBA port(s) WWPN as a NVME Target");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) static int lpfc_poll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) module_param(lpfc_poll, int, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) " 0 - none,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) " 1 - poll with interrupts enabled"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) " 3 - poll and disable FCP ring interrupts");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) static DEVICE_ATTR_RW(lpfc_poll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) int lpfc_no_hba_reset_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) unsigned long lpfc_no_hba_reset[MAX_HBAS_NO_RESET] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) module_param_array(lpfc_no_hba_reset, ulong, &lpfc_no_hba_reset_cnt, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) MODULE_PARM_DESC(lpfc_no_hba_reset, "WWPN of HBAs that should not be reset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) LPFC_ATTR(sli_mode, 0, 0, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) "SLI mode selector:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) " 0 - auto (SLI-3 if supported),"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) " 2 - select SLI-2 even on SLI-3 capable HBAs,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) " 3 - select SLI-3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) LPFC_ATTR_R(enable_npiv, 1, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) "Enable NPIV functionality");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) LPFC_ATTR_R(fcf_failover_policy, 1, 1, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) "FCF Fast failover=1 Priority failover=2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) # lpfc_enable_rrq: Track XRI/OXID reuse after IO failures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) # 0x0 = disabled, XRI/OXID use not tracked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) # 0x1 = XRI/OXID reuse is timed with ratov, RRQ sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) # 0x2 = XRI/OXID reuse is timed with ratov, No RRQ sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) LPFC_ATTR_R(enable_rrq, 2, 0, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) "Enable RRQ functionality");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) # lpfc_suppress_link_up: Bring link up at initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) # 0x0 = bring link up (issue MBX_INIT_LINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) # 0x1 = do NOT bring link up at initialization(MBX_INIT_LINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) # 0x2 = never bring up link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) # Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) LPFC_DELAY_INIT_LINK_INDEFINITELY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) "Suppress Link Up at initialization");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) lpfc_pls_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) return scnprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) phba->sli4_hba.pc_sli4_params.pls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) static DEVICE_ATTR(pls, 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) lpfc_pls_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) lpfc_pt_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) return scnprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) (phba->hba_flag & HBA_PERSISTENT_TOPO) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) static DEVICE_ATTR(pt, 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) lpfc_pt_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) # lpfc_cnt: Number of IOCBs allocated for ELS, CT, and ABTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) # 1 - (1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) # 2 - (2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) # 3 - (3072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) # 4 - (4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) # 5 - (5120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) lpfc_iocb_hw_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) return scnprintf(buf, PAGE_SIZE, "%d\n", phba->iocb_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) static DEVICE_ATTR(iocb_hw, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) lpfc_iocb_hw_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) lpfc_txq_hw_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) return scnprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) pring ? pring->txq_max : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) static DEVICE_ATTR(txq_hw, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) lpfc_txq_hw_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) lpfc_txcmplq_hw_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) struct lpfc_hba *phba = ((struct lpfc_vport *) shost->hostdata)->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) struct lpfc_sli_ring *pring = lpfc_phba_elsring(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) return scnprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) pring ? pring->txcmplq_max : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) static DEVICE_ATTR(txcmplq_hw, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) lpfc_txcmplq_hw_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) # until the timer expires. Value range is [0,255]. Default value is 30.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) static int lpfc_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) static int lpfc_devloss_tmo = LPFC_DEF_DEVLOSS_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) module_param(lpfc_nodev_tmo, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) MODULE_PARM_DESC(lpfc_nodev_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) "Seconds driver will hold I/O waiting "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) "for a device to come back");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) * lpfc_nodev_tmo_show - Return the hba dev loss timeout value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) * @buf: on return contains the dev loss timeout in decimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) return scnprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) * lpfc_nodev_tmo_init - Set the hba nodev timeout value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) * @vport: lpfc vport structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) * @val: contains the nodev timeout value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) * If the devloss tmo is already set then nodev tmo is set to devloss tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) * a kernel error message is printed and zero is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) * Else if val is in range then nodev tmo and devloss tmo are set to val.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) * Otherwise nodev tmo is set to the default value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) * zero if already set or if val is in range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) if (vport->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) vport->cfg_nodev_tmo = vport->cfg_devloss_tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) if (val != LPFC_DEF_DEVLOSS_TMO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) "0407 Ignoring lpfc_nodev_tmo module "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) "parameter because lpfc_devloss_tmo "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) "is set.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) vport->cfg_nodev_tmo = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) vport->cfg_devloss_tmo = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) "0400 lpfc_nodev_tmo attribute cannot be set to"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) " %d, allowed range is [%d, %d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) vport->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) * lpfc_update_rport_devloss_tmo - Update dev loss tmo value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) * @vport: lpfc vport structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) * Update all the ndlp's dev loss tmo with the vport devloss tmo value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) #if (IS_ENABLED(CONFIG_NVME_FC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) struct lpfc_nvme_rport *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) struct nvme_fc_remote_port *remoteport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) if (!NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) if (ndlp->rport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) #if (IS_ENABLED(CONFIG_NVME_FC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) spin_lock(&vport->phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) rport = lpfc_ndlp_get_nrport(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) if (rport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) remoteport = rport->remoteport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) spin_unlock(&vport->phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) if (rport && remoteport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) nvme_fc_set_remoteport_devloss(remoteport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) vport->cfg_devloss_tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) * lpfc_nodev_tmo_set - Set the vport nodev tmo and devloss tmo values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) * @vport: lpfc vport structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) * @val: contains the tmo value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) * If the devloss tmo is already set or the vport dev loss tmo has changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) * then a kernel error message is printed and zero is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) * Else if val is in range then nodev tmo and devloss tmo are set to val.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) * Otherwise nodev tmo is set to the default value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) * zero if already set or if val is in range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) if (vport->dev_loss_tmo_changed ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) "0401 Ignoring change to lpfc_nodev_tmo "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) "because lpfc_devloss_tmo is set.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) vport->cfg_nodev_tmo = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) vport->cfg_devloss_tmo = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) * For compat: set the fc_host dev loss so new rports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) * will get the value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) fc_host_dev_loss_tmo(lpfc_shost_from_vport(vport)) = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) lpfc_update_rport_devloss_tmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) "0403 lpfc_nodev_tmo attribute cannot be set to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) "%d, allowed range is [%d, %d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) lpfc_vport_param_store(nodev_tmo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) static DEVICE_ATTR_RW(lpfc_nodev_tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) # lpfc_devloss_tmo: If set, it will hold all I/O errors on devices that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) # disappear until the timer expires. Value range is [0,255]. Default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) # value is 30.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) module_param(lpfc_devloss_tmo, int, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) MODULE_PARM_DESC(lpfc_devloss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) "Seconds driver will hold I/O waiting "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) "for a device to come back");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) lpfc_vport_param_show(devloss_tmo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) * lpfc_devloss_tmo_set - Sets vport nodev tmo, devloss tmo values, changed bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) * @vport: lpfc vport structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) * @val: contains the tmo value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) * If val is in a valid range then set the vport nodev tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) * devloss tmo, also set the vport dev loss tmo changed flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) * Else a kernel error message is printed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) * zero if val is in range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) vport->cfg_nodev_tmo = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) vport->cfg_devloss_tmo = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) vport->dev_loss_tmo_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) fc_host_dev_loss_tmo(lpfc_shost_from_vport(vport)) = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) lpfc_update_rport_devloss_tmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) "0404 lpfc_devloss_tmo attribute cannot be set to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) "%d, allowed range is [%d, %d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) lpfc_vport_param_store(devloss_tmo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) static DEVICE_ATTR_RW(lpfc_devloss_tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) * lpfc_suppress_rsp: Enable suppress rsp feature is firmware supports it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) * lpfc_suppress_rsp = 0 Disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) * lpfc_suppress_rsp = 1 Enable (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) LPFC_ATTR_R(suppress_rsp, 1, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) "Enable suppress rsp feature is firmware supports it");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) * lpfc_nvmet_mrq: Specify number of RQ pairs for processing NVMET cmds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) * lpfc_nvmet_mrq = 0 driver will calcualte optimal number of RQ pairs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) * lpfc_nvmet_mrq = 1 use a single RQ pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) * lpfc_nvmet_mrq >= 2 use specified RQ pairs for MRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) LPFC_ATTR_R(nvmet_mrq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) LPFC_NVMET_MRQ_AUTO, LPFC_NVMET_MRQ_AUTO, LPFC_NVMET_MRQ_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) "Specify number of RQ pairs for processing NVMET cmds");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) * lpfc_nvmet_mrq_post: Specify number of RQ buffer to initially post
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) * to each NVMET RQ. Range 64 to 2048, default is 512.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) LPFC_ATTR_R(nvmet_mrq_post,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) LPFC_NVMET_RQE_DEF_POST, LPFC_NVMET_RQE_MIN_POST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) LPFC_NVMET_RQE_DEF_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) "Specify number of RQ buffers to initially post");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) * lpfc_enable_fc4_type: Defines what FC4 types are supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) * Supported Values: 1 - register just FCP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) * 3 - register both FCP and NVME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) * Supported values are [1,3]. Default value is 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) LPFC_ATTR_R(enable_fc4_type, LPFC_DEF_ENBL_FC4_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) LPFC_ENABLE_FCP, LPFC_MAX_ENBL_FC4_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) "Enable FC4 Protocol support - FCP / NVME");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) # lpfc_log_verbose: Only turn this flag on if you are willing to risk being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) # deluged with LOTS of information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) # You can set a bit mask to record specific types of verbose messages:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) # See lpfc_logmsh.h for definitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffffffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) "Verbose logging bit-mask");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) # lpfc_enable_da_id: This turns on the DA_ID CT command that deregisters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) # objects that have been registered with the nameserver after login.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) LPFC_VPORT_ATTR_R(enable_da_id, 1, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) "Deregister nameserver objects before LOGO");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) # lun_queue_depth: This parameter is used to limit the number of outstanding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) # commands per FCP LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) LPFC_VPORT_ATTR_R(lun_queue_depth, 64, 1, 512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) "Max number of FCP commands we can queue to a specific LUN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) # tgt_queue_depth: This parameter is used to limit the number of outstanding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) # commands per target port. Value range is [10,65535]. Default value is 65535.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) static uint lpfc_tgt_queue_depth = LPFC_MAX_TGT_QDEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) module_param(lpfc_tgt_queue_depth, uint, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) MODULE_PARM_DESC(lpfc_tgt_queue_depth, "Set max Target queue depth");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) lpfc_vport_param_show(tgt_queue_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) lpfc_vport_param_init(tgt_queue_depth, LPFC_MAX_TGT_QDEPTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) * lpfc_tgt_queue_depth_store: Sets an attribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) * @phba: pointer the the adapter structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) * @val: integer attribute value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) * Description: Sets the parameter to the new value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) * zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) * -EINVAL if val is invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) lpfc_tgt_queue_depth_set(struct lpfc_vport *vport, uint val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) if (!lpfc_rangecheck(val, LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) if (val == vport->cfg_tgt_queue_depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) vport->cfg_tgt_queue_depth = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) /* Next loop thru nodelist and change cmd_qdepth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) lpfc_vport_param_store(tgt_queue_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) static DEVICE_ATTR_RW(lpfc_tgt_queue_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) # hba_queue_depth: This parameter is used to limit the number of outstanding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) # commands per lpfc HBA. Value range is [32,8192]. If this parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) # value is greater than the maximum number of exchanges supported by the HBA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) # then maximum number of exchanges supported by the HBA is used to determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) # the hba_queue_depth.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) LPFC_ATTR_R(hba_queue_depth, 8192, 32, 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) "Max number of FCP commands we can queue to a lpfc HBA");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) # peer_port_login: This parameter allows/prevents logins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) # between peer ports hosted on the same physical port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) # When this parameter is set 0 peer ports of same physical port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) # are not allowed to login to each other.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) # When this parameter is set 1 peer ports of same physical port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) # are allowed to login to each other.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) # Default value of this parameter is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) LPFC_VPORT_ATTR_R(peer_port_login, 0, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) "Allow peer ports on the same physical port to login to each "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) "other.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) # restrict_login: This parameter allows/prevents logins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) # between Virtual Ports and remote initiators.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) # When this parameter is not set (0) Virtual Ports will accept PLOGIs from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) # other initiators and will attempt to PLOGI all remote ports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) # When this parameter is set (1) Virtual Ports will reject PLOGIs from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) # remote ports and will not attempt to PLOGI to other initiators.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) # This parameter does not restrict to the physical port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) # This parameter does not restrict logins to Fabric resident remote ports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) # Default value of this parameter is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) static int lpfc_restrict_login = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) module_param(lpfc_restrict_login, int, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) MODULE_PARM_DESC(lpfc_restrict_login,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) "Restrict virtual ports login to remote initiators.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) lpfc_vport_param_show(restrict_login);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) * lpfc_restrict_login_init - Set the vport restrict login flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) * @vport: lpfc vport structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) * @val: contains the restrict login value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) * If val is not in a valid range then log a kernel error message and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) * the vport restrict login to one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) * If the port type is physical clear the restrict login flag and return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) * Else set the restrict login flag to val.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) * zero if val is in range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) lpfc_restrict_login_init(struct lpfc_vport *vport, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) if (val < 0 || val > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) "0422 lpfc_restrict_login attribute cannot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) "be set to %d, allowed range is [0, 1]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) vport->cfg_restrict_login = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) if (vport->port_type == LPFC_PHYSICAL_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) vport->cfg_restrict_login = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) vport->cfg_restrict_login = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) * lpfc_restrict_login_set - Set the vport restrict login flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) * @vport: lpfc vport structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) * @val: contains the restrict login value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) * If val is not in a valid range then log a kernel error message and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) * the vport restrict login to one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) * If the port type is physical and the val is not zero log a kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) * error message, clear the restrict login flag and return zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) * Else set the restrict login flag to val.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) * zero if val is in range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) lpfc_restrict_login_set(struct lpfc_vport *vport, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) if (val < 0 || val > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) "0425 lpfc_restrict_login attribute cannot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) "be set to %d, allowed range is [0, 1]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) vport->cfg_restrict_login = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) if (vport->port_type == LPFC_PHYSICAL_PORT && val != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) "0468 lpfc_restrict_login must be 0 for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) "Physical ports.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) vport->cfg_restrict_login = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) vport->cfg_restrict_login = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) lpfc_vport_param_store(restrict_login);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) static DEVICE_ATTR_RW(lpfc_restrict_login);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) # Some disk devices have a "select ID" or "select Target" capability.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) # From a protocol standpoint "select ID" usually means select the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) # Fibre channel "ALPA". In the FC-AL Profile there is an "informative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) # annex" which contains a table that maps a "select ID" (a number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) # between 0 and 7F) to an ALPA. By default, for compatibility with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) # older drivers, the lpfc driver scans this table from low ALPA to high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) # ALPA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) # Turning on the scan-down variable (on = 1, off = 0) will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) # cause the lpfc driver to use an inverted table, effectively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) # scanning ALPAs from high to low. Value range is [0,1]. Default value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) # (Note: This "select ID" functionality is a LOOP ONLY characteristic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) # and will not work across a fabric. Also this parameter will take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) # effect only in the case when ALPA map is not available.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) "Start scanning for devices from highest ALPA to lowest");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) # lpfc_topology: link topology for init link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) # 0x0 = attempt loop mode then point-to-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) # 0x01 = internal loopback mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) # 0x02 = attempt point-to-point mode only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) # 0x04 = attempt loop mode only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) # 0x06 = attempt point-to-point mode then loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) # Set point-to-point mode if you want to run as an N_Port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) # Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) LPFC_ATTR(topology, 0, 0, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) "Select Fibre Channel topology");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) * lpfc_topology_set - Set the adapters topology field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) * @val: topology value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) * If val is in a valid range then set the adapter's topology field and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) * issue a lip; if the lip fails reset the topology to the old value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) * If the value is not in range log a kernel error message and return an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) * zero if val is in range and lip okay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) * non-zero return value from lpfc_issue_lip()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) lpfc_topology_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) int nolip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) const char *val_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) uint32_t prev_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) if (!strncmp(buf, "nolip ", strlen("nolip "))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) nolip = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) val_buf = &buf[strlen("nolip ")];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) if (!isdigit(val_buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) if (sscanf(val_buf, "%i", &val) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) if (val >= 0 && val <= 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) prev_val = phba->cfg_topology;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) if (phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) val == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) "3113 Loop mode not supported at speed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) * The 'topology' is not a configurable parameter if :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) * - persistent topology enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) * - G7/G6 with no private loop support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) if ((phba->hba_flag & HBA_PERSISTENT_TOPO ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) (!phba->sli4_hba.pc_sli4_params.pls &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC))) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) val == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) "3114 Loop mode not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) phba->cfg_topology = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) if (nolip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) "3054 lpfc_topology changed from %d to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) prev_val, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) if (prev_val != val && phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) phba->fc_topology_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) phba->cfg_topology = prev_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) "%d:0467 lpfc_topology attribute cannot be set to %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) "allowed range is [0, 6]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) phba->brd_no, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) lpfc_param_show(topology)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) static DEVICE_ATTR_RW(lpfc_topology);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) * lpfc_static_vport_show: Read callback function for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) * lpfc_static_vport sysfs file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) * @dev: Pointer to class device object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) * @attr: device attribute structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) * @buf: Data buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) * This function is the read call back function for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) * lpfc_static_vport sysfs file. The lpfc_static_vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) * sysfs file report the mageability of the vport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) lpfc_static_vport_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) if (vport->vport_flag & STATIC_VPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) sprintf(buf, "1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) sprintf(buf, "0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) * Sysfs attribute to control the statistical data collection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) static DEVICE_ATTR_RO(lpfc_static_vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) * lpfc_stat_data_ctrl_store - write call back for lpfc_stat_data_ctrl sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) * @dev: Pointer to class device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) * @buf: Data buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) * @count: Size of the data buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) * This function get called when a user write to the lpfc_stat_data_ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) * sysfs file. This function parse the command written to the sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) * and take appropriate action. These commands are used for controlling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) * driver statistical data collection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) * Following are the command this function handles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) * setbucket <bucket_type> <base> <step>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) * = Set the latency buckets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) * destroybucket = destroy all the buckets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) * start = start data collection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) * stop = stop data collection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) * reset = reset the collected data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) #define LPFC_MAX_DATA_CTRL_LEN 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) static char bucket_data[LPFC_MAX_DATA_CTRL_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) char *str_ptr, *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) struct lpfc_vport **vports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) struct Scsi_Host *v_shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) char *bucket_type_str, *base_str, *step_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) unsigned long base, step, bucket_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) if (!strncmp(buf, "setbucket", strlen("setbucket"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) if (strlen(buf) > (LPFC_MAX_DATA_CTRL_LEN - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) strncpy(bucket_data, buf, LPFC_MAX_DATA_CTRL_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) str_ptr = &bucket_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) /* Ignore this token - this is command token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) token = strsep(&str_ptr, "\t ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) if (!token)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) bucket_type_str = strsep(&str_ptr, "\t ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) if (!bucket_type_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) if (!strncmp(bucket_type_str, "linear", strlen("linear")))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) bucket_type = LPFC_LINEAR_BUCKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) else if (!strncmp(bucket_type_str, "power2", strlen("power2")))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) bucket_type = LPFC_POWER2_BUCKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) base_str = strsep(&str_ptr, "\t ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) if (!base_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) base = simple_strtoul(base_str, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) step_str = strsep(&str_ptr, "\t ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) if (!step_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) step = simple_strtoul(step_str, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) if (!step)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) /* Block the data collection for every vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) vports = lpfc_create_vport_work_array(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) if (vports == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) v_shost = lpfc_shost_from_vport(vports[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) spin_lock_irq(v_shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) /* Block and reset data collection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) vports[i]->stat_data_blocked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) if (vports[i]->stat_data_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) lpfc_vport_reset_stat_data(vports[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) spin_unlock_irq(v_shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) /* Set the bucket attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) phba->bucket_type = bucket_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) phba->bucket_base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) phba->bucket_step = step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) v_shost = lpfc_shost_from_vport(vports[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) /* Unblock data collection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) spin_lock_irq(v_shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) vports[i]->stat_data_blocked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) spin_unlock_irq(v_shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) lpfc_destroy_vport_work_array(phba, vports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) if (!strncmp(buf, "destroybucket", strlen("destroybucket"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) vports = lpfc_create_vport_work_array(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) if (vports == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) v_shost = lpfc_shost_from_vport(vports[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) vports[i]->stat_data_blocked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) lpfc_free_bucket(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) vport->stat_data_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) vports[i]->stat_data_blocked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) lpfc_destroy_vport_work_array(phba, vports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) phba->bucket_type = LPFC_NO_BUCKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) phba->bucket_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) phba->bucket_step = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) if (!strncmp(buf, "start", strlen("start"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) /* If no buckets configured return error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) if (phba->bucket_type == LPFC_NO_BUCKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) if (vport->stat_data_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) lpfc_alloc_bucket(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) vport->stat_data_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) if (!strncmp(buf, "stop", strlen("stop"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) if (vport->stat_data_enabled == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) lpfc_free_bucket(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) vport->stat_data_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) if (!strncmp(buf, "reset", strlen("reset"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) if ((phba->bucket_type == LPFC_NO_BUCKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) || !vport->stat_data_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) vport->stat_data_blocked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) lpfc_vport_reset_stat_data(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) vport->stat_data_blocked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) * lpfc_stat_data_ctrl_show - Read function for lpfc_stat_data_ctrl sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) * @dev: Pointer to class device object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) * @buf: Data buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) * This function is the read call back function for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) * lpfc_stat_data_ctrl sysfs file. This function report the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) * current statistical data collection state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) lpfc_stat_data_ctrl_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) int index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) char *bucket_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) unsigned long bucket_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) switch (phba->bucket_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) case LPFC_LINEAR_BUCKET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) bucket_type = "linear";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) case LPFC_POWER2_BUCKET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) bucket_type = "power2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) bucket_type = "No Bucket";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) sprintf(&buf[index], "Statistical Data enabled :%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) "blocked :%d, Bucket type :%s, Bucket base :%d,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) " Bucket step :%d\nLatency Ranges :",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) vport->stat_data_enabled, vport->stat_data_blocked,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) bucket_type, phba->bucket_base, phba->bucket_step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) index = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) if (phba->bucket_type != LPFC_NO_BUCKET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) if (phba->bucket_type == LPFC_LINEAR_BUCKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) bucket_value = phba->bucket_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) phba->bucket_step * i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) bucket_value = phba->bucket_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) (1 << i) * phba->bucket_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) if (index + 10 > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) sprintf(&buf[index], "%08ld ", bucket_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) index = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) sprintf(&buf[index], "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) * Sysfs attribute to control the statistical data collection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) static DEVICE_ATTR_RW(lpfc_stat_data_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) * lpfc_drvr_stat_data: sysfs attr to get driver statistical data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) * Each Bucket takes 11 characters and 1 new line + 17 bytes WWN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) * for each target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) #define STAT_DATA_SIZE_PER_TARGET(NUM_BUCKETS) ((NUM_BUCKETS) * 11 + 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) #define MAX_STAT_DATA_SIZE_PER_TARGET \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) STAT_DATA_SIZE_PER_TARGET(LPFC_MAX_BUCKET_COUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) * sysfs_drvr_stat_data_read - Read function for lpfc_drvr_stat_data attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) * @filp: sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) * @kobj: Pointer to the kernel object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) * @bin_attr: Attribute object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) * @buff: Buffer pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) * @off: File offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) * @count: Buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) * This function is the read call back function for lpfc_drvr_stat_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) * sysfs file. This function export the statistical data to user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) * applications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) sysfs_drvr_stat_data_read(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) struct bin_attribute *bin_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) char *buf, loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) struct device *dev = container_of(kobj, struct device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) int i = 0, index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) unsigned long nport_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) struct lpfc_nodelist *ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) nport_index = (unsigned long)off /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) MAX_STAT_DATA_SIZE_PER_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) if (!vport->stat_data_enabled || vport->stat_data_blocked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) || (phba->bucket_type == LPFC_NO_BUCKET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) if (!NLP_CHK_NODE_ACT(ndlp) || !ndlp->lat_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) if (nport_index > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) nport_index--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) if ((index + MAX_STAT_DATA_SIZE_PER_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) > count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) if (!ndlp->lat_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) /* Print the WWN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) sprintf(&buf[index], "%02x%02x%02x%02x%02x%02x%02x%02x:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) ndlp->nlp_portname.u.wwn[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) ndlp->nlp_portname.u.wwn[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) ndlp->nlp_portname.u.wwn[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) ndlp->nlp_portname.u.wwn[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) ndlp->nlp_portname.u.wwn[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) ndlp->nlp_portname.u.wwn[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) ndlp->nlp_portname.u.wwn[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) ndlp->nlp_portname.u.wwn[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) index = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) sprintf(&buf[index], "%010u,",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) ndlp->lat_data[i].cmd_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) index = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) sprintf(&buf[index], "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) index = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) static struct bin_attribute sysfs_drvr_stat_data_attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) .attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) .name = "lpfc_drvr_stat_data",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) .mode = S_IRUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) .read = sysfs_drvr_stat_data_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) .write = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) # lpfc_link_speed: Link speed selection for initializing the Fibre Channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) # connection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) # Value range is [0,16]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) * lpfc_link_speed_set - Set the adapters link speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) * @val: link speed value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) * If val is in a valid range then set the adapter's link speed field and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) * issue a lip; if the lip fails reset the link speed to the old value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) * If the value is not in range log a kernel error message and return an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) * zero if val is in range and lip okay.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) * non-zero return value from lpfc_issue_lip()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) int val = LPFC_USER_LINK_SPEED_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) int nolip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) const char *val_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) uint32_t prev_val, if_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) if (if_type >= LPFC_SLI_INTF_IF_TYPE_2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) phba->hba_flag & HBA_FORCED_LINK_SPEED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) if (!strncmp(buf, "nolip ", strlen("nolip "))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) nolip = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) val_buf = &buf[strlen("nolip ")];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) if (!isdigit(val_buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) if (sscanf(val_buf, "%i", &val) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) "3055 lpfc_link_speed changed from %d to %d %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) phba->cfg_link_speed, val, nolip ? "(nolip)" : "(lip)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) "2879 lpfc_link_speed attribute cannot be set "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) "to %d. Speed is not supported by this port.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) if (val >= LPFC_USER_LINK_SPEED_16G &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) "3112 lpfc_link_speed attribute cannot be set "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) "to %d. Speed is not supported in loop mode.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) case LPFC_USER_LINK_SPEED_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) case LPFC_USER_LINK_SPEED_1G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) case LPFC_USER_LINK_SPEED_2G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) case LPFC_USER_LINK_SPEED_4G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) case LPFC_USER_LINK_SPEED_8G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) case LPFC_USER_LINK_SPEED_16G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) case LPFC_USER_LINK_SPEED_32G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) case LPFC_USER_LINK_SPEED_64G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) prev_val = phba->cfg_link_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) phba->cfg_link_speed = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) if (nolip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) phba->cfg_link_speed = prev_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) "0469 lpfc_link_speed attribute cannot be set to %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) "allowed values are [%s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) val, LPFC_LINK_SPEED_STRING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) static int lpfc_link_speed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) module_param(lpfc_link_speed, int, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) MODULE_PARM_DESC(lpfc_link_speed, "Select link speed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) lpfc_param_show(link_speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) * lpfc_link_speed_init - Set the adapters link speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) * @val: link speed value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) * If val is in a valid range then set the adapter's link speed field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) * If the value is not in range log a kernel error message, clear the link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) * speed and return an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) * zero if val saved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) lpfc_link_speed_init(struct lpfc_hba *phba, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) if (val >= LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) "3111 lpfc_link_speed of %d cannot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) "support loop mode, setting topology to default.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) phba->cfg_topology = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) case LPFC_USER_LINK_SPEED_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) case LPFC_USER_LINK_SPEED_1G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) case LPFC_USER_LINK_SPEED_2G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) case LPFC_USER_LINK_SPEED_4G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) case LPFC_USER_LINK_SPEED_8G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) case LPFC_USER_LINK_SPEED_16G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) case LPFC_USER_LINK_SPEED_32G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) case LPFC_USER_LINK_SPEED_64G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) phba->cfg_link_speed = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) "0405 lpfc_link_speed attribute cannot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) "be set to %d, allowed values are "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) "["LPFC_LINK_SPEED_STRING"]\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) static DEVICE_ATTR_RW(lpfc_link_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) # lpfc_aer_support: Support PCIe device Advanced Error Reporting (AER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) # 0 = aer disabled or not supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) # 1 = aer supported and enabled (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) # Value range is [0,1]. Default value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) LPFC_ATTR(aer_support, 1, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) "Enable PCIe device AER support");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) lpfc_param_show(aer_support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) * lpfc_aer_support_store - Set the adapter for aer support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) * @buf: containing enable or disable aer flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) * @count: unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) * If the val is 1 and currently the device's AER capability was not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) * enabled, invoke the kernel's enable AER helper routine, trying to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) * enable the device's AER capability. If the helper routine enabling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) * AER returns success, update the device's cfg_aer_support flag to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) * indicate AER is supported by the device; otherwise, if the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) * AER capability is already enabled to support AER, then do nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) * If the val is 0 and currently the device's AER support was enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) * invoke the kernel's disable AER helper routine. After that, update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) * the device's cfg_aer_support flag to indicate AER is not supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) * by the device; otherwise, if the device AER capability is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) * disabled from supporting AER, then do nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) * length of the buf on success if val is in range the intended mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) * is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) * -EINVAL if val out of range or intended mode is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) int val = 0, rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) if (!isdigit(buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) if (sscanf(buf, "%i", &val) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) if (phba->hba_flag & HBA_AER_ENABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) rc = pci_disable_pcie_error_reporting(phba->pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) phba->hba_flag &= ~HBA_AER_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) phba->cfg_aer_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) rc = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) phba->cfg_aer_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) rc = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) if (!(phba->hba_flag & HBA_AER_ENABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) rc = pci_enable_pcie_error_reporting(phba->pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) phba->hba_flag |= HBA_AER_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) phba->cfg_aer_support = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) rc = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) phba->cfg_aer_support = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) rc = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) static DEVICE_ATTR_RW(lpfc_aer_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) * @buf: containing flag 1 for aer cleanup state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) * @count: unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) * If the @buf contains 1 and the device currently has the AER support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) * enabled, then invokes the kernel AER helper routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) * pci_aer_clear_nonfatal_status() to clean up the uncorrectable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) * error status register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) * -EINVAL if the buf does not contain the 1 or the device is not currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) * enabled with the AER support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) int val, rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) if (!isdigit(buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) if (sscanf(buf, "%i", &val) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) if (val != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) if (phba->hba_flag & HBA_AER_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) rc = pci_aer_clear_nonfatal_status(phba->pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) lpfc_aer_cleanup_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) * lpfc_sriov_nr_virtfn_store - Enable the adapter for sr-iov virtual functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) * @buf: containing the string the number of vfs to be enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) * @count: unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) * When this api is called either through user sysfs, the driver shall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) * try to enable or disable SR-IOV virtual functions according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) * following:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) * If zero virtual function has been enabled to the physical function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) * the driver shall invoke the pci enable virtual function api trying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) * to enable the virtual functions. If the nr_vfn provided is greater
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) * than the maximum supported, the maximum virtual function number will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) * be used for invoking the api; otherwise, the nr_vfn provided shall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) * be used for invoking the api. If the api call returned success, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) * actual number of virtual functions enabled will be set to the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) * cfg_sriov_nr_virtfn; otherwise, -EINVAL shall be returned and driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) * cfg_sriov_nr_virtfn remains zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) * If none-zero virtual functions have already been enabled to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) * physical function, as reflected by the driver's cfg_sriov_nr_virtfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) * -EINVAL will be returned and the driver does nothing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) * If the nr_vfn provided is zero and none-zero virtual functions have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) * been enabled, as indicated by the driver's cfg_sriov_nr_virtfn, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) * disabling virtual function api shall be invoded to disable all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) * virtual functions and driver's cfg_sriov_nr_virtfn shall be set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) * zero. Otherwise, if zero virtual function has been enabled, do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) * nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) * length of the buf on success if val is in range the intended mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) * is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) * -EINVAL if val out of range or intended mode is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) lpfc_sriov_nr_virtfn_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) struct pci_dev *pdev = phba->pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) int val = 0, rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) /* Sanity check on user data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) if (!isdigit(buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) if (sscanf(buf, "%i", &val) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) /* Request disabling virtual functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) if (val == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) if (phba->cfg_sriov_nr_virtfn > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) pci_disable_sriov(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) phba->cfg_sriov_nr_virtfn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) /* Request enabling virtual functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) if (phba->cfg_sriov_nr_virtfn > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) "3018 There are %d virtual functions "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) "enabled on physical function.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) phba->cfg_sriov_nr_virtfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) if (val <= LPFC_MAX_VFN_PER_PFN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) phba->cfg_sriov_nr_virtfn = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) "3019 Enabling %d virtual functions is not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) "allowed.\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) rc = lpfc_sli_probe_sriov_nr_virtfn(phba, phba->cfg_sriov_nr_virtfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) phba->cfg_sriov_nr_virtfn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) rc = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) LPFC_ATTR(sriov_nr_virtfn, LPFC_DEF_VFN_PER_PFN, 0, LPFC_MAX_VFN_PER_PFN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) "Enable PCIe device SR-IOV virtual fn");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) lpfc_param_show(sriov_nr_virtfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) static DEVICE_ATTR_RW(lpfc_sriov_nr_virtfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) * lpfc_request_firmware_store - Request for Linux generic firmware upgrade
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) * @buf: containing the string the number of vfs to be enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) * @count: unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) * length of the buf on success if val is in range the intended mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) * is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) * -EINVAL if val out of range or intended mode is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) lpfc_request_firmware_upgrade_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) int val = 0, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) /* Sanity check on user data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) if (!isdigit(buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) if (sscanf(buf, "%i", &val) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) if (val != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) rc = lpfc_sli4_request_firmware_update(phba, RUN_FW_UPGRADE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) rc = strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) static int lpfc_req_fw_upgrade;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) module_param(lpfc_req_fw_upgrade, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) MODULE_PARM_DESC(lpfc_req_fw_upgrade, "Enable Linux generic firmware upgrade");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) lpfc_param_show(request_firmware_upgrade)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) * lpfc_request_firmware_upgrade_init - Enable initial linux generic fw upgrade
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) * @val: 0 or 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) * Set the initial Linux generic firmware upgrade enable or disable flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) * zero if val saved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) lpfc_request_firmware_upgrade_init(struct lpfc_hba *phba, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) if (val >= 0 && val <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) phba->cfg_request_firmware_upgrade = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) static DEVICE_ATTR(lpfc_req_fw_upgrade, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) lpfc_request_firmware_upgrade_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) lpfc_request_firmware_upgrade_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) * lpfc_force_rscn_store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) * @buf: unused string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) * @count: unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) * Force the switch to send a RSCN to all other NPorts in our zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) * If we are direct connect pt2pt, build the RSCN command ourself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) * and send to the other NPort. Not supported for private loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) * 0 - on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) * -EIO - if command is not sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) lpfc_force_rscn_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) i = lpfc_issue_els_rscn(vport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) * lpfc_force_rscn: Force an RSCN to be sent to all remote NPorts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) * connected to the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) * Value range is any ascii value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) static int lpfc_force_rscn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) module_param(lpfc_force_rscn, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) MODULE_PARM_DESC(lpfc_force_rscn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) "Force an RSCN to be sent to all remote NPorts");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) lpfc_param_show(force_rscn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) * lpfc_force_rscn_init - Force an RSCN to be sent to all remote NPorts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) * @val: unused value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) * zero if val saved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) lpfc_force_rscn_init(struct lpfc_hba *phba, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) static DEVICE_ATTR_RW(lpfc_force_rscn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) * lpfc_fcp_imax_store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) * @buf: string with the number of fast-path FCP interrupts per second.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) * @count: unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) * If val is in a valid range [636,651042], then set the adapter's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) * maximum number of fast-path FCP interrupts per second.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) * length of the buf on success if val is in range the intended mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) * is supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) * -EINVAL if val out of range or intended mode is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) struct lpfc_eq_intr_info *eqi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) uint32_t usdelay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) int val = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) /* fcp_imax is only valid for SLI4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) if (phba->sli_rev != LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) /* Sanity check on user data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) if (!isdigit(buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) if (sscanf(buf, "%i", &val) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) * Value range for the HBA is [5000,5000000]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) * The value for each EQ depends on how many EQs are configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) * Allow value == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) if (val && (val < LPFC_MIN_IMAX || val > LPFC_MAX_IMAX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) phba->cfg_auto_imax = (val) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) if (phba->cfg_fcp_imax && !val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) queue_delayed_work(phba->wq, &phba->eq_delay_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) msecs_to_jiffies(LPFC_EQ_DELAY_MSECS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) for_each_present_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) eqi = per_cpu_ptr(phba->sli4_hba.eq_info, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) eqi->icnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) phba->cfg_fcp_imax = (uint32_t)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) if (phba->cfg_fcp_imax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) usdelay = LPFC_SEC_TO_USEC / phba->cfg_fcp_imax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) usdelay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) for (i = 0; i < phba->cfg_irq_chann; i += LPFC_MAX_EQ_DELAY_EQID_CNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) lpfc_modify_hba_eq_delay(phba, i, LPFC_MAX_EQ_DELAY_EQID_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) usdelay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) # lpfc_fcp_imax: The maximum number of fast-path FCP interrupts per second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) # for the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) # Value range is [5,000 to 5,000,000]. Default value is 50,000.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) static int lpfc_fcp_imax = LPFC_DEF_IMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) module_param(lpfc_fcp_imax, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) MODULE_PARM_DESC(lpfc_fcp_imax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) "Set the maximum number of FCP interrupts per second per HBA");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) lpfc_param_show(fcp_imax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) * lpfc_fcp_imax_init - Set the initial sr-iov virtual function enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) * @val: link speed value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) * If val is in a valid range [636,651042], then initialize the adapter's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) * maximum number of fast-path FCP interrupts per second.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) * zero if val saved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) lpfc_fcp_imax_init(struct lpfc_hba *phba, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) if (phba->sli_rev != LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) phba->cfg_fcp_imax = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) if ((val >= LPFC_MIN_IMAX && val <= LPFC_MAX_IMAX) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) (val == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) phba->cfg_fcp_imax = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) "3016 lpfc_fcp_imax: %d out of range, using default\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) phba->cfg_fcp_imax = LPFC_DEF_IMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) static DEVICE_ATTR_RW(lpfc_fcp_imax);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) * lpfc_cq_max_proc_limit_store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) * @buf: string with the cq max processing limit of cqes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) * @count: unused variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) * If val is in a valid range, then set value on each cq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) * The length of the buf: if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) * -ERANGE: if val is not in the valid range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) * -EINVAL: if bad value format or intended mode is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) lpfc_cq_max_proc_limit_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) struct lpfc_queue *eq, *cq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) /* cq_max_proc_limit is only valid for SLI4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) if (phba->sli_rev != LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) /* Sanity check on user data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) if (!isdigit(buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) if (kstrtoul(buf, 0, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) if (val < LPFC_CQ_MIN_PROC_LIMIT || val > LPFC_CQ_MAX_PROC_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) phba->cfg_cq_max_proc_limit = (uint32_t)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) /* set the values on the cq's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) for (i = 0; i < phba->cfg_irq_chann; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) /* Get the EQ corresponding to the IRQ vector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) eq = phba->sli4_hba.hba_eq_hdl[i].eq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) if (!eq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) list_for_each_entry(cq, &eq->child_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) cq->max_proc_limit = min(phba->cfg_cq_max_proc_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) cq->entry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) * lpfc_cq_max_proc_limit: The maximum number CQE entries processed in an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) * itteration of CQ processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) static int lpfc_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) module_param(lpfc_cq_max_proc_limit, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) MODULE_PARM_DESC(lpfc_cq_max_proc_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) "Set the maximum number CQEs processed in an iteration of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) "CQ processing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) lpfc_param_show(cq_max_proc_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) * lpfc_cq_poll_threshold: Set the threshold of CQE completions in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) * single handler call which should request a polled completion rather
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) * than re-enabling interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) LPFC_ATTR_RW(cq_poll_threshold, LPFC_CQ_DEF_THRESHOLD_TO_POLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) LPFC_CQ_MIN_THRESHOLD_TO_POLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) LPFC_CQ_MAX_THRESHOLD_TO_POLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) "CQE Processing Threshold to enable Polling");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) * lpfc_cq_max_proc_limit_init - Set the initial cq max_proc_limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) * @val: entry limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) * If val is in a valid range, then initialize the adapter's maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) * value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) * Always returns 0 for success, even if value not always set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) * requested value. If value out of range or not supported, will fall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) * back to default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) lpfc_cq_max_proc_limit_init(struct lpfc_hba *phba, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) phba->cfg_cq_max_proc_limit = LPFC_CQ_DEF_MAX_PROC_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) if (phba->sli_rev != LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) if (val >= LPFC_CQ_MIN_PROC_LIMIT && val <= LPFC_CQ_MAX_PROC_LIMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) phba->cfg_cq_max_proc_limit = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) "0371 "LPFC_DRIVER_NAME"_cq_max_proc_limit: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) "%d out of range, using default\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) phba->cfg_cq_max_proc_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) static DEVICE_ATTR_RW(lpfc_cq_max_proc_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) * lpfc_state_show - Display current driver CPU affinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) * @buf: on return contains text describing the state of the link.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) struct lpfc_vector_map_info *cpup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) if ((phba->sli_rev != LPFC_SLI_REV4) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) (phba->intr_type != MSIX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) switch (phba->cfg_fcp_cpu_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) len += scnprintf(buf + len, PAGE_SIZE-len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) "fcp_cpu_map: No mapping (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) phba->cfg_fcp_cpu_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) len += scnprintf(buf + len, PAGE_SIZE-len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) "fcp_cpu_map: HBA centric mapping (%d): "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) "%d of %d CPUs online from %d possible CPUs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) phba->cfg_fcp_cpu_map, num_online_cpus(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) num_present_cpus(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) phba->sli4_hba.num_possible_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) while (phba->sli4_hba.curr_disp_cpu <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) phba->sli4_hba.num_possible_cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) cpup = &phba->sli4_hba.cpu_map[phba->sli4_hba.curr_disp_cpu];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) if (!cpu_present(phba->sli4_hba.curr_disp_cpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) "CPU %02d not present\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) phba->sli4_hba.curr_disp_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) else if (cpup->eq == LPFC_VECTOR_MAP_EMPTY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) len += scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) "CPU %02d hdwq None "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) "physid %d coreid %d ht %d ua %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) phba->sli4_hba.curr_disp_cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) cpup->phys_id, cpup->core_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) (cpup->flag & LPFC_CPU_MAP_HYPER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) len += scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) "CPU %02d EQ None hdwq %04d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) "physid %d coreid %d ht %d ua %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) phba->sli4_hba.curr_disp_cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) cpup->hdwq, cpup->phys_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) cpup->core_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) (cpup->flag & LPFC_CPU_MAP_HYPER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) (cpup->flag & LPFC_CPU_MAP_UNASSIGN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) len += scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) "CPU %02d hdwq None "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) "physid %d coreid %d ht %d ua %d IRQ %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) phba->sli4_hba.curr_disp_cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) cpup->phys_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) cpup->core_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) (cpup->flag & LPFC_CPU_MAP_HYPER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) lpfc_get_irq(cpup->eq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) len += scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) "CPU %02d EQ %04d hdwq %04d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) "physid %d coreid %d ht %d ua %d IRQ %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) phba->sli4_hba.curr_disp_cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) cpup->eq, cpup->hdwq, cpup->phys_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) cpup->core_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) (cpup->flag & LPFC_CPU_MAP_HYPER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) (cpup->flag & LPFC_CPU_MAP_UNASSIGN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) lpfc_get_irq(cpup->eq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) phba->sli4_hba.curr_disp_cpu++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) /* display max number of CPUs keeping some margin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) if (phba->sli4_hba.curr_disp_cpu <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) phba->sli4_hba.num_possible_cpu &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) (len >= (PAGE_SIZE - 64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) len += scnprintf(buf + len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) PAGE_SIZE - len, "more...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) if (phba->sli4_hba.curr_disp_cpu == phba->sli4_hba.num_possible_cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) phba->sli4_hba.curr_disp_cpu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) * lpfc_fcp_cpu_map_store - Change CPU affinity of driver vectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) * @dev: class device that is converted into a Scsi_host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) * @buf: one or more lpfc_polling_flags values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) * @count: not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) * -EINVAL - Not implemented yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) lpfc_fcp_cpu_map_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) # lpfc_fcp_cpu_map: Defines how to map CPUs to IRQ vectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) # for the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) # Value range is [0 to 1]. Default value is LPFC_HBA_CPU_MAP (1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) # 0 - Do not affinitze IRQ vectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) # 1 - Affintize HBA vectors with respect to each HBA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) # (start with CPU0 for each HBA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) # This also defines how Hardware Queues are mapped to specific CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) static int lpfc_fcp_cpu_map = LPFC_HBA_CPU_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) module_param(lpfc_fcp_cpu_map, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) MODULE_PARM_DESC(lpfc_fcp_cpu_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) "Defines how to map CPUs to IRQ vectors per HBA");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) * lpfc_fcp_cpu_map_init - Set the initial sr-iov virtual function enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) * @val: link speed value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) * If val is in a valid range [0-2], then affinitze the adapter's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) * MSIX vectors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) * zero if val saved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) * -EINVAL val out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) lpfc_fcp_cpu_map_init(struct lpfc_hba *phba, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) if (phba->sli_rev != LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) phba->cfg_fcp_cpu_map = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) if (val >= LPFC_MIN_CPU_MAP && val <= LPFC_MAX_CPU_MAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) phba->cfg_fcp_cpu_map = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) "3326 lpfc_fcp_cpu_map: %d out of range, using "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) "default\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) phba->cfg_fcp_cpu_map = LPFC_HBA_CPU_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) static DEVICE_ATTR_RW(lpfc_fcp_cpu_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) # lpfc_fcp_class: Determines FC class to use for the FCP protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) # Value range is [2,3]. Default value is 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) "Select Fibre Channel class of service for FCP sequences");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) # lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) # is [0,1]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) "Use ADISC on rediscovery to authenticate FCP devices");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) # lpfc_first_burst_size: First burst size to use on the NPorts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) # that support first burst.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) # Value range is [0,65536]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) LPFC_VPORT_ATTR_RW(first_burst_size, 0, 0, 65536,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) "First burst size for Targets that support first burst");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) * lpfc_nvmet_fb_size: NVME Target mode supported first burst size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) * When the driver is configured as an NVME target, this value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) * communicated to the NVME initiator in the PRLI response. It is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) * used only when the lpfc_nvme_enable_fb and lpfc_nvmet_support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) * parameters are set and the target is sending the PRLI RSP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) * Parameter supported on physical port only - no NPIV support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) * Value range is [0,65536]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) LPFC_ATTR_RW(nvmet_fb_size, 0, 0, 65536,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) "NVME Target mode first burst size in 512B increments.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) * lpfc_nvme_enable_fb: Enable NVME first burst on I and T functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) * For the Initiator (I), enabling this parameter means that an NVMET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) * PRLI response with FBA enabled and an FB_SIZE set to a nonzero value will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) * processed by the initiator for subsequent NVME FCP IO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) * Currently, this feature is not supported on the NVME target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) * Value range is [0,1]. Default value is 0 (disabled).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) LPFC_ATTR_RW(nvme_enable_fb, 0, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) "Enable First Burst feature for NVME Initiator.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) # lpfc_max_scsicmpl_time: Use scsi command completion time to control I/O queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) # depth. Default value is 0. When the value of this parameter is zero the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) # SCSI command completion time is not used for controlling I/O queue depth. When
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) # the parameter is set to a non-zero value, the I/O queue depth is controlled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) # to limit the I/O completion time to the parameter value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) # The value is set in milliseconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) LPFC_VPORT_ATTR(max_scsicmpl_time, 0, 0, 60000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) "Use command completion time to control queue depth");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) lpfc_vport_param_show(max_scsicmpl_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) struct lpfc_nodelist *ndlp, *next_ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) if (val == vport->cfg_max_scsicmpl_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) if ((val < 0) || (val > 60000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) vport->cfg_max_scsicmpl_time = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) if (!NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) ndlp->cmd_qdepth = vport->cfg_tgt_queue_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) lpfc_vport_param_store(max_scsicmpl_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) static DEVICE_ATTR_RW(lpfc_max_scsicmpl_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) # lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) # range is [0,1]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) # lpfc_xri_rebalancing: enable or disable XRI rebalancing feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) # range is [0,1]. Default value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) LPFC_ATTR_R(xri_rebalancing, 1, 0, 1, "Enable/Disable XRI rebalancing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) * lpfc_io_sched: Determine scheduling algrithmn for issuing FCP cmds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) * range is [0,1]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) * For [0], FCP commands are issued to Work Queues based on upper layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) * hardware queue index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) * For [1], FCP commands are issued to a Work Queue associated with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) * current CPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) * LPFC_FCP_SCHED_BY_HDWQ == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) * LPFC_FCP_SCHED_BY_CPU == 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) * The driver dynamically sets this to 1 (BY_CPU) if it's able to set up cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) * affinity for FCP/NVME I/Os through Work Queues associated with the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) * CPU. Otherwise, the default 0 (Round Robin) scheduling of FCP/NVME I/Os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) * through WQs will be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) LPFC_ATTR_RW(fcp_io_sched, LPFC_FCP_SCHED_BY_CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) LPFC_FCP_SCHED_BY_HDWQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) LPFC_FCP_SCHED_BY_CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) "Determine scheduling algorithm for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) "issuing commands [0] - Hardware Queue, [1] - Current CPU");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) * lpfc_ns_query: Determine algrithmn for NameServer queries after RSCN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) * range is [0,1]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) * For [0], GID_FT is used for NameServer queries after RSCN (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) * For [1], GID_PT is used for NameServer queries after RSCN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) LPFC_ATTR_RW(ns_query, LPFC_NS_QUERY_GID_FT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) LPFC_NS_QUERY_GID_FT, LPFC_NS_QUERY_GID_PT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) "Determine algorithm NameServer queries after RSCN "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) "[0] - GID_FT, [1] - GID_PT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) # lpfc_fcp2_no_tgt_reset: Determine bus reset behavior
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) # range is [0,1]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) # For [0], bus reset issues target reset to ALL devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) # For [1], bus reset issues target reset to non-FCP2 devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) LPFC_ATTR_RW(fcp2_no_tgt_reset, 0, 0, 1, "Determine bus reset behavior for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) "FCP2 devices [0] - issue tgt reset, [1] - no tgt reset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) # lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) # cr_delay (msec) or cr_count outstanding commands. cr_delay can take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) # value [0,63]. cr_count can take value [1,255]. Default value of cr_delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) # is 0. Default value of cr_count is 1. The cr_count feature is disabled if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) # cr_delay is set to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) "interrupt response is generated");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) "interrupt response is generated");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) # lpfc_multi_ring_support: Determines how many rings to spread available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) # cmd/rsp IOCB entries across.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) # Value range is [1,2]. Default value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) "SLI rings to spread IOCB entries across");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) # lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) # identifies what rctl value to configure the additional ring for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) # Value range is [1,0xff]. Default value is 4 (Unsolicated Data).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) LPFC_ATTR_R(multi_ring_rctl, FC_RCTL_DD_UNSOL_DATA, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) 255, "Identifies RCTL for additional ring configuration");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) # lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) # identifies what type value to configure the additional ring for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) # Value range is [1,0xff]. Default value is 5 (LLC/SNAP).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) LPFC_ATTR_R(multi_ring_type, FC_TYPE_IP, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) 255, "Identifies TYPE for additional ring configuration");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) # lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) # 0 = SmartSAN functionality disabled (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) # 1 = SmartSAN functionality enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) # This parameter will override the value of lpfc_fdmi_on module parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) # Value range is [0,1]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) # lpfc_fdmi_on: Controls FDMI support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) # 0 No FDMI support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) # 1 Traditional FDMI support (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) # Traditional FDMI support means the driver will assume FDMI-2 support;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) # however, if that fails, it will fallback to FDMI-1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) # If lpfc_enable_SmartSAN is set to 1, the driver ignores lpfc_fdmi_on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) # If lpfc_enable_SmartSAN is set 0, the driver uses the current value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) # lpfc_fdmi_on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) # Value range [0,1]. Default value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) LPFC_ATTR_R(fdmi_on, 1, 0, 1, "Enable FDMI support");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) # Specifies the maximum number of ELS cmds we can have outstanding (for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) # discovery). Value range is [1,64]. Default value = 32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) "during discovery");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) # lpfc_max_luns: maximum allowed LUN ID. This is the highest LUN ID that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) # will be scanned by the SCSI midlayer when sequential scanning is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) # used; and is also the highest LUN ID allowed when the SCSI midlayer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) # parses REPORT_LUN responses. The lpfc driver has no LUN count or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) # LUN ID limit, but the SCSI midlayer requires this field for the uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) # above. The lpfc driver limits the default value to 255 for two reasons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) # As it bounds the sequential scan loop, scanning for thousands of luns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) # on a target can take minutes of wall clock time. Additionally,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) # there are FC targets, such as JBODs, that only recognize 8-bits of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) # LUN ID. When they receive a value greater than 8 bits, they chop off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) # the high order bits. In other words, they see LUN IDs 0, 256, 512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) # and so on all as LUN ID 0. This causes the linux kernel, which sees
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) # valid responses at each of the LUN IDs, to believe there are multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) # devices present, when in fact, there is only 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) # A customer that is aware of their target behaviors, and the results as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) # indicated above, is welcome to increase the lpfc_max_luns value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) # As mentioned, this value is not used by the lpfc driver, only the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) # SCSI midlayer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) # Value range is [0,65535]. Default value is 255.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) # NOTE: The SCSI layer might probe all allowed LUN on some old targets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) LPFC_VPORT_ULL_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN ID");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) # Value range is [1,255], default value is 10.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) "Milliseconds driver will wait between polling FCP ring");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) # lpfc_task_mgmt_tmo: Maximum time to wait for task management commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) # to complete in seconds. Value range is [5,180], default value is 60.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) LPFC_ATTR_RW(task_mgmt_tmo, 60, 5, 180,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) "Maximum time to wait for task management commands to complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) # lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) # support this feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) # 0 = MSI disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) # 1 = MSI enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) # 2 = MSI-X enabled (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) # Value range is [0,2]. Default value is 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) "MSI-X (2), if possible");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) * lpfc_nvme_oas: Use the oas bit when sending NVME/NVMET IOs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) * 0 = NVME OAS disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) * 1 = NVME OAS enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) * Value range is [0,1]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) LPFC_ATTR_RW(nvme_oas, 0, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) "Use OAS bit on NVME IOs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) * 0 = Put NVME Command in SGL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) * 1 = Embed NVME Command in WQE (unless G7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) * 2 = Embed NVME Command in WQE (force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683) * Value range is [0,2]. Default value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) "Embed NVME Command in WQE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) * lpfc_fcp_mq_threshold: Set the maximum number of Hardware Queues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) * the driver will advertise it supports to the SCSI layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) * 0 = Set nr_hw_queues by the number of CPUs or HW queues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693) * 1,256 = Manually specify nr_hw_queue value to be advertised,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) * Value range is [0,256]. Default value is 8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) LPFC_ATTR_R(fcp_mq_threshold, LPFC_FCP_MQ_THRESHOLD_DEF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) LPFC_FCP_MQ_THRESHOLD_MIN, LPFC_FCP_MQ_THRESHOLD_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) "Set the number of SCSI Queues advertised");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) * lpfc_hdw_queue: Set the number of Hardware Queues the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) * will advertise it supports to the NVME and SCSI layers. This also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) * will map to the number of CQ/WQ pairs the driver will create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) * The NVME Layer will try to create this many, plus 1 administrative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) * hardware queue. The administrative queue will always map to WQ 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) * A hardware IO queue maps (qidx) to a specific driver CQ/WQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) * 0 = Configure the number of hdw queues to the number of active CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) * 1,256 = Manually specify how many hdw queues to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) * Value range is [0,256]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) LPFC_ATTR_R(hdw_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) LPFC_HBA_HDWQ_DEF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) LPFC_HBA_HDWQ_MIN, LPFC_HBA_HDWQ_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) "Set the number of I/O Hardware Queues");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) #if IS_ENABLED(CONFIG_X86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) * lpfc_cpumask_irq_mode_init - initalizes cpumask of phba based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) * irq_chann_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) * @phba: Pointer to HBA context object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) lpfc_cpumask_irq_mode_init(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) unsigned int cpu, first_cpu, numa_node = NUMA_NO_NODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) const struct cpumask *sibling_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731) struct cpumask *aff_mask = &phba->sli4_hba.irq_aff_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) cpumask_clear(aff_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) if (phba->irq_chann_mode == NUMA_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) /* Check if we're a NUMA architecture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) numa_node = dev_to_node(&phba->pcidev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) if (numa_node == NUMA_NO_NODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) phba->irq_chann_mode = NORMAL_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745) switch (phba->irq_chann_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) case NUMA_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) if (cpu_to_node(cpu) == numa_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) cpumask_set_cpu(cpu, aff_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) case NHT_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) sibling_mask = topology_sibling_cpumask(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752) first_cpu = cpumask_first(sibling_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) if (first_cpu < nr_cpu_ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) cpumask_set_cpu(first_cpu, aff_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) lpfc_assign_default_irq_chann(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) #if IS_ENABLED(CONFIG_X86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) switch (boot_cpu_data.x86_vendor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) case X86_VENDOR_AMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) /* If AMD architecture, then default is NUMA_MODE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) phba->irq_chann_mode = NUMA_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) case X86_VENDOR_INTEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) /* If Intel architecture, then default is no hyperthread mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) phba->irq_chann_mode = NHT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) phba->irq_chann_mode = NORMAL_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) lpfc_cpumask_irq_mode_init(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) phba->irq_chann_mode = NORMAL_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) * lpfc_irq_chann: Set the number of IRQ vectors that are available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) * for Hardware Queues to utilize. This also will map to the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) * of EQ / MSI-X vectors the driver will create. This should never be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) * more than the number of Hardware Queues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) * 0 = Configure number of IRQ Channels to:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) * if AMD architecture, number of CPUs on HBA's NUMA node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) * if Intel architecture, number of physical CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) * otherwise, number of active CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) * [1,256] = Manually specify how many IRQ Channels to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) * Value range is [0,256]. Default value is [0].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) static uint lpfc_irq_chann = LPFC_IRQ_CHANN_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) module_param(lpfc_irq_chann, uint, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) MODULE_PARM_DESC(lpfc_irq_chann, "Set number of interrupt vectors to allocate");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) /* lpfc_irq_chann_init - Set the hba irq_chann initial value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) * @val: contains the initial value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) * Validates the initial value is within range and assigns it to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) * adapter. If not in range, an error message is posted and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) * default value is assigned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) * zero if value is in range and is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) * -EINVAL if value was out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) lpfc_irq_chann_init(struct lpfc_hba *phba, uint32_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) const struct cpumask *aff_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) if (phba->cfg_use_msi != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) "8532 use_msi = %u ignoring cfg_irq_numa\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) phba->cfg_use_msi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) phba->irq_chann_mode = NORMAL_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831) /* Check if default setting was passed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) if (val == LPFC_IRQ_CHANN_DEF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) lpfc_assign_default_irq_chann(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) if (phba->irq_chann_mode != NORMAL_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) aff_mask = &phba->sli4_hba.irq_aff_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838) if (cpumask_empty(aff_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) "8533 Could not identify CPUS for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) "mode %d, ignoring\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) phba->irq_chann_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) phba->irq_chann_mode = NORMAL_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) phba->cfg_irq_chann = cpumask_weight(aff_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) /* If no hyperthread mode, then set hdwq count to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) * aff_mask weight as well
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) if (phba->irq_chann_mode == NHT_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) phba->cfg_hdw_queue = phba->cfg_irq_chann;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) "8543 lpfc_irq_chann set to %u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) "(mode: %d)\n", phba->cfg_irq_chann,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857) phba->irq_chann_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) if (val > LPFC_IRQ_CHANN_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862) "8545 lpfc_irq_chann attribute cannot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) "be set to %u, allowed range is "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) "[%u,%u]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) LPFC_IRQ_CHANN_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) LPFC_IRQ_CHANN_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) phba->cfg_irq_chann = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) * lpfc_irq_chann_show - Display value of irq_chann
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) * @buf: on return contains a string with the list sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) lpfc_irq_chann_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) return scnprintf(buf, PAGE_SIZE, "%u\n", phba->cfg_irq_chann);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) static DEVICE_ATTR_RO(lpfc_irq_chann);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) # lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) # 0 = HBA resets disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) # 1 = HBA resets enabled (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) # 2 = HBA reset via PCI bus reset enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) # Value range is [0,2]. Default value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) LPFC_ATTR_RW(enable_hba_reset, 1, 0, 2, "Enable HBA resets from the driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908) # lpfc_enable_hba_heartbeat: Disable HBA heartbeat timer..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) # 0 = HBA Heartbeat disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) # 1 = HBA Heartbeat enabled (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911) # Value range is [0,1]. Default value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) LPFC_ATTR_R(enable_hba_heartbeat, 0, 0, 1, "Enable HBA Heartbeat.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) # lpfc_EnableXLane: Enable Express Lane Feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917) # 0x0 Express Lane Feature disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) # 0x1 Express Lane Feature enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) # Value range is [0,1]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) LPFC_ATTR_R(EnableXLane, 0, 0, 1, "Enable Express Lane Feature.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) # lpfc_XLanePriority: Define CS_CTL priority for Express Lane Feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) # 0x0 - 0x7f = CS_CTL field in FC header (high 7 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) # Value range is [0x0,0x7f]. Default value is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928) LPFC_ATTR_RW(XLanePriority, 0, 0x0, 0x7f, "CS_CTL for Express Lane Feature.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931) # lpfc_enable_bg: Enable BlockGuard (Emulex's Implementation of T10-DIF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) # 0 = BlockGuard disabled (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) # 1 = BlockGuard enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) # Value range is [0,1]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) # lpfc_prot_mask: i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) # - Bit mask of host protection capabilities used to register with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) # SCSI mid-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) # - Only meaningful if BG is turned on (lpfc_enable_bg=1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) # - Allows you to ultimately specify which profiles to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) # - Default will result in registering capabilities for all profiles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) # - SHOST_DIF_TYPE1_PROTECTION 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) # HBA supports T10 DIF Type 1: HBA to Target Type 1 Protection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) # - SHOST_DIX_TYPE0_PROTECTION 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948) # HBA supports DIX Type 0: Host to HBA protection only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) # - SHOST_DIX_TYPE1_PROTECTION 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) # HBA supports DIX Type 1: Host to HBA Type 1 protection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) LPFC_ATTR(prot_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) (SHOST_DIF_TYPE1_PROTECTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955) SHOST_DIX_TYPE0_PROTECTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) SHOST_DIX_TYPE1_PROTECTION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) (SHOST_DIF_TYPE1_PROTECTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) SHOST_DIX_TYPE0_PROTECTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) SHOST_DIX_TYPE1_PROTECTION),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) "T10-DIF host protection capabilities mask");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) # lpfc_prot_guard: i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) # - Bit mask of protection guard types to register with the SCSI mid-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) # - Guard types are currently either 1) T10-DIF CRC 2) IP checksum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967) # - Allows you to ultimately specify which profiles to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) # - Default will result in registering capabilities for all guard types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) LPFC_ATTR(prot_guard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) SHOST_DIX_GUARD_IP, SHOST_DIX_GUARD_CRC, SHOST_DIX_GUARD_IP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) "T10-DIF host protection guard type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) * Delay initial NPort discovery when Clean Address bit is cleared in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) * FLOGI/FDISC accept and FCID/Fabric name/Fabric portname is changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) * This parameter can have value 0 or 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) * When this parameter is set to 0, no delay is added to the initial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) * discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) * When this parameter is set to non-zero value, initial Nport discovery is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) * delayed by ra_tov seconds when Clean Address bit is cleared in FLOGI/FDISC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) * accept and FCID/Fabric name/Fabric portname is changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984) * Driver always delay Nport discovery for subsequent FLOGI/FDISC completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) * when Clean Address bit is cleared in FLOGI/FDISC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) * accept and FCID/Fabric name/Fabric portname is changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) * Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) LPFC_ATTR(delay_discovery, 0, 0, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) "Delay NPort discovery when Clean Address bit is cleared.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) * lpfc_sg_seg_cnt - Initial Maximum DMA Segment Count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) * This value can be set to values between 64 and 4096. The default value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) * is 64, but may be increased to allow for larger Max I/O sizes. The scsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) * and nvme layers will allow I/O sizes up to (MAX_SEG_COUNT * SEG_SIZE).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) * Because of the additional overhead involved in setting up T10-DIF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998) * this parameter will be limited to 128 if BlockGuard is enabled under SLI4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) * and will be limited to 512 if BlockGuard is enabled under SLI3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) static uint lpfc_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002) module_param(lpfc_sg_seg_cnt, uint, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) MODULE_PARM_DESC(lpfc_sg_seg_cnt, "Max Scatter Gather Segment Count");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006) * lpfc_sg_seg_cnt_show - Display the scatter/gather list sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) * configured for the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) * @dev: class converted to a Scsi_host structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) * @attr: device attribute, not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) * @buf: on return contains a string with the list sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015) lpfc_sg_seg_cnt_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023) len = scnprintf(buf, PAGE_SIZE, "SGL sz: %d total SGEs: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) phba->cfg_sg_dma_buf_size, phba->cfg_total_seg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) "Cfg: %d SCSI: %d NVME: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) phba->cfg_sg_seg_cnt, phba->cfg_scsi_seg_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) phba->cfg_nvme_seg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) static DEVICE_ATTR_RO(lpfc_sg_seg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) * lpfc_sg_seg_cnt_init - Set the hba sg_seg_cnt initial value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) * @val: contains the initial value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) * Validates the initial value is within range and assigns it to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) * adapter. If not in range, an error message is posted and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) * default value is assigned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) * zero if value is in range and is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) * -EINVAL if value was out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) lpfc_sg_seg_cnt_init(struct lpfc_hba *phba, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) if (val >= LPFC_MIN_SG_SEG_CNT && val <= LPFC_MAX_SG_SEG_CNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) phba->cfg_sg_seg_cnt = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) "0409 "LPFC_DRIVER_NAME"_sg_seg_cnt attribute cannot "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) "be set to %d, allowed range is [%d, %d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) val, LPFC_MIN_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060) phba->cfg_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) * lpfc_enable_mds_diags: Enable MDS Diagnostics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) * 0 = MDS Diagnostics disabled (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) * 1 = MDS Diagnostics enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) * Value range is [0,1]. Default value is 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) LPFC_ATTR_RW(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) * lpfc_ras_fwlog_buffsize: Firmware logging host buffer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) * 0 = Disable firmware logging (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) * [1-4] = Multiple of 1/4th Mb of host memory for FW logging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) * Value range [0..4]. Default value is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) LPFC_ATTR(ras_fwlog_buffsize, 0, 0, 4, "Host memory for FW logging");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) lpfc_param_show(ras_fwlog_buffsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082) lpfc_ras_fwlog_buffsize_set(struct lpfc_hba *phba, uint val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085) enum ras_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) if (!lpfc_rangecheck(val, 0, 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) if (phba->cfg_ras_fwlog_buffsize == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) if (phba->cfg_ras_fwlog_func != PCI_FUNC(phba->pcidev->devfn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) state = phba->ras_fwlog.state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100) if (state == REG_INPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "6147 RAS Logging "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) "registration is in progress\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106) /* For disable logging: stop the logs and free the DMA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) * For ras_fwlog_buffsize size change we still need to free and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) * reallocate the DMA in lpfc_sli4_ras_fwlog_init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) phba->cfg_ras_fwlog_buffsize = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) if (state == ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) lpfc_ras_stop_fwlog(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) lpfc_sli4_ras_dma_free(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) lpfc_sli4_ras_init(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) if (phba->ras_fwlog.ras_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) ret = lpfc_sli4_ras_fwlog_init(phba, phba->cfg_ras_fwlog_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) LPFC_RAS_ENABLE_LOGGING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) lpfc_param_store(ras_fwlog_buffsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) static DEVICE_ATTR_RW(lpfc_ras_fwlog_buffsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) * lpfc_ras_fwlog_level: Firmware logging verbosity level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) * Valid only if firmware logging is enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) * 0(Least Verbosity) 4 (most verbosity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) * Value range is [0..4]. Default value is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) LPFC_ATTR_RW(ras_fwlog_level, 0, 0, 4, "Firmware Logging Level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) * lpfc_ras_fwlog_func: Firmware logging enabled on function number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136) * Default function which has RAS support : 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) * Value Range is [0..7].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) * FW logging is a global action and enablement is via a specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) * port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) LPFC_ATTR_RW(ras_fwlog_func, 0, 0, 7, "Firmware Logging Enabled on Function");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) * lpfc_enable_bbcr: Enable BB Credit Recovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) * 0 = BB Credit Recovery disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) * 1 = BB Credit Recovery enabled (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) * Value range is [0,1]. Default value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) * lpfc_enable_dpp: Enable DPP on G7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) * 0 = DPP on G7 disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) * 1 = DPP on G7 enabled (default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155) * Value range is [0,1]. Default value is 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157) LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) struct device_attribute *lpfc_hba_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) &dev_attr_nvme_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) &dev_attr_scsi_stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) &dev_attr_bg_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) &dev_attr_bg_guard_err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) &dev_attr_bg_apptag_err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) &dev_attr_bg_reftag_err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) &dev_attr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) &dev_attr_serialnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168) &dev_attr_modeldesc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) &dev_attr_modelname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) &dev_attr_programtype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) &dev_attr_portnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) &dev_attr_fwrev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) &dev_attr_hdw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) &dev_attr_option_rom_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) &dev_attr_link_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) &dev_attr_num_discovered_ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) &dev_attr_menlo_mgmt_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) &dev_attr_lpfc_drvr_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) &dev_attr_lpfc_enable_fip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) &dev_attr_lpfc_temp_sensor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) &dev_attr_lpfc_log_verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) &dev_attr_lpfc_lun_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) &dev_attr_lpfc_tgt_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) &dev_attr_lpfc_hba_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) &dev_attr_lpfc_peer_port_login,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) &dev_attr_lpfc_nodev_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) &dev_attr_lpfc_devloss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188) &dev_attr_lpfc_enable_fc4_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) &dev_attr_lpfc_fcp_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) &dev_attr_lpfc_use_adisc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191) &dev_attr_lpfc_first_burst_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) &dev_attr_lpfc_ack0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) &dev_attr_lpfc_xri_rebalancing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194) &dev_attr_lpfc_topology,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195) &dev_attr_lpfc_scan_down,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196) &dev_attr_lpfc_link_speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) &dev_attr_lpfc_fcp_io_sched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198) &dev_attr_lpfc_ns_query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) &dev_attr_lpfc_fcp2_no_tgt_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) &dev_attr_lpfc_cr_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201) &dev_attr_lpfc_cr_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202) &dev_attr_lpfc_multi_ring_support,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) &dev_attr_lpfc_multi_ring_rctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) &dev_attr_lpfc_multi_ring_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) &dev_attr_lpfc_fdmi_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) &dev_attr_lpfc_enable_SmartSAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) &dev_attr_lpfc_max_luns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) &dev_attr_lpfc_enable_npiv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) &dev_attr_lpfc_fcf_failover_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210) &dev_attr_lpfc_enable_rrq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) &dev_attr_nport_evt_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) &dev_attr_board_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) &dev_attr_max_vpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) &dev_attr_used_vpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) &dev_attr_max_rpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) &dev_attr_used_rpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217) &dev_attr_max_xri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) &dev_attr_used_xri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) &dev_attr_npiv_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220) &dev_attr_issue_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) &dev_attr_lpfc_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) &dev_attr_lpfc_poll_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) &dev_attr_lpfc_task_mgmt_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) &dev_attr_lpfc_use_msi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225) &dev_attr_lpfc_nvme_oas,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) &dev_attr_lpfc_nvme_embed_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) &dev_attr_lpfc_fcp_imax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) &dev_attr_lpfc_force_rscn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229) &dev_attr_lpfc_cq_poll_threshold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) &dev_attr_lpfc_cq_max_proc_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231) &dev_attr_lpfc_fcp_cpu_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232) &dev_attr_lpfc_fcp_mq_threshold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233) &dev_attr_lpfc_hdw_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) &dev_attr_lpfc_irq_chann,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) &dev_attr_lpfc_suppress_rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236) &dev_attr_lpfc_nvmet_mrq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) &dev_attr_lpfc_nvmet_mrq_post,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) &dev_attr_lpfc_nvme_enable_fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) &dev_attr_lpfc_nvmet_fb_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) &dev_attr_lpfc_enable_bg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) &dev_attr_lpfc_soft_wwnn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) &dev_attr_lpfc_soft_wwpn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243) &dev_attr_lpfc_soft_wwn_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) &dev_attr_lpfc_enable_hba_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245) &dev_attr_lpfc_enable_hba_heartbeat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) &dev_attr_lpfc_EnableXLane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) &dev_attr_lpfc_XLanePriority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248) &dev_attr_lpfc_xlane_lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249) &dev_attr_lpfc_xlane_tgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) &dev_attr_lpfc_xlane_vpt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) &dev_attr_lpfc_xlane_lun_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252) &dev_attr_lpfc_xlane_lun_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253) &dev_attr_lpfc_xlane_priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) &dev_attr_lpfc_sg_seg_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255) &dev_attr_lpfc_max_scsicmpl_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256) &dev_attr_lpfc_stat_data_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257) &dev_attr_lpfc_aer_support,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258) &dev_attr_lpfc_aer_state_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259) &dev_attr_lpfc_sriov_nr_virtfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260) &dev_attr_lpfc_req_fw_upgrade,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6261) &dev_attr_lpfc_suppress_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262) &dev_attr_iocb_hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263) &dev_attr_pls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264) &dev_attr_pt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) &dev_attr_txq_hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266) &dev_attr_txcmplq_hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267) &dev_attr_lpfc_sriov_hw_max_virtfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) &dev_attr_protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269) &dev_attr_lpfc_xlane_supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270) &dev_attr_lpfc_enable_mds_diags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271) &dev_attr_lpfc_ras_fwlog_buffsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272) &dev_attr_lpfc_ras_fwlog_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273) &dev_attr_lpfc_ras_fwlog_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) &dev_attr_lpfc_enable_bbcr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275) &dev_attr_lpfc_enable_dpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) struct device_attribute *lpfc_vport_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280) &dev_attr_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281) &dev_attr_link_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282) &dev_attr_num_discovered_ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) &dev_attr_lpfc_drvr_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284) &dev_attr_lpfc_log_verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285) &dev_attr_lpfc_lun_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286) &dev_attr_lpfc_tgt_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) &dev_attr_lpfc_nodev_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) &dev_attr_lpfc_devloss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289) &dev_attr_lpfc_hba_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290) &dev_attr_lpfc_peer_port_login,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) &dev_attr_lpfc_restrict_login,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) &dev_attr_lpfc_fcp_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293) &dev_attr_lpfc_use_adisc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294) &dev_attr_lpfc_first_burst_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295) &dev_attr_lpfc_max_luns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296) &dev_attr_nport_evt_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) &dev_attr_npiv_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298) &dev_attr_lpfc_enable_da_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299) &dev_attr_lpfc_max_scsicmpl_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300) &dev_attr_lpfc_stat_data_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) &dev_attr_lpfc_static_vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306) * sysfs_ctlreg_write - Write method for writing to ctlreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) * @filp: open sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308) * @kobj: kernel kobject that contains the kernel class device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309) * @bin_attr: kernel attributes passed to us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) * @buf: contains the data to be written to the adapter IOREG space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) * @off: offset into buffer to beginning of data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312) * @count: bytes to transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315) * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316) * Uses the adapter io control registers to send buf contents to the adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) * -ERANGE off and count combo out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320) * -EINVAL off, count or buff address invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) * -EPERM adapter is offline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322) * value of count, buf contents written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325) sysfs_ctlreg_write(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326) struct bin_attribute *bin_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327) char *buf, loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) size_t buf_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330) struct device *dev = container_of(kobj, struct device, kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335) if (phba->sli_rev >= LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338) if ((off + count) > FF_REG_AREA_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341) if (count <= LPFC_REG_WRITE_KEY_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344) if (off % 4 || count % 4 || (unsigned long)buf % 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347) /* This is to protect HBA registers from accidental writes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348) if (memcmp(buf, LPFC_REG_WRITE_KEY, LPFC_REG_WRITE_KEY_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351) if (!(vport->fc_flag & FC_OFFLINE_MODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6354) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355) for (buf_off = 0; buf_off < count - LPFC_REG_WRITE_KEY_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) buf_off += sizeof(uint32_t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) writel(*((uint32_t *)(buf + buf_off + LPFC_REG_WRITE_KEY_SIZE)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358) phba->ctrl_regs_memmap_p + off + buf_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366) * sysfs_ctlreg_read - Read method for reading from ctlreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367) * @filp: open sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) * @kobj: kernel kobject that contains the kernel class device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369) * @bin_attr: kernel attributes passed to us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370) * @buf: if successful contains the data from the adapter IOREG space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) * @off: offset into buffer to beginning of data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372) * @count: bytes to transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375) * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376) * Uses the adapter io control registers to read data into buf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379) * -ERANGE off and count combo out of range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380) * -EINVAL off, count or buff address invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381) * value of count, buf contents read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384) sysfs_ctlreg_read(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385) struct bin_attribute *bin_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386) char *buf, loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6388) size_t buf_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) uint32_t * tmp_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390) struct device *dev = container_of(kobj, struct device, kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395) if (phba->sli_rev >= LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398) if (off > FF_REG_AREA_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401) if ((off + count) > FF_REG_AREA_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) count = FF_REG_AREA_SIZE - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404) if (count == 0) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406) if (off % 4 || count % 4 || (unsigned long)buf % 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411) for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6412) tmp_ptr = (uint32_t *)(buf + buf_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413) *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421) static struct bin_attribute sysfs_ctlreg_attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422) .attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) .name = "ctlreg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424) .mode = S_IRUSR | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426) .size = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427) .read = sysfs_ctlreg_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428) .write = sysfs_ctlreg_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432) * sysfs_mbox_write - Write method for writing information via mbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433) * @filp: open sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434) * @kobj: kernel kobject that contains the kernel class device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) * @bin_attr: kernel attributes passed to us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436) * @buf: contains the data to be written to sysfs mbox.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437) * @off: offset into buffer to beginning of data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438) * @count: bytes to transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441) * Deprecated function. All mailbox access from user space is performed via the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442) * bsg interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445) * -EPERM operation not permitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448) sysfs_mbox_write(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449) struct bin_attribute *bin_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) char *buf, loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456) * sysfs_mbox_read - Read method for reading information via mbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457) * @filp: open sysfs file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458) * @kobj: kernel kobject that contains the kernel class device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459) * @bin_attr: kernel attributes passed to us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) * @buf: contains the data to be read from sysfs mbox.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461) * @off: offset into buffer to beginning of data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462) * @count: bytes to transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465) * Deprecated function. All mailbox access from user space is performed via the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) * bsg interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469) * -EPERM operation not permitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472) sysfs_mbox_read(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473) struct bin_attribute *bin_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474) char *buf, loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479) static struct bin_attribute sysfs_mbox_attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480) .attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481) .name = "mbox",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) .mode = S_IRUSR | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484) .size = MAILBOX_SYSFS_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485) .read = sysfs_mbox_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) .write = sysfs_mbox_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490) * lpfc_alloc_sysfs_attr - Creates the ctlreg and mbox entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) * @vport: address of lpfc vport structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) * Return codes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494) * zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495) * error return code from sysfs_create_bin_file()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498) lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503) error = sysfs_create_bin_file(&shost->shost_dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) &sysfs_drvr_stat_data_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506) /* Virtual ports do not need ctrl_reg and mbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507) if (error || vport->port_type == LPFC_NPIV_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) error = sysfs_create_bin_file(&shost->shost_dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) &sysfs_ctlreg_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) goto out_remove_stat_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515) error = sysfs_create_bin_file(&shost->shost_dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516) &sysfs_mbox_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) goto out_remove_ctlreg_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521) out_remove_ctlreg_attr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522) sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523) out_remove_stat_attr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) sysfs_remove_bin_file(&shost->shost_dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525) &sysfs_drvr_stat_data_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531) * lpfc_free_sysfs_attr - Removes the ctlreg and mbox entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532) * @vport: address of lpfc vport structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535) lpfc_free_sysfs_attr(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) sysfs_remove_bin_file(&shost->shost_dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539) &sysfs_drvr_stat_data_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540) /* Virtual ports do not need ctrl_reg and mbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) if (vport->port_type == LPFC_NPIV_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543) sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544) sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548) * Dynamic FC Host Attributes Support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552) * lpfc_get_host_symbolic_name - Copy symbolic name into the scsi host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553) * @shost: kernel scsi host pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) lpfc_get_host_symbolic_name(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558) struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560) lpfc_vport_symbolic_node_name(vport, fc_host_symbolic_name(shost),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561) sizeof fc_host_symbolic_name(shost));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565) * lpfc_get_host_port_id - Copy the vport DID into the scsi host port id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) * @shost: kernel scsi host pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569) lpfc_get_host_port_id(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) /* note: fc_myDID already in cpu endianness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574) fc_host_port_id(shost) = vport->fc_myDID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578) * lpfc_get_host_port_type - Set the value of the scsi host port type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579) * @shost: kernel scsi host pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582) lpfc_get_host_port_type(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589) if (vport->port_type == LPFC_NPIV_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591) } else if (lpfc_is_link_up(phba)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) if (vport->fc_flag & FC_PUBLIC_LOOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594) fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598) if (vport->fc_flag & FC_FABRIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601) fc_host_port_type(shost) = FC_PORTTYPE_PTP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610) * lpfc_get_host_port_state - Set the value of the scsi host port state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611) * @shost: kernel scsi host pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) lpfc_get_host_port_state(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621) if (vport->fc_flag & FC_OFFLINE_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622) fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) switch (phba->link_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) case LPFC_LINK_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626) case LPFC_LINK_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627) fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629) case LPFC_LINK_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) case LPFC_CLEAR_LA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631) case LPFC_HBA_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632) /* Links up, reports port state accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) if (vport->port_state < LPFC_VPORT_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) fc_host_port_state(shost) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635) FC_PORTSTATE_BYPASSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637) fc_host_port_state(shost) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) FC_PORTSTATE_ONLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) case LPFC_HBA_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653) * lpfc_get_host_speed - Set the value of the scsi host speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654) * @shost: kernel scsi host pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657) lpfc_get_host_speed(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664) if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) switch(phba->fc_linkspeed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) case LPFC_LINK_SPEED_1GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667) fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669) case LPFC_LINK_SPEED_2GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670) fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672) case LPFC_LINK_SPEED_4GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673) fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675) case LPFC_LINK_SPEED_8GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676) fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678) case LPFC_LINK_SPEED_10GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679) fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681) case LPFC_LINK_SPEED_16GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682) fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684) case LPFC_LINK_SPEED_32GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685) fc_host_speed(shost) = FC_PORTSPEED_32GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687) case LPFC_LINK_SPEED_64GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688) fc_host_speed(shost) = FC_PORTSPEED_64GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690) case LPFC_LINK_SPEED_128GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691) fc_host_speed(shost) = FC_PORTSPEED_128GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694) fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) } else if (lpfc_is_link_up(phba) && (phba->hba_flag & HBA_FCOE_MODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698) switch (phba->fc_linkspeed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699) case LPFC_ASYNC_LINK_SPEED_1GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700) fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702) case LPFC_ASYNC_LINK_SPEED_10GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705) case LPFC_ASYNC_LINK_SPEED_20GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706) fc_host_speed(shost) = FC_PORTSPEED_20GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708) case LPFC_ASYNC_LINK_SPEED_25GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709) fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) case LPFC_ASYNC_LINK_SPEED_40GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712) fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714) case LPFC_ASYNC_LINK_SPEED_100GBPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715) fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718) fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722) fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6727) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6728) * lpfc_get_host_fabric_name - Set the value of the scsi host fabric name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6729) * @shost: kernel scsi host pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732) lpfc_get_host_fabric_name (struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736) u64 node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) if ((vport->port_state > LPFC_FLOGI) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741) ((vport->fc_flag & FC_FABRIC) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742) ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) (vport->fc_flag & FC_PUBLIC_LOOP))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) node_name = wwn_to_u64(phba->fc_fabparam.nodeName.u.wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746) /* fabric is local port if there is no F/FL_Port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747) node_name = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) fc_host_fabric_name(shost) = node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755) * lpfc_get_stats - Return statistical information about the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756) * @shost: kernel scsi host pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759) * NULL on error for link down, no mbox pool, sli2 active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760) * management not allowed, memory allocation error, or mbox error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763) * NULL for error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764) * address of the adapter host statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766) static struct fc_host_statistics *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767) lpfc_get_stats(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771) struct lpfc_sli *psli = &phba->sli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772) struct fc_host_statistics *hs = &phba->link_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) struct lpfc_lnk_stat * lso = &psli->lnk_stat_offsets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) LPFC_MBOXQ_t *pmboxq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) MAILBOX_t *pmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779) * prevent udev from issuing mailbox commands until the port is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780) * configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782) if (phba->link_state < LPFC_LINK_DOWN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783) !phba->mbox_mem_pool ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784) (phba->sli.sli_flag & LPFC_SLI_ACTIVE) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6787) if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6788) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790) pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791) if (!pmboxq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795) pmb = &pmboxq->u.mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) pmb->mbxCommand = MBX_READ_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) pmb->mbxOwner = OWN_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798) pmboxq->ctx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) pmboxq->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801) if (vport->fc_flag & FC_OFFLINE_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803) if (rc != MBX_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808) rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) if (rc != MBX_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810) if (rc != MBX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816) memset(hs, 0, sizeof (struct fc_host_statistics));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818) hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820) * The MBX_READ_STATUS returns tx_k_bytes which has to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) * converted to words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) hs->tx_words = (uint64_t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) ((uint64_t)pmb->un.varRdStatus.xmitByteCnt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825) * (uint64_t)256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827) hs->rx_words = (uint64_t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) ((uint64_t)pmb->un.varRdStatus.rcvByteCnt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) * (uint64_t)256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831) memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) pmb->mbxCommand = MBX_READ_LNK_STAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) pmb->mbxOwner = OWN_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834) pmboxq->ctx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835) pmboxq->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837) if (vport->fc_flag & FC_OFFLINE_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839) if (rc != MBX_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844) rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) if (rc != MBX_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846) if (rc != MBX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854) hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857) hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858) hs->error_frames = pmb->un.varRdLnk.crcCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860) hs->link_failure_count -= lso->link_failure_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) hs->loss_of_sync_count -= lso->loss_of_sync_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) hs->loss_of_signal_count -= lso->loss_of_signal_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863) hs->prim_seq_protocol_err_count -= lso->prim_seq_protocol_err_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864) hs->invalid_tx_word_count -= lso->invalid_tx_word_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865) hs->invalid_crc_count -= lso->invalid_crc_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866) hs->error_frames -= lso->error_frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868) if (phba->hba_flag & HBA_FCOE_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869) hs->lip_count = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) hs->nos_count = (phba->link_events >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871) hs->nos_count -= lso->link_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872) } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873) hs->lip_count = (phba->fc_eventTag >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) hs->lip_count -= lso->link_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875) hs->nos_count = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877) hs->lip_count = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878) hs->nos_count = (phba->fc_eventTag >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) hs->nos_count -= lso->link_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882) hs->dumped_frames = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884) hs->seconds_since_last_reset = ktime_get_seconds() - psli->stats_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) return hs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) * lpfc_reset_stats - Copy the adapter link stats information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893) * @shost: kernel scsi host pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) lpfc_reset_stats(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900) struct lpfc_sli *psli = &phba->sli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901) struct lpfc_lnk_stat *lso = &psli->lnk_stat_offsets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902) LPFC_MBOXQ_t *pmboxq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903) MAILBOX_t *pmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906) if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) if (!pmboxq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912) memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) pmb = &pmboxq->u.mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) pmb->mbxCommand = MBX_READ_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916) pmb->mbxOwner = OWN_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) pmb->un.varWords[0] = 0x1; /* reset request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918) pmboxq->ctx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) pmboxq->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) if ((vport->fc_flag & FC_OFFLINE_MODE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922) (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) if (rc != MBX_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929) rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) if (rc != MBX_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931) if (rc != MBX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937) memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938) pmb->mbxCommand = MBX_READ_LNK_STAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) pmb->mbxOwner = OWN_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940) pmboxq->ctx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941) pmboxq->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) if ((vport->fc_flag & FC_OFFLINE_MODE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944) (!(psli->sli_flag & LPFC_SLI_ACTIVE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945) rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946) if (rc != MBX_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951) rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952) if (rc != MBX_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953) if (rc != MBX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959) lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) lso->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961) lso->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962) lso->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963) lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965) lso->error_frames = pmb->un.varRdLnk.crcCnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966) if (phba->hba_flag & HBA_FCOE_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967) lso->link_events = (phba->link_events >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) lso->link_events = (phba->fc_eventTag >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971) psli->stats_start = ktime_get_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973) mempool_free(pmboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979) * The LPFC driver treats linkdown handling as target loss events so there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6980) * are no sysfs handlers for link_down_tmo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6981) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6983) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6984) * lpfc_get_node_by_target - Return the nodelist for a target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6985) * @starget: kernel scsi target pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6986) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6987) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6988) * address of the node list if found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6989) * NULL target not found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6990) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6991) static struct lpfc_nodelist *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6992) lpfc_get_node_by_target(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6994) struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6995) struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6996) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6998) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6999) /* Search for this, mapped, target ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7000) list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7001) if (NLP_CHK_NODE_ACT(ndlp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7002) ndlp->nlp_state == NLP_STE_MAPPED_NODE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7003) starget->id == ndlp->nlp_sid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7004) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7005) return ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7008) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7009) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7012) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7013) * lpfc_get_starget_port_id - Set the target port id to the ndlp DID or -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7014) * @starget: kernel scsi target pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7015) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7016) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7017) lpfc_get_starget_port_id(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7019) struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7021) fc_starget_port_id(starget) = ndlp ? ndlp->nlp_DID : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7024) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7025) * lpfc_get_starget_node_name - Set the target node name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7026) * @starget: kernel scsi target pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7027) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7028) * Description: Set the target node name to the ndlp node name wwn or zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7029) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7030) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7031) lpfc_get_starget_node_name(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7033) struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7035) fc_starget_node_name(starget) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7036) ndlp ? wwn_to_u64(ndlp->nlp_nodename.u.wwn) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7039) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7040) * lpfc_get_starget_port_name - Set the target port name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7041) * @starget: kernel scsi target pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7042) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7043) * Description: set the target port name to the ndlp port name wwn or zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7044) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7045) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7046) lpfc_get_starget_port_name(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7048) struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7050) fc_starget_port_name(starget) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7051) ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7054) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7055) * lpfc_set_rport_loss_tmo - Set the rport dev loss tmo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7056) * @rport: fc rport address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7057) * @timeout: new value for dev loss tmo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7058) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7059) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7060) * If timeout is non zero set the dev_loss_tmo to timeout, else set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7061) * dev_loss_tmo to one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7062) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7063) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7064) lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7066) struct lpfc_rport_data *rdata = rport->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7067) struct lpfc_nodelist *ndlp = rdata->pnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7068) #if (IS_ENABLED(CONFIG_NVME_FC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7069) struct lpfc_nvme_rport *nrport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7070) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7072) if (timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7073) rport->dev_loss_tmo = timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7074) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7075) rport->dev_loss_tmo = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7077) if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7078) dev_info(&rport->dev, "Cannot find remote node to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7079) "set rport dev loss tmo, port_id x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7080) rport->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7081) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7084) #if (IS_ENABLED(CONFIG_NVME_FC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7085) nrport = lpfc_ndlp_get_nrport(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7087) if (nrport && nrport->remoteport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7088) nvme_fc_set_remoteport_devloss(nrport->remoteport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7089) rport->dev_loss_tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7090) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7093) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7094) * lpfc_rport_show_function - Return rport target information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7095) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7096) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7097) * Macro that uses field to generate a function with the name lpfc_show_rport_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7098) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7099) * lpfc_show_rport_##field: returns the bytes formatted in buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7100) * @cdev: class converted to an fc_rport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7101) * @buf: on return contains the target_field or zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7103) * Returns: size of formatted string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7104) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7105) #define lpfc_rport_show_function(field, format_string, sz, cast) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7106) static ssize_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7107) lpfc_show_rport_##field (struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7108) struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7109) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7110) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7111) struct fc_rport *rport = transport_class_to_rport(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7112) struct lpfc_rport_data *rdata = rport->hostdata; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7113) return scnprintf(buf, sz, format_string, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7114) (rdata->target) ? cast rdata->target->field : 0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7117) #define lpfc_rport_rd_attr(field, format_string, sz) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7118) lpfc_rport_show_function(field, format_string, sz, ) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7119) static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7121) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7122) * lpfc_set_vport_symbolic_name - Set the vport's symbolic name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7123) * @fc_vport: The fc_vport who's symbolic name has been changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7125) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7126) * This function is called by the transport after the @fc_vport's symbolic name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7127) * has been changed. This function re-registers the symbolic name with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7128) * switch to propagate the change into the fabric if the vport is active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7129) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7130) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7131) lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7133) struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7135) if (vport->port_state == LPFC_VPORT_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7136) lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7139) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7140) * lpfc_hba_log_verbose_init - Set hba's log verbose level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7141) * @phba: Pointer to lpfc_hba struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7143) * This function is called by the lpfc_get_cfgparam() routine to set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7144) * module lpfc_log_verbose into the @phba cfg_log_verbose for use with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7145) * log message according to the module's lpfc_log_verbose parameter setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7146) * before hba port or vport created.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7147) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7148) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7149) lpfc_hba_log_verbose_init(struct lpfc_hba *phba, uint32_t verbose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7151) phba->cfg_log_verbose = verbose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7154) struct fc_function_template lpfc_transport_functions = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7155) /* fixed attributes the driver supports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7156) .show_host_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7157) .show_host_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7158) .show_host_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7159) .show_host_supported_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7160) .show_host_supported_speeds = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7161) .show_host_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7163) .get_host_symbolic_name = lpfc_get_host_symbolic_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7164) .show_host_symbolic_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7166) /* dynamic attributes the driver supports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7167) .get_host_port_id = lpfc_get_host_port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7168) .show_host_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7170) .get_host_port_type = lpfc_get_host_port_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7171) .show_host_port_type = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7173) .get_host_port_state = lpfc_get_host_port_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7174) .show_host_port_state = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7176) /* active_fc4s is shown but doesn't change (thus no get function) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7177) .show_host_active_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7179) .get_host_speed = lpfc_get_host_speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7180) .show_host_speed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7182) .get_host_fabric_name = lpfc_get_host_fabric_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7183) .show_host_fabric_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7186) * The LPFC driver treats linkdown handling as target loss events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7187) * so there are no sysfs handlers for link_down_tmo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7188) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7190) .get_fc_host_stats = lpfc_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7191) .reset_fc_host_stats = lpfc_reset_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7193) .dd_fcrport_size = sizeof(struct lpfc_rport_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7194) .show_rport_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7195) .show_rport_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7197) .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7198) .show_rport_dev_loss_tmo = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7200) .get_starget_port_id = lpfc_get_starget_port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7201) .show_starget_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7203) .get_starget_node_name = lpfc_get_starget_node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7204) .show_starget_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7206) .get_starget_port_name = lpfc_get_starget_port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7207) .show_starget_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7209) .issue_fc_host_lip = lpfc_issue_lip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7210) .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7211) .terminate_rport_io = lpfc_terminate_rport_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7213) .dd_fcvport_size = sizeof(struct lpfc_vport *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7215) .vport_disable = lpfc_vport_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7217) .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7219) .bsg_request = lpfc_bsg_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7220) .bsg_timeout = lpfc_bsg_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7221) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7223) struct fc_function_template lpfc_vport_transport_functions = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7224) /* fixed attributes the driver supports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7225) .show_host_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7226) .show_host_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7227) .show_host_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7228) .show_host_supported_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7229) .show_host_supported_speeds = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7230) .show_host_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7232) .get_host_symbolic_name = lpfc_get_host_symbolic_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7233) .show_host_symbolic_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7235) /* dynamic attributes the driver supports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7236) .get_host_port_id = lpfc_get_host_port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7237) .show_host_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7239) .get_host_port_type = lpfc_get_host_port_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7240) .show_host_port_type = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7242) .get_host_port_state = lpfc_get_host_port_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7243) .show_host_port_state = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7245) /* active_fc4s is shown but doesn't change (thus no get function) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7246) .show_host_active_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7248) .get_host_speed = lpfc_get_host_speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7249) .show_host_speed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7251) .get_host_fabric_name = lpfc_get_host_fabric_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7252) .show_host_fabric_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7255) * The LPFC driver treats linkdown handling as target loss events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7256) * so there are no sysfs handlers for link_down_tmo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7259) .get_fc_host_stats = lpfc_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7260) .reset_fc_host_stats = lpfc_reset_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7262) .dd_fcrport_size = sizeof(struct lpfc_rport_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7263) .show_rport_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7264) .show_rport_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7266) .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7267) .show_rport_dev_loss_tmo = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7269) .get_starget_port_id = lpfc_get_starget_port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7270) .show_starget_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7272) .get_starget_node_name = lpfc_get_starget_node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7273) .show_starget_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7275) .get_starget_port_name = lpfc_get_starget_port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7276) .show_starget_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7278) .dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7279) .terminate_rport_io = lpfc_terminate_rport_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7281) .vport_disable = lpfc_vport_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7283) .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7284) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7286) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7287) * lpfc_get_hba_function_mode - Used to determine the HBA function in FCoE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7288) * Mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7289) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7290) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7291) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7292) lpfc_get_hba_function_mode(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7294) /* If the adapter supports FCoE mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7295) switch (phba->pcidev->device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7296) case PCI_DEVICE_ID_SKYHAWK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7297) case PCI_DEVICE_ID_SKYHAWK_VF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7298) case PCI_DEVICE_ID_LANCER_FCOE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7299) case PCI_DEVICE_ID_LANCER_FCOE_VF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7300) case PCI_DEVICE_ID_ZEPHYR_DCSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7301) case PCI_DEVICE_ID_HORNET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7302) case PCI_DEVICE_ID_TIGERSHARK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7303) case PCI_DEVICE_ID_TOMCAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7304) phba->hba_flag |= HBA_FCOE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7306) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7307) /* for others, clear the flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7308) phba->hba_flag &= ~HBA_FCOE_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7312) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7313) * lpfc_get_cfgparam - Used during probe_one to init the adapter structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7314) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7315) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7316) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7317) lpfc_get_cfgparam(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7319) lpfc_hba_log_verbose_init(phba, lpfc_log_verbose);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7320) lpfc_fcp_io_sched_init(phba, lpfc_fcp_io_sched);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7321) lpfc_ns_query_init(phba, lpfc_ns_query);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7322) lpfc_fcp2_no_tgt_reset_init(phba, lpfc_fcp2_no_tgt_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7323) lpfc_cr_delay_init(phba, lpfc_cr_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7324) lpfc_cr_count_init(phba, lpfc_cr_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7325) lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7326) lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7327) lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7328) lpfc_ack0_init(phba, lpfc_ack0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7329) lpfc_xri_rebalancing_init(phba, lpfc_xri_rebalancing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7330) lpfc_topology_init(phba, lpfc_topology);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7331) lpfc_link_speed_init(phba, lpfc_link_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7332) lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7333) lpfc_task_mgmt_tmo_init(phba, lpfc_task_mgmt_tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7334) lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7335) lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7336) lpfc_enable_rrq_init(phba, lpfc_enable_rrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7337) lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7338) lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7339) lpfc_use_msi_init(phba, lpfc_use_msi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7340) lpfc_nvme_oas_init(phba, lpfc_nvme_oas);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7341) lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7342) lpfc_fcp_imax_init(phba, lpfc_fcp_imax);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7343) lpfc_force_rscn_init(phba, lpfc_force_rscn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7344) lpfc_cq_poll_threshold_init(phba, lpfc_cq_poll_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7345) lpfc_cq_max_proc_limit_init(phba, lpfc_cq_max_proc_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7346) lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7347) lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7348) lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7350) lpfc_EnableXLane_init(phba, lpfc_EnableXLane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7351) if (phba->sli_rev != LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7352) phba->cfg_EnableXLane = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7353) lpfc_XLanePriority_init(phba, lpfc_XLanePriority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7355) memset(phba->cfg_oas_tgt_wwpn, 0, (8 * sizeof(uint8_t)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7356) memset(phba->cfg_oas_vpt_wwpn, 0, (8 * sizeof(uint8_t)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7357) phba->cfg_oas_lun_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7358) phba->cfg_oas_lun_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7359) phba->cfg_oas_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7360) phba->cfg_oas_priority = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7361) lpfc_enable_bg_init(phba, lpfc_enable_bg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7362) lpfc_prot_mask_init(phba, lpfc_prot_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7363) lpfc_prot_guard_init(phba, lpfc_prot_guard);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7364) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7365) phba->cfg_poll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7366) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7367) phba->cfg_poll = lpfc_poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7369) /* Get the function mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7370) lpfc_get_hba_function_mode(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7372) /* BlockGuard allowed for FC only. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7373) if (phba->cfg_enable_bg && phba->hba_flag & HBA_FCOE_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7374) lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7375) "0581 BlockGuard feature not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7376) /* If set, clear the BlockGuard support param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7377) phba->cfg_enable_bg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7378) } else if (phba->cfg_enable_bg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7379) phba->sli3_options |= LPFC_SLI3_BG_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7382) lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7384) lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7385) lpfc_nvmet_mrq_init(phba, lpfc_nvmet_mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7386) lpfc_nvmet_mrq_post_init(phba, lpfc_nvmet_mrq_post);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7388) /* Initialize first burst. Target vs Initiator are different. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7389) lpfc_nvme_enable_fb_init(phba, lpfc_nvme_enable_fb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7390) lpfc_nvmet_fb_size_init(phba, lpfc_nvmet_fb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7391) lpfc_fcp_mq_threshold_init(phba, lpfc_fcp_mq_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7392) lpfc_hdw_queue_init(phba, lpfc_hdw_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7393) lpfc_irq_chann_init(phba, lpfc_irq_chann);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7394) lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7395) lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7397) if (phba->sli_rev != LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7398) /* NVME only supported on SLI4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7399) phba->nvmet_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7400) phba->cfg_nvmet_mrq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7401) phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7402) phba->cfg_enable_bbcr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7403) phba->cfg_xri_rebalancing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7404) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7405) /* We MUST have FCP support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7406) if (!(phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7407) phba->cfg_enable_fc4_type |= LPFC_ENABLE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7410) phba->cfg_auto_imax = (phba->cfg_fcp_imax) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7412) phba->cfg_enable_pbde = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7414) /* A value of 0 means use the number of CPUs found in the system */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7415) if (phba->cfg_hdw_queue == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7416) phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7417) if (phba->cfg_irq_chann == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7418) phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7419) if (phba->cfg_irq_chann > phba->cfg_hdw_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7420) phba->cfg_irq_chann = phba->cfg_hdw_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7422) phba->cfg_soft_wwnn = 0L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7423) phba->cfg_soft_wwpn = 0L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7424) lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7425) lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7426) lpfc_aer_support_init(phba, lpfc_aer_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7427) lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7428) lpfc_request_firmware_upgrade_init(phba, lpfc_req_fw_upgrade);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7429) lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7430) lpfc_delay_discovery_init(phba, lpfc_delay_discovery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7431) lpfc_sli_mode_init(phba, lpfc_sli_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7432) lpfc_enable_mds_diags_init(phba, lpfc_enable_mds_diags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7433) lpfc_ras_fwlog_buffsize_init(phba, lpfc_ras_fwlog_buffsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7434) lpfc_ras_fwlog_level_init(phba, lpfc_ras_fwlog_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7435) lpfc_ras_fwlog_func_init(phba, lpfc_ras_fwlog_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7437) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7440) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7441) * lpfc_nvme_mod_param_dep - Adjust module parameter value based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7442) * dependencies between protocols and roles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7443) * @phba: lpfc_hba pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7444) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7445) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7446) lpfc_nvme_mod_param_dep(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7448) int logit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7450) if (phba->cfg_hdw_queue > phba->sli4_hba.num_present_cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7451) phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7452) logit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7454) if (phba->cfg_irq_chann > phba->sli4_hba.num_present_cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7455) phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7456) logit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7458) if (phba->cfg_irq_chann > phba->cfg_hdw_queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7459) phba->cfg_irq_chann = phba->cfg_hdw_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7460) logit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7462) if (logit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7463) lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7464) "2006 Reducing Queues - CPU limitation: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7465) "IRQ %d HDWQ %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7466) phba->cfg_irq_chann,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7467) phba->cfg_hdw_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7469) if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7470) phba->nvmet_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7471) phba->cfg_enable_fc4_type &= ~LPFC_ENABLE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7473) lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7474) "6013 %s x%x fb_size x%x, fb_max x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7475) "NVME Target PRLI ACC enable_fb ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7476) phba->cfg_nvme_enable_fb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7477) phba->cfg_nvmet_fb_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7478) LPFC_NVMET_FB_SZ_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7480) if (phba->cfg_nvme_enable_fb == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7481) phba->cfg_nvmet_fb_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7482) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7483) if (phba->cfg_nvmet_fb_size > LPFC_NVMET_FB_SZ_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7484) phba->cfg_nvmet_fb_size = LPFC_NVMET_FB_SZ_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7487) if (!phba->cfg_nvmet_mrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7488) phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7490) /* Adjust lpfc_nvmet_mrq to avoid running out of WQE slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7491) if (phba->cfg_nvmet_mrq > phba->cfg_hdw_queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7492) phba->cfg_nvmet_mrq = phba->cfg_hdw_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7493) lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7494) "6018 Adjust lpfc_nvmet_mrq to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7495) phba->cfg_nvmet_mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7497) if (phba->cfg_nvmet_mrq > LPFC_NVMET_MRQ_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7498) phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7500) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7501) /* Not NVME Target mode. Turn off Target parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7502) phba->nvmet_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7503) phba->cfg_nvmet_mrq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7504) phba->cfg_nvmet_fb_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7508) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7509) * lpfc_get_vport_cfgparam - Used during port create, init the vport structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7510) * @vport: lpfc_vport pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7511) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7512) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7513) lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7515) lpfc_log_verbose_init(vport, lpfc_log_verbose);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7516) lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7517) lpfc_tgt_queue_depth_init(vport, lpfc_tgt_queue_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7518) lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7519) lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7520) lpfc_peer_port_login_init(vport, lpfc_peer_port_login);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7521) lpfc_restrict_login_init(vport, lpfc_restrict_login);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7522) lpfc_fcp_class_init(vport, lpfc_fcp_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7523) lpfc_use_adisc_init(vport, lpfc_use_adisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7524) lpfc_first_burst_size_init(vport, lpfc_first_burst_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7525) lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7526) lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7527) lpfc_max_luns_init(vport, lpfc_max_luns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7528) lpfc_scan_down_init(vport, lpfc_scan_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7529) lpfc_enable_da_id_init(vport, lpfc_enable_da_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7530) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7531) }