summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2026-04-02 21:35:53 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2026-04-02 21:35:53 -0400
commit927722dcfe0a5294433bb087387cc52a46cbf675 (patch)
tree1d1c91ad60c30c46a989e4f894ffa570b279dc17 /drivers/scsi
parent6daa8dd037459a1d1b105bd1008fa2a32f8708e5 (diff)
parent7f1e2c1cce1cad097d14f384c2461c1ff6cac0d0 (diff)
Merge patch series "Update lpfc to revision 15.0.0.0"
Justin Tee <justintee8345@gmail.com> says: Update lpfc to revision 15.0.0.0 This patch set adds support for the G8 ASIC found on the LPe42100 series adapter models. Updates are made to irq affinity assignment, mailbox command handling related to initialization, SGL construction, firmware download diagnostics, and the removal of an outdated performance feature. We also add 128G link speed selection and support. The patches were cut against Martin's 7.1/scsi-queue tree. Link: https://patch.msgid.link/20260331205928.119833-1-justintee8345@gmail.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/lpfc/lpfc.h9
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c27
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c18
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h3
-rw-r--r--drivers/scsi/lpfc/lpfc_hw4.h37
-rw-r--r--drivers/scsi/lpfc/lpfc_ids.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c53
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c38
-rw-r--r--drivers/scsi/lpfc/lpfc_nvme.c56
-rw-r--r--drivers/scsi/lpfc/lpfc_nvmet.c37
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c137
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c27
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h2
16 files changed, 225 insertions, 235 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 49ed55db1e47..b67ea1730dcf 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2026 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. *
@@ -810,9 +810,10 @@ struct unsol_rcv_ct_ctx {
#define LPFC_USER_LINK_SPEED_16G 16 /* 16 Gigabaud */
#define LPFC_USER_LINK_SPEED_32G 32 /* 32 Gigabaud */
#define LPFC_USER_LINK_SPEED_64G 64 /* 64 Gigabaud */
-#define LPFC_USER_LINK_SPEED_MAX LPFC_USER_LINK_SPEED_64G
+#define LPFC_USER_LINK_SPEED_128G 128 /* 128 Gigabaud */
+#define LPFC_USER_LINK_SPEED_MAX LPFC_USER_LINK_SPEED_128G
-#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32, 64"
+#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32, 64, 128"
enum nemb_type {
nemb_mse = 1,
@@ -1015,7 +1016,6 @@ struct lpfc_hba {
#define LPFC_SLI3_CRP_ENABLED 0x08
#define LPFC_SLI3_BG_ENABLED 0x20
#define LPFC_SLI3_DSS_ENABLED 0x40
-#define LPFC_SLI4_PERFH_ENABLED 0x80
#define LPFC_SLI4_PHWQ_ENABLED 0x100
uint32_t iocb_cmd_size;
uint32_t iocb_rsp_size;
@@ -1188,7 +1188,6 @@ struct lpfc_hba {
uint32_t cfg_ras_fwlog_func;
uint32_t cfg_enable_bbcr; /* Enable BB Credit Recovery */
uint32_t cfg_enable_dpp; /* Enable Direct Packet Push */
- uint32_t cfg_enable_pbde;
uint32_t cfg_enable_mi;
struct nvmet_fc_target_port *targetport;
lpfc_vpd_t vpd; /* vital product data */
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 53f41d68e0d8..c91fa44b12d4 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1,8 +1,8 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
- * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
+ * Copyright (C) 2017-2026 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. *
* www.broadcom.com *
@@ -4415,7 +4415,7 @@ static DEVICE_ATTR_RO(lpfc_static_vport);
/*
# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
# connection.
-# Value range is [0,16]. Default value is 0.
+# Value range is [0,128]. Default value is 0.
*/
/**
* lpfc_link_speed_store - Set the adapters link speed
@@ -4468,14 +4468,15 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
"3055 lpfc_link_speed changed from %d to %d %s\n",
phba->cfg_link_speed, val, nolip ? "(nolip)" : "(lip)");
- if (((val == LPFC_USER_LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
- ((val == LPFC_USER_LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
- ((val == LPFC_USER_LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
- ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) ||
- ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) ||
- ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) ||
- ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) ||
- ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) {
+ if ((val == LPFC_USER_LINK_SPEED_1G && !(phba->lmt & LMT_1Gb)) ||
+ (val == LPFC_USER_LINK_SPEED_2G && !(phba->lmt & LMT_2Gb)) ||
+ (val == LPFC_USER_LINK_SPEED_4G && !(phba->lmt & LMT_4Gb)) ||
+ (val == LPFC_USER_LINK_SPEED_8G && !(phba->lmt & LMT_8Gb)) ||
+ (val == LPFC_USER_LINK_SPEED_10G && !(phba->lmt & LMT_10Gb)) ||
+ (val == LPFC_USER_LINK_SPEED_16G && !(phba->lmt & LMT_16Gb)) ||
+ (val == LPFC_USER_LINK_SPEED_32G && !(phba->lmt & LMT_32Gb)) ||
+ (val == LPFC_USER_LINK_SPEED_64G && !(phba->lmt & LMT_64Gb)) ||
+ (val == LPFC_USER_LINK_SPEED_128G && !(phba->lmt & LMT_128Gb))) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2879 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported by this port.\n",
@@ -4500,6 +4501,7 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
case LPFC_USER_LINK_SPEED_16G:
case LPFC_USER_LINK_SPEED_32G:
case LPFC_USER_LINK_SPEED_64G:
+ case LPFC_USER_LINK_SPEED_128G:
prev_val = phba->cfg_link_speed;
phba->cfg_link_speed = val;
if (nolip)
@@ -4564,6 +4566,7 @@ lpfc_link_speed_init(struct lpfc_hba *phba, int val)
case LPFC_USER_LINK_SPEED_16G:
case LPFC_USER_LINK_SPEED_32G:
case LPFC_USER_LINK_SPEED_64G:
+ case LPFC_USER_LINK_SPEED_128G:
phba->cfg_link_speed = val;
return 0;
default:
@@ -7467,8 +7470,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
phba->cfg_auto_imax = (phba->cfg_fcp_imax) ? 0 : 1;
- phba->cfg_enable_pbde = 0;
-
/* A value of 0 means use the number of CPUs found in the system */
if (phba->cfg_hdw_queue == 0)
phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index d70a4039a345..4e3fe89283e4 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -4329,18 +4329,28 @@ lpfc_format_edc_cgn_desc(struct lpfc_hba *phba, struct fc_tlv_desc *tlv)
static bool
lpfc_link_is_lds_capable(struct lpfc_hba *phba)
{
- if (!(phba->lmt & LMT_64Gb))
+ if (!(phba->lmt & (LMT_64Gb | LMT_128Gb)))
return false;
if (phba->sli_rev != LPFC_SLI_REV4)
return false;
if (phba->sli4_hba.conf_trunk) {
- if (phba->trunk_link.phy_lnk_speed == LPFC_USER_LINK_SPEED_64G)
+ switch (phba->trunk_link.phy_lnk_speed) {
+ case LPFC_USER_LINK_SPEED_128G:
+ case LPFC_USER_LINK_SPEED_64G:
return true;
- } else if (phba->fc_linkspeed == LPFC_LINK_SPEED_64GHZ) {
+ default:
+ return false;
+ }
+ }
+
+ switch (phba->fc_linkspeed) {
+ case LPFC_LINK_SPEED_128GHZ:
+ case LPFC_LINK_SPEED_64GHZ:
return true;
+ default:
+ return false;
}
- return false;
}
/**
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 3fffe9b88e63..f3a85f6c796e 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -3817,7 +3817,7 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
if (phba->cmf_active_mode != LPFC_CFG_OFF)
lpfc_cmf_signal_init(phba);
- if (phba->lmt & LMT_64Gb)
+ if (phba->lmt & (LMT_64Gb | LMT_128Gb))
lpfc_read_lds_params(phba);
} else if (attn_type == LPFC_ATT_LINK_DOWN ||
@@ -4410,7 +4410,7 @@ out:
LOG_INIT | LOG_ELS | LOG_DISCOVERY,
"4220 Issue EDC status x%x Data x%x\n",
rc, phba->cgn_init_reg_signal);
- } else if (phba->lmt & LMT_64Gb) {
+ } else if (phba->lmt & (LMT_64Gb | LMT_128Gb)) {
/* may send link fault capability descriptor */
lpfc_issue_els_edc(vport, 0);
} else {
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index b2e353590ebb..6326f7353dd6 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2026 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. *
@@ -1771,6 +1771,7 @@ struct lpfc_fdmi_reg_portattr {
#define PCI_DEVICE_ID_LANCER_G6_FC 0xe300
#define PCI_DEVICE_ID_LANCER_G7_FC 0xf400
#define PCI_DEVICE_ID_LANCER_G7P_FC 0xf500
+#define PCI_DEVICE_ID_LANCER_G8_FC 0xd300
#define PCI_DEVICE_ID_SAT_SMB 0xf011
#define PCI_DEVICE_ID_SAT_MID 0xf015
#define PCI_DEVICE_ID_RFLY 0xf095
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index c000474c3066..f91bde4a6c38 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -1,8 +1,8 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
- * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
+ * Copyright (C) 2017-2026 Broadcom. All Rights Reserved. The term *
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
* Copyright (C) 2009-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.broadcom.com *
@@ -100,7 +100,8 @@ struct lpfc_sli_intf {
#define lpfc_sli_intf_sli_family_MASK 0x0000000F
#define lpfc_sli_intf_sli_family_WORD word0
#define LPFC_SLI_INTF_FAMILY_BE2 0x0
-#define LPFC_SLI_INTF_FAMILY_BE3 0x1
+#define LPFC_SLI_INTF_ASIC_ID 0x1 /* Refer to ASIC_ID register */
+#define LPFC_SLI_INTF_FAMILY_BE3 0x3
#define LPFC_SLI_INTF_FAMILY_LNCR_A0 0xa
#define LPFC_SLI_INTF_FAMILY_LNCR_B0 0xb
#define LPFC_SLI_INTF_FAMILY_G6 0xc
@@ -118,6 +119,17 @@ struct lpfc_sli_intf {
#define LPFC_SLI_INTF_IF_TYPE_VIRT 1
};
+struct lpfc_asic_id {
+ u32 word0;
+#define lpfc_asic_id_gen_num_SHIFT 8
+#define lpfc_asic_id_gen_num_MASK 0x000000FF
+#define lpfc_asic_id_gen_num_WORD word0
+#define LPFC_SLI_INTF_FAMILY_G8 0x10
+#define lpfc_asic_id_rev_num_SHIFT 0
+#define lpfc_asic_id_rev_num_MASK 0x000000FF
+#define lpfc_asic_id_rev_num_WORD word0
+};
+
#define LPFC_SLI4_MBX_EMBED true
#define LPFC_SLI4_MBX_NEMBED false
@@ -624,6 +636,10 @@ struct lpfc_register {
#define LPFC_PORT_SEM_UE_RECOVERABLE 0xE000
#define LPFC_PORT_SEM_MASK 0xF000
+
+/* The following are config space register offsets */
+#define LPFC_ASIC_ID_OFFSET 0x0308
+
/* The following BAR0 Registers apply to SLI4 if_type 0 UCNAs. */
#define LPFC_UERR_STATUS_HI 0x00A4
#define LPFC_UERR_STATUS_LO 0x00A0
@@ -632,7 +648,6 @@ struct lpfc_register {
/* The following BAR0 register sets are defined for if_type 0 and 2 UCNAs. */
#define LPFC_SLI_INTF 0x0058
-#define LPFC_SLI_ASIC_VER 0x009C
#define LPFC_CTL_PORT_SEM_OFFSET 0x400
#define lpfc_port_smphr_perr_SHIFT 31
@@ -3062,9 +3077,6 @@ struct lpfc_mbx_request_features {
#define lpfc_mbx_rq_ftr_rq_iaar_SHIFT 9
#define lpfc_mbx_rq_ftr_rq_iaar_MASK 0x00000001
#define lpfc_mbx_rq_ftr_rq_iaar_WORD word2
-#define lpfc_mbx_rq_ftr_rq_perfh_SHIFT 11
-#define lpfc_mbx_rq_ftr_rq_perfh_MASK 0x00000001
-#define lpfc_mbx_rq_ftr_rq_perfh_WORD word2
#define lpfc_mbx_rq_ftr_rq_mrqp_SHIFT 16
#define lpfc_mbx_rq_ftr_rq_mrqp_MASK 0x00000001
#define lpfc_mbx_rq_ftr_rq_mrqp_WORD word2
@@ -3096,9 +3108,6 @@ struct lpfc_mbx_request_features {
#define lpfc_mbx_rq_ftr_rsp_ifip_SHIFT 7
#define lpfc_mbx_rq_ftr_rsp_ifip_MASK 0x00000001
#define lpfc_mbx_rq_ftr_rsp_ifip_WORD word3
-#define lpfc_mbx_rq_ftr_rsp_perfh_SHIFT 11
-#define lpfc_mbx_rq_ftr_rsp_perfh_MASK 0x00000001
-#define lpfc_mbx_rq_ftr_rsp_perfh_WORD word3
#define lpfc_mbx_rq_ftr_rsp_mrqp_SHIFT 16
#define lpfc_mbx_rq_ftr_rsp_mrqp_MASK 0x00000001
#define lpfc_mbx_rq_ftr_rsp_mrqp_WORD word3
@@ -3461,10 +3470,6 @@ struct lpfc_sli4_parameters {
#define cfg_pvl_MASK 0x00000001
#define cfg_pvl_WORD word19
-#define cfg_pbde_SHIFT 20
-#define cfg_pbde_MASK 0x00000001
-#define cfg_pbde_WORD word19
-
uint32_t word20;
#define cfg_max_tow_xri_SHIFT 0
#define cfg_max_tow_xri_MASK 0x0000ffff
@@ -4484,9 +4489,6 @@ struct wqe_common {
#define wqe_irsp_SHIFT 4
#define wqe_irsp_MASK 0x00000001
#define wqe_irsp_WORD word11
-#define wqe_pbde_SHIFT 5
-#define wqe_pbde_MASK 0x00000001
-#define wqe_pbde_WORD word11
#define wqe_sup_SHIFT 6
#define wqe_sup_MASK 0x00000001
#define wqe_sup_WORD word11
@@ -4978,6 +4980,7 @@ union lpfc_wqe128 {
#define MAGIC_NUMBER_G6 0xFEAA0003
#define MAGIC_NUMBER_G7 0xFEAA0005
#define MAGIC_NUMBER_G7P 0xFEAA0020
+#define MAGIC_NUMBER_G8 0xFEAA0070
struct lpfc_grp_hdr {
uint32_t size;
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h
index 0b1616e93cf4..a0a6e2d379b8 100644
--- a/drivers/scsi/lpfc/lpfc_ids.h
+++ b/drivers/scsi/lpfc/lpfc_ids.h
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2026 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. *
@@ -118,6 +118,8 @@ const struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G7P_FC,
PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G8_FC,
+ PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK,
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF,
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 5b7955b50835..968a25235a2d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2,7 +2,7 @@
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2017-2026 Broadcom. All Rights Reserved. The term *
- * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.broadcom.com *
@@ -789,7 +789,9 @@ lpfc_hba_init_link_fc_topology(struct lpfc_hba *phba, uint32_t fc_topology,
((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_32G) &&
!(phba->lmt & LMT_32Gb)) ||
((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_64G) &&
- !(phba->lmt & LMT_64Gb))) {
+ !(phba->lmt & LMT_64Gb)) ||
+ ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_128G) &&
+ !(phba->lmt & LMT_128Gb))) {
/* Reset link speed to auto */
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
"1302 Invalid speed for this board:%d "
@@ -2535,7 +2537,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
return;
}
- if (phba->lmt & LMT_64Gb)
+ if (phba->lmt & LMT_128Gb)
+ max_speed = 128;
+ else if (phba->lmt & LMT_64Gb)
max_speed = 64;
else if (phba->lmt & LMT_32Gb)
max_speed = 32;
@@ -2753,6 +2757,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
case PCI_DEVICE_ID_LANCER_G7P_FC:
m = (typeof(m)){"LPe38000", "PCIe", "Fibre Channel Adapter"};
break;
+ case PCI_DEVICE_ID_LANCER_G8_FC:
+ m = (typeof(m)){"LPe42100", "PCIe", "Fibre Channel Adapter"};
+ break;
case PCI_DEVICE_ID_SKYHAWK:
case PCI_DEVICE_ID_SKYHAWK_VF:
oneConnect = 1;
@@ -10144,6 +10151,10 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
phba->cfg_link_speed =
LPFC_USER_LINK_SPEED_64G;
break;
+ case LINK_SPEED_128G:
+ phba->cfg_link_speed =
+ LPFC_USER_LINK_SPEED_128G;
+ break;
case 0xffff:
phba->cfg_link_speed =
LPFC_USER_LINK_SPEED_AUTO;
@@ -11793,6 +11804,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
unsigned long bar0map_len, bar1map_len, bar2map_len;
int error;
uint32_t if_type;
+ u8 sli_family;
if (!pdev)
return -ENODEV;
@@ -11823,6 +11835,14 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba)
return -ENODEV;
}
+ /* Check if ASIC_ID register should be read */
+ sli_family = bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf);
+ if (sli_family == LPFC_SLI_INTF_ASIC_ID) {
+ if (pci_read_config_dword(pdev, LPFC_ASIC_ID_OFFSET,
+ &phba->sli4_hba.asic_id.word0))
+ return -ENODEV;
+ }
+
if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
/*
* Get the bus address of SLI4 device Bar regions and the
@@ -13041,6 +13061,10 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
/* Iterate to next offline or online cpu in aff_mask */
cpu = cpumask_next(cpu, aff_mask);
+ /* Reached the end of the aff_mask */
+ if (cpu >= nr_cpu_ids)
+ break;
+
/* Find next online cpu in aff_mask to set affinity */
cpu_select = lpfc_next_online_cpu(aff_mask, cpu);
} else if (vectors == 1) {
@@ -13714,7 +13738,9 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
sli4_params->cqv = bf_get(cfg_cqv, mbx_sli4_parameters);
sli4_params->mqv = bf_get(cfg_mqv, mbx_sli4_parameters);
sli4_params->wqv = bf_get(cfg_wqv, mbx_sli4_parameters);
- sli4_params->rqv = bf_get(cfg_rqv, mbx_sli4_parameters);
+ sli4_params->rqv =
+ (sli4_params->if_type < LPFC_SLI_INTF_IF_TYPE_2) ?
+ LPFC_Q_CREATE_VERSION_0 : LPFC_Q_CREATE_VERSION_1;
sli4_params->eqav = bf_get(cfg_eqav, mbx_sli4_parameters);
sli4_params->cqav = bf_get(cfg_cqav, mbx_sli4_parameters);
sli4_params->wqsize = bf_get(cfg_wqsize, mbx_sli4_parameters);
@@ -13776,12 +13802,6 @@ fcponly:
if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)
phba->cfg_sg_seg_cnt = LPFC_MAX_NVME_SEG_CNT;
- /* Enable embedded Payload BDE if support is indicated */
- if (bf_get(cfg_pbde, mbx_sli4_parameters))
- phba->cfg_enable_pbde = 1;
- else
- phba->cfg_enable_pbde = 0;
-
/*
* To support Suppress Response feature we must satisfy 3 conditions.
* lpfc_suppress_rsp module parameter must be set (default).
@@ -13816,9 +13836,8 @@ fcponly:
phba->fcp_embed_io = 0;
lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME,
- "6422 XIB %d PBDE %d: FCP %d NVME %d %d %d\n",
+ "6422 XIB %d: FCP %d NVME %d %d %d\n",
bf_get(cfg_xib, mbx_sli4_parameters),
- phba->cfg_enable_pbde,
phba->fcp_embed_io, sli4_params->nvme,
phba->cfg_nvme_embed_cmd, phba->cfg_suppress_rsp);
@@ -14483,6 +14502,12 @@ lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset,
u8 sli_family;
sli_family = bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf);
+
+ /* Refer to ASIC_ID register case */
+ if (sli_family == LPFC_SLI_INTF_ASIC_ID)
+ sli_family = bf_get(lpfc_asic_id_gen_num,
+ &phba->sli4_hba.asic_id);
+
/* Three cases: (1) FW was not supported on the detected adapter.
* (2) FW update has been locked out administratively.
* (3) Some other error during FW update.
@@ -14495,7 +14520,9 @@ lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset,
(sli_family == LPFC_SLI_INTF_FAMILY_G7 &&
magic_number != MAGIC_NUMBER_G7) ||
(sli_family == LPFC_SLI_INTF_FAMILY_G7P &&
- magic_number != MAGIC_NUMBER_G7P)) {
+ magic_number != MAGIC_NUMBER_G7P) ||
+ (sli_family == LPFC_SLI_INTF_FAMILY_G8 &&
+ magic_number != MAGIC_NUMBER_G8)) {
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
"3030 This firmware version is not supported on"
" this HBA model. Device:%x Magic:%x Type:%x "
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index d07c2786cb12..4c058904758d 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.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-2026 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. *
@@ -625,6 +625,10 @@ lpfc_init_link(struct lpfc_hba * phba,
mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
mb->un.varInitLnk.link_speed = LINK_SPEED_64G;
break;
+ case LPFC_USER_LINK_SPEED_128G:
+ mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
+ mb->un.varInitLnk.link_speed = LINK_SPEED_128G;
+ break;
case LPFC_USER_LINK_SPEED_AUTO:
default:
mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
@@ -2139,7 +2143,6 @@ lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)
/* Set up host requested features. */
bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1);
- bf_set(lpfc_mbx_rq_ftr_rq_perfh, &mboxq->u.mqe.un.req_ftrs, 1);
/* Enable DIF (block guard) only if configured to do so. */
if (phba->cfg_enable_bg)
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 5e431928de0b..9c449055a55e 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2026 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. *
@@ -316,8 +316,7 @@ lpfc_defer_plogi_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *login_mbox)
struct lpfc_iocbq *save_iocb;
struct lpfc_nodelist *ndlp;
MAILBOX_t *mb = &login_mbox->u.mb;
-
- int rc;
+ int rc = 0;
ndlp = login_mbox->ctx_ndlp;
save_iocb = login_mbox->ctx_u.save_iocb;
@@ -346,7 +345,7 @@ lpfc_defer_plogi_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *login_mbox)
* completes. This ensures, in Pt2Pt, that the PLOGI LS_ACC is sent
* before the PRLI.
*/
- if (!test_bit(FC_PT2PT, &ndlp->vport->fc_flag)) {
+ if (!test_bit(FC_PT2PT, &ndlp->vport->fc_flag) || mb->mbxStatus || rc) {
/* Now process the REG_RPI cmpl */
lpfc_mbx_cmpl_reg_login(phba, login_mbox);
clear_bit(NLP_ACC_REGLOGIN, &ndlp->nlp_flag);
@@ -525,13 +524,13 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
/* Issue CONFIG_LINK for SLI3 or REG_VFI for SLI4,
* to account for updated TOV's / parameters
*/
- if (phba->sli_rev == LPFC_SLI_REV4)
- lpfc_issue_reg_vfi(vport);
- else {
+ if (phba->sli_rev == LPFC_SLI_REV4) {
+ rc = lpfc_issue_reg_vfi(vport);
+ } else {
link_mbox = mempool_alloc(phba->mbox_mem_pool,
GFP_KERNEL);
if (!link_mbox)
- goto out;
+ goto rsp_rjt;
lpfc_config_link(phba, link_mbox);
link_mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
link_mbox->vport = vport;
@@ -544,11 +543,13 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED) {
mempool_free(link_mbox, phba->mbox_mem_pool);
- goto out;
+ goto rsp_rjt;
}
}
lpfc_can_disctmo(vport);
+ if (rc)
+ goto rsp_rjt;
}
clear_bit(NLP_SUPPRESS_RSP, &ndlp->nlp_flag);
@@ -562,11 +563,11 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
login_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!login_mbox)
- goto out;
+ goto rsp_rjt;
save_iocb = kzalloc_obj(*save_iocb);
if (!save_iocb)
- goto out;
+ goto free_login_mbox;
/* Save info from cmd IOCB to be used in rsp after all mbox completes */
memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb,
@@ -586,7 +587,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
rc = lpfc_reg_rpi(phba, vport->vpi, remote_did,
(uint8_t *)sp, login_mbox, ndlp->nlp_rpi);
if (rc)
- goto out;
+ goto free_save_iocb;
login_mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
login_mbox->vport = vport;
@@ -659,7 +660,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
login_mbox->mbox_cmpl = lpfc_defer_plogi_acc;
login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
if (!login_mbox->ctx_ndlp)
- goto out;
+ goto free_save_iocb;
login_mbox->ctx_u.save_iocb = save_iocb; /* For PLOGI ACC */
@@ -670,16 +671,17 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
rc = lpfc_sli_issue_mbox(phba, login_mbox, MBX_NOWAIT);
if (rc == MBX_NOT_FINISHED) {
lpfc_nlp_put(ndlp);
- goto out;
+ goto free_save_iocb;
}
lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE);
return 1;
-out:
- kfree(save_iocb);
- if (login_mbox)
- mempool_free(login_mbox, phba->mbox_mem_pool);
+free_save_iocb:
+ kfree(save_iocb);
+free_login_mbox:
+ mempool_free(login_mbox, phba->mbox_mem_pool);
+rsp_rjt:
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE;
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 74c2820c64f3..71714ea390d9 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -1296,8 +1296,6 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport,
/* Word 10 */
bf_set(wqe_xchg, &wqe->fcp_iwrite.wqe_com, LPFC_NVME_XCHG);
- /* Words 13 14 15 are for PBDE support */
-
/* add the VMID tags as per switch response */
if (unlikely(lpfc_ncmd->cur_iocbq.cmd_flag & LPFC_IO_VMID)) {
if (phba->pport->vmid_priority_tagging) {
@@ -1335,16 +1333,13 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
{
struct lpfc_hba *phba = vport->phba;
struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd;
- union lpfc_wqe128 *wqe = &lpfc_ncmd->cur_iocbq.wqe;
struct sli4_sge *sgl = lpfc_ncmd->dma_sgl;
struct sli4_hybrid_sgl *sgl_xtra = NULL;
struct scatterlist *data_sg;
- struct sli4_sge *first_data_sgl;
- struct ulp_bde64 *bde;
dma_addr_t physaddr = 0;
uint32_t dma_len = 0;
uint32_t dma_offset = 0;
- int nseg, i, j;
+ int nseg, i, j, k;
bool lsp_just_set = false;
/* Fix up the command and response DMA stuff. */
@@ -1361,7 +1356,6 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
*/
sgl += 2;
- first_data_sgl = sgl;
lpfc_ncmd->seg_cnt = nCmd->sg_cnt;
if (lpfc_ncmd->seg_cnt > lpfc_nvme_template.max_sgl_segments) {
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
@@ -1385,6 +1379,9 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
/* for tracking the segment boundaries */
j = 2;
+ k = 5;
+ if (unlikely(!phba->cfg_xpsgl))
+ k = 1;
for (i = 0; i < nseg; i++) {
if (data_sg == NULL) {
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
@@ -1403,9 +1400,8 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
bf_set(lpfc_sli4_sge_last, sgl, 0);
/* expand the segment */
- if (!lsp_just_set &&
- !((j + 1) % phba->border_sge_num) &&
- ((nseg - 1) != i)) {
+ if (!lsp_just_set && (nseg != (i + k)) &&
+ !((j + k) % phba->border_sge_num)) {
/* set LSP type */
bf_set(lpfc_sli4_sge_type, sgl,
LPFC_SGE_TYPE_LSP);
@@ -1428,8 +1424,8 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
}
}
- if (!(bf_get(lpfc_sli4_sge_type, sgl) &
- LPFC_SGE_TYPE_LSP)) {
+ if (bf_get(lpfc_sli4_sge_type, sgl) !=
+ LPFC_SGE_TYPE_LSP) {
if ((nseg - 1) == i)
bf_set(lpfc_sli4_sge_last, sgl, 1);
@@ -1450,40 +1446,26 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport,
sgl++;
lsp_just_set = false;
+ j++;
} else {
sgl->word2 = cpu_to_le32(sgl->word2);
-
- sgl->sge_len = cpu_to_le32(
- phba->cfg_sg_dma_buf_size);
+ /* will remaining SGEs fill the next SGL? */
+ if ((nseg - i) < phba->border_sge_num)
+ sgl->sge_len =
+ cpu_to_le32((nseg - i) *
+ sizeof(*sgl));
+ else
+ sgl->sge_len =
+ cpu_to_le32(phba->cfg_sg_dma_buf_size);
sgl = (struct sli4_sge *)sgl_xtra->dma_sgl;
i = i - 1;
lsp_just_set = true;
+ j += k;
+ k = 1;
}
-
- j++;
}
-
- /* PBDE support for first data SGE only */
- if (nseg == 1 && phba->cfg_enable_pbde) {
- /* Words 13-15 */
- bde = (struct ulp_bde64 *)
- &wqe->words[13];
- bde->addrLow = first_data_sgl->addr_lo;
- bde->addrHigh = first_data_sgl->addr_hi;
- bde->tus.f.bdeSize =
- le32_to_cpu(first_data_sgl->sge_len);
- bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
- bde->tus.w = cpu_to_le32(bde->tus.w);
-
- /* Word 11 - set PBDE bit */
- bf_set(wqe_pbde, &wqe->generic.wqe_com, 1);
- } else {
- memset(&wqe->words[13], 0, (sizeof(uint32_t) * 3));
- /* Word 11 - PBDE bit disabled by default template */
- }
-
} else {
lpfc_ncmd->seg_cnt = 0;
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
index debd9317103a..72f3f6f9444d 100644
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
+++ b/drivers/scsi/lpfc/lpfc_nvmet.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-2026 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. *
@@ -118,12 +118,9 @@ lpfc_nvmet_cmd_template(void)
bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0);
bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 0);
bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, 0);
- bf_set(wqe_pbde, &wqe->fcp_tsend.wqe_com, 0);
/* Word 12 - fcp_data_len is variable */
- /* Word 13, 14, 15 - PBDE is zero */
-
/* TRECEIVE template */
wqe = &lpfc_treceive_cmd_template;
memset(wqe, 0, sizeof(union lpfc_wqe128));
@@ -158,18 +155,15 @@ lpfc_nvmet_cmd_template(void)
bf_set(wqe_lenloc, &wqe->fcp_treceive.wqe_com, LPFC_WQE_LENLOC_WORD12);
bf_set(wqe_xc, &wqe->fcp_tsend.wqe_com, 1);
- /* Word 11 - pbde is variable */
+ /* Word 11 */
bf_set(wqe_cmd_type, &wqe->fcp_treceive.wqe_com, FCP_COMMAND_TRECEIVE);
bf_set(wqe_cqid, &wqe->fcp_treceive.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
bf_set(wqe_sup, &wqe->fcp_treceive.wqe_com, 0);
bf_set(wqe_irsp, &wqe->fcp_treceive.wqe_com, 0);
bf_set(wqe_irsplen, &wqe->fcp_treceive.wqe_com, 0);
- bf_set(wqe_pbde, &wqe->fcp_treceive.wqe_com, 1);
/* Word 12 - fcp_data_len is variable */
- /* Word 13, 14, 15 - PBDE is variable */
-
/* TRSP template */
wqe = &lpfc_trsp_cmd_template;
memset(wqe, 0, sizeof(union lpfc_wqe128));
@@ -207,7 +201,6 @@ lpfc_nvmet_cmd_template(void)
bf_set(wqe_sup, &wqe->fcp_trsp.wqe_com, 0);
bf_set(wqe_irsp, &wqe->fcp_trsp.wqe_com, 0);
bf_set(wqe_irsplen, &wqe->fcp_trsp.wqe_com, 0);
- bf_set(wqe_pbde, &wqe->fcp_trsp.wqe_com, 0);
/* Word 12, 13, 14, 15 - is zero */
}
@@ -2722,7 +2715,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
struct ulp_bde64 *bde;
dma_addr_t physaddr;
int i, cnt, nsegs;
- bool use_pbde = false;
int xc = 1;
if (!lpfc_is_link_up(phba)) {
@@ -2907,15 +2899,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
if (!xc)
bf_set(wqe_xc, &wqe->fcp_treceive.wqe_com, 0);
- /* Word 11 - check for pbde */
- if (nsegs == 1 && phba->cfg_enable_pbde) {
- use_pbde = true;
- /* Word 11 - PBDE bit already preset by template */
- } else {
- /* Overwrite default template setting */
- bf_set(wqe_pbde, &wqe->fcp_treceive.wqe_com, 0);
- }
-
/* Word 12 */
wqe->fcp_tsend.fcp_data_len = rsp->transfer_length;
@@ -3023,19 +3006,9 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba,
}
bde = (struct ulp_bde64 *)&wqe->words[13];
- if (use_pbde) {
- /* decrement sgl ptr backwards once to first data sge */
- sgl--;
-
- /* Words 13-15 (PBDE) */
- bde->addrLow = sgl->addr_lo;
- bde->addrHigh = sgl->addr_hi;
- bde->tus.f.bdeSize = le32_to_cpu(sgl->sge_len);
- bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
- bde->tus.w = cpu_to_le32(bde->tus.w);
- } else {
- memset(bde, 0, sizeof(struct ulp_bde64));
- }
+
+ memset(bde, 0, sizeof(struct ulp_bde64));
+
ctxp->state = LPFC_NVME_STE_DATA;
ctxp->entry_cnt++;
return nvmewqe;
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index e9d27703bc44..1dce33b79beb 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1938,7 +1938,7 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
uint32_t dma_len;
uint32_t dma_offset = 0;
struct sli4_hybrid_sgl *sgl_xtra = NULL;
- int j;
+ int j, k;
bool lsp_just_set = false;
status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop);
@@ -2001,13 +2001,16 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
/* assumption: caller has already run dma_map_sg on command data */
sgde = scsi_sglist(sc);
j = 3;
+ k = 5;
+ if (unlikely(!phba->cfg_xpsgl))
+ k = 1;
for (i = 0; i < datasegcnt; i++) {
/* clear it */
sgl->word2 = 0;
- /* do we need to expand the segment */
- if (!lsp_just_set && !((j + 1) % phba->border_sge_num) &&
- ((datasegcnt - 1) != i)) {
+ /* do we need to expand the segment? */
+ if (!lsp_just_set && (datasegcnt != (i + k)) &&
+ !((j + k) % phba->border_sge_num)) {
/* set LSP type */
bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_LSP);
@@ -2026,7 +2029,7 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA);
}
- if (!(bf_get(lpfc_sli4_sge_type, sgl) & LPFC_SGE_TYPE_LSP)) {
+ if (bf_get(lpfc_sli4_sge_type, sgl) != LPFC_SGE_TYPE_LSP) {
if ((datasegcnt - 1) == i)
bf_set(lpfc_sli4_sge_last, sgl, 1);
physaddr = sg_dma_address(sgde);
@@ -2043,20 +2046,23 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
sgl++;
num_sge++;
+ j++;
lsp_just_set = false;
-
} else {
sgl->word2 = cpu_to_le32(sgl->word2);
- sgl->sge_len = cpu_to_le32(phba->cfg_sg_dma_buf_size);
-
+ /* will remaining SGEs fill the next SGL? */
+ if ((datasegcnt - i) < phba->border_sge_num)
+ sgl->sge_len = cpu_to_le32((datasegcnt - i) *
+ sizeof(*sgl));
+ else
+ sgl->sge_len =
+ cpu_to_le32(phba->cfg_sg_dma_buf_size);
sgl = (struct sli4_sge *)sgl_xtra->dma_sgl;
i = i - 1;
-
+ j += k;
lsp_just_set = true;
+ k = 1;
}
-
- j++;
-
}
out:
@@ -2109,6 +2115,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
struct scatterlist *sgde = NULL; /* s/g data entry */
struct scatterlist *sgpe = NULL; /* s/g prot entry */
struct sli4_sge_diseed *diseed = NULL;
+ struct sli4_sge_le *lsp_sgl = NULL;
dma_addr_t dataphysaddr, protphysaddr;
unsigned short curr_prot = 0;
unsigned int split_offset;
@@ -2125,8 +2132,8 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
uint32_t rc;
#endif
uint32_t checking = 1;
- uint32_t dma_offset = 0, num_sge = 0;
- int j = 2;
+ uint32_t dma_offset = 0, num_sge = 0, lsp_len;
+ int j = 2, k = 4;
struct sli4_hybrid_sgl *sgl_xtra = NULL;
sgpe = scsi_prot_sglist(sc);
@@ -2157,6 +2164,8 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
}
#endif
+ if (unlikely(!phba->cfg_xpsgl))
+ k = 0;
split_offset = 0;
do {
/* Check to see if we ran out of space */
@@ -2164,10 +2173,10 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
!(phba->cfg_xpsgl))
return num_sge + 3;
- /* DISEED and DIF have to be together */
- if (!((j + 1) % phba->border_sge_num) ||
- !((j + 2) % phba->border_sge_num) ||
- !((j + 3) % phba->border_sge_num)) {
+ /* DISEED and DIF have to be together */
+ if (!((j + k + 1) % phba->border_sge_num) ||
+ !((j + k + 2) % phba->border_sge_num) ||
+ !((j + k + 3) % phba->border_sge_num)) {
sgl->word2 = 0;
/* set LSP type */
@@ -2186,9 +2195,18 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
sgl->word2 = cpu_to_le32(sgl->word2);
sgl->sge_len = cpu_to_le32(phba->cfg_sg_dma_buf_size);
+ if (lsp_sgl) {
+ j++;
+ if (j % phba->border_sge_num) {
+ lsp_len = j * (sizeof(*sgl));
+ lsp_sgl->sge_len = cpu_to_le32(lsp_len);
+ }
+ }
+ lsp_sgl = (struct sli4_sge_le *)sgl;
sgl = (struct sli4_sge *)sgl_xtra->dma_sgl;
j = 0;
+ k = 0;
}
/* setup DISEED with what we have */
@@ -2291,7 +2309,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
return 0;
}
- if (!((j + 1) % phba->border_sge_num)) {
+ if (!((j + k + 1) % phba->border_sge_num)) {
sgl->word2 = 0;
/* set LSP type */
@@ -2313,8 +2331,11 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
sgl->word2 = cpu_to_le32(sgl->word2);
sgl->sge_len = cpu_to_le32(
phba->cfg_sg_dma_buf_size);
+ lsp_sgl = (struct sli4_sge_le *)sgl;
sgl = (struct sli4_sge *)sgl_xtra->dma_sgl;
+ j = 0;
+ k = 0;
} else {
dataphysaddr = sg_dma_address(sgde) +
split_offset;
@@ -2362,11 +2383,9 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
/* Move to the next s/g segment if possible */
sgde = sg_next(sgde);
-
sgl++;
+ j++;
}
-
- j++;
}
if (protgroup_offset) {
@@ -2381,6 +2400,14 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
sgl--;
bf_set(lpfc_sli4_sge_last, sgl, 1);
alldone = 1;
+
+ /* Reset length in previous LSP where necessary */
+ if (lsp_sgl) {
+ if (j % phba->border_sge_num) {
+ lsp_len = j * (sizeof(*sgl));
+ lsp_sgl->sge_len = cpu_to_le32(lsp_len);
+ }
+ }
} else if (curr_prot < protcnt) {
/* advance to next prot buffer */
sgpe = sg_next(sgpe);
@@ -2392,7 +2419,6 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
"9085 BLKGRD: bug in %s\n", __func__);
}
-
} while (!alldone);
out:
@@ -3050,15 +3076,13 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
struct scatterlist *sgel = NULL;
struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
struct sli4_sge *sgl = (struct sli4_sge *)lpfc_cmd->dma_sgl;
- struct sli4_sge *first_data_sgl;
struct lpfc_iocbq *pwqeq = &lpfc_cmd->cur_iocbq;
struct lpfc_vport *vport = phba->pport;
union lpfc_wqe128 *wqe = &pwqeq->wqe;
dma_addr_t physaddr;
uint32_t dma_len;
uint32_t dma_offset = 0;
- int nseg, i, j;
- struct ulp_bde64 *bde;
+ int nseg, i, j, k;
bool lsp_just_set = false;
struct sli4_hybrid_sgl *sgl_xtra = NULL;
@@ -3085,7 +3109,6 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
bf_set(lpfc_sli4_sge_last, sgl, 0);
sgl->word2 = cpu_to_le32(sgl->word2);
sgl += 1;
- first_data_sgl = sgl;
lpfc_cmd->seg_cnt = nseg;
if (!phba->cfg_xpsgl &&
lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
@@ -3114,6 +3137,9 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
/* for tracking segment boundaries */
sgel = scsi_sglist(scsi_cmnd);
j = 2;
+ k = 5;
+ if (unlikely(!phba->cfg_xpsgl))
+ k = 1;
for (i = 0; i < nseg; i++) {
sgl->word2 = 0;
if (nseg == 1) {
@@ -3124,9 +3150,8 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
bf_set(lpfc_sli4_sge_last, sgl, 0);
/* do we need to expand the segment */
- if (!lsp_just_set &&
- !((j + 1) % phba->border_sge_num) &&
- ((nseg - 1) != i)) {
+ if (!lsp_just_set && (nseg != (i + k)) &&
+ !((j + k) % phba->border_sge_num)) {
/* set LSP type */
bf_set(lpfc_sli4_sge_type, sgl,
LPFC_SGE_TYPE_LSP);
@@ -3150,8 +3175,8 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
}
}
- if (!(bf_get(lpfc_sli4_sge_type, sgl) &
- LPFC_SGE_TYPE_LSP)) {
+ if (bf_get(lpfc_sli4_sge_type, sgl) !=
+ LPFC_SGE_TYPE_LSP) {
if ((nseg - 1) == i)
bf_set(lpfc_sli4_sge_last, sgl, 1);
@@ -3171,43 +3196,24 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
sgl++;
lsp_just_set = false;
-
+ j++;
} else {
sgl->word2 = cpu_to_le32(sgl->word2);
- sgl->sge_len = cpu_to_le32(
- phba->cfg_sg_dma_buf_size);
-
+ /* will remaining SGEs fill the next SGL? */
+ if ((nseg - i) < phba->border_sge_num)
+ sgl->sge_len =
+ cpu_to_le32((nseg - i) *
+ sizeof(*sgl));
+ else
+ sgl->sge_len =
+ cpu_to_le32(phba->cfg_sg_dma_buf_size);
sgl = (struct sli4_sge *)sgl_xtra->dma_sgl;
i = i - 1;
lsp_just_set = true;
+ j += k;
+ k = 1;
}
-
- j++;
- }
-
- /* PBDE support for first data SGE only.
- * For FCoE, we key off Performance Hints.
- * For FC, we key off lpfc_enable_pbde.
- */
- if (nseg == 1 &&
- ((phba->sli3_options & LPFC_SLI4_PERFH_ENABLED) ||
- phba->cfg_enable_pbde)) {
- /* Words 13-15 */
- bde = (struct ulp_bde64 *)
- &wqe->words[13];
- bde->addrLow = first_data_sgl->addr_lo;
- bde->addrHigh = first_data_sgl->addr_hi;
- bde->tus.f.bdeSize =
- le32_to_cpu(first_data_sgl->sge_len);
- bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
- bde->tus.w = cpu_to_le32(bde->tus.w);
-
- /* Word 11 - set PBDE bit */
- bf_set(wqe_pbde, &wqe->generic.wqe_com, 1);
- } else {
- memset(&wqe->words[13], 0, (sizeof(uint32_t) * 3));
- /* Word 11 - PBDE bit disabled by default template */
}
} else {
sgl += 1;
@@ -3215,13 +3221,6 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
sgl->word2 = le32_to_cpu(sgl->word2);
bf_set(lpfc_sli4_sge_last, sgl, 1);
sgl->word2 = cpu_to_le32(sgl->word2);
-
- if ((phba->sli3_options & LPFC_SLI4_PERFH_ENABLED) ||
- phba->cfg_enable_pbde) {
- bde = (struct ulp_bde64 *)
- &wqe->words[13];
- memset(bde, 0, (sizeof(uint32_t) * 3));
- }
}
/*
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 218714ca6af7..d38fb374b379 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -136,15 +136,12 @@ void lpfc_wqe_cmd_template(void)
bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 0);
bf_set(wqe_wqes, &wqe->fcp_iread.wqe_com, 1);
- /* Word 11 - pbde is variable */
+ /* Word 11 */
bf_set(wqe_cmd_type, &wqe->fcp_iread.wqe_com, COMMAND_DATA_IN);
bf_set(wqe_cqid, &wqe->fcp_iread.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
- bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 0);
/* Word 12 - is zero */
- /* Word 13, 14, 15 - PBDE is variable */
-
/* IWRITE template */
wqe = &lpfc_iwrite_cmd_template;
memset(wqe, 0, sizeof(union lpfc_wqe128));
@@ -176,15 +173,12 @@ void lpfc_wqe_cmd_template(void)
bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 0);
bf_set(wqe_wqes, &wqe->fcp_iwrite.wqe_com, 1);
- /* Word 11 - pbde is variable */
+ /* Word 11 */
bf_set(wqe_cmd_type, &wqe->fcp_iwrite.wqe_com, COMMAND_DATA_OUT);
bf_set(wqe_cqid, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
- bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 0);
/* Word 12 - is zero */
- /* Word 13, 14, 15 - PBDE is variable */
-
/* ICMND template */
wqe = &lpfc_icmnd_cmd_template;
memset(wqe, 0, sizeof(union lpfc_wqe128));
@@ -217,7 +211,6 @@ void lpfc_wqe_cmd_template(void)
/* Word 11 */
bf_set(wqe_cmd_type, &wqe->fcp_icmd.wqe_com, COMMAND_DATA_IN);
bf_set(wqe_cqid, &wqe->fcp_icmd.wqe_com, LPFC_WQE_CQ_ID_DEFAULT);
- bf_set(wqe_pbde, &wqe->fcp_icmd.wqe_com, 0);
/* Word 12, 13, 14, 15 - is zero */
}
@@ -8732,14 +8725,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
ftr_rsp++;
}
- /* Performance Hints are ONLY for FCoE */
- if (test_bit(HBA_FCOE_MODE, &phba->hba_flag)) {
- if (bf_get(lpfc_mbx_rq_ftr_rsp_perfh, &mqe->un.req_ftrs))
- phba->sli3_options |= LPFC_SLI4_PERFH_ENABLED;
- else
- phba->sli3_options &= ~LPFC_SLI4_PERFH_ENABLED;
- }
-
/*
* If the port cannot support the host's requested features
* then turn off the global config parameters to disable the
@@ -14337,13 +14322,15 @@ lpfc_sli4_sp_handle_mbox_event(struct lpfc_hba *phba, struct lpfc_mcqe *mcqe)
/* Get the reference to the active mbox command */
spin_lock_irqsave(&phba->hbalock, iflags);
pmb = phba->sli.mbox_active;
+ spin_unlock_irqrestore(&phba->hbalock, iflags);
if (unlikely(!pmb)) {
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
- "1832 No pending MBOX command to handle\n");
- spin_unlock_irqrestore(&phba->hbalock, iflags);
+ "1832 No pending MBOX command to handle, "
+ "mcqe: x%08x x%08x x%08x x%08x\n",
+ mcqe->word0, mcqe->mcqe_tag0,
+ mcqe->mcqe_tag1, mcqe->trailer);
goto out_no_mqe_complete;
}
- spin_unlock_irqrestore(&phba->hbalock, iflags);
mqe = &pmb->u.mqe;
pmbox = (MAILBOX_t *)&pmb->u.mqe;
mbox = phba->mbox;
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 2a5462a3ff64..2744786d9c94 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -841,6 +841,7 @@ struct lpfc_sli4_hba {
uint32_t ue_to_sr;
uint32_t ue_to_rp;
struct lpfc_register sli_intf;
+ struct lpfc_register asic_id;
struct lpfc_pc_sli4_params pc_sli4_params;
struct lpfc_bbscn_params bbscn_params;
struct lpfc_hba_eq_hdl *hba_eq_hdl; /* HBA per-WQ handle */
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 31a0cd9db1c2..d6e6e436fbfc 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -20,7 +20,7 @@
* included with this package. *
*******************************************************************/
-#define LPFC_DRIVER_VERSION "14.4.0.14"
+#define LPFC_DRIVER_VERSION "15.0.0.0"
#define LPFC_DRIVER_NAME "lpfc"
/* Used for SLI 2/3 */