mirror of https://gitee.com/openkylin/linux.git
scsi: lpfc: Add FC-AL support to lpe32000 models
In the past, the lpe32000 models, based their main support being for 32G, and as FC-AL is not supported in the FC standards past 8G, did not support FC-AL operation. This patch adds private-loop FC-AL support for the LPE32000 adapters when a link is 8G or below. To avoid conditions where link rate may change, which would cause non-connectivity to the AL device, FC-AL mode must become a persistent setting and the link kept at a speed supporting FC-AL. The patch: - Adds a pls attribute indicating whether the adapter properly supports FC-AL. - Adds support for the adapter to indicate that topology should be fixed and the topology types to be configured. - Adds a pt attribute to report the persistent topology if present. Link: https://lore.kernel.org/r/20191018211832.7917-15-jsmart2021@gmail.com Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
e7d8595272
commit
83c6cb1ae8
|
@ -731,6 +731,7 @@ struct lpfc_hba {
|
|||
#define HBA_FCOE_MODE 0x4 /* HBA function in FCoE Mode */
|
||||
#define HBA_SP_QUEUE_EVT 0x8 /* Slow-path qevt posted to worker thread*/
|
||||
#define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */
|
||||
#define HBA_PERSISTENT_TOPO 0x20 /* Persistent topology support in hba */
|
||||
#define ELS_XRI_ABORT_EVENT 0x40
|
||||
#define ASYNC_EVENT 0x80
|
||||
#define LINK_DISABLED 0x100 /* Link disabled by user */
|
||||
|
|
|
@ -3535,6 +3535,31 @@ LPFC_ATTR_R(enable_rrq, 2, 0, 2,
|
|||
LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK,
|
||||
LPFC_DELAY_INIT_LINK_INDEFINITELY,
|
||||
"Suppress Link Up at initialization");
|
||||
|
||||
static ssize_t
|
||||
lpfc_pls_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct Scsi_Host *shost = class_to_shost(dev);
|
||||
struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n",
|
||||
phba->sli4_hba.pc_sli4_params.pls);
|
||||
}
|
||||
static DEVICE_ATTR(pls, 0444,
|
||||
lpfc_pls_show, NULL);
|
||||
|
||||
static ssize_t
|
||||
lpfc_pt_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct Scsi_Host *shost = class_to_shost(dev);
|
||||
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);
|
||||
}
|
||||
static DEVICE_ATTR(pt, 0444,
|
||||
lpfc_pt_show, NULL);
|
||||
|
||||
/*
|
||||
# lpfc_cnt: Number of IOCBs allocated for ELS, CT, and ABTS
|
||||
# 1 - (1024)
|
||||
|
@ -4095,7 +4120,16 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr,
|
|||
val);
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC ||
|
||||
/*
|
||||
* The 'topology' is not a configurable parameter if :
|
||||
* - persistent topology enabled
|
||||
* - G7 adapters
|
||||
* - G6 with no private loop support
|
||||
*/
|
||||
|
||||
if (((phba->hba_flag & HBA_PERSISTENT_TOPO) ||
|
||||
(!phba->sli4_hba.pc_sli4_params.pls &&
|
||||
phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC) ||
|
||||
phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) &&
|
||||
val == 4) {
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
|
||||
|
@ -6117,6 +6151,8 @@ struct device_attribute *lpfc_hba_attrs[] = {
|
|||
&dev_attr_lpfc_req_fw_upgrade,
|
||||
&dev_attr_lpfc_suppress_link_up,
|
||||
&dev_attr_iocb_hw,
|
||||
&dev_attr_pls,
|
||||
&dev_attr_pt,
|
||||
&dev_attr_txq_hw,
|
||||
&dev_attr_txcmplq_hw,
|
||||
&dev_attr_lpfc_fips_level,
|
||||
|
|
|
@ -2809,6 +2809,15 @@ struct lpfc_mbx_read_config {
|
|||
#define lpfc_mbx_rd_conf_trunk_SHIFT 12
|
||||
#define lpfc_mbx_rd_conf_trunk_MASK 0x0000000F
|
||||
#define lpfc_mbx_rd_conf_trunk_WORD word2
|
||||
#define lpfc_mbx_rd_conf_pt_SHIFT 20
|
||||
#define lpfc_mbx_rd_conf_pt_MASK 0x00000003
|
||||
#define lpfc_mbx_rd_conf_pt_WORD word2
|
||||
#define lpfc_mbx_rd_conf_tf_SHIFT 22
|
||||
#define lpfc_mbx_rd_conf_tf_MASK 0x00000001
|
||||
#define lpfc_mbx_rd_conf_tf_WORD word2
|
||||
#define lpfc_mbx_rd_conf_ptv_SHIFT 23
|
||||
#define lpfc_mbx_rd_conf_ptv_MASK 0x00000001
|
||||
#define lpfc_mbx_rd_conf_ptv_WORD word2
|
||||
#define lpfc_mbx_rd_conf_topology_SHIFT 24
|
||||
#define lpfc_mbx_rd_conf_topology_MASK 0x000000FF
|
||||
#define lpfc_mbx_rd_conf_topology_WORD word2
|
||||
|
@ -3479,6 +3488,9 @@ struct lpfc_sli4_parameters {
|
|||
#define cfg_bv1s_SHIFT 10
|
||||
#define cfg_bv1s_MASK 0x00000001
|
||||
#define cfg_bv1s_WORD word19
|
||||
#define cfg_pvl_SHIFT 13
|
||||
#define cfg_pvl_MASK 0x00000001
|
||||
#define cfg_pvl_WORD word19
|
||||
|
||||
#define cfg_nsler_SHIFT 12
|
||||
#define cfg_nsler_MASK 0x00000001
|
||||
|
|
|
@ -8239,6 +8239,94 @@ lpfc_destroy_bootstrap_mbox(struct lpfc_hba *phba)
|
|||
memset(&phba->sli4_hba.bmbx, 0, sizeof(struct lpfc_bmbx));
|
||||
}
|
||||
|
||||
static const char * const lpfc_topo_to_str[] = {
|
||||
"Loop then P2P",
|
||||
"Loopback",
|
||||
"P2P Only",
|
||||
"Unsupported",
|
||||
"Loop Only",
|
||||
"Unsupported",
|
||||
"P2P then Loop",
|
||||
};
|
||||
|
||||
/**
|
||||
* lpfc_map_topology - Map the topology read from READ_CONFIG
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
* @rdconf: pointer to read config data
|
||||
*
|
||||
* This routine is invoked to map the topology values as read
|
||||
* from the read config mailbox command. If the persistent
|
||||
* topology feature is supported, the firmware will provide the
|
||||
* saved topology information to be used in INIT_LINK
|
||||
*
|
||||
**/
|
||||
#define LINK_FLAGS_DEF 0x0
|
||||
#define LINK_FLAGS_P2P 0x1
|
||||
#define LINK_FLAGS_LOOP 0x2
|
||||
static void
|
||||
lpfc_map_topology(struct lpfc_hba *phba, struct lpfc_mbx_read_config *rd_config)
|
||||
{
|
||||
u8 ptv, tf, pt;
|
||||
|
||||
ptv = bf_get(lpfc_mbx_rd_conf_ptv, rd_config);
|
||||
tf = bf_get(lpfc_mbx_rd_conf_tf, rd_config);
|
||||
pt = bf_get(lpfc_mbx_rd_conf_pt, rd_config);
|
||||
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||
"2027 Read Config Data : ptv:0x%x, tf:0x%x pt:0x%x",
|
||||
ptv, tf, pt);
|
||||
if (!ptv) {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
|
||||
"2019 FW does not support persistent topology "
|
||||
"Using driver parameter defined value [%s]",
|
||||
lpfc_topo_to_str[phba->cfg_topology]);
|
||||
return;
|
||||
}
|
||||
/* FW supports persistent topology - override module parameter value */
|
||||
phba->hba_flag |= HBA_PERSISTENT_TOPO;
|
||||
switch (phba->pcidev->device) {
|
||||
case PCI_DEVICE_ID_LANCER_G7_FC:
|
||||
if (tf || (pt == LINK_FLAGS_LOOP)) {
|
||||
/* Invalid values from FW - use driver params */
|
||||
phba->hba_flag &= ~HBA_PERSISTENT_TOPO;
|
||||
} else {
|
||||
/* Prism only supports PT2PT topology */
|
||||
phba->cfg_topology = FLAGS_TOPOLOGY_MODE_PT_PT;
|
||||
}
|
||||
break;
|
||||
case PCI_DEVICE_ID_LANCER_G6_FC:
|
||||
if (!tf) {
|
||||
phba->cfg_topology = ((pt == LINK_FLAGS_LOOP)
|
||||
? FLAGS_TOPOLOGY_MODE_LOOP
|
||||
: FLAGS_TOPOLOGY_MODE_PT_PT);
|
||||
} else {
|
||||
phba->hba_flag &= ~HBA_PERSISTENT_TOPO;
|
||||
}
|
||||
break;
|
||||
default: /* G5 */
|
||||
if (tf) {
|
||||
/* If topology failover set - pt is '0' or '1' */
|
||||
phba->cfg_topology = (pt ? FLAGS_TOPOLOGY_MODE_PT_LOOP :
|
||||
FLAGS_TOPOLOGY_MODE_LOOP_PT);
|
||||
} else {
|
||||
phba->cfg_topology = ((pt == LINK_FLAGS_P2P)
|
||||
? FLAGS_TOPOLOGY_MODE_PT_PT
|
||||
: FLAGS_TOPOLOGY_MODE_LOOP);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (phba->hba_flag & HBA_PERSISTENT_TOPO) {
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||
"2020 Using persistent topology value [%s]",
|
||||
lpfc_topo_to_str[phba->cfg_topology]);
|
||||
} else {
|
||||
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
|
||||
"2021 Invalid topology values from FW "
|
||||
"Using driver parameter defined value [%s]",
|
||||
lpfc_topo_to_str[phba->cfg_topology]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_sli4_read_config - Get the config parameters.
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
|
@ -8350,6 +8438,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
|
|||
phba->max_vpi = (phba->sli4_hba.max_cfg_param.max_vpi > 0) ?
|
||||
(phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0;
|
||||
phba->max_vports = phba->max_vpi;
|
||||
lpfc_map_topology(phba, rd_config);
|
||||
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
|
||||
"2003 cfg params Extents? %d "
|
||||
"XRI(B:%d M:%d), "
|
||||
|
@ -11542,6 +11631,7 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
|
|||
sli4_params->cqav = bf_get(cfg_cqav, mbx_sli4_parameters);
|
||||
sli4_params->wqsize = bf_get(cfg_wqsize, mbx_sli4_parameters);
|
||||
sli4_params->bv1s = bf_get(cfg_bv1s, mbx_sli4_parameters);
|
||||
sli4_params->pls = bf_get(cfg_pvl, mbx_sli4_parameters);
|
||||
sli4_params->sgl_pages_max = bf_get(cfg_sgl_page_cnt,
|
||||
mbx_sli4_parameters);
|
||||
sli4_params->wqpcnt = bf_get(cfg_wqpcnt, mbx_sli4_parameters);
|
||||
|
|
|
@ -515,6 +515,7 @@ lpfc_init_link(struct lpfc_hba * phba,
|
|||
|
||||
if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC ||
|
||||
phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) &&
|
||||
!(phba->sli4_hba.pc_sli4_params.pls) &&
|
||||
mb->un.varInitLnk.link_flags & FLAGS_TOPOLOGY_MODE_LOOP) {
|
||||
mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
|
||||
phba->cfg_topology = FLAGS_TOPOLOGY_MODE_PT_PT;
|
||||
|
|
|
@ -514,6 +514,7 @@ struct lpfc_pc_sli4_params {
|
|||
uint8_t cqav;
|
||||
uint8_t wqsize;
|
||||
uint8_t bv1s;
|
||||
uint8_t pls;
|
||||
#define LPFC_WQ_SZ64_SUPPORT 1
|
||||
#define LPFC_WQ_SZ128_SUPPORT 2
|
||||
uint8_t wqpcnt;
|
||||
|
|
Loading…
Reference in New Issue