octeontx2-af: Reset MAC features in FLR
authorHariprasad Kelam <hkelam@marvell.com>
Fri, 30 Jun 2023 06:28:45 +0000 (11:58 +0530)
committerDavid S. Miller <davem@davemloft.net>
Sun, 2 Jul 2023 14:47:19 +0000 (15:47 +0100)
AF driver configures MAC features like internal loopback and PFC upon
receiving the request from PF and its VF netdev. But these
features are not getting reset in FLR.  This patch fixes the issue by
resetting the same.

Fixes: 23999b30ae67 ("octeontx2-af: Enable or disable CGX internal loopback")
Fixes: 1121f6b02e7a ("octeontx2-af: Priority flow control configuration support")
Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/af/cgx.c
drivers/net/ethernet/marvell/octeontx2/af/cgx.h
drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h
drivers/net/ethernet/marvell/octeontx2/af/rpm.c
drivers/net/ethernet/marvell/octeontx2/af/rpm.h
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c

index f4bdca662d616452358065570172d62f873894bf..592037f4e55b60670723a63ccba48258cf0c83b7 100644 (file)
@@ -537,14 +537,15 @@ static u32 cgx_get_lmac_fifo_len(void *cgxd, int lmac_id)
 int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable)
 {
        struct cgx *cgx = cgxd;
-       u8 lmac_type;
+       struct lmac *lmac;
        u64 cfg;
 
        if (!is_lmac_valid(cgx, lmac_id))
                return -ENODEV;
 
-       lmac_type = cgx->mac_ops->get_lmac_type(cgx, lmac_id);
-       if (lmac_type == LMAC_MODE_SGMII || lmac_type == LMAC_MODE_QSGMII) {
+       lmac = lmac_pdata(lmac_id, cgx);
+       if (lmac->lmac_type == LMAC_MODE_SGMII ||
+           lmac->lmac_type == LMAC_MODE_QSGMII) {
                cfg = cgx_read(cgx, lmac_id, CGXX_GMP_PCS_MRX_CTL);
                if (enable)
                        cfg |= CGXX_GMP_PCS_MRX_CTL_LBK;
@@ -1563,6 +1564,23 @@ int cgx_lmac_linkup_start(void *cgxd)
        return 0;
 }
 
+int cgx_lmac_reset(void *cgxd, int lmac_id, u8 pf_req_flr)
+{
+       struct cgx *cgx = cgxd;
+       u64 cfg;
+
+       if (!is_lmac_valid(cgx, lmac_id))
+               return -ENODEV;
+
+       /* Resetting PFC related CSRs */
+       cfg = 0xff;
+       cgx_write(cgxd, lmac_id, CGXX_CMRX_RX_LOGL_XON, cfg);
+
+       if (pf_req_flr)
+               cgx_lmac_internal_loopback(cgxd, lmac_id, false);
+       return 0;
+}
+
 static int cgx_configure_interrupt(struct cgx *cgx, struct lmac *lmac,
                                   int cnt, bool req_free)
 {
@@ -1682,6 +1700,7 @@ static int cgx_lmac_init(struct cgx *cgx)
                cgx->lmac_idmap[lmac->lmac_id] = lmac;
                set_bit(lmac->lmac_id, &cgx->lmac_bmap);
                cgx->mac_ops->mac_pause_frm_config(cgx, lmac->lmac_id, true);
+               lmac->lmac_type = cgx->mac_ops->get_lmac_type(cgx, lmac->lmac_id);
        }
 
        return cgx_lmac_verify_fwi_version(cgx);
@@ -1778,6 +1797,7 @@ static struct mac_ops     cgx_mac_ops    = {
        .mac_tx_enable =                cgx_lmac_tx_enable,
        .pfc_config =                   cgx_lmac_pfc_config,
        .mac_get_pfc_frm_cfg   =        cgx_lmac_get_pfc_frm_cfg,
+       .mac_reset   =                  cgx_lmac_reset,
 };
 
 static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
index 5a20d93004c7181a37a2c862f57edc8ad10a6957..5741141796880a6068bd8560c6f56cf945906550 100644 (file)
@@ -35,6 +35,7 @@
 #define CGXX_CMRX_INT_ENA_W1S          0x058
 #define CGXX_CMRX_RX_ID_MAP            0x060
 #define CGXX_CMRX_RX_STAT0             0x070
+#define CGXX_CMRX_RX_LOGL_XON          0x100
 #define CGXX_CMRX_RX_LMACS             0x128
 #define CGXX_CMRX_RX_DMAC_CTL0         (0x1F8 + mac_ops->csr_offset)
 #define CGX_DMAC_CTL0_CAM_ENABLE       BIT_ULL(3)
@@ -181,4 +182,5 @@ int cgx_lmac_get_pfc_frm_cfg(void *cgxd, int lmac_id, u8 *tx_pause,
                             u8 *rx_pause);
 int verify_lmac_fc_cfg(void *cgxd, int lmac_id, u8 tx_pause, u8 rx_pause,
                       int pfvf_idx);
+int cgx_lmac_reset(void *cgxd, int lmac_id, u8 pf_req_flr);
 #endif /* CGX_H */
index 39aaf0e4467dcffddc77f359e59987eb2fefe0b6..0b4cba03f2e8371012af5f71e3b763dc7dcac7c3 100644 (file)
@@ -24,6 +24,7 @@
  * @cgx:               parent cgx port
  * @mcast_filters_count:  Number of multicast filters installed
  * @lmac_id:           lmac port id
+ * @lmac_type:         lmac type like SGMII/XAUI
  * @cmd_pend:          flag set before new command is started
  *                     flag cleared after command response is received
  * @name:              lmac port name
@@ -43,6 +44,7 @@ struct lmac {
        struct cgx *cgx;
        u8 mcast_filters_count;
        u8 lmac_id;
+       u8 lmac_type;
        bool cmd_pend;
        char *name;
 };
@@ -125,6 +127,7 @@ struct mac_ops {
 
        int                     (*mac_get_pfc_frm_cfg)(void *cgxd, int lmac_id,
                                                       u8 *tx_pause, u8 *rx_pause);
+       int                     (*mac_reset)(void *cgxd, int lmac_id, u8 pf_req_flr);
 
        /* FEC stats */
        int                     (*get_fec_stats)(void *cgxd, int lmac_id,
index a433f92c51eae63bc6b44e287e27e0e71bcb5ab3..b4fcb20c3f4fddb5512fcd2cb211fba521dc7b76 100644 (file)
@@ -37,6 +37,7 @@ static struct mac_ops         rpm_mac_ops   = {
        .mac_tx_enable =                rpm_lmac_tx_enable,
        .pfc_config =                   rpm_lmac_pfc_config,
        .mac_get_pfc_frm_cfg   =        rpm_lmac_get_pfc_frm_cfg,
+       .mac_reset   =                  rpm_lmac_reset,
 };
 
 static struct mac_ops          rpm2_mac_ops   = {
@@ -68,6 +69,7 @@ static struct mac_ops         rpm2_mac_ops   = {
        .mac_tx_enable =                rpm_lmac_tx_enable,
        .pfc_config =                   rpm_lmac_pfc_config,
        .mac_get_pfc_frm_cfg   =        rpm_lmac_get_pfc_frm_cfg,
+       .mac_reset   =                  rpm_lmac_reset,
 };
 
 bool is_dev_rpm2(void *rpmd)
@@ -537,14 +539,15 @@ u32 rpm2_get_lmac_fifo_len(void *rpmd, int lmac_id)
 int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable)
 {
        rpm_t *rpm = rpmd;
-       u8 lmac_type;
+       struct lmac *lmac;
        u64 cfg;
 
        if (!is_lmac_valid(rpm, lmac_id))
                return -ENODEV;
-       lmac_type = rpm->mac_ops->get_lmac_type(rpm, lmac_id);
 
-       if (lmac_type == LMAC_MODE_QSGMII || lmac_type == LMAC_MODE_SGMII) {
+       lmac = lmac_pdata(lmac_id, rpm);
+       if (lmac->lmac_type == LMAC_MODE_QSGMII ||
+           lmac->lmac_type == LMAC_MODE_SGMII) {
                dev_err(&rpm->pdev->dev, "loopback not supported for LPC mode\n");
                return 0;
        }
@@ -713,3 +716,24 @@ int rpm_get_fec_stats(void *rpmd, int lmac_id, struct cgx_fec_stats_rsp *rsp)
 
        return 0;
 }
+
+int rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr)
+{
+       u64 rx_logl_xon, cfg;
+       rpm_t *rpm = rpmd;
+
+       if (!is_lmac_valid(rpm, lmac_id))
+               return -ENODEV;
+
+       /* Resetting PFC related CSRs */
+       rx_logl_xon = is_dev_rpm2(rpm) ? RPM2_CMRX_RX_LOGL_XON :
+                                        RPMX_CMRX_RX_LOGL_XON;
+       cfg = 0xff;
+
+       rpm_write(rpm, lmac_id, rx_logl_xon, cfg);
+
+       if (pf_req_flr)
+               rpm_lmac_internal_loopback(rpm, lmac_id, false);
+
+       return 0;
+}
index be294eebab26512e06ebc3d35ec10c4334a43f17..b79cfbc6f87705f38627ae83d55a329cf0c4c922 100644 (file)
@@ -74,6 +74,7 @@
 #define RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA              0x80A8
 #define RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA             0x8108
 #define RPM_DEFAULT_PAUSE_TIME                          0x7FF
+#define RPMX_CMRX_RX_LOGL_XON                          0x4100
 
 #define RPMX_MTI_MAC100X_XIF_MODE                      0x8100
 #define RPMX_ONESTEP_ENABLE                            BIT_ULL(5)
@@ -132,4 +133,5 @@ int rpm_lmac_get_pfc_frm_cfg(void *rpmd, int lmac_id, u8 *tx_pause,
 int rpm2_get_nr_lmacs(void *rpmd);
 bool is_dev_rpm2(void *rpmd);
 int rpm_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp);
+int rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr);
 #endif /* RPM_H */
index 0069e60afa3b024c656461ae84668d23091a707c..8dbc35c481f6b28ebc9e3c4fdddfd570d27c5dc4 100644 (file)
@@ -2629,6 +2629,7 @@ static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc)
         * Since LF is detached use LF number as -1.
         */
        rvu_npc_free_mcam_entries(rvu, pcifunc, -1);
+       rvu_mac_reset(rvu, pcifunc);
 
        mutex_unlock(&rvu->flr_lock);
 }
index d4b8d4546de2e702478dfb34fede10f7cc6fbf65..e8e65fd7888dfb283b3b9da41a6b980fd939732a 100644 (file)
@@ -895,6 +895,7 @@ int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable);
 int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause,
                               u16 pfc_en);
 int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause);
+void rvu_mac_reset(struct rvu *rvu, u16 pcifunc);
 u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac);
 int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
                             int type);
index 48611e60322841b8ee92a96b452d771b78c74ba3..4b8559ac0404f05aa3996fb09975a20b57202c89 100644 (file)
@@ -1250,3 +1250,21 @@ int rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu *rvu,
        mac_ops->mac_get_pfc_frm_cfg(cgxd, lmac_id, &rsp->tx_pause, &rsp->rx_pause);
        return err;
 }
+
+void rvu_mac_reset(struct rvu *rvu, u16 pcifunc)
+{
+       int pf = rvu_get_pf(pcifunc);
+       struct mac_ops *mac_ops;
+       struct cgx *cgxd;
+       u8 cgx, lmac;
+
+       if (!is_pf_cgxmapped(rvu, pf))
+               return;
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx, &lmac);
+       cgxd = rvu_cgx_pdata(cgx, rvu);
+       mac_ops = get_mac_ops(cgxd);
+
+       if (mac_ops->mac_reset(cgxd, lmac, !is_vf(pcifunc)))
+               dev_err(rvu->dev, "Failed to reset MAC\n");
+}