]> git.baikalelectronics.ru Git - kernel.git/commitdiff
octeontx2-af: cn10k: mcs: Add mailboxes for port related operations
authorGeetha sowjanya <gakula@marvell.com>
Sat, 1 Oct 2022 04:59:43 +0000 (10:29 +0530)
committerDavid S. Miller <davem@davemloft.net>
Mon, 3 Oct 2022 11:50:18 +0000 (12:50 +0100)
There are set of configurations to be done at MCS port level like
bringing port out of reset, making port as operational or bypass.
This patch adds all the port related mailbox message handlers
so that AF consumers can use them.

Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Signed-off-by: Vamsi Attunuru <vattunuru@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/mcs.c
drivers/net/ethernet/marvell/octeontx2/af/mcs.h
drivers/net/ethernet/marvell/octeontx2/af/mcs_reg.h
drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c

index e26c3b0c4dcbc6430ff129bc1e2dc56243eccd64..207cd4fa6980e6f6bb228e193164cd2263e4cd83 100644 (file)
@@ -293,9 +293,21 @@ M(NIX_BANDPROF_ALLOC,      0x801d, nix_bandprof_alloc, nix_bandprof_alloc_req, \
 M(NIX_BANDPROF_FREE,   0x801e, nix_bandprof_free, nix_bandprof_free_req,   \
                                msg_rsp)                                    \
 M(NIX_BANDPROF_GET_HWINFO, 0x801f, nix_bandprof_get_hwinfo, msg_req,           \
-                               nix_bandprof_get_hwinfo_rsp)
-
-/* Messages initiated by AF (range 0xC00 - 0xDFF) */
+                               nix_bandprof_get_hwinfo_rsp)                \
+/* MCS mbox IDs (range 0xA000 - 0xBFFF) */                                     \
+M(MCS_SET_ACTIVE_LMAC, 0xa00a, mcs_set_active_lmac, mcs_set_active_lmac,       \
+                               msg_rsp)                                        \
+M(MCS_GET_HW_INFO,     0xa00b, mcs_get_hw_info, msg_req, mcs_hw_info)          \
+M(MCS_SET_LMAC_MODE,   0xa013, mcs_set_lmac_mode, mcs_set_lmac_mode, msg_rsp)  \
+M(MCS_PORT_RESET,      0xa018, mcs_port_reset, mcs_port_reset_req, msg_rsp)    \
+M(MCS_PORT_CFG_SET,    0xa019, mcs_port_cfg_set, mcs_port_cfg_set_req, msg_rsp)\
+M(MCS_PORT_CFG_GET,    0xa020, mcs_port_cfg_get, mcs_port_cfg_get_req,         \
+                               mcs_port_cfg_get_rsp)                           \
+M(MCS_CUSTOM_TAG_CFG_GET, 0xa021, mcs_custom_tag_cfg_get,                      \
+                                 mcs_custom_tag_cfg_get_req,                   \
+                                 mcs_custom_tag_cfg_get_rsp)
+
+/* Messages initiated by AF (range 0xC00 - 0xEFF) */
 #define MBOX_UP_CGX_MESSAGES                                           \
 M(CGX_LINK_EVENT,      0xC00, cgx_link_event, cgx_link_info_msg, msg_rsp)
 
@@ -1657,4 +1669,97 @@ enum cgx_af_status {
        LMAC_AF_ERR_EXACT_MATCH_TBL_LOOK_UP_FAILED = -1110,
 };
 
+enum mcs_direction {
+       MCS_RX,
+       MCS_TX,
+};
+
+struct mcs_hw_info {
+       struct mbox_msghdr hdr;
+       u8 num_mcs_blks;        /* Number of MCS blocks */
+       u8 tcam_entries;        /* RX/TX Tcam entries per mcs block */
+       u8 secy_entries;        /* RX/TX SECY entries per mcs block */
+       u8 sc_entries;          /* RX/TX SC CAM entries per mcs block */
+       u8 sa_entries;          /* PN table entries = SA entries */
+       u64 rsvd[16];
+};
+
+struct mcs_set_active_lmac {
+       struct mbox_msghdr hdr;
+       u32 lmac_bmap;  /* bitmap of active lmac per mcs block */
+       u8 mcs_id;
+       u16 chan_base; /* MCS channel base */
+       u64 rsvd;
+};
+
+struct mcs_set_lmac_mode {
+       struct mbox_msghdr hdr;
+       u8 mode;        /* 1:Bypass 0:Operational */
+       u8 lmac_id;
+       u8 mcs_id;
+       u64 rsvd;
+};
+
+struct mcs_port_reset_req {
+       struct mbox_msghdr hdr;
+       u8 reset;
+       u8 mcs_id;
+       u8 port_id;
+       u64 rsvd;
+};
+
+struct mcs_port_cfg_set_req {
+       struct mbox_msghdr hdr;
+       u8 cstm_tag_rel_mode_sel;
+       u8 custom_hdr_enb;
+       u8 fifo_skid;
+       u8 port_mode;
+       u8 port_id;
+       u8 mcs_id;
+       u64 rsvd;
+};
+
+struct mcs_port_cfg_get_req {
+       struct mbox_msghdr hdr;
+       u8 port_id;
+       u8 mcs_id;
+       u64 rsvd;
+};
+
+struct mcs_port_cfg_get_rsp {
+       struct mbox_msghdr hdr;
+       u8 cstm_tag_rel_mode_sel;
+       u8 custom_hdr_enb;
+       u8 fifo_skid;
+       u8 port_mode;
+       u8 port_id;
+       u8 mcs_id;
+       u64 rsvd;
+};
+
+struct mcs_custom_tag_cfg_get_req {
+       struct mbox_msghdr hdr;
+       u8 mcs_id;
+       u8 dir;
+       u64 rsvd;
+};
+
+struct mcs_custom_tag_cfg_get_rsp {
+       struct mbox_msghdr hdr;
+       u16 cstm_etype[8];
+       u8 cstm_indx[8];
+       u8 cstm_etype_en;
+       u8 mcs_id;
+       u8 dir;
+       u64 rsvd;
+};
+
+/* MCS mailbox error codes
+ * Range 1201 - 1300.
+ */
+enum mcs_af_status {
+       MCS_AF_ERR_INVALID_MCSID        = -1201,
+       MCS_AF_ERR_NOT_MAPPED           = -1202,
+};
+
 #endif /* MBOX_H */
index 259ccb42af6b07f85b1550a7bec84f530b8a5a4f..555f3b220d20cb27f1fc8f556c070bb1e3083a83 100644 (file)
@@ -107,6 +107,100 @@ struct mcs *mcs_get_pdata(int mcs_id)
        return NULL;
 }
 
+void mcs_set_port_cfg(struct mcs *mcs, struct mcs_port_cfg_set_req *req)
+{
+       u64 val = 0;
+
+       mcs_reg_write(mcs, MCSX_PAB_RX_SLAVE_PORT_CFGX(req->port_id),
+                     req->port_mode & MCS_PORT_MODE_MASK);
+
+       req->cstm_tag_rel_mode_sel &= 0x3;
+
+       if (mcs->hw->mcs_blks > 1) {
+               req->fifo_skid &= MCS_PORT_FIFO_SKID_MASK;
+               val = (u32)req->fifo_skid << 0x10;
+               val |= req->fifo_skid;
+               mcs_reg_write(mcs, MCSX_PAB_RX_SLAVE_FIFO_SKID_CFGX(req->port_id), val);
+               mcs_reg_write(mcs, MCSX_PEX_TX_SLAVE_CUSTOM_TAG_REL_MODE_SEL(req->port_id),
+                             req->cstm_tag_rel_mode_sel);
+               val = mcs_reg_read(mcs, MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION);
+
+               if (req->custom_hdr_enb)
+                       val |= BIT_ULL(req->port_id);
+               else
+                       val &= ~BIT_ULL(req->port_id);
+
+               mcs_reg_write(mcs, MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION, val);
+       } else {
+               val = mcs_reg_read(mcs, MCSX_PEX_TX_SLAVE_PORT_CONFIG(req->port_id));
+               val |= (req->cstm_tag_rel_mode_sel << 2);
+               mcs_reg_write(mcs, MCSX_PEX_TX_SLAVE_PORT_CONFIG(req->port_id), val);
+       }
+}
+
+void mcs_get_port_cfg(struct mcs *mcs, struct mcs_port_cfg_get_req *req,
+                     struct mcs_port_cfg_get_rsp *rsp)
+{
+       u64 reg = 0;
+
+       rsp->port_mode = mcs_reg_read(mcs, MCSX_PAB_RX_SLAVE_PORT_CFGX(req->port_id)) &
+                        MCS_PORT_MODE_MASK;
+
+       if (mcs->hw->mcs_blks > 1) {
+               reg = MCSX_PAB_RX_SLAVE_FIFO_SKID_CFGX(req->port_id);
+               rsp->fifo_skid = mcs_reg_read(mcs, reg) & MCS_PORT_FIFO_SKID_MASK;
+               reg = MCSX_PEX_TX_SLAVE_CUSTOM_TAG_REL_MODE_SEL(req->port_id);
+               rsp->cstm_tag_rel_mode_sel = mcs_reg_read(mcs, reg) & 0x3;
+               if (mcs_reg_read(mcs, MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION) & BIT_ULL(req->port_id))
+                       rsp->custom_hdr_enb = 1;
+       } else {
+               reg = MCSX_PEX_TX_SLAVE_PORT_CONFIG(req->port_id);
+               rsp->cstm_tag_rel_mode_sel = mcs_reg_read(mcs, reg) >> 2;
+       }
+
+       rsp->port_id = req->port_id;
+       rsp->mcs_id = req->mcs_id;
+}
+
+void mcs_get_custom_tag_cfg(struct mcs *mcs, struct mcs_custom_tag_cfg_get_req *req,
+                           struct mcs_custom_tag_cfg_get_rsp *rsp)
+{
+       u64 reg = 0, val = 0;
+       u8 idx;
+
+       for (idx = 0; idx < MCS_MAX_CUSTOM_TAGS; idx++) {
+               if (mcs->hw->mcs_blks > 1)
+                       reg  = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_CUSTOM_TAGX(idx) :
+                               MCSX_PEX_TX_SLAVE_CUSTOM_TAGX(idx);
+               else
+                       reg = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_VLAN_CFGX(idx) :
+                               MCSX_PEX_TX_SLAVE_VLAN_CFGX(idx);
+
+               val = mcs_reg_read(mcs, reg);
+               if (mcs->hw->mcs_blks > 1) {
+                       rsp->cstm_etype[idx] = val & GENMASK(15, 0);
+                       rsp->cstm_indx[idx] = (val >> 0x16) & 0x3;
+                       reg = (req->dir == MCS_RX) ? MCSX_PEX_RX_SLAVE_ETYPE_ENABLE :
+                               MCSX_PEX_TX_SLAVE_ETYPE_ENABLE;
+                       rsp->cstm_etype_en = mcs_reg_read(mcs, reg) & 0xFF;
+               } else {
+                       rsp->cstm_etype[idx] = (val >> 0x1) & GENMASK(15, 0);
+                       rsp->cstm_indx[idx] = (val >> 0x11) & 0x3;
+                       rsp->cstm_etype_en |= (val & 0x1) << idx;
+               }
+       }
+
+       rsp->mcs_id = req->mcs_id;
+       rsp->dir = req->dir;
+}
+
+void mcs_reset_port(struct mcs *mcs, u8 port_id, u8 reset)
+{
+       u64 reg = MCSX_MCS_TOP_SLAVE_PORT_RESET(port_id);
+
+       mcs_reg_write(mcs, reg, reset & 0x1);
+}
+
 /* Set lmac to bypass/operational mode */
 void mcs_set_lmac_mode(struct mcs *mcs, int lmac_id, u8 mode)
 {
index 002fee898e7b759ea2e5be9bd1802631b8abf394..c11d507a77e3f68025437862896ce55dc63d8c50 100644 (file)
 
 #define MCS_ID_MASK                    0x7
 
+#define MCS_PORT_MODE_MASK             0x3
+#define MCS_PORT_FIFO_SKID_MASK                0x3F
+#define MCS_MAX_CUSTOM_TAGS            0x8
+
 /* Reserved resources for default bypass entry */
 #define MCS_RSRC_RSVD_CNT              1
 
@@ -79,6 +83,12 @@ int mcs_set_lmac_channels(int mcs_id, u16 base);
 
 int mcs_install_flowid_bypass_entry(struct mcs *mcs);
 void mcs_set_lmac_mode(struct mcs *mcs, int lmac_id, u8 mode);
+void mcs_reset_port(struct mcs *mcs, u8 port_id, u8 reset);
+void mcs_set_port_cfg(struct mcs *mcs, struct mcs_port_cfg_set_req *req);
+void mcs_get_port_cfg(struct mcs *mcs, struct mcs_port_cfg_get_req *req,
+                     struct mcs_port_cfg_get_rsp *rsp);
+void mcs_get_custom_tag_cfg(struct mcs *mcs, struct mcs_custom_tag_cfg_get_req *req,
+                           struct mcs_custom_tag_cfg_get_rsp *rsp);
 
 /* CN10K-B APIs */
 void cn10kb_mcs_set_hw_capabilities(struct mcs *mcs);
index 61bf8ab257f9d3da5ac6945e51dd8f4a8a4d1e3b..1ce3442a96d9eb47d16a1ccc1bc7aeb4a4ed30eb 100644 (file)
 
 /* Registers */
 #define MCSX_IP_MODE                                   0x900c8ull
+#define MCSX_MCS_TOP_SLAVE_PORT_RESET(a) ({    \
+       u64 offset;                                     \
+                                                       \
+       offset = 0x408ull;                              \
+       if (mcs->hw->mcs_blks > 1)                      \
+               offset = 0xa28ull;                      \
+       offset += (a) * 0x8ull;                         \
+       offset; })
+
 
 #define MCSX_MCS_TOP_SLAVE_CHANNEL_CFG(a) ({           \
        u64 offset;                                     \
                offset = 0x60000ull;                    \
        offset; })
 
+#define MCSX_MIL_RX_LMACX_CFG(a) ({                    \
+       u64 offset;                                     \
+                                                       \
+       offset = 0x900a8ull;                            \
+       if (mcs->hw->mcs_blks > 1)                      \
+               offset = 0x700a8ull;                    \
+       offset += (a) * 0x800ull;                       \
+       offset; })
+
+#define MCSX_HIL_GLOBAL ({                             \
+       u64 offset;                                     \
+                                                       \
+       offset = 0xc0000ull;                            \
+       if (mcs->hw->mcs_blks > 1)                      \
+               offset = 0xa0000ull;                    \
+       offset; })
+
 #define MCSX_LINK_LMACX_CFG(a) ({                      \
        u64 offset;                                     \
                                                        \
 /* PEX registers */
 #define MCSX_PEX_RX_SLAVE_VLAN_CFGX(a)          (0x3b58ull + (a) * 0x8ull)
 #define MCSX_PEX_TX_SLAVE_VLAN_CFGX(a)          (0x46f8ull + (a) * 0x8ull)
+#define MCSX_PEX_TX_SLAVE_CUSTOM_TAG_REL_MODE_SEL(a)   (0x788ull + (a) * 0x8ull)
+#define MCSX_PEX_TX_SLAVE_PORT_CONFIG(a)               (0x4738ull + (a) * 0x8ull)
+
+#define MCSX_PEX_RX_SLAVE_PEX_CONFIGURATION ({         \
+       u64 offset;                                     \
+                                                       \
+       offset = 0x3b50ull;                             \
+       if (mcs->hw->mcs_blks > 1)                      \
+               offset = 0x4c0ull;                      \
+       offset; })
 
 /* CNF10K-B */
 #define MCSX_PEX_RX_SLAVE_CUSTOM_TAGX(a)        (0x4c8ull + (a) * 0x8ull)
index c3f5b39bf17cb7373897729733d563afc51b57f5..9eaa8ee452d56b448cbae027938d45f5bc0cb0e3 100644 (file)
 #include "rvu.h"
 #include "lmac_common.h"
 
+int rvu_mbox_handler_mcs_set_lmac_mode(struct rvu *rvu,
+                                      struct mcs_set_lmac_mode *req,
+                                      struct msg_rsp *rsp)
+{
+       struct mcs *mcs;
+
+       if (req->mcs_id >= rvu->mcs_blk_cnt)
+               return MCS_AF_ERR_INVALID_MCSID;
+
+       mcs = mcs_get_pdata(req->mcs_id);
+
+       if (BIT_ULL(req->lmac_id) & mcs->hw->lmac_bmap)
+               mcs_set_lmac_mode(mcs, req->lmac_id, req->mode);
+
+       return 0;
+}
+
+int rvu_mbox_handler_mcs_get_hw_info(struct rvu *rvu,
+                                    struct msg_req *req,
+                                    struct mcs_hw_info *rsp)
+{
+       struct mcs *mcs;
+
+       if (!rvu->mcs_blk_cnt)
+               return MCS_AF_ERR_NOT_MAPPED;
+
+       /* MCS resources are same across all blocks */
+       mcs = mcs_get_pdata(0);
+       rsp->num_mcs_blks = rvu->mcs_blk_cnt;
+       rsp->tcam_entries = mcs->hw->tcam_entries;
+       rsp->secy_entries = mcs->hw->secy_entries;
+       rsp->sc_entries = mcs->hw->sc_entries;
+       rsp->sa_entries = mcs->hw->sa_entries;
+       return 0;
+}
+
+int rvu_mbox_handler_mcs_port_reset(struct rvu *rvu, struct mcs_port_reset_req *req,
+                                   struct msg_rsp *rsp)
+{
+       struct mcs *mcs;
+
+       if (req->mcs_id >= rvu->mcs_blk_cnt)
+               return MCS_AF_ERR_INVALID_MCSID;
+
+       mcs = mcs_get_pdata(req->mcs_id);
+
+       mcs_reset_port(mcs, req->port_id, req->reset);
+
+       return 0;
+}
+
+int rvu_mbox_handler_mcs_set_active_lmac(struct rvu *rvu,
+                                        struct mcs_set_active_lmac *req,
+                                        struct msg_rsp *rsp)
+{
+       struct mcs *mcs;
+
+       if (req->mcs_id >= rvu->mcs_blk_cnt)
+               return MCS_AF_ERR_INVALID_MCSID;
+
+       mcs = mcs_get_pdata(req->mcs_id);
+       if (!mcs)
+               return MCS_AF_ERR_NOT_MAPPED;
+
+       mcs->hw->lmac_bmap = req->lmac_bmap;
+       mcs_set_lmac_channels(req->mcs_id, req->chan_base);
+       return 0;
+}
+
+int rvu_mbox_handler_mcs_port_cfg_set(struct rvu *rvu, struct mcs_port_cfg_set_req *req,
+                                     struct msg_rsp *rsp)
+{
+       struct mcs *mcs;
+
+       if (req->mcs_id >= rvu->mcs_blk_cnt)
+               return MCS_AF_ERR_INVALID_MCSID;
+
+       mcs = mcs_get_pdata(req->mcs_id);
+
+       if (mcs->hw->lmac_cnt <= req->port_id || !(mcs->hw->lmac_bmap & BIT_ULL(req->port_id)))
+               return -EINVAL;
+
+       mcs_set_port_cfg(mcs, req);
+
+       return 0;
+}
+
+int rvu_mbox_handler_mcs_port_cfg_get(struct rvu *rvu, struct mcs_port_cfg_get_req *req,
+                                     struct mcs_port_cfg_get_rsp *rsp)
+{
+       struct mcs *mcs;
+
+       if (req->mcs_id >= rvu->mcs_blk_cnt)
+               return MCS_AF_ERR_INVALID_MCSID;
+
+       mcs = mcs_get_pdata(req->mcs_id);
+
+       if (mcs->hw->lmac_cnt <= req->port_id || !(mcs->hw->lmac_bmap & BIT_ULL(req->port_id)))
+               return -EINVAL;
+
+       mcs_get_port_cfg(mcs, req, rsp);
+
+       return 0;
+}
+
+int rvu_mbox_handler_mcs_custom_tag_cfg_get(struct rvu *rvu, struct mcs_custom_tag_cfg_get_req *req,
+                                           struct mcs_custom_tag_cfg_get_rsp *rsp)
+{
+       struct mcs *mcs;
+
+       if (req->mcs_id >= rvu->mcs_blk_cnt)
+               return MCS_AF_ERR_INVALID_MCSID;
+
+       mcs = mcs_get_pdata(req->mcs_id);
+
+       mcs_get_custom_tag_cfg(mcs, req, rsp);
+
+       return 0;
+}
+
 static void rvu_mcs_set_lmac_bmap(struct rvu *rvu)
 {
        struct mcs *mcs = mcs_get_pdata(0);
@@ -32,7 +152,8 @@ static void rvu_mcs_set_lmac_bmap(struct rvu *rvu)
 int rvu_mcs_init(struct rvu *rvu)
 {
        struct rvu_hwinfo *hw = rvu->hw;
-       int err = 0;
+       int lmac, err = 0, mcs_id;
+       struct mcs *mcs;
 
        rvu->mcs_blk_cnt = mcs_get_blkcnt();
 
@@ -48,5 +169,11 @@ int rvu_mcs_init(struct rvu *rvu)
                rvu_mcs_set_lmac_bmap(rvu);
        }
 
+       for (mcs_id = 0; mcs_id < rvu->mcs_blk_cnt; mcs_id++) {
+               mcs = mcs_get_pdata(mcs_id);
+               for (lmac = 0; lmac < mcs->hw->lmac_cnt; lmac++)
+                       mcs_set_lmac_mode(mcs, lmac, 0);
+       }
+
        return err;
 }