]> git.baikalelectronics.ru Git - kernel.git/commitdiff
octeontx2-af: Support to enable/disable HW timestamping
authorZyta Szpak <zyta@marvell.com>
Mon, 24 Aug 2020 15:50:00 +0000 (21:20 +0530)
committerDavid S. Miller <davem@davemloft.net>
Tue, 25 Aug 2020 01:15:45 +0000 (18:15 -0700)
Four new mbox messages ids and handler are added in order to
enable or disable timestamping procedure on tx and rx side.
Additionally when PTP is enabled, the packet parser must skip
over 8 bytes and start analyzing packet data there. To make NPC
profiles work seemlesly PTR_ADVANCE of IKPU is set so that
parsing can be done as before when all data pointers
are shifted by 8 bytes automatically.

Co-developed-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: Zyta Szpak <zyta@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Acked-by: Jakub Kicinski <kuba@kernel.org>
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/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c

index a4e65da8d95b5de8cbabd96a6fe96c43695cff8f..8f17e26dca538cad2966bc2b86846c390c0df929 100644 (file)
@@ -468,6 +468,35 @@ static void cgx_lmac_pause_frm_config(struct cgx *cgx, int lmac_id, bool enable)
        }
 }
 
+void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable)
+{
+       struct cgx *cgx = cgxd;
+       u64 cfg;
+
+       if (!cgx)
+               return;
+
+       if (enable) {
+               /* Enable inbound PTP timestamping */
+               cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL);
+               cfg |= CGX_GMP_GMI_RXX_FRM_CTL_PTP_MODE;
+               cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg);
+
+               cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
+               cfg |= CGX_SMUX_RX_FRM_CTL_PTP_MODE;
+               cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);
+       } else {
+               /* Disable inbound PTP stamping */
+               cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL);
+               cfg &= ~CGX_GMP_GMI_RXX_FRM_CTL_PTP_MODE;
+               cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg);
+
+               cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
+               cfg &= ~CGX_SMUX_RX_FRM_CTL_PTP_MODE;
+               cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);
+       }
+}
+
 /* CGX Firmware interface low level support */
 static int cgx_fwi_cmd_send(u64 req, u64 *resp, struct lmac *lmac)
 {
index 394f96591feb4562fa2a25725def59b2352c92d6..27ca3291682bc031d84f0943a2490375472da6fd 100644 (file)
 
 #define CGXX_SMUX_RX_FRM_CTL           0x20020
 #define CGX_SMUX_RX_FRM_CTL_CTL_BCK    BIT_ULL(3)
+#define CGX_SMUX_RX_FRM_CTL_PTP_MODE   BIT_ULL(12)
 #define CGXX_GMP_GMI_RXX_FRM_CTL       0x38028
 #define CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK        BIT_ULL(3)
+#define CGX_GMP_GMI_RXX_FRM_CTL_PTP_MODE BIT_ULL(12)
 #define CGXX_SMUX_TX_CTL               0x20178
 #define CGXX_SMUX_TX_PAUSE_PKT_TIME    0x20110
 #define CGXX_SMUX_TX_PAUSE_PKT_INTERVAL        0x20120
@@ -139,4 +141,6 @@ int cgx_lmac_get_pause_frm(void *cgxd, int lmac_id,
                           u8 *tx_pause, u8 *rx_pause);
 int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
                           u8 tx_pause, u8 rx_pause);
+void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable);
+
 #endif /* CGX_H */
index 6dfd0f90cd704971cab55f336cbbe530a24211f5..c89b0980913a43723a66b855997d5b260395b134 100644 (file)
@@ -143,6 +143,8 @@ M(CGX_STOP_LINKEVENTS,      0x208, cgx_stop_linkevents, msg_req, msg_rsp)   \
 M(CGX_GET_LINKINFO,    0x209, cgx_get_linkinfo, msg_req, cgx_link_info_msg) \
 M(CGX_INTLBK_ENABLE,   0x20A, cgx_intlbk_enable, msg_req, msg_rsp)     \
 M(CGX_INTLBK_DISABLE,  0x20B, cgx_intlbk_disable, msg_req, msg_rsp)    \
+M(CGX_PTP_RX_ENABLE,   0x20C, cgx_ptp_rx_enable, msg_req, msg_rsp)     \
+M(CGX_PTP_RX_DISABLE,  0x20D, cgx_ptp_rx_disable, msg_req, msg_rsp)    \
 M(CGX_CFG_PAUSE_FRM,   0x20E, cgx_cfg_pause_frm, cgx_pause_frm_cfg,    \
                               cgx_pause_frm_cfg)                       \
 /* NPA mbox IDs (range 0x400 - 0x5FF) */                               \
@@ -213,6 +215,8 @@ M(NIX_LSO_FORMAT_CFG,       0x8011, nix_lso_format_cfg,                     \
                                 nix_lso_format_cfg,                    \
                                 nix_lso_format_cfg_rsp)                \
 M(NIX_RXVLAN_ALLOC,    0x8012, nix_rxvlan_alloc, msg_req, msg_rsp)     \
+M(NIX_LF_PTP_TX_ENABLE, 0x8013, nix_lf_ptp_tx_enable, msg_req, msg_rsp)        \
+M(NIX_LF_PTP_TX_DISABLE, 0x8014, nix_lf_ptp_tx_disable, msg_req, msg_rsp) \
 M(NIX_BP_ENABLE,       0x8016, nix_bp_enable, nix_bp_cfg_req,  \
                                nix_bp_cfg_rsp) \
 M(NIX_BP_DISABLE,      0x8017, nix_bp_disable, nix_bp_cfg_req, msg_rsp) \
index dcf25a0920084108ecf0d46e7154985cb22ce74f..62c3ed2fde28312c50a133c57c59d3616c800a91 100644 (file)
@@ -469,6 +469,7 @@ int rvu_npc_init(struct rvu *rvu);
 void rvu_npc_freemem(struct rvu *rvu);
 int rvu_npc_get_pkind(struct rvu *rvu, u16 pf);
 void rvu_npc_set_pkind(struct rvu *rvu, int pkind, struct rvu_pfvf *pfvf);
+int npc_config_ts_kpuaction(struct rvu *rvu, int pf, u16 pcifunc, bool en);
 void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
                                 int nixlf, u64 chan, u8 *mac_addr);
 void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
index f3c82e489897f943524eb70f203f1ada886ac3e3..fe3389c144b5d26efc298af4852a8d146b659ef1 100644 (file)
@@ -509,6 +509,45 @@ int rvu_mbox_handler_cgx_promisc_disable(struct rvu *rvu, struct msg_req *req,
        return 0;
 }
 
+static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
+{
+       int pf = rvu_get_pf(pcifunc);
+       u8 cgx_id, lmac_id;
+       void *cgxd;
+
+       /* This msg is expected only from PFs that are mapped to CGX LMACs,
+        * if received from other PF/VF simply ACK, nothing to do.
+        */
+       if ((pcifunc & RVU_PFVF_FUNC_MASK) ||
+           !is_pf_cgxmapped(rvu, pf))
+               return -ENODEV;
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+       cgxd = rvu_cgx_pdata(cgx_id, rvu);
+
+       cgx_lmac_ptp_config(cgxd, lmac_id, enable);
+       /* If PTP is enabled then inform NPC that packets to be
+        * parsed by this PF will have their data shifted by 8 bytes
+        * and if PTP is disabled then no shift is required
+        */
+       if (npc_config_ts_kpuaction(rvu, pf, pcifunc, enable))
+               return -EINVAL;
+
+       return 0;
+}
+
+int rvu_mbox_handler_cgx_ptp_rx_enable(struct rvu *rvu, struct msg_req *req,
+                                      struct msg_rsp *rsp)
+{
+       return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, true);
+}
+
+int rvu_mbox_handler_cgx_ptp_rx_disable(struct rvu *rvu, struct msg_req *req,
+                                       struct msg_rsp *rsp)
+{
+       return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, false);
+}
+
 static int rvu_cgx_config_linkevents(struct rvu *rvu, u16 pcifunc, bool en)
 {
        int pf = rvu_get_pf(pcifunc);
index 36953d4f51c73af7a710e1397a8431e5ab863a6a..bb8c607cdcba5382371f1bbe7cfe5f99efcb1102 100644 (file)
@@ -3319,6 +3319,49 @@ void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
        nix_ctx_free(rvu, pfvf);
 }
 
+#define NIX_AF_LFX_TX_CFG_PTP_EN       BIT_ULL(32)
+
+static int rvu_nix_lf_ptp_tx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
+{
+       struct rvu_hwinfo *hw = rvu->hw;
+       struct rvu_block *block;
+       int blkaddr;
+       int nixlf;
+       u64 cfg;
+
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+       if (blkaddr < 0)
+               return NIX_AF_ERR_AF_LF_INVALID;
+
+       block = &hw->block[blkaddr];
+       nixlf = rvu_get_lf(rvu, block, pcifunc, 0);
+       if (nixlf < 0)
+               return NIX_AF_ERR_AF_LF_INVALID;
+
+       cfg = rvu_read64(rvu, blkaddr, NIX_AF_LFX_TX_CFG(nixlf));
+
+       if (enable)
+               cfg |= NIX_AF_LFX_TX_CFG_PTP_EN;
+       else
+               cfg &= ~NIX_AF_LFX_TX_CFG_PTP_EN;
+
+       rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_CFG(nixlf), cfg);
+
+       return 0;
+}
+
+int rvu_mbox_handler_nix_lf_ptp_tx_enable(struct rvu *rvu, struct msg_req *req,
+                                         struct msg_rsp *rsp)
+{
+       return rvu_nix_lf_ptp_tx_cfg(rvu, req->hdr.pcifunc, true);
+}
+
+int rvu_mbox_handler_nix_lf_ptp_tx_disable(struct rvu *rvu, struct msg_req *req,
+                                          struct msg_rsp *rsp)
+{
+       return rvu_nix_lf_ptp_tx_cfg(rvu, req->hdr.pcifunc, false);
+}
+
 int rvu_mbox_handler_nix_lso_format_cfg(struct rvu *rvu,
                                        struct nix_lso_format_cfg *req,
                                        struct nix_lso_format_cfg_rsp *rsp)
index 0a214084406a65aa5ebb99f7c77696d1a4390a33..e2e585d4de9bc6fcaf2adad37a6417237fd21116 100644 (file)
@@ -27,6 +27,7 @@
 #define NIXLF_PROMISC_ENTRY    2
 
 #define NPC_PARSE_RESULT_DMAC_OFFSET   8
+#define NPC_HW_TSTAMP_OFFSET           8
 
 static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
                                      int blkaddr, u16 pcifunc);
@@ -61,6 +62,36 @@ int rvu_npc_get_pkind(struct rvu *rvu, u16 pf)
        return -1;
 }
 
+#define NPC_AF_ACTION0_PTR_ADVANCE     GENMASK_ULL(27, 20)
+
+int npc_config_ts_kpuaction(struct rvu *rvu, int pf, u16 pcifunc, bool enable)
+{
+       int pkind, blkaddr;
+       u64 val;
+
+       pkind = rvu_npc_get_pkind(rvu, pf);
+       if (pkind < 0) {
+               dev_err(rvu->dev, "%s: pkind not mapped\n", __func__);
+               return -EINVAL;
+       }
+
+       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, pcifunc);
+       if (blkaddr < 0) {
+               dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
+               return -EINVAL;
+       }
+
+       val = rvu_read64(rvu, blkaddr, NPC_AF_PKINDX_ACTION0(pkind));
+       val &= ~NPC_AF_ACTION0_PTR_ADVANCE;
+       /* If timestamp is enabled then configure NPC to shift 8 bytes */
+       if (enable)
+               val |= FIELD_PREP(NPC_AF_ACTION0_PTR_ADVANCE,
+                                 NPC_HW_TSTAMP_OFFSET);
+       rvu_write64(rvu, blkaddr, NPC_AF_PKINDX_ACTION0(pkind), val);
+
+       return 0;
+}
+
 static int npc_get_nixlf_mcam_index(struct npc_mcam *mcam,
                                    u16 pcifunc, int nixlf, int type)
 {