octeontx2-af: Enable or disable CGX internal loopback
authorGeetha sowjanya <gakula@marvell.com>
Tue, 16 Oct 2018 11:27:10 +0000 (16:57 +0530)
committerDavid S. Miller <davem@davemloft.net>
Thu, 18 Oct 2018 04:33:42 +0000 (21:33 -0700)
Add support to enable or disable internal loopback mode in CGX.
New mbox IDs CGX_INTLBK_ENABLE/DISABLE added for this.

Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Signed-off-by: Linu Cherian <lcherian@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/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c

index 077f83f4f2f0824f98e8b22f16fb2fd7a0a7910c..352501b54aee6b10fdc105d29365d8fe3d85d82c 100644 (file)
@@ -194,6 +194,36 @@ static inline u8 cgx_get_lmac_type(struct cgx *cgx, int lmac_id)
        return (cfg >> CGX_LMAC_TYPE_SHIFT) & CGX_LMAC_TYPE_MASK;
 }
 
+/* Configure CGX LMAC in internal loopback mode */
+int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable)
+{
+       struct cgx *cgx = cgxd;
+       u8 lmac_type;
+       u64 cfg;
+
+       if (!cgx || lmac_id >= cgx->lmac_count)
+               return -ENODEV;
+
+       lmac_type = cgx_get_lmac_type(cgx, lmac_id);
+       if (lmac_type == LMAC_MODE_SGMII || 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;
+               else
+                       cfg &= ~CGXX_GMP_PCS_MRX_CTL_LBK;
+               cgx_write(cgx, lmac_id, CGXX_GMP_PCS_MRX_CTL, cfg);
+       } else {
+               cfg = cgx_read(cgx, lmac_id, CGXX_SPUX_CONTROL1);
+               if (enable)
+                       cfg |= CGXX_SPUX_CONTROL1_LBK;
+               else
+                       cfg &= ~CGXX_SPUX_CONTROL1_LBK;
+               cgx_write(cgx, lmac_id, CGXX_SPUX_CONTROL1, cfg);
+       }
+       return 0;
+}
+EXPORT_SYMBOL(cgx_lmac_internal_loopback);
+
 void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable)
 {
        struct cgx *cgx = cgx_get_pdata(cgx_id);
index c89edfaacbe61faebe0c8ed07cc74bd19d2ae9b0..ada25ed0765bf1ff9e8bd4019a39d0bf7228ba25 100644 (file)
 #define CGXX_SCRATCH0_REG              0x1050
 #define CGXX_SCRATCH1_REG              0x1058
 #define CGX_CONST                      0x2000
+#define CGXX_SPUX_CONTROL1             0x10000
+#define  CGXX_SPUX_CONTROL1_LBK                        BIT_ULL(14)
+#define CGXX_GMP_PCS_MRX_CTL           0x30000
+#define  CGXX_GMP_PCS_MRX_CTL_LBK              BIT_ULL(14)
 
 #define CGX_COMMAND_REG                        CGXX_SCRATCH1_REG
 #define CGX_EVENT_REG                  CGXX_SCRATCH0_REG
@@ -100,6 +104,7 @@ int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable);
 int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr);
 u64 cgx_lmac_addr_get(u8 cgx_id, u8 lmac_id);
 void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable);
+int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable);
 int cgx_get_link_info(void *cgxd, int lmac_id,
                      struct cgx_link_user_info *linfo);
 #endif /* CGX_H */
index 9f3790b507a6aec31d3e61122aa97321e1621d92..be1cb16c18e0bbbb552281a8d9ab09a406825bf0 100644 (file)
@@ -136,6 +136,8 @@ M(CGX_PROMISC_DISABLE,      0x206, msg_req, msg_rsp)                        \
 M(CGX_START_LINKEVENTS, 0x207, msg_req, msg_rsp)                       \
 M(CGX_STOP_LINKEVENTS, 0x208, msg_req, msg_rsp)                        \
 M(CGX_GET_LINKINFO,    0x209, msg_req, cgx_link_info_msg)              \
+M(CGX_INTLBK_ENABLE,   0x20A, msg_req, msg_rsp)                        \
+M(CGX_INTLBK_DISABLE,  0x20B, msg_req, msg_rsp)                        \
 /* NPA mbox IDs (range 0x400 - 0x5FF) */                               \
 /* SSO/SSOW mbox IDs (range 0x600 - 0x7FF) */                          \
 /* TIM mbox IDs (range 0x800 - 0x9FF) */                               \
index 83478086ddb871b4bfafd854acafedd8bb53e9da..88454cb90bb4ab1362cf0100b227fcbc52fbf387 100644 (file)
@@ -192,4 +192,8 @@ int rvu_mbox_handler_CGX_STOP_LINKEVENTS(struct rvu *rvu, struct msg_req *req,
                                         struct msg_rsp *rsp);
 int rvu_mbox_handler_CGX_GET_LINKINFO(struct rvu *rvu, struct msg_req *req,
                                      struct cgx_link_info_msg *rsp);
+int rvu_mbox_handler_CGX_INTLBK_ENABLE(struct rvu *rvu, struct msg_req *req,
+                                      struct msg_rsp *rsp);
+int rvu_mbox_handler_CGX_INTLBK_DISABLE(struct rvu *rvu, struct msg_req *req,
+                                       struct msg_rsp *rsp);
 #endif /* RVU_H */
index e917f28b220c4d3addb5f4f6e5f5734691c19dea..e0aee217663755556950f9d644850a1cce3ab0b8 100644 (file)
@@ -479,3 +479,34 @@ int rvu_mbox_handler_CGX_GET_LINKINFO(struct rvu *rvu, struct msg_req *req,
                                &rsp->link_info);
        return err;
 }
+
+static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en)
+{
+       int pf = rvu_get_pf(pcifunc);
+       u8 cgx_id, lmac_id;
+
+       /* 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);
+
+       return cgx_lmac_internal_loopback(rvu_cgx_pdata(cgx_id, rvu),
+                                         lmac_id, en);
+}
+
+int rvu_mbox_handler_CGX_INTLBK_ENABLE(struct rvu *rvu, struct msg_req *req,
+                                      struct msg_rsp *rsp)
+{
+       rvu_cgx_config_intlbk(rvu, req->hdr.pcifunc, true);
+       return 0;
+}
+
+int rvu_mbox_handler_CGX_INTLBK_DISABLE(struct rvu *rvu, struct msg_req *req,
+                                       struct msg_rsp *rsp)
+{
+       rvu_cgx_config_intlbk(rvu, req->hdr.pcifunc, false);
+       return 0;
+}