octeontx2-pf: Reset MAC stats during probe
authorSai Krishna <saikrishnag@marvell.com>
Sun, 31 Mar 2024 12:48:19 +0000 (18:18 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 3 Apr 2024 10:03:40 +0000 (11:03 +0100)
Reset CGX/RPM MAC HW statistics at the time of driver probe()

Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
Signed-off-by: Sai Krishna <saikrishnag@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/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/rpm.c
drivers/net/ethernet/marvell/octeontx2/af/rpm.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c

index b86f3224f0b783015367f160f191a81470756345..27935c54b91bc7acb1467d9a892e1c0ecbbc6399 100644 (file)
@@ -24,6 +24,8 @@
 #define DRV_NAME       "Marvell-CGX/RPM"
 #define DRV_STRING      "Marvell CGX/RPM Driver"
 
+#define CGX_RX_STAT_GLOBAL_INDEX       9
+
 static LIST_HEAD(cgx_list);
 
 /* Convert firmware speed encoding to user format(Mbps) */
@@ -701,6 +703,30 @@ u64 cgx_features_get(void *cgxd)
        return ((struct cgx *)cgxd)->hw_features;
 }
 
+int cgx_stats_reset(void *cgxd, int lmac_id)
+{
+       struct cgx *cgx = cgxd;
+       int stat_id;
+
+       if (!is_lmac_valid(cgx, lmac_id))
+               return -ENODEV;
+
+       for (stat_id = 0 ; stat_id < CGX_RX_STATS_COUNT; stat_id++) {
+               if (stat_id >= CGX_RX_STAT_GLOBAL_INDEX)
+               /* pass lmac as 0 for CGX_CMR_RX_STAT9-12 */
+                       cgx_write(cgx, 0,
+                                 (CGXX_CMRX_RX_STAT0 + (stat_id * 8)), 0);
+               else
+                       cgx_write(cgx, lmac_id,
+                                 (CGXX_CMRX_RX_STAT0 + (stat_id * 8)), 0);
+       }
+
+       for (stat_id = 0 ; stat_id < CGX_TX_STATS_COUNT; stat_id++)
+               cgx_write(cgx, lmac_id, CGXX_CMRX_TX_STAT0 + (stat_id * 8), 0);
+
+       return 0;
+}
+
 static int cgx_set_fec_stats_count(struct cgx_link_user_info *linfo)
 {
        if (!linfo->fec)
@@ -1788,6 +1814,7 @@ static struct mac_ops     cgx_mac_ops    = {
        .pfc_config =                   cgx_lmac_pfc_config,
        .mac_get_pfc_frm_cfg   =        cgx_lmac_get_pfc_frm_cfg,
        .mac_reset   =                  cgx_lmac_reset,
+       .mac_stats_reset       =        cgx_stats_reset,
 };
 
 static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
index 6f7d1dee58308c8ac3f3e6e1a995831c57c4fcac..dc9ace30554af67a5849a945101e599e648cd4d4 100644 (file)
@@ -141,6 +141,7 @@ int cgx_lmac_evh_register(struct cgx_event_cb *cb, void *cgxd, int lmac_id);
 int cgx_lmac_evh_unregister(void *cgxd, int lmac_id);
 int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat);
 int cgx_get_rx_stats(void *cgxd, int lmac_id, int idx, u64 *rx_stat);
+int cgx_stats_reset(void *cgxd, int lmac_id);
 int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable);
 int cgx_lmac_tx_enable(void *cgxd, int lmac_id, bool enable);
 int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr);
index 0b4cba03f2e8371012af5f71e3b763dc7dcac7c3..9ffc6790c51307caced691e23f2e4aff24e922a5 100644 (file)
@@ -132,6 +132,7 @@ struct mac_ops {
        /* FEC stats */
        int                     (*get_fec_stats)(void *cgxd, int lmac_id,
                                                 struct cgx_fec_stats_rsp *rsp);
+       int                     (*mac_stats_reset)(void *cgxd, int lmac_id);
 };
 
 struct cgx {
index 3d801a1a4f701895e72ce237710e05505998dfb7..4a77f6fe262207032e8538ffc8ea8c6c565045da 100644 (file)
@@ -174,6 +174,7 @@ M(CGX_FEC_STATS,    0x217, cgx_fec_stats, msg_req, cgx_fec_stats_rsp) \
 M(CGX_SET_LINK_MODE,   0x218, cgx_set_link_mode, cgx_set_link_mode_req,\
                               cgx_set_link_mode_rsp)   \
 M(CGX_GET_PHY_FEC_STATS, 0x219, cgx_get_phy_fec_stats, msg_req, msg_rsp) \
+M(CGX_STATS_RST,       0x21A, cgx_stats_rst, msg_req, msg_rsp)         \
 M(CGX_FEATURES_GET,    0x21B, cgx_features_get, msg_req,               \
                               cgx_features_info_msg)                   \
 M(RPM_STATS,           0x21C, rpm_stats, msg_req, rpm_stats_rsp)       \
index 76218f1cb45958f3963ed340997051846093ec94..1b34cf9c97035a6b90f8c61e056750b97c713018 100644 (file)
@@ -38,6 +38,7 @@ static struct mac_ops         rpm_mac_ops   = {
        .pfc_config =                   rpm_lmac_pfc_config,
        .mac_get_pfc_frm_cfg   =        rpm_lmac_get_pfc_frm_cfg,
        .mac_reset   =                  rpm_lmac_reset,
+       .mac_stats_reset                 =        rpm_stats_reset,
 };
 
 static struct mac_ops          rpm2_mac_ops   = {
@@ -70,6 +71,7 @@ static struct mac_ops         rpm2_mac_ops   = {
        .pfc_config =                   rpm_lmac_pfc_config,
        .mac_get_pfc_frm_cfg   =        rpm_lmac_get_pfc_frm_cfg,
        .mac_reset   =                  rpm_lmac_reset,
+       .mac_stats_reset            =   rpm_stats_reset,
 };
 
 bool is_dev_rpm2(void *rpmd)
@@ -443,6 +445,21 @@ int rpm_get_tx_stats(void *rpmd, int lmac_id, int idx, u64 *tx_stat)
        return 0;
 }
 
+int rpm_stats_reset(void *rpmd, int lmac_id)
+{
+       rpm_t *rpm = rpmd;
+       u64 cfg;
+
+       if (!is_lmac_valid(rpm, lmac_id))
+               return -ENODEV;
+
+       cfg = rpm_read(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL);
+       cfg |= RPMX_CMD_CLEAR_TX | RPMX_CMD_CLEAR_RX | BIT_ULL(lmac_id);
+       rpm_write(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL, cfg);
+
+       return 0;
+}
+
 u8 rpm_get_lmac_type(void *rpmd, int lmac_id)
 {
        rpm_t *rpm = rpmd;
index b79cfbc6f87705f38627ae83d55a329cf0c4c922..34b11deb0f3c1dd34514baeb8a84375cee914cc9 100644 (file)
@@ -85,6 +85,8 @@
 #define RPMX_MTI_STAT_STATN_CONTROL                    0x10018
 #define RPMX_MTI_STAT_DATA_HI_CDC                      0x10038
 #define RPMX_RSFEC_RX_CAPTURE                          BIT_ULL(27)
+#define RPMX_CMD_CLEAR_RX                              BIT_ULL(30)
+#define RPMX_CMD_CLEAR_TX                              BIT_ULL(31)
 #define RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_2          0x40050
 #define RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_3          0x40058
 #define RPMX_MTI_FCFECX_VL0_CCW_LO                     0x38618
@@ -134,4 +136,5 @@ 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);
+int rpm_stats_reset(void *rpmd, int lmac_id);
 #endif /* RPM_H */
index 72e060cf6b6181d9ccd22b2f3a126c6b7f063a83..9d2836077d9fbbe09baf991b046340e4bfc4ea76 100644 (file)
@@ -602,6 +602,35 @@ int rvu_mbox_handler_rpm_stats(struct rvu *rvu, struct msg_req *req,
        return rvu_lmac_get_stats(rvu, req, (void *)rsp);
 }
 
+int rvu_mbox_handler_cgx_stats_rst(struct rvu *rvu, struct msg_req *req,
+                                  struct msg_rsp *rsp)
+{
+       int pf = rvu_get_pf(req->hdr.pcifunc);
+       struct rvu_pfvf *parent_pf;
+       struct mac_ops *mac_ops;
+       u8 cgx_idx, lmac;
+       void *cgxd;
+
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+               return LMAC_AF_ERR_PERM_DENIED;
+
+       parent_pf = &rvu->pf[pf];
+       /* To ensure reset cgx stats won't affect VF stats,
+        *  check if it used by only PF interface.
+        *  If not, return
+        */
+       if (parent_pf->cgx_users > 1) {
+               dev_info(rvu->dev, "CGX busy, could not reset statistics\n");
+               return 0;
+       }
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
+       cgxd = rvu_cgx_pdata(cgx_idx, rvu);
+       mac_ops = get_mac_ops(cgxd);
+
+       return mac_ops->mac_stats_reset(cgxd, lmac);
+}
+
 int rvu_mbox_handler_cgx_fec_stats(struct rvu *rvu,
                                   struct msg_req *req,
                                   struct cgx_fec_stats_rsp *rsp)
index 7e16a341ec588f2818154827cf7a08cbe9d256a9..c5de3ba33e2f0e363fb2d2944fa401a944fc8848 100644 (file)
@@ -961,6 +961,7 @@ void otx2_get_mac_from_af(struct net_device *netdev);
 void otx2_config_irq_coalescing(struct otx2_nic *pfvf, int qidx);
 int otx2_config_pause_frm(struct otx2_nic *pfvf);
 void otx2_setup_segmentation(struct otx2_nic *pfvf);
+int otx2_reset_mac_stats(struct otx2_nic *pfvf);
 
 /* RVU block related APIs */
 int otx2_attach_npa_nix(struct otx2_nic *pfvf);
index 5d8359b540985a197e535cf0809302e3f9fcf265..9afeefea3b65037744851851871cadc1169b2fa1 100644 (file)
@@ -1146,6 +1146,23 @@ static int otx2_cgx_config_linkevents(struct otx2_nic *pf, bool enable)
        return err;
 }
 
+int otx2_reset_mac_stats(struct otx2_nic *pfvf)
+{
+       struct msg_req *req;
+       int err;
+
+       mutex_lock(&pfvf->mbox.lock);
+       req = otx2_mbox_alloc_msg_cgx_stats_rst(&pfvf->mbox);
+       if (!req) {
+               mutex_unlock(&pfvf->mbox.lock);
+               return -ENOMEM;
+       }
+
+       err = otx2_sync_mbox_msg(&pfvf->mbox);
+       mutex_unlock(&pfvf->mbox.lock);
+       return err;
+}
+
 static int otx2_cgx_config_loopback(struct otx2_nic *pf, bool enable)
 {
        struct msg_req *msg;
@@ -3034,6 +3051,9 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        netdev->min_mtu = OTX2_MIN_MTU;
        netdev->max_mtu = otx2_get_max_mtu(pf);
 
+       /* reset CGX/RPM MAC stats */
+       otx2_reset_mac_stats(pf);
+
        err = register_netdev(netdev);
        if (err) {
                dev_err(dev, "Failed to register netdevice\n");