]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
scsi: lpfc: Add FC-AL support to lpe32000 models
authorJames Smart <jsmart2021@gmail.com>
Fri, 18 Oct 2019 21:18:30 +0000 (14:18 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 25 Oct 2019 01:02:06 +0000 (21:02 -0400)
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>
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_hw4.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_mbox.c
drivers/scsi/lpfc/lpfc_sli4.h

index 884d6076d7aab7b3f52b95cc7eeec671961451f2..4559f1700c6d51382a0570fd3d30184f9da33173 100644 (file)
@@ -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 */
index ba504cc6e8ede42c3975ab59dd7e52b5a62abdd1..e738c1529d2d7139609c6d37d947d19c7a7e4c43 100644 (file)
@@ -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,
index 818a0f4325af7b47a18ee80bf53aef1ecf6e145c..d40bfe5aa21fef4dc673d3aff11904773233fb98 100644 (file)
@@ -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
index d821adbb00475c6e91175a67d9005495ef3627d0..686677dd52a44ae587c3756005bc9ce34b400ffd 100644 (file)
@@ -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);
index 8abe933bad090d23b2799bb91577f4e0bef2ee97..d1773c01d2b303b5a28463a0f3b7d5f33f136c1f 100644 (file)
@@ -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;
index c9e068ca0fec32067b78b045dc62aa55adabb85b..bbe24c19b1d93041aaa57323efcef340e544f9e6 100644 (file)
@@ -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;