summaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc/lpfc_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_attr.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c199
1 files changed, 172 insertions, 27 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 3c534b3cfe91..54ee8ecec3b3 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
@@ -291,6 +291,138 @@ buffer_done:
return len;
}
+static ssize_t
+lpfc_vmid_info_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(dev);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
+ struct lpfc_hba *phba = vport->phba;
+ struct lpfc_vmid *vmp;
+ int len = 0, i, j, k, cpu;
+ char hxstr[LPFC_MAX_VMID_SIZE * 3] = {0};
+ struct timespec64 curr_tm;
+ struct lpfc_vmid_priority_range *vr;
+ u64 *lta, rct_acc = 0, max_lta = 0;
+ struct tm tm_val;
+
+ ktime_get_ts64(&curr_tm);
+
+ len += scnprintf(buf + len, PAGE_SIZE - len, "Key 'vmid':\n");
+
+ /* if enabled continue, else return */
+ if (lpfc_is_vmid_enabled(phba)) {
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "lpfc VMID Page: ON\n\n");
+ } else {
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "lpfc VMID Page: OFF\n\n");
+ return len;
+ }
+
+ /* if using priority tagging */
+ if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO) {
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "VMID priority ranges:\n");
+ vr = vport->vmid_priority.vmid_range;
+ for (i = 0; i < vport->vmid_priority.num_descriptors; ++i) {
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "\t[x%x - x%x], qos: x%x\n",
+ vr->low, vr->high, vr->qos);
+ vr++;
+ }
+ }
+
+ for (i = 0; i < phba->cfg_max_vmid; i++) {
+ vmp = &vport->vmid[i];
+ max_lta = 0;
+
+ /* only if the slot is used */
+ if (!(vmp->flag & LPFC_VMID_SLOT_USED) ||
+ !(vmp->flag & LPFC_VMID_REGISTERED))
+ continue;
+
+ /* if using priority tagging */
+ if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO) {
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "VEM ID: %02x:%02x:%02x:%02x:"
+ "%02x:%02x:%02x:%02x:%02x:%02x:"
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ vport->lpfc_vmid_host_uuid[0],
+ vport->lpfc_vmid_host_uuid[1],
+ vport->lpfc_vmid_host_uuid[2],
+ vport->lpfc_vmid_host_uuid[3],
+ vport->lpfc_vmid_host_uuid[4],
+ vport->lpfc_vmid_host_uuid[5],
+ vport->lpfc_vmid_host_uuid[6],
+ vport->lpfc_vmid_host_uuid[7],
+ vport->lpfc_vmid_host_uuid[8],
+ vport->lpfc_vmid_host_uuid[9],
+ vport->lpfc_vmid_host_uuid[10],
+ vport->lpfc_vmid_host_uuid[11],
+ vport->lpfc_vmid_host_uuid[12],
+ vport->lpfc_vmid_host_uuid[13],
+ vport->lpfc_vmid_host_uuid[14],
+ vport->lpfc_vmid_host_uuid[15]);
+ }
+
+ /* IO stats */
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "ID00 READs:%llx WRITEs:%llx\n",
+ vmp->io_rd_cnt,
+ vmp->io_wr_cnt);
+ for (j = 0, k = 0; j < strlen(vmp->host_vmid); j++, k += 3)
+ sprintf((char *)(hxstr + k), "%2x ", vmp->host_vmid[j]);
+ /* UUIDs */
+ len += scnprintf(buf + len, PAGE_SIZE - len, "UUID:\n");
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n", hxstr);
+
+ len += scnprintf(buf + len, PAGE_SIZE - len, "String (%s)\n",
+ vmp->host_vmid);
+
+ if (vport->phba->pport->vmid_flag & LPFC_VMID_TYPE_PRIO)
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "CS_CTL VMID: 0x%x\n",
+ vmp->un.cs_ctl_vmid);
+ else
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "Application id: 0x%x\n",
+ vmp->un.app_id);
+
+ /* calculate the last access time */
+ for_each_possible_cpu(cpu) {
+ lta = per_cpu_ptr(vmp->last_io_time, cpu);
+ if (!lta)
+ continue;
+
+ /* if last access time is less than timeout */
+ if (time_after((unsigned long)*lta, jiffies))
+ continue;
+
+ if (*lta > max_lta)
+ max_lta = *lta;
+ }
+
+ rct_acc = jiffies_to_msecs(jiffies - max_lta) / 1000;
+ /* current time */
+ time64_to_tm(ktime_get_real_seconds(),
+ -(sys_tz.tz_minuteswest * 60) - rct_acc, &tm_val);
+
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "Last Access Time :"
+ "%ld-%d-%dT%02d:%02d:%02d\n\n",
+ 1900 + tm_val.tm_year, tm_val.tm_mon + 1,
+ tm_val.tm_mday, tm_val.tm_hour,
+ tm_val.tm_min, tm_val.tm_sec);
+
+ if (len >= PAGE_SIZE)
+ return len;
+
+ memset(hxstr, 0, LPFC_MAX_VMID_SIZE * 3);
+ }
+ return len;
+}
+
/**
* lpfc_drvr_version_show - Return the Emulex driver string with version number
* @dev: class unused variable.
@@ -322,7 +454,7 @@ lpfc_enable_fip_show(struct device *dev, struct device_attribute *attr,
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba;
- if (phba->hba_flag & HBA_FIP_SUPPORT)
+ if (test_bit(HBA_FIP_SUPPORT, &phba->hba_flag))
return scnprintf(buf, PAGE_SIZE, "1\n");
else
return scnprintf(buf, PAGE_SIZE, "0\n");
@@ -1049,7 +1181,7 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
case LPFC_INIT_MBX_CMDS:
case LPFC_LINK_DOWN:
case LPFC_HBA_ERROR:
- if (phba->hba_flag & LINK_DISABLED)
+ if (test_bit(LINK_DISABLED, &phba->hba_flag))
len += scnprintf(buf + len, PAGE_SIZE-len,
"Link Down - User disabled\n");
else
@@ -1292,7 +1424,7 @@ lpfc_issue_lip(struct Scsi_Host *shost)
* it doesn't make any sense to allow issue_lip
*/
if (test_bit(FC_OFFLINE_MODE, &vport->fc_flag) ||
- (phba->hba_flag & LINK_DISABLED) ||
+ test_bit(LINK_DISABLED, &phba->hba_flag) ||
(phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO))
return -EPERM;
@@ -1831,6 +1963,7 @@ static int
lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out)
{
LPFC_MBOXQ_t *mbox = NULL;
+ u32 payload_len;
unsigned long val = 0;
char *pval = NULL;
int rc = 0;
@@ -1869,9 +2002,11 @@ lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out)
if (!mbox)
return -ENOMEM;
+ payload_len = sizeof(struct lpfc_mbx_set_trunk_mode) -
+ sizeof(struct lpfc_sli4_cfg_mhdr);
lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
LPFC_MBOX_OPCODE_FCOE_FC_SET_TRUNK_MODE,
- 12, LPFC_SLI4_MBX_EMBED);
+ payload_len, LPFC_SLI4_MBX_EMBED);
bf_set(lpfc_mbx_set_trunk_mode,
&mbox->u.mqe.un.set_trunk_mode,
@@ -1907,6 +2042,11 @@ lpfc_xcvr_data_show(struct device *dev, struct device_attribute *attr,
/* Get transceiver information */
rdp_context = kmalloc(sizeof(*rdp_context), GFP_KERNEL);
+ if (!rdp_context) {
+ len = scnprintf(buf, PAGE_SIZE - len,
+ "SPF info NA: alloc failure\n");
+ return len;
+ }
rc = lpfc_get_sfp_info_wait(phba, rdp_context);
if (rc) {
@@ -2570,7 +2710,7 @@ lpfc_poll_store(struct device *dev, struct device_attribute *attr,
(old_val & DISABLE_FCP_RING_INT))
{
spin_unlock_irq(&phba->hbalock);
- del_timer(&phba->fcp_poll_timer);
+ timer_delete(&phba->fcp_poll_timer);
spin_lock_irq(&phba->hbalock);
if (lpfc_readl(phba->HCregaddr, &creg_val)) {
spin_unlock_irq(&phba->hbalock);
@@ -3003,6 +3143,7 @@ static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL);
static DEVICE_ATTR(lpfc_xlane_supported, S_IRUGO, lpfc_oas_supported_show,
NULL);
static DEVICE_ATTR(cmf_info, 0444, lpfc_cmf_info_show, NULL);
+static DEVICE_ATTR_RO(lpfc_vmid_info);
#define WWN_SZ 8
/**
@@ -3635,7 +3776,8 @@ lpfc_pt_show(struct device *dev, struct device_attribute *attr, char *buf)
struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
return scnprintf(buf, PAGE_SIZE, "%d\n",
- (phba->hba_flag & HBA_PERSISTENT_TOPO) ? 1 : 0);
+ test_bit(HBA_PERSISTENT_TOPO,
+ &phba->hba_flag) ? 1 : 0);
}
static DEVICE_ATTR(pt, 0444,
lpfc_pt_show, NULL);
@@ -4205,8 +4347,8 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr,
&phba->sli4_hba.sli_intf);
if_type = bf_get(lpfc_sli_intf_if_type,
&phba->sli4_hba.sli_intf);
- if ((phba->hba_flag & HBA_PERSISTENT_TOPO ||
- (!phba->sli4_hba.pc_sli4_params.pls &&
+ if ((test_bit(HBA_PERSISTENT_TOPO, &phba->hba_flag) ||
+ (!phba->sli4_hba.pc_sli4_params.pls &&
(sli_family == LPFC_SLI_INTF_FAMILY_G6 ||
if_type == LPFC_SLI_INTF_IF_TYPE_6))) &&
val == 4) {
@@ -4309,7 +4451,7 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
if (if_type >= LPFC_SLI_INTF_IF_TYPE_2 &&
- phba->hba_flag & HBA_FORCED_LINK_SPEED)
+ test_bit(HBA_FORCED_LINK_SPEED, &phba->hba_flag))
return -EPERM;
if (!strncmp(buf, "nolip ", strlen("nolip "))) {
@@ -6108,6 +6250,7 @@ static struct attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_vmid_inactivity_timeout.attr,
&dev_attr_lpfc_vmid_app_header.attr,
&dev_attr_lpfc_vmid_priority_tagging.attr,
+ &dev_attr_lpfc_vmid_info.attr,
NULL,
};
@@ -6176,7 +6319,7 @@ const struct attribute_group *lpfc_vport_groups[] = {
**/
static ssize_t
sysfs_ctlreg_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
+ const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
size_t buf_off;
@@ -6235,7 +6378,7 @@ sysfs_ctlreg_write(struct file *filp, struct kobject *kobj,
**/
static ssize_t
sysfs_ctlreg_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
+ const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
size_t buf_off;
@@ -6271,14 +6414,14 @@ sysfs_ctlreg_read(struct file *filp, struct kobject *kobj,
return count;
}
-static struct bin_attribute sysfs_ctlreg_attr = {
+static const struct bin_attribute sysfs_ctlreg_attr = {
.attr = {
.name = "ctlreg",
.mode = S_IRUSR | S_IWUSR,
},
.size = 256,
- .read = sysfs_ctlreg_read,
- .write = sysfs_ctlreg_write,
+ .read_new = sysfs_ctlreg_read,
+ .write_new = sysfs_ctlreg_write,
};
/**
@@ -6299,7 +6442,7 @@ static struct bin_attribute sysfs_ctlreg_attr = {
**/
static ssize_t
sysfs_mbox_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
+ const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
return -EPERM;
@@ -6323,20 +6466,20 @@ sysfs_mbox_write(struct file *filp, struct kobject *kobj,
**/
static ssize_t
sysfs_mbox_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
+ const struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
return -EPERM;
}
-static struct bin_attribute sysfs_mbox_attr = {
+static const struct bin_attribute sysfs_mbox_attr = {
.attr = {
.name = "mbox",
.mode = S_IRUSR | S_IWUSR,
},
.size = MAILBOX_SYSFS_MAX,
- .read = sysfs_mbox_read,
- .write = sysfs_mbox_write,
+ .read_new = sysfs_mbox_read,
+ .write_new = sysfs_mbox_write,
};
/**
@@ -6497,7 +6640,8 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba;
- if ((lpfc_is_link_up(phba)) && (!(phba->hba_flag & HBA_FCOE_MODE))) {
+ if ((lpfc_is_link_up(phba)) &&
+ !test_bit(HBA_FCOE_MODE, &phba->hba_flag)) {
switch(phba->fc_linkspeed) {
case LPFC_LINK_SPEED_1GHZ:
fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
@@ -6533,7 +6677,8 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
break;
}
- } else if (lpfc_is_link_up(phba) && (phba->hba_flag & HBA_FCOE_MODE)) {
+ } else if (lpfc_is_link_up(phba) &&
+ test_bit(HBA_FCOE_MODE, &phba->hba_flag)) {
switch (phba->fc_linkspeed) {
case LPFC_ASYNC_LINK_SPEED_1GBPS:
fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
@@ -6718,7 +6863,7 @@ lpfc_get_stats(struct Scsi_Host *shost)
hs->invalid_crc_count -= lso->invalid_crc_count;
hs->error_frames -= lso->error_frames;
- if (phba->hba_flag & HBA_FCOE_MODE) {
+ if (test_bit(HBA_FCOE_MODE, &phba->hba_flag)) {
hs->lip_count = -1;
hs->nos_count = (phba->link_events >> 1);
hs->nos_count -= lso->link_events;
@@ -6816,7 +6961,7 @@ lpfc_reset_stats(struct Scsi_Host *shost)
lso->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
lso->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
lso->error_frames = pmb->un.varRdLnk.crcCnt;
- if (phba->hba_flag & HBA_FCOE_MODE)
+ if (test_bit(HBA_FCOE_MODE, &phba->hba_flag))
lso->link_events = (phba->link_events >> 1);
else
lso->link_events = (phba->fc_eventTag >> 1);
@@ -7161,11 +7306,11 @@ lpfc_get_hba_function_mode(struct lpfc_hba *phba)
case PCI_DEVICE_ID_ZEPHYR_DCSP:
case PCI_DEVICE_ID_TIGERSHARK:
case PCI_DEVICE_ID_TOMCAT:
- phba->hba_flag |= HBA_FCOE_MODE;
+ set_bit(HBA_FCOE_MODE, &phba->hba_flag);
break;
default:
/* for others, clear the flag */
- phba->hba_flag &= ~HBA_FCOE_MODE;
+ clear_bit(HBA_FCOE_MODE, &phba->hba_flag);
}
}
@@ -7236,7 +7381,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
lpfc_get_hba_function_mode(phba);
/* BlockGuard allowed for FC only. */
- if (phba->cfg_enable_bg && phba->hba_flag & HBA_FCOE_MODE) {
+ if (phba->cfg_enable_bg && test_bit(HBA_FCOE_MODE, &phba->hba_flag)) {
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"0581 BlockGuard feature not supported\n");
/* If set, clear the BlockGuard support param */