diff mbox series

[net-next,5/9] octeontx2-af: Add packet path between representor and VF

Message ID 20240416050616.6056-6-gakula@marvell.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series Introduce RVU representors | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 8 this patch: 8
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 2 maintainers not CCed: jerinj@marvell.com lcherian@marvell.com
netdev/build_clang fail Errors and warnings before: 946 this patch: 946
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 964 this patch: 969
netdev/checkpatch warning WARNING: line length of 88 exceeds 80 columns WARNING: line length of 96 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Geetha sowjanya April 16, 2024, 5:06 a.m. UTC
This patch installs tcam rules to stree traffic representors
and VF when swicthdev mode is set. To support this a HW loopback
channel is reserved. Through this channel packet are routed
between representor and VFs. "ESW_CFG" mbox is defined to
notify AF for installing rules.

Signed-off-by: Geetha sowjanya <gakula@marvell.com>
---
 .../net/ethernet/marvell/octeontx2/af/mbox.h  |   7 +
 .../net/ethernet/marvell/octeontx2/af/rvu.h   |   7 +-
 .../marvell/octeontx2/af/rvu_devlink.c        |   6 +
 .../ethernet/marvell/octeontx2/af/rvu_nix.c   |   7 +-
 .../ethernet/marvell/octeontx2/af/rvu_rep.c   | 241 +++++++++++++++++-
 .../marvell/octeontx2/af/rvu_switch.c         |  18 +-
 .../net/ethernet/marvell/octeontx2/nic/rep.c  |  19 ++
 7 files changed, 297 insertions(+), 8 deletions(-)

Comments

Kalesh Anakkur Purayil April 17, 2024, 4:10 a.m. UTC | #1
On Tue, Apr 16, 2024 at 10:38 AM Geetha sowjanya <gakula@marvell.com> wrote:
>
> This patch installs tcam rules to stree traffic representors
> and VF when swicthdev mode is set. To support this a HW loopback
> channel is reserved. Through this channel packet are routed
> between representor and VFs. "ESW_CFG" mbox is defined to
> notify AF for installing rules.
>
> Signed-off-by: Geetha sowjanya <gakula@marvell.com>
> ---
>  .../net/ethernet/marvell/octeontx2/af/mbox.h  |   7 +
>  .../net/ethernet/marvell/octeontx2/af/rvu.h   |   7 +-
>  .../marvell/octeontx2/af/rvu_devlink.c        |   6 +
>  .../ethernet/marvell/octeontx2/af/rvu_nix.c   |   7 +-
>  .../ethernet/marvell/octeontx2/af/rvu_rep.c   | 241 +++++++++++++++++-
>  .../marvell/octeontx2/af/rvu_switch.c         |  18 +-
>  .../net/ethernet/marvell/octeontx2/nic/rep.c  |  19 ++
>  7 files changed, 297 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
> index c77c02730cf9..3b36da28a8f4 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
> @@ -144,6 +144,7 @@ M(LMTST_TBL_SETUP,  0x00a, lmtst_tbl_setup, lmtst_tbl_setup_req,    \
>  M(SET_VF_PERM,         0x00b, set_vf_perm, set_vf_perm, msg_rsp)       \
>  M(PTP_GET_CAP,         0x00c, ptp_get_cap, msg_req, ptp_get_cap_rsp)   \
>  M(GET_REP_CNT,         0x00d, get_rep_cnt, msg_req, get_rep_cnt_rsp)   \
> +M(ESW_CFG,             0x00e, esw_cfg, esw_cfg_req, msg_rsp)   \
>  /* CGX mbox IDs (range 0x200 - 0x3FF) */                               \
>  M(CGX_START_RXTX,      0x200, cgx_start_rxtx, msg_req, msg_rsp)        \
>  M(CGX_STOP_RXTX,       0x201, cgx_stop_rxtx, msg_req, msg_rsp)         \
> @@ -1532,6 +1533,12 @@ struct get_rep_cnt_rsp {
>         u64 rsvd;
>  };
>
> +struct esw_cfg_req {
> +       struct mbox_msghdr hdr;
> +       u8 ena;
> +       u64 rsvd;
> +};
> +
>  struct flow_msg {
>         unsigned char dmac[6];
>         unsigned char smac[6];
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
> index 1d76d52d7a5d..c8572d79a968 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
> @@ -596,6 +596,7 @@ struct rvu {
>         u16                     rep_pcifunc;
>         int                     rep_cnt;
>         u16                     *rep2pfvf_map;
> +       u8                      rep_mode;
>  };
>
>  static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
> @@ -1025,7 +1026,7 @@ int rvu_ndc_fix_locked_cacheline(struct rvu *rvu, int blkaddr);
>  /* RVU Switch */
>  void rvu_switch_enable(struct rvu *rvu);
>  void rvu_switch_disable(struct rvu *rvu);
> -void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc);
> +void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
>  void rvu_switch_enable_lbk_link(struct rvu *rvu, u16 pcifunc, bool ena);
>
>  int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
> @@ -1039,4 +1040,8 @@ int rvu_mcs_flr_handler(struct rvu *rvu, u16 pcifunc);
>  void rvu_mcs_ptp_cfg(struct rvu *rvu, u8 rpm_id, u8 lmac_id, bool ena);
>  void rvu_mcs_exit(struct rvu *rvu);
>
> +/* Representor APIs */
> +int rvu_rep_pf_init(struct rvu *rvu);
> +int rvu_rep_install_mcam_rules(struct rvu *rvu);
> +void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
>  #endif /* RVU_H */
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
> index 96c04f7d93f8..8a3b7fb61883 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
> @@ -1464,6 +1464,9 @@ static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
>         struct rvu *rvu = rvu_dl->rvu;
>         struct rvu_switch *rswitch;
>
> +       if (rvu->rep_mode)
> +               return -EOPNOTSUPP;
> +
>         rswitch = &rvu->rswitch;
>         *mode = rswitch->mode;
>
> @@ -1477,6 +1480,9 @@ static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
>         struct rvu *rvu = rvu_dl->rvu;
>         struct rvu_switch *rswitch;
>
> +       if (rvu->rep_mode)
> +               return -EOPNOTSUPP;
> +
>         rswitch = &rvu->rswitch;
>         switch (mode) {
>         case DEVLINK_ESWITCH_MODE_LEGACY:
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> index 4ef5bb7b337f..75d5c1bc00e1 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> @@ -2738,7 +2738,7 @@ void rvu_nix_tx_tl2_cfg(struct rvu *rvu, int blkaddr, u16 pcifunc,
>         int schq;
>         u64 cfg;
>
> -       if (!is_pf_cgxmapped(rvu, pf))
> +       if (!is_pf_cgxmapped(rvu, pf) && !is_rep_dev(rvu, pcifunc))
>                 return;
>
>         cfg = enable ? (BIT_ULL(12) | RVU_SWITCH_LBK_CHAN) : 0;
> @@ -4368,8 +4368,6 @@ int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,
>         if (test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) && from_vf)
>                 ether_addr_copy(pfvf->default_mac, req->mac_addr);
>
> -       rvu_switch_update_rules(rvu, pcifunc);
> -
>         return 0;
>  }
>
> @@ -5159,7 +5157,7 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
>         pfvf = rvu_get_pfvf(rvu, pcifunc);
>         set_bit(NIXLF_INITIALIZED, &pfvf->flags);
>
> -       rvu_switch_update_rules(rvu, pcifunc);
> +       rvu_switch_update_rules(rvu, pcifunc, true);
>
>         return rvu_cgx_start_stop_io(rvu, pcifunc, true);
>  }
> @@ -5187,6 +5185,7 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
>         if (err)
>                 return err;
>
> +       rvu_switch_update_rules(rvu, pcifunc, false);
>         rvu_cgx_tx_enable(rvu, pcifunc, true);
>
>         return 0;
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
> index d07cb356d3d6..5c015e8dfbbe 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
> @@ -13,6 +13,246 @@
>  #include "rvu.h"
>  #include "rvu_reg.h"
>
> +static u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc)
> +{
> +       int id;
> +
> +       for (id = 0; id < rvu->rep_cnt; id++)
> +               if (rvu->rep2pfvf_map[id] == pcifunc)
> +                       return id;
> +       return -ENODEV;
> +}
> +
> +static int rvu_rep_tx_vlan_cfg(struct rvu *rvu,  u16 pcifunc,
> +                              u16 vlan_tci, int *vidx)
> +{
> +       struct nix_vtag_config req = {0};
> +       struct nix_vtag_config_rsp rsp = {0};
> +       u64 etype = ETH_P_8021Q;
> +       int err;
> +
> +       /* Insert vlan tag */
> +       req.hdr.pcifunc = pcifunc;
> +       req.vtag_size = VTAGSIZE_T4;
> +       req.cfg_type = 0; /* tx vlan cfg */
> +       req.tx.cfg_vtag0 = true;
> +       req.tx.vtag0 = etype << 48 | ntohs(vlan_tci);
> +
> +       err = rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp);
> +       if (err) {
> +               dev_err(rvu->dev, "Tx vlan config failed\n");
> +               return err;
> +       }
> +       *vidx = rsp.vtag0_idx;
> +       return 0;
> +}
> +
> +static int rvu_rep_rx_vlan_cfg(struct rvu *rvu, u16 pcifunc)
> +{
> +       struct nix_vtag_config req = {0};
> +       struct nix_vtag_config_rsp rsp;
> +
> +       /* config strip, capture and size */
> +       req.hdr.pcifunc = pcifunc;
> +       req.vtag_size = VTAGSIZE_T4;
> +       req.cfg_type = 1; /* rx vlan cfg */
> +       req.rx.vtag_type = NIX_AF_LFX_RX_VTAG_TYPE0;
> +       req.rx.strip_vtag = true;
> +       req.rx.capture_vtag = false;
> +
> +       return rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp);
> +}
> +
> +static int rvu_rep_install_rx_rule(struct rvu *rvu, u16 pcifunc,
> +                                  u16 entry, bool rte)
> +{
> +       struct npc_install_flow_req req = { 0 };
> +       struct npc_install_flow_rsp rsp = { 0 };
> +       struct rvu_pfvf *pfvf;
> +       u16 vlan_tci, rep_id;
> +
> +       pfvf = rvu_get_pfvf(rvu, pcifunc);
> +
> +       /* To stree the traffic from Representee to Representor */
> +       rep_id = (u16)rvu_rep_get_vlan_id(rvu, pcifunc);
> +       if (rte) {
> +               vlan_tci = rep_id | 0x1ull << 8;
> +               req.vf = rvu->rep_pcifunc;
> +               req.op = NIX_RX_ACTIONOP_UCAST;
> +               req.index = rep_id;
> +       } else {
> +               vlan_tci = rep_id;
> +               req.vf = pcifunc;
> +               req.op = NIX_RX_ACTION_DEFAULT;
> +       }
> +
> +       rvu_rep_rx_vlan_cfg(rvu, req.vf);
> +       req.entry = entry;
> +       req.hdr.pcifunc = 0; /* AF is requester */
> +       req.features = BIT_ULL(NPC_OUTER_VID) | BIT_ULL(NPC_VLAN_ETYPE_CTAG);
> +       req.vtag0_valid = true;
> +       req.vtag0_type = NIX_AF_LFX_RX_VTAG_TYPE0;
> +       req.packet.vlan_etype = ETH_P_8021Q;
> +       req.mask.vlan_etype = ETH_P_8021Q;
> +       req.packet.vlan_tci = vlan_tci;
> +       req.mask.vlan_tci = 0xffff;
> +
> +       req.channel = RVU_SWITCH_LBK_CHAN;
> +       req.chan_mask = 0xffff;
> +       req.intf = pfvf->nix_rx_intf;
> +
> +       return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
> +}
> +
> +static int rvu_rep_install_tx_rule(struct rvu *rvu, u16 pcifunc, u16 entry,
> +                                  bool rte)
> +{
> +       struct npc_install_flow_req req = { 0 };
> +       struct npc_install_flow_rsp rsp = { 0 };
> +       struct rvu_pfvf *pfvf;
> +       int vidx, err;
> +       u16 vlan_tci;
> +       u8 lbkid;
> +
> +       pfvf = rvu_get_pfvf(rvu, pcifunc);
> +       vlan_tci = rvu_rep_get_vlan_id(rvu, pcifunc);
> +       if (rte)
> +               vlan_tci |= 0x1ull << 8;
> +
> +       err = rvu_rep_tx_vlan_cfg(rvu, pcifunc, vlan_tci, &vidx);
> +       if (err)
> +               return err;
> +
> +       lbkid = pfvf->nix_blkaddr == BLKADDR_NIX0 ? 0 : 1;
> +       req.hdr.pcifunc = 0; /* AF is requester */
> +       if (rte) {
> +               req.vf = pcifunc;
> +       } else {
> +               req.vf = rvu->rep_pcifunc;
> +               req.packet.sq_id = vlan_tci;
> +               req.mask.sq_id = 0xffff;
> +       }
> +
> +       req.entry = entry;
> +       req.intf = pfvf->nix_tx_intf;
> +       req.op = NIX_TX_ACTIONOP_UCAST_CHAN;
> +       req.index = (lbkid << 8) | RVU_SWITCH_LBK_CHAN;
> +       req.set_cntr = 1;
> +       req.vtag0_def = vidx;
> +       req.vtag0_op = 1;
> +       return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
> +}
> +
> +int rvu_rep_install_mcam_rules(struct rvu *rvu)
> +{
> +       struct rvu_switch *rswitch = &rvu->rswitch;
> +       u16 start = rswitch->start_entry;
> +       struct rvu_hwinfo *hw = rvu->hw;
> +       u16 pcifunc, entry = 0;
> +       int pf, vf, numvfs;
> +       int err, nixlf, i;
> +       u8 rep;
> +
> +       for (pf = 1; pf < hw->total_pfs; pf++) {
> +               if (!is_pf_cgxmapped(rvu, pf))
> +                       continue;
> +
> +               pcifunc = pf << RVU_PFVF_PF_SHIFT;
> +               rvu_get_nix_blkaddr(rvu, pcifunc);
> +               rep = true;
> +               for (i = 0; i < 2; i++) {
> +                       err = rvu_rep_install_rx_rule(rvu, pcifunc, start + entry, rep);
> +                       if (err)
> +                               return err;
> +                       rswitch->entry2pcifunc[entry++] = pcifunc;
> +
> +                       err = rvu_rep_install_tx_rule(rvu, pcifunc, start + entry, rep);
> +                       if (err)
> +                               return err;
> +                       rswitch->entry2pcifunc[entry++] = pcifunc;
> +                       rep = false;
> +               }
> +
> +               rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
> +               for (vf = 0; vf < numvfs; vf++) {
> +                       pcifunc = pf << RVU_PFVF_PF_SHIFT |
> +                                 ((vf + 1) & RVU_PFVF_FUNC_MASK);
> +                       rvu_get_nix_blkaddr(rvu, pcifunc);
> +
> +                       /* Skip installimg rules if nixlf is not attached */
> +                       err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
> +                       if (err)
> +                               continue;
> +                       rep = true;
> +                       for (i = 0; i < 2; i++) {
> +                               err = rvu_rep_install_rx_rule(rvu, pcifunc, start + entry, rep);
> +                               if (err)
> +                                       return err;
> +                               rswitch->entry2pcifunc[entry++] = pcifunc;
> +
> +                               err = rvu_rep_install_tx_rule(rvu, pcifunc, start + entry, rep);
> +                               if (err)
> +                                       return err;
> +                               rswitch->entry2pcifunc[entry++] = pcifunc;
> +                               rep = false;
> +                       }
> +               }
> +       }
> +       return 0;
> +}
> +
> +void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena)
> +{
> +       struct rvu_switch *rswitch = &rvu->rswitch;
> +       struct npc_mcam *mcam = &rvu->hw->mcam;
> +       u32 max = rswitch->used_entries;
> +       int blkaddr;
> +       u16 entry;
> +
> +       if (!rswitch->used_entries)
> +               return;
> +
> +       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
> +
> +       if (blkaddr < 0)
> +               return;
> +
> +       rvu_switch_enable_lbk_link(rvu, pcifunc, ena);
> +       mutex_lock(&mcam->lock);
> +       for (entry = 0; entry < max; entry++) {
> +               if (rswitch->entry2pcifunc[entry] == pcifunc)
> +                       npc_enable_mcam_entry(rvu, mcam, blkaddr, entry, ena);
> +       }
> +       mutex_unlock(&mcam->lock);
> +}
> +
> +int rvu_rep_pf_init(struct rvu *rvu)
> +{
> +       u16 pcifunc = rvu->rep_pcifunc;
> +       struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
> +
> +       set_bit(NIXLF_INITIALIZED, &pfvf->flags);
> +       rvu_switch_enable_lbk_link(rvu, pcifunc, true);
> +       rvu_rep_rx_vlan_cfg(rvu, pcifunc);
> +       return 0;
> +}
> +
> +int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct esw_cfg_req *req,
> +                            struct msg_rsp *rsp)
> +{
> +       if (req->hdr.pcifunc != rvu->rep_pcifunc)
> +               return 0;
> +
> +       rvu->rep_mode = req->ena;
> +
> +       if (req->ena)
> +               rvu_switch_enable(rvu);
> +       else
> +               rvu_switch_disable(rvu);
> +
> +       return 0;
> +}
> +
>  int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
>                                  struct get_rep_cnt_rsp *rsp)
>  {
> @@ -45,4 +285,3 @@ int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
>         }
>         return 0;
>  }
> -
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
> index ceb81eebf65e..268efb7c1c15 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
> @@ -166,6 +166,8 @@ void rvu_switch_enable(struct rvu *rvu)
>
>         alloc_req.contig = true;
>         alloc_req.count = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs;
> +       if (rvu->rep_mode)
> +               alloc_req.count = alloc_req.count * 4;
>         ret = rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &alloc_req,
>                                                     &alloc_rsp);
>         if (ret) {
> @@ -189,7 +191,12 @@ void rvu_switch_enable(struct rvu *rvu)
>         rswitch->used_entries = alloc_rsp.count;
>         rswitch->start_entry = alloc_rsp.entry;
>
> -       ret = rvu_switch_install_rules(rvu);
> +       if (rvu->rep_mode) {
> +               rvu_rep_pf_init(rvu);
> +               ret = rvu_rep_install_mcam_rules(rvu);
> +       } else {
> +               ret = rvu_switch_install_rules(rvu);
> +       }
>         if (ret)
>                 goto uninstall_rules;
>
> @@ -222,6 +229,9 @@ void rvu_switch_disable(struct rvu *rvu)
>         if (!rswitch->used_entries)
>                 return;
>
> +       if (rvu->rep_mode)
> +               goto free_ents;
> +
>         for (pf = 1; pf < hw->total_pfs; pf++) {
>                 if (!is_pf_cgxmapped(rvu, pf))
>                         continue;
> @@ -249,6 +259,7 @@ void rvu_switch_disable(struct rvu *rvu)
>                 }
>         }
>
> +free_ents:
>         uninstall_req.start = rswitch->start_entry;
>         uninstall_req.end =  rswitch->start_entry + rswitch->used_entries - 1;
>         free_req.all = 1;
> @@ -258,12 +269,15 @@ void rvu_switch_disable(struct rvu *rvu)
>         kfree(rswitch->entry2pcifunc);
>  }
>
> -void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc)
> +void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc, bool ena)
>  {
>         struct rvu_switch *rswitch = &rvu->rswitch;
>         u32 max = rswitch->used_entries;
>         u16 entry;
>
> +       if (rvu->rep_mode)
> +               return rvu_rep_update_rules(rvu, pcifunc, ena);
> +
>         if (!rswitch->used_entries)
>                 return;
>
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> index 187b00156bcd..1329617f8d6f 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> @@ -28,6 +28,22 @@ MODULE_DESCRIPTION(DRV_STRING);
>  MODULE_LICENSE("GPL");
>  MODULE_DEVICE_TABLE(pci, rvu_rep_id_table);
>
> +static int rvu_eswitch_config(struct otx2_nic *priv, u8 ena)
> +{
> +       struct esw_cfg_req *req;
> +
> +       mutex_lock(&priv->mbox.lock);
> +       req = otx2_mbox_alloc_msg_esw_cfg(&priv->mbox);
> +       if (!req) {
> +               mutex_unlock(&priv->mbox.lock);
> +               return -ENOMEM;
> +       }
> +       req->ena = ena;
> +       otx2_sync_mbox_msg(&priv->mbox);
> +       mutex_unlock(&priv->mbox.lock);
> +       return 0;
> +}
> +
>  static netdev_tx_t rvu_rep_xmit(struct sk_buff *skb, struct net_device *dev)
>  {
>         struct rep_dev *rep = netdev_priv(dev);
> @@ -170,6 +186,8 @@ static void rvu_rep_free_netdev(struct otx2_nic *priv)
>
>  void rvu_rep_destroy(struct otx2_nic *priv)
>  {
> +       /* Remove mcam rules */
> +       rvu_eswitch_config(priv, false);
>         rvu_rep_free_cq_rsrc(priv);
>         rvu_rep_free_netdev(priv);
>  }
> @@ -221,6 +239,7 @@ int rvu_rep_create(struct otx2_nic *priv)
>         if (err)
>                 goto exit;
>
> +       rvu_eswitch_config(priv, true);
>         return 0;
>  exit:
>         rvu_rep_free_netdev(priv);
> --
> 2.25.1
>
>
Kalesh Anakkur Purayil April 17, 2024, 4:15 a.m. UTC | #2
On Wed, Apr 17, 2024 at 9:40 AM Kalesh Anakkur Purayil
<kalesh-anakkur.purayil@broadcom.com> wrote:
>
> On Tue, Apr 16, 2024 at 10:38 AM Geetha sowjanya <gakula@marvell.com> wrote:
> >
> > This patch installs tcam rules to stree traffic representors
> > and VF when swicthdev mode is set. To support this a HW loopback
> > channel is reserved. Through this channel packet are routed
> > between representor and VFs. "ESW_CFG" mbox is defined to
> > notify AF for installing rules.
> >
> > Signed-off-by: Geetha sowjanya <gakula@marvell.com>
> > ---
> >  .../net/ethernet/marvell/octeontx2/af/mbox.h  |   7 +
> >  .../net/ethernet/marvell/octeontx2/af/rvu.h   |   7 +-
> >  .../marvell/octeontx2/af/rvu_devlink.c        |   6 +
> >  .../ethernet/marvell/octeontx2/af/rvu_nix.c   |   7 +-
> >  .../ethernet/marvell/octeontx2/af/rvu_rep.c   | 241 +++++++++++++++++-
> >  .../marvell/octeontx2/af/rvu_switch.c         |  18 +-
> >  .../net/ethernet/marvell/octeontx2/nic/rep.c  |  19 ++
> >  7 files changed, 297 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
> > index c77c02730cf9..3b36da28a8f4 100644
> > --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
> > +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
> > @@ -144,6 +144,7 @@ M(LMTST_TBL_SETUP,  0x00a, lmtst_tbl_setup, lmtst_tbl_setup_req,    \
> >  M(SET_VF_PERM,         0x00b, set_vf_perm, set_vf_perm, msg_rsp)       \
> >  M(PTP_GET_CAP,         0x00c, ptp_get_cap, msg_req, ptp_get_cap_rsp)   \
> >  M(GET_REP_CNT,         0x00d, get_rep_cnt, msg_req, get_rep_cnt_rsp)   \
> > +M(ESW_CFG,             0x00e, esw_cfg, esw_cfg_req, msg_rsp)   \
> >  /* CGX mbox IDs (range 0x200 - 0x3FF) */                               \
> >  M(CGX_START_RXTX,      0x200, cgx_start_rxtx, msg_req, msg_rsp)        \
> >  M(CGX_STOP_RXTX,       0x201, cgx_stop_rxtx, msg_req, msg_rsp)         \
> > @@ -1532,6 +1533,12 @@ struct get_rep_cnt_rsp {
> >         u64 rsvd;
> >  };
> >
> > +struct esw_cfg_req {
> > +       struct mbox_msghdr hdr;
> > +       u8 ena;
> > +       u64 rsvd;
> > +};
> > +
> >  struct flow_msg {
> >         unsigned char dmac[6];
> >         unsigned char smac[6];
> > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
> > index 1d76d52d7a5d..c8572d79a968 100644
> > --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
> > +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
> > @@ -596,6 +596,7 @@ struct rvu {
> >         u16                     rep_pcifunc;
> >         int                     rep_cnt;
> >         u16                     *rep2pfvf_map;
> > +       u8                      rep_mode;
> >  };
> >
> >  static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
> > @@ -1025,7 +1026,7 @@ int rvu_ndc_fix_locked_cacheline(struct rvu *rvu, int blkaddr);
> >  /* RVU Switch */
> >  void rvu_switch_enable(struct rvu *rvu);
> >  void rvu_switch_disable(struct rvu *rvu);
> > -void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc);
> > +void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
> >  void rvu_switch_enable_lbk_link(struct rvu *rvu, u16 pcifunc, bool ena);
> >
> >  int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
> > @@ -1039,4 +1040,8 @@ int rvu_mcs_flr_handler(struct rvu *rvu, u16 pcifunc);
> >  void rvu_mcs_ptp_cfg(struct rvu *rvu, u8 rpm_id, u8 lmac_id, bool ena);
> >  void rvu_mcs_exit(struct rvu *rvu);
> >
> > +/* Representor APIs */
> > +int rvu_rep_pf_init(struct rvu *rvu);
> > +int rvu_rep_install_mcam_rules(struct rvu *rvu);
> > +void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
> >  #endif /* RVU_H */
> > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
> > index 96c04f7d93f8..8a3b7fb61883 100644
> > --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
> > +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
> > @@ -1464,6 +1464,9 @@ static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
> >         struct rvu *rvu = rvu_dl->rvu;
> >         struct rvu_switch *rswitch;
> >
> > +       if (rvu->rep_mode)
> > +               return -EOPNOTSUPP;
> > +
> >         rswitch = &rvu->rswitch;
> >         *mode = rswitch->mode;
> >
> > @@ -1477,6 +1480,9 @@ static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
> >         struct rvu *rvu = rvu_dl->rvu;
> >         struct rvu_switch *rswitch;
> >
> > +       if (rvu->rep_mode)
> > +               return -EOPNOTSUPP;
> > +
> >         rswitch = &rvu->rswitch;
> >         switch (mode) {
> >         case DEVLINK_ESWITCH_MODE_LEGACY:
> > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> > index 4ef5bb7b337f..75d5c1bc00e1 100644
> > --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> > +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> > @@ -2738,7 +2738,7 @@ void rvu_nix_tx_tl2_cfg(struct rvu *rvu, int blkaddr, u16 pcifunc,
> >         int schq;
> >         u64 cfg;
> >
> > -       if (!is_pf_cgxmapped(rvu, pf))
> > +       if (!is_pf_cgxmapped(rvu, pf) && !is_rep_dev(rvu, pcifunc))
> >                 return;
> >
> >         cfg = enable ? (BIT_ULL(12) | RVU_SWITCH_LBK_CHAN) : 0;
> > @@ -4368,8 +4368,6 @@ int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,
> >         if (test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) && from_vf)
> >                 ether_addr_copy(pfvf->default_mac, req->mac_addr);
> >
> > -       rvu_switch_update_rules(rvu, pcifunc);
> > -
> >         return 0;
> >  }
> >
> > @@ -5159,7 +5157,7 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
> >         pfvf = rvu_get_pfvf(rvu, pcifunc);
> >         set_bit(NIXLF_INITIALIZED, &pfvf->flags);
> >
> > -       rvu_switch_update_rules(rvu, pcifunc);
> > +       rvu_switch_update_rules(rvu, pcifunc, true);
> >
> >         return rvu_cgx_start_stop_io(rvu, pcifunc, true);
> >  }
> > @@ -5187,6 +5185,7 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
> >         if (err)
> >                 return err;
> >
> > +       rvu_switch_update_rules(rvu, pcifunc, false);
> >         rvu_cgx_tx_enable(rvu, pcifunc, true);
> >
> >         return 0;
> > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
> > index d07cb356d3d6..5c015e8dfbbe 100644
> > --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
> > +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
> > @@ -13,6 +13,246 @@
> >  #include "rvu.h"
> >  #include "rvu_reg.h"
> >
> > +static u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc)
> > +{
> > +       int id;
> > +
> > +       for (id = 0; id < rvu->rep_cnt; id++)
> > +               if (rvu->rep2pfvf_map[id] == pcifunc)
> > +                       return id;
> > +       return -ENODEV;
> > +}
> > +
> > +static int rvu_rep_tx_vlan_cfg(struct rvu *rvu,  u16 pcifunc,
> > +                              u16 vlan_tci, int *vidx)
> > +{
> > +       struct nix_vtag_config req = {0};
> > +       struct nix_vtag_config_rsp rsp = {0};
[Kalesh] RCT order. Also I think {0} is not needed and you can just use {}
> > +       u64 etype = ETH_P_8021Q;
> > +       int err;
> > +
> > +       /* Insert vlan tag */
> > +       req.hdr.pcifunc = pcifunc;
> > +       req.vtag_size = VTAGSIZE_T4;
> > +       req.cfg_type = 0; /* tx vlan cfg */
> > +       req.tx.cfg_vtag0 = true;
> > +       req.tx.vtag0 = etype << 48 | ntohs(vlan_tci);
> > +
> > +       err = rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp);
> > +       if (err) {
> > +               dev_err(rvu->dev, "Tx vlan config failed\n");
> > +               return err;
> > +       }
> > +       *vidx = rsp.vtag0_idx;
> > +       return 0;
> > +}
> > +
> > +static int rvu_rep_rx_vlan_cfg(struct rvu *rvu, u16 pcifunc)
> > +{
> > +       struct nix_vtag_config req = {0};
> > +       struct nix_vtag_config_rsp rsp;
> > +
> > +       /* config strip, capture and size */
> > +       req.hdr.pcifunc = pcifunc;
> > +       req.vtag_size = VTAGSIZE_T4;
> > +       req.cfg_type = 1; /* rx vlan cfg */
> > +       req.rx.vtag_type = NIX_AF_LFX_RX_VTAG_TYPE0;
> > +       req.rx.strip_vtag = true;
> > +       req.rx.capture_vtag = false;
> > +
> > +       return rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp);
> > +}
> > +
> > +static int rvu_rep_install_rx_rule(struct rvu *rvu, u16 pcifunc,
> > +                                  u16 entry, bool rte)
> > +{
> > +       struct npc_install_flow_req req = { 0 };
> > +       struct npc_install_flow_rsp rsp = { 0 };
> > +       struct rvu_pfvf *pfvf;
> > +       u16 vlan_tci, rep_id;
> > +
> > +       pfvf = rvu_get_pfvf(rvu, pcifunc);
> > +
> > +       /* To stree the traffic from Representee to Representor */
[Kalesh] Typo. did you mean steer?
> > +       rep_id = (u16)rvu_rep_get_vlan_id(rvu, pcifunc);
> > +       if (rte) {
> > +               vlan_tci = rep_id | 0x1ull << 8;
> > +               req.vf = rvu->rep_pcifunc;
> > +               req.op = NIX_RX_ACTIONOP_UCAST;
> > +               req.index = rep_id;
> > +       } else {
> > +               vlan_tci = rep_id;
> > +               req.vf = pcifunc;
> > +               req.op = NIX_RX_ACTION_DEFAULT;
> > +       }
> > +
> > +       rvu_rep_rx_vlan_cfg(rvu, req.vf);
> > +       req.entry = entry;
> > +       req.hdr.pcifunc = 0; /* AF is requester */
> > +       req.features = BIT_ULL(NPC_OUTER_VID) | BIT_ULL(NPC_VLAN_ETYPE_CTAG);
> > +       req.vtag0_valid = true;
> > +       req.vtag0_type = NIX_AF_LFX_RX_VTAG_TYPE0;
> > +       req.packet.vlan_etype = ETH_P_8021Q;
> > +       req.mask.vlan_etype = ETH_P_8021Q;
> > +       req.packet.vlan_tci = vlan_tci;
> > +       req.mask.vlan_tci = 0xffff;
> > +
> > +       req.channel = RVU_SWITCH_LBK_CHAN;
> > +       req.chan_mask = 0xffff;
> > +       req.intf = pfvf->nix_rx_intf;
> > +
> > +       return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
> > +}
> > +
> > +static int rvu_rep_install_tx_rule(struct rvu *rvu, u16 pcifunc, u16 entry,
> > +                                  bool rte)
> > +{
> > +       struct npc_install_flow_req req = { 0 };
> > +       struct npc_install_flow_rsp rsp = { 0 };
> > +       struct rvu_pfvf *pfvf;
> > +       int vidx, err;
> > +       u16 vlan_tci;
> > +       u8 lbkid;
> > +
> > +       pfvf = rvu_get_pfvf(rvu, pcifunc);
> > +       vlan_tci = rvu_rep_get_vlan_id(rvu, pcifunc);
> > +       if (rte)
> > +               vlan_tci |= 0x1ull << 8;
> > +
> > +       err = rvu_rep_tx_vlan_cfg(rvu, pcifunc, vlan_tci, &vidx);
> > +       if (err)
> > +               return err;
> > +
> > +       lbkid = pfvf->nix_blkaddr == BLKADDR_NIX0 ? 0 : 1;
> > +       req.hdr.pcifunc = 0; /* AF is requester */
> > +       if (rte) {
> > +               req.vf = pcifunc;
> > +       } else {
> > +               req.vf = rvu->rep_pcifunc;
> > +               req.packet.sq_id = vlan_tci;
> > +               req.mask.sq_id = 0xffff;
> > +       }
> > +
> > +       req.entry = entry;
> > +       req.intf = pfvf->nix_tx_intf;
> > +       req.op = NIX_TX_ACTIONOP_UCAST_CHAN;
> > +       req.index = (lbkid << 8) | RVU_SWITCH_LBK_CHAN;
> > +       req.set_cntr = 1;
> > +       req.vtag0_def = vidx;
> > +       req.vtag0_op = 1;
> > +       return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
> > +}
> > +
> > +int rvu_rep_install_mcam_rules(struct rvu *rvu)
> > +{
> > +       struct rvu_switch *rswitch = &rvu->rswitch;
> > +       u16 start = rswitch->start_entry;
> > +       struct rvu_hwinfo *hw = rvu->hw;
> > +       u16 pcifunc, entry = 0;
> > +       int pf, vf, numvfs;
> > +       int err, nixlf, i;
> > +       u8 rep;
> > +
> > +       for (pf = 1; pf < hw->total_pfs; pf++) {
> > +               if (!is_pf_cgxmapped(rvu, pf))
> > +                       continue;
> > +
> > +               pcifunc = pf << RVU_PFVF_PF_SHIFT;
> > +               rvu_get_nix_blkaddr(rvu, pcifunc);
> > +               rep = true;
> > +               for (i = 0; i < 2; i++) {
> > +                       err = rvu_rep_install_rx_rule(rvu, pcifunc, start + entry, rep);
> > +                       if (err)
> > +                               return err;
> > +                       rswitch->entry2pcifunc[entry++] = pcifunc;
> > +
> > +                       err = rvu_rep_install_tx_rule(rvu, pcifunc, start + entry, rep);
> > +                       if (err)
> > +                               return err;
> > +                       rswitch->entry2pcifunc[entry++] = pcifunc;
> > +                       rep = false;
> > +               }
> > +
> > +               rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
> > +               for (vf = 0; vf < numvfs; vf++) {
> > +                       pcifunc = pf << RVU_PFVF_PF_SHIFT |
> > +                                 ((vf + 1) & RVU_PFVF_FUNC_MASK);
> > +                       rvu_get_nix_blkaddr(rvu, pcifunc);
> > +
> > +                       /* Skip installimg rules if nixlf is not attached */
> > +                       err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
> > +                       if (err)
> > +                               continue;
> > +                       rep = true;
> > +                       for (i = 0; i < 2; i++) {
> > +                               err = rvu_rep_install_rx_rule(rvu, pcifunc, start + entry, rep);
> > +                               if (err)
> > +                                       return err;
> > +                               rswitch->entry2pcifunc[entry++] = pcifunc;
> > +
> > +                               err = rvu_rep_install_tx_rule(rvu, pcifunc, start + entry, rep);
> > +                               if (err)
> > +                                       return err;
> > +                               rswitch->entry2pcifunc[entry++] = pcifunc;
> > +                               rep = false;
> > +                       }
> > +               }
> > +       }
> > +       return 0;
> > +}
> > +
> > +void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena)
> > +{
> > +       struct rvu_switch *rswitch = &rvu->rswitch;
> > +       struct npc_mcam *mcam = &rvu->hw->mcam;
[Kalesh: maintain RCT order
> > +       u32 max = rswitch->used_entries;
> > +       int blkaddr;
> > +       u16 entry;
> > +
> > +       if (!rswitch->used_entries)
> > +               return;
> > +
> > +       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
> > +
[Kalesh] No need of a blank line here
> > +       if (blkaddr < 0)
> > +               return;
> > +
> > +       rvu_switch_enable_lbk_link(rvu, pcifunc, ena);
> > +       mutex_lock(&mcam->lock);
> > +       for (entry = 0; entry < max; entry++) {
> > +               if (rswitch->entry2pcifunc[entry] == pcifunc)
> > +                       npc_enable_mcam_entry(rvu, mcam, blkaddr, entry, ena);
> > +       }
> > +       mutex_unlock(&mcam->lock);
> > +}
> > +
> > +int rvu_rep_pf_init(struct rvu *rvu)
> > +{
> > +       u16 pcifunc = rvu->rep_pcifunc;
> > +       struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
> > +
> > +       set_bit(NIXLF_INITIALIZED, &pfvf->flags);
> > +       rvu_switch_enable_lbk_link(rvu, pcifunc, true);
> > +       rvu_rep_rx_vlan_cfg(rvu, pcifunc);
> > +       return 0;
[Kalesh] This function returns 0 unconditionally, maybe you can change
it to void?
> > +}
> > +
> > +int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct esw_cfg_req *req,
> > +                            struct msg_rsp *rsp)
> > +{
> > +       if (req->hdr.pcifunc != rvu->rep_pcifunc)
> > +               return 0;
> > +
> > +       rvu->rep_mode = req->ena;
> > +
> > +       if (req->ena)
> > +               rvu_switch_enable(rvu);
> > +       else
> > +               rvu_switch_disable(rvu);
> > +
> > +       return 0;
[Kalesh] This function returns 0 unconditionally, maybe you can change
it to void?
> > +}
> > +
> >  int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
> >                                  struct get_rep_cnt_rsp *rsp)
> >  {
> > @@ -45,4 +285,3 @@ int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
> >         }
> >         return 0;
> >  }
> > -
> > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
> > index ceb81eebf65e..268efb7c1c15 100644
> > --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
> > +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
> > @@ -166,6 +166,8 @@ void rvu_switch_enable(struct rvu *rvu)
> >
> >         alloc_req.contig = true;
> >         alloc_req.count = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs;
> > +       if (rvu->rep_mode)
> > +               alloc_req.count = alloc_req.count * 4;
> >         ret = rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &alloc_req,
> >                                                     &alloc_rsp);
> >         if (ret) {
> > @@ -189,7 +191,12 @@ void rvu_switch_enable(struct rvu *rvu)
> >         rswitch->used_entries = alloc_rsp.count;
> >         rswitch->start_entry = alloc_rsp.entry;
> >
> > -       ret = rvu_switch_install_rules(rvu);
> > +       if (rvu->rep_mode) {
> > +               rvu_rep_pf_init(rvu);
> > +               ret = rvu_rep_install_mcam_rules(rvu);
> > +       } else {
> > +               ret = rvu_switch_install_rules(rvu);
> > +       }
> >         if (ret)
> >                 goto uninstall_rules;
> >
> > @@ -222,6 +229,9 @@ void rvu_switch_disable(struct rvu *rvu)
> >         if (!rswitch->used_entries)
> >                 return;
> >
> > +       if (rvu->rep_mode)
> > +               goto free_ents;
> > +
> >         for (pf = 1; pf < hw->total_pfs; pf++) {
> >                 if (!is_pf_cgxmapped(rvu, pf))
> >                         continue;
> > @@ -249,6 +259,7 @@ void rvu_switch_disable(struct rvu *rvu)
> >                 }
> >         }
> >
> > +free_ents:
> >         uninstall_req.start = rswitch->start_entry;
> >         uninstall_req.end =  rswitch->start_entry + rswitch->used_entries - 1;
> >         free_req.all = 1;
> > @@ -258,12 +269,15 @@ void rvu_switch_disable(struct rvu *rvu)
> >         kfree(rswitch->entry2pcifunc);
> >  }
> >
> > -void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc)
> > +void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc, bool ena)
> >  {
> >         struct rvu_switch *rswitch = &rvu->rswitch;
> >         u32 max = rswitch->used_entries;
> >         u16 entry;
> >
> > +       if (rvu->rep_mode)
> > +               return rvu_rep_update_rules(rvu, pcifunc, ena);
> > +
> >         if (!rswitch->used_entries)
> >                 return;
> >
> > diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> > index 187b00156bcd..1329617f8d6f 100644
> > --- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> > +++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> > @@ -28,6 +28,22 @@ MODULE_DESCRIPTION(DRV_STRING);
> >  MODULE_LICENSE("GPL");
> >  MODULE_DEVICE_TABLE(pci, rvu_rep_id_table);
> >
> > +static int rvu_eswitch_config(struct otx2_nic *priv, u8 ena)
> > +{
> > +       struct esw_cfg_req *req;
> > +
> > +       mutex_lock(&priv->mbox.lock);
> > +       req = otx2_mbox_alloc_msg_esw_cfg(&priv->mbox);
> > +       if (!req) {
> > +               mutex_unlock(&priv->mbox.lock);
> > +               return -ENOMEM;
> > +       }
> > +       req->ena = ena;
> > +       otx2_sync_mbox_msg(&priv->mbox);
> > +       mutex_unlock(&priv->mbox.lock);
> > +       return 0;
> > +}
> > +
> >  static netdev_tx_t rvu_rep_xmit(struct sk_buff *skb, struct net_device *dev)
> >  {
> >         struct rep_dev *rep = netdev_priv(dev);
> > @@ -170,6 +186,8 @@ static void rvu_rep_free_netdev(struct otx2_nic *priv)
> >
> >  void rvu_rep_destroy(struct otx2_nic *priv)
> >  {
> > +       /* Remove mcam rules */
> > +       rvu_eswitch_config(priv, false);
> >         rvu_rep_free_cq_rsrc(priv);
> >         rvu_rep_free_netdev(priv);
> >  }
> > @@ -221,6 +239,7 @@ int rvu_rep_create(struct otx2_nic *priv)
> >         if (err)
> >                 goto exit;
> >
> > +       rvu_eswitch_config(priv, true);
> >         return 0;
> >  exit:
> >         rvu_rep_free_netdev(priv);
> > --
> > 2.25.1
> >
> >
>
>
> --
> Regards,
> Kalesh A P
Geetha sowjanya April 17, 2024, 1:48 p.m. UTC | #3
Hi,

> -----Original Message-----
> From: Kalesh Anakkur Purayil <kalesh-anakkur.purayil@broadcom.com>
> Sent: Wednesday, April 17, 2024 9:46 AM
> To: Geethasowjanya Akula <gakula@marvell.com>
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; kuba@kernel.org;
> davem@davemloft.net; pabeni@redhat.com; edumazet@google.com; Sunil
> Kovvuri Goutham <sgoutham@marvell.com>; Subbaraya Sundeep Bhatta
> <sbhatta@marvell.com>; Hariprasad Kelam <hkelam@marvell.com>
> Subject: [EXTERNAL] Re: [net-next PATCH 5/9] octeontx2-af: Add packet path
> between representor and VF
> 
> Prioritize security for external emails: Confirm sender and content safety
> before clicking links or opening attachments
> 
> ----------------------------------------------------------------------
> On Wed, Apr 17, 2024 at 9:40 AM Kalesh Anakkur Purayil
> <kalesh-anakkur.purayil@broadcom.com> wrote:
> >
> > On Tue, Apr 16, 2024 at 10:38 AM Geetha sowjanya <gakula@marvell.com>
> wrote:
> > >
> > > This patch installs tcam rules to stree traffic representors
> > > and VF when swicthdev mode is set. To support this a HW loopback
> > > channel is reserved. Through this channel packet are routed
> > > between representor and VFs. "ESW_CFG" mbox is defined to
> > > notify AF for installing rules.
> > >
> > > Signed-off-by: Geetha sowjanya <gakula@marvell.com>
> > > ---
> > >  .../net/ethernet/marvell/octeontx2/af/mbox.h  |   7 +
> > >  .../net/ethernet/marvell/octeontx2/af/rvu.h   |   7 +-
> > >  .../marvell/octeontx2/af/rvu_devlink.c        |   6 +
> > >  .../ethernet/marvell/octeontx2/af/rvu_nix.c   |   7 +-
> > >  .../ethernet/marvell/octeontx2/af/rvu_rep.c   | 241 +++++++++++++++++-
> > >  .../marvell/octeontx2/af/rvu_switch.c         |  18 +-
> > >  .../net/ethernet/marvell/octeontx2/nic/rep.c  |  19 ++
> > >  7 files changed, 297 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
> b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
> > > index c77c02730cf9..3b36da28a8f4 100644
> > > --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
> > > +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
> > > @@ -144,6 +144,7 @@ M(LMTST_TBL_SETUP,  0x00a, lmtst_tbl_setup,
> lmtst_tbl_setup_req,    \
> > >  M(SET_VF_PERM,         0x00b, set_vf_perm, set_vf_perm, msg_rsp)       \
> > >  M(PTP_GET_CAP,         0x00c, ptp_get_cap, msg_req, ptp_get_cap_rsp)   \
> > >  M(GET_REP_CNT,         0x00d, get_rep_cnt, msg_req, get_rep_cnt_rsp)   \
> > > +M(ESW_CFG,             0x00e, esw_cfg, esw_cfg_req, msg_rsp)   \
> > >  /* CGX mbox IDs (range 0x200 - 0x3FF) */                               \
> > >  M(CGX_START_RXTX,      0x200, cgx_start_rxtx, msg_req, msg_rsp)        \
> > >  M(CGX_STOP_RXTX,       0x201, cgx_stop_rxtx, msg_req, msg_rsp)         \
> > > @@ -1532,6 +1533,12 @@ struct get_rep_cnt_rsp {
> > >         u64 rsvd;
> > >  };
> > >
> > > +struct esw_cfg_req {
> > > +       struct mbox_msghdr hdr;
> > > +       u8 ena;
> > > +       u64 rsvd;
> > > +};
> > > +
> > >  struct flow_msg {
> > >         unsigned char dmac[6];
> > >         unsigned char smac[6];
> > > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
> b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
> > > index 1d76d52d7a5d..c8572d79a968 100644
> > > --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
> > > +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
> > > @@ -596,6 +596,7 @@ struct rvu {
> > >         u16                     rep_pcifunc;
> > >         int                     rep_cnt;
> > >         u16                     *rep2pfvf_map;
> > > +       u8                      rep_mode;
> > >  };
> > >
> > >  static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64
> val)
> > > @@ -1025,7 +1026,7 @@ int rvu_ndc_fix_locked_cacheline(struct rvu
> *rvu, int blkaddr);
> > >  /* RVU Switch */
> > >  void rvu_switch_enable(struct rvu *rvu);
> > >  void rvu_switch_disable(struct rvu *rvu);
> > > -void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc);
> > > +void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
> > >  void rvu_switch_enable_lbk_link(struct rvu *rvu, u16 pcifunc, bool ena);
> > >
> > >  int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8
> dir,
> > > @@ -1039,4 +1040,8 @@ int rvu_mcs_flr_handler(struct rvu *rvu, u16
> pcifunc);
> > >  void rvu_mcs_ptp_cfg(struct rvu *rvu, u8 rpm_id, u8 lmac_id, bool ena);
> > >  void rvu_mcs_exit(struct rvu *rvu);
> > >
> > > +/* Representor APIs */
> > > +int rvu_rep_pf_init(struct rvu *rvu);
> > > +int rvu_rep_install_mcam_rules(struct rvu *rvu);
> > > +void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
> > >  #endif /* RVU_H */
> > > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
> b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
> > > index 96c04f7d93f8..8a3b7fb61883 100644
> > > --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
> > > +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
> > > @@ -1464,6 +1464,9 @@ static int rvu_devlink_eswitch_mode_get(struct
> devlink *devlink, u16 *mode)
> > >         struct rvu *rvu = rvu_dl->rvu;
> > >         struct rvu_switch *rswitch;
> > >
> > > +       if (rvu->rep_mode)
> > > +               return -EOPNOTSUPP;
> > > +
> > >         rswitch = &rvu->rswitch;
> > >         *mode = rswitch->mode;
> > >
> > > @@ -1477,6 +1480,9 @@ static int rvu_devlink_eswitch_mode_set(struct
> devlink *devlink, u16 mode,
> > >         struct rvu *rvu = rvu_dl->rvu;
> > >         struct rvu_switch *rswitch;
> > >
> > > +       if (rvu->rep_mode)
> > > +               return -EOPNOTSUPP;
> > > +
> > >         rswitch = &rvu->rswitch;
> > >         switch (mode) {
> > >         case DEVLINK_ESWITCH_MODE_LEGACY:
> > > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> > > index 4ef5bb7b337f..75d5c1bc00e1 100644
> > > --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> > > +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
> > > @@ -2738,7 +2738,7 @@ void rvu_nix_tx_tl2_cfg(struct rvu *rvu, int
> blkaddr, u16 pcifunc,
> > >         int schq;
> > >         u64 cfg;
> > >
> > > -       if (!is_pf_cgxmapped(rvu, pf))
> > > +       if (!is_pf_cgxmapped(rvu, pf) && !is_rep_dev(rvu, pcifunc))
> > >                 return;
> > >
> > >         cfg = enable ? (BIT_ULL(12) | RVU_SWITCH_LBK_CHAN) : 0;
> > > @@ -4368,8 +4368,6 @@ int
> rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,
> > >         if (test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) && from_vf)
> > >                 ether_addr_copy(pfvf->default_mac, req->mac_addr);
> > >
> > > -       rvu_switch_update_rules(rvu, pcifunc);
> > > -
> > >         return 0;
> > >  }
> > >
> > > @@ -5159,7 +5157,7 @@ int rvu_mbox_handler_nix_lf_start_rx(struct
> rvu *rvu, struct msg_req *req,
> > >         pfvf = rvu_get_pfvf(rvu, pcifunc);
> > >         set_bit(NIXLF_INITIALIZED, &pfvf->flags);
> > >
> > > -       rvu_switch_update_rules(rvu, pcifunc);
> > > +       rvu_switch_update_rules(rvu, pcifunc, true);
> > >
> > >         return rvu_cgx_start_stop_io(rvu, pcifunc, true);
> > >  }
> > > @@ -5187,6 +5185,7 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu
> *rvu, struct msg_req *req,
> > >         if (err)
> > >                 return err;
> > >
> > > +       rvu_switch_update_rules(rvu, pcifunc, false);
> > >         rvu_cgx_tx_enable(rvu, pcifunc, true);
> > >
> > >         return 0;
> > > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
> b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
> > > index d07cb356d3d6..5c015e8dfbbe 100644
> > > --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
> > > +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
> > > @@ -13,6 +13,246 @@
> > >  #include "rvu.h"
> > >  #include "rvu_reg.h"
> > >
> > > +static u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc)
> > > +{
> > > +       int id;
> > > +
> > > +       for (id = 0; id < rvu->rep_cnt; id++)
> > > +               if (rvu->rep2pfvf_map[id] == pcifunc)
> > > +                       return id;
> > > +       return -ENODEV;
> > > +}
> > > +
> > > +static int rvu_rep_tx_vlan_cfg(struct rvu *rvu,  u16 pcifunc,
> > > +                              u16 vlan_tci, int *vidx)
> > > +{
> > > +       struct nix_vtag_config req = {0};
> > > +       struct nix_vtag_config_rsp rsp = {0};
> [Kalesh] RCT order. Also I think {0} is not needed and you can just use {}
Ack.
> > > +       u64 etype = ETH_P_8021Q;
> > > +       int err;
> > > +
> > > +       /* Insert vlan tag */
> > > +       req.hdr.pcifunc = pcifunc;
> > > +       req.vtag_size = VTAGSIZE_T4;
> > > +       req.cfg_type = 0; /* tx vlan cfg */
> > > +       req.tx.cfg_vtag0 = true;
> > > +       req.tx.vtag0 = etype << 48 | ntohs(vlan_tci);
> > > +
> > > +       err = rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp);
> > > +       if (err) {
> > > +               dev_err(rvu->dev, "Tx vlan config failed\n");
> > > +               return err;
> > > +       }
> > > +       *vidx = rsp.vtag0_idx;
> > > +       return 0;
> > > +}
> > > +
> > > +static int rvu_rep_rx_vlan_cfg(struct rvu *rvu, u16 pcifunc)
> > > +{
> > > +       struct nix_vtag_config req = {0};
> > > +       struct nix_vtag_config_rsp rsp;
> > > +
> > > +       /* config strip, capture and size */
> > > +       req.hdr.pcifunc = pcifunc;
> > > +       req.vtag_size = VTAGSIZE_T4;
> > > +       req.cfg_type = 1; /* rx vlan cfg */
> > > +       req.rx.vtag_type = NIX_AF_LFX_RX_VTAG_TYPE0;
> > > +       req.rx.strip_vtag = true;
> > > +       req.rx.capture_vtag = false;
> > > +
> > > +       return rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp);
> > > +}
> > > +
> > > +static int rvu_rep_install_rx_rule(struct rvu *rvu, u16 pcifunc,
> > > +                                  u16 entry, bool rte)
> > > +{
> > > +       struct npc_install_flow_req req = { 0 };
> > > +       struct npc_install_flow_rsp rsp = { 0 };
> > > +       struct rvu_pfvf *pfvf;
> > > +       u16 vlan_tci, rep_id;
> > > +
> > > +       pfvf = rvu_get_pfvf(rvu, pcifunc);
> > > +
> > > +       /* To stree the traffic from Representee to Representor */
> [Kalesh] Typo. did you mean steer?
> > > +       rep_id = (u16)rvu_rep_get_vlan_id(rvu, pcifunc);
> > > +       if (rte) {
> > > +               vlan_tci = rep_id | 0x1ull << 8;
> > > +               req.vf = rvu->rep_pcifunc;
> > > +               req.op = NIX_RX_ACTIONOP_UCAST;
> > > +               req.index = rep_id;
> > > +       } else {
> > > +               vlan_tci = rep_id;
> > > +               req.vf = pcifunc;
> > > +               req.op = NIX_RX_ACTION_DEFAULT;
> > > +       }
> > > +
> > > +       rvu_rep_rx_vlan_cfg(rvu, req.vf);
> > > +       req.entry = entry;
> > > +       req.hdr.pcifunc = 0; /* AF is requester */
> > > +       req.features = BIT_ULL(NPC_OUTER_VID) |
> BIT_ULL(NPC_VLAN_ETYPE_CTAG);
> > > +       req.vtag0_valid = true;
> > > +       req.vtag0_type = NIX_AF_LFX_RX_VTAG_TYPE0;
> > > +       req.packet.vlan_etype = ETH_P_8021Q;
> > > +       req.mask.vlan_etype = ETH_P_8021Q;
> > > +       req.packet.vlan_tci = vlan_tci;
> > > +       req.mask.vlan_tci = 0xffff;
> > > +
> > > +       req.channel = RVU_SWITCH_LBK_CHAN;
> > > +       req.chan_mask = 0xffff;
> > > +       req.intf = pfvf->nix_rx_intf;
> > > +
> > > +       return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
> > > +}
> > > +
> > > +static int rvu_rep_install_tx_rule(struct rvu *rvu, u16 pcifunc, u16 entry,
> > > +                                  bool rte)
> > > +{
> > > +       struct npc_install_flow_req req = { 0 };
> > > +       struct npc_install_flow_rsp rsp = { 0 };
> > > +       struct rvu_pfvf *pfvf;
> > > +       int vidx, err;
> > > +       u16 vlan_tci;
> > > +       u8 lbkid;
> > > +
> > > +       pfvf = rvu_get_pfvf(rvu, pcifunc);
> > > +       vlan_tci = rvu_rep_get_vlan_id(rvu, pcifunc);
> > > +       if (rte)
> > > +               vlan_tci |= 0x1ull << 8;
> > > +
> > > +       err = rvu_rep_tx_vlan_cfg(rvu, pcifunc, vlan_tci, &vidx);
> > > +       if (err)
> > > +               return err;
> > > +
> > > +       lbkid = pfvf->nix_blkaddr == BLKADDR_NIX0 ? 0 : 1;
> > > +       req.hdr.pcifunc = 0; /* AF is requester */
> > > +       if (rte) {
> > > +               req.vf = pcifunc;
> > > +       } else {
> > > +               req.vf = rvu->rep_pcifunc;
> > > +               req.packet.sq_id = vlan_tci;
> > > +               req.mask.sq_id = 0xffff;
> > > +       }
> > > +
> > > +       req.entry = entry;
> > > +       req.intf = pfvf->nix_tx_intf;
> > > +       req.op = NIX_TX_ACTIONOP_UCAST_CHAN;
> > > +       req.index = (lbkid << 8) | RVU_SWITCH_LBK_CHAN;
> > > +       req.set_cntr = 1;
> > > +       req.vtag0_def = vidx;
> > > +       req.vtag0_op = 1;
> > > +       return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
> > > +}
> > > +
> > > +int rvu_rep_install_mcam_rules(struct rvu *rvu)
> > > +{
> > > +       struct rvu_switch *rswitch = &rvu->rswitch;
> > > +       u16 start = rswitch->start_entry;
> > > +       struct rvu_hwinfo *hw = rvu->hw;
> > > +       u16 pcifunc, entry = 0;
> > > +       int pf, vf, numvfs;
> > > +       int err, nixlf, i;
> > > +       u8 rep;
> > > +
> > > +       for (pf = 1; pf < hw->total_pfs; pf++) {
> > > +               if (!is_pf_cgxmapped(rvu, pf))
> > > +                       continue;
> > > +
> > > +               pcifunc = pf << RVU_PFVF_PF_SHIFT;
> > > +               rvu_get_nix_blkaddr(rvu, pcifunc);
> > > +               rep = true;
> > > +               for (i = 0; i < 2; i++) {
> > > +                       err = rvu_rep_install_rx_rule(rvu, pcifunc, start + entry, rep);
> > > +                       if (err)
> > > +                               return err;
> > > +                       rswitch->entry2pcifunc[entry++] = pcifunc;
> > > +
> > > +                       err = rvu_rep_install_tx_rule(rvu, pcifunc, start + entry, rep);
> > > +                       if (err)
> > > +                               return err;
> > > +                       rswitch->entry2pcifunc[entry++] = pcifunc;
> > > +                       rep = false;
> > > +               }
> > > +
> > > +               rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
> > > +               for (vf = 0; vf < numvfs; vf++) {
> > > +                       pcifunc = pf << RVU_PFVF_PF_SHIFT |
> > > +                                 ((vf + 1) & RVU_PFVF_FUNC_MASK);
> > > +                       rvu_get_nix_blkaddr(rvu, pcifunc);
> > > +
> > > +                       /* Skip installimg rules if nixlf is not attached */
> > > +                       err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
> > > +                       if (err)
> > > +                               continue;
> > > +                       rep = true;
> > > +                       for (i = 0; i < 2; i++) {
> > > +                               err = rvu_rep_install_rx_rule(rvu, pcifunc, start + entry,
> rep);
> > > +                               if (err)
> > > +                                       return err;
> > > +                               rswitch->entry2pcifunc[entry++] = pcifunc;
> > > +
> > > +                               err = rvu_rep_install_tx_rule(rvu, pcifunc, start + entry,
> rep);
> > > +                               if (err)
> > > +                                       return err;
> > > +                               rswitch->entry2pcifunc[entry++] = pcifunc;
> > > +                               rep = false;
> > > +                       }
> > > +               }
> > > +       }
> > > +       return 0;
> > > +}
> > > +
> > > +void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena)
> > > +{
> > > +       struct rvu_switch *rswitch = &rvu->rswitch;
> > > +       struct npc_mcam *mcam = &rvu->hw->mcam;
> [Kalesh: maintain RCT order
> > > +       u32 max = rswitch->used_entries;
> > > +       int blkaddr;
> > > +       u16 entry;
> > > +
> > > +       if (!rswitch->used_entries)
> > > +               return;
> > > +
> > > +       blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
> > > +
> [Kalesh] No need of a blank line here
> > > +       if (blkaddr < 0)
> > > +               return;
> > > +
> > > +       rvu_switch_enable_lbk_link(rvu, pcifunc, ena);
> > > +       mutex_lock(&mcam->lock);
> > > +       for (entry = 0; entry < max; entry++) {
> > > +               if (rswitch->entry2pcifunc[entry] == pcifunc)
> > > +                       npc_enable_mcam_entry(rvu, mcam, blkaddr, entry, ena);
> > > +       }
> > > +       mutex_unlock(&mcam->lock);
> > > +}
> > > +
> > > +int rvu_rep_pf_init(struct rvu *rvu)
> > > +{
> > > +       u16 pcifunc = rvu->rep_pcifunc;
> > > +       struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
> > > +
> > > +       set_bit(NIXLF_INITIALIZED, &pfvf->flags);
> > > +       rvu_switch_enable_lbk_link(rvu, pcifunc, true);
> > > +       rvu_rep_rx_vlan_cfg(rvu, pcifunc);
> > > +       return 0;
> [Kalesh] This function returns 0 unconditionally, maybe you can change
> it to void?'
Ack.
> > > +}
> > > +
> > > +int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct esw_cfg_req *req,
> > > +                            struct msg_rsp *rsp)
> > > +{
> > > +       if (req->hdr.pcifunc != rvu->rep_pcifunc)
> > > +               return 0;
> > > +
> > > +       rvu->rep_mode = req->ena;
> > > +
> > > +       if (req->ena)
> > > +               rvu_switch_enable(rvu);
> > > +       else
> > > +               rvu_switch_disable(rvu);
> > > +
> > > +       return 0;
> [Kalesh] This function returns 0 unconditionally, maybe you can change
> it to void?
> > > +}
> > > +
> > >  int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
> > >                                  struct get_rep_cnt_rsp *rsp)
> > >  {
> > > @@ -45,4 +285,3 @@ int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu,
> struct msg_req *req,
> > >         }
> > >         return 0;
> > >  }
> > > -
> > > diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
> b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
> > > index ceb81eebf65e..268efb7c1c15 100644
> > > --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
> > > +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
> > > @@ -166,6 +166,8 @@ void rvu_switch_enable(struct rvu *rvu)
> > >
> > >         alloc_req.contig = true;
> > >         alloc_req.count = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs;
> > > +       if (rvu->rep_mode)
> > > +               alloc_req.count = alloc_req.count * 4;
> > >         ret = rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &alloc_req,
> > >                                                     &alloc_rsp);
> > >         if (ret) {
> > > @@ -189,7 +191,12 @@ void rvu_switch_enable(struct rvu *rvu)
> > >         rswitch->used_entries = alloc_rsp.count;
> > >         rswitch->start_entry = alloc_rsp.entry;
> > >
> > > -       ret = rvu_switch_install_rules(rvu);
> > > +       if (rvu->rep_mode) {
> > > +               rvu_rep_pf_init(rvu);
> > > +               ret = rvu_rep_install_mcam_rules(rvu);
> > > +       } else {
> > > +               ret = rvu_switch_install_rules(rvu);
> > > +       }
> > >         if (ret)
> > >                 goto uninstall_rules;
> > >
> > > @@ -222,6 +229,9 @@ void rvu_switch_disable(struct rvu *rvu)
> > >         if (!rswitch->used_entries)
> > >                 return;
> > >
> > > +       if (rvu->rep_mode)
> > > +               goto free_ents;
> > > +
> > >         for (pf = 1; pf < hw->total_pfs; pf++) {
> > >                 if (!is_pf_cgxmapped(rvu, pf))
> > >                         continue;
> > > @@ -249,6 +259,7 @@ void rvu_switch_disable(struct rvu *rvu)
> > >                 }
> > >         }
> > >
> > > +free_ents:
> > >         uninstall_req.start = rswitch->start_entry;
> > >         uninstall_req.end =  rswitch->start_entry + rswitch->used_entries - 1;
> > >         free_req.all = 1;
> > > @@ -258,12 +269,15 @@ void rvu_switch_disable(struct rvu *rvu)
> > >         kfree(rswitch->entry2pcifunc);
> > >  }
> > >
> > > -void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc)
> > > +void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc, bool ena)
> > >  {
> > >         struct rvu_switch *rswitch = &rvu->rswitch;
> > >         u32 max = rswitch->used_entries;
> > >         u16 entry;
> > >
> > > +       if (rvu->rep_mode)
> > > +               return rvu_rep_update_rules(rvu, pcifunc, ena);
> > > +
> > >         if (!rswitch->used_entries)
> > >                 return;
> > >
> > > diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> > > index 187b00156bcd..1329617f8d6f 100644
> > > --- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> > > +++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
> > > @@ -28,6 +28,22 @@ MODULE_DESCRIPTION(DRV_STRING);
> > >  MODULE_LICENSE("GPL");
> > >  MODULE_DEVICE_TABLE(pci, rvu_rep_id_table);
> > >
> > > +static int rvu_eswitch_config(struct otx2_nic *priv, u8 ena)
> > > +{
> > > +       struct esw_cfg_req *req;
> > > +
> > > +       mutex_lock(&priv->mbox.lock);
> > > +       req = otx2_mbox_alloc_msg_esw_cfg(&priv->mbox);
> > > +       if (!req) {
> > > +               mutex_unlock(&priv->mbox.lock);
> > > +               return -ENOMEM;
> > > +       }
> > > +       req->ena = ena;
> > > +       otx2_sync_mbox_msg(&priv->mbox);
> > > +       mutex_unlock(&priv->mbox.lock);
> > > +       return 0;
> > > +}
> > > +
> > >  static netdev_tx_t rvu_rep_xmit(struct sk_buff *skb, struct net_device
> *dev)
> > >  {
> > >         struct rep_dev *rep = netdev_priv(dev);
> > > @@ -170,6 +186,8 @@ static void rvu_rep_free_netdev(struct otx2_nic
> *priv)
> > >
> > >  void rvu_rep_destroy(struct otx2_nic *priv)
> > >  {
> > > +       /* Remove mcam rules */
> > > +       rvu_eswitch_config(priv, false);
> > >         rvu_rep_free_cq_rsrc(priv);
> > >         rvu_rep_free_netdev(priv);
> > >  }
> > > @@ -221,6 +239,7 @@ int rvu_rep_create(struct otx2_nic *priv)
> > >         if (err)
> > >                 goto exit;
> > >
> > > +       rvu_eswitch_config(priv, true);
> > >         return 0;
> > >  exit:
> > >         rvu_rep_free_netdev(priv);
> > > --
> > > 2.25.1
> > >
> > >
> >
> >
> > --
> > Regards,
> > Kalesh A P
> 
> 
> 
> --
> Regards,
> Kalesh A P

Thanks for the feedback. Will submit v2 addressing all the issues.
Dan Carpenter April 17, 2024, 6:08 p.m. UTC | #4
Hi Geetha,

kernel test robot noticed the following build warnings:

url:    https://github.com/intel-lab-lkp/linux/commits/Geetha-sowjanya/octeontx2-pf-Refactoring-RVU-driver/20240416-131052
base:   net-next/main
patch link:    https://lore.kernel.org/r/20240416050616.6056-6-gakula%40marvell.com
patch subject: [net-next PATCH 5/9] octeontx2-af: Add packet path between representor and VF
config: alpha-randconfig-r081-20240417 (https://download.01.org/0day-ci/archive/20240417/202404172319.ys4PQfP0-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 13.2.0

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202404172319.ys4PQfP0-lkp@intel.com/

smatch warnings:
drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c:23 rvu_rep_get_vlan_id() warn: signedness bug returning '(-19)'

vim +23 drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c

5c25d7a685d906 Geetha sowjanya 2024-04-16  16  static u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc)
                                                      ^^^
u16 type

5c25d7a685d906 Geetha sowjanya 2024-04-16  17  {
5c25d7a685d906 Geetha sowjanya 2024-04-16  18  	int id;
5c25d7a685d906 Geetha sowjanya 2024-04-16  19  
5c25d7a685d906 Geetha sowjanya 2024-04-16  20  	for (id = 0; id < rvu->rep_cnt; id++)
5c25d7a685d906 Geetha sowjanya 2024-04-16  21  		if (rvu->rep2pfvf_map[id] == pcifunc)
5c25d7a685d906 Geetha sowjanya 2024-04-16  22  			return id;
5c25d7a685d906 Geetha sowjanya 2024-04-16 @23  	return -ENODEV;
                                                ^^^^^^^^^^^^^^

5c25d7a685d906 Geetha sowjanya 2024-04-16  24  }
diff mbox series

Patch

diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index c77c02730cf9..3b36da28a8f4 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -144,6 +144,7 @@  M(LMTST_TBL_SETUP,	0x00a, lmtst_tbl_setup, lmtst_tbl_setup_req,    \
 M(SET_VF_PERM,		0x00b, set_vf_perm, set_vf_perm, msg_rsp)	\
 M(PTP_GET_CAP,		0x00c, ptp_get_cap, msg_req, ptp_get_cap_rsp)	\
 M(GET_REP_CNT,		0x00d, get_rep_cnt, msg_req, get_rep_cnt_rsp)	\
+M(ESW_CFG,		0x00e, esw_cfg, esw_cfg_req, msg_rsp)	\
 /* CGX mbox IDs (range 0x200 - 0x3FF) */				\
 M(CGX_START_RXTX,	0x200, cgx_start_rxtx, msg_req, msg_rsp)	\
 M(CGX_STOP_RXTX,	0x201, cgx_stop_rxtx, msg_req, msg_rsp)		\
@@ -1532,6 +1533,12 @@  struct get_rep_cnt_rsp {
 	u64 rsvd;
 };
 
+struct esw_cfg_req {
+	struct mbox_msghdr hdr;
+	u8 ena;
+	u64 rsvd;
+};
+
 struct flow_msg {
 	unsigned char dmac[6];
 	unsigned char smac[6];
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index 1d76d52d7a5d..c8572d79a968 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -596,6 +596,7 @@  struct rvu {
 	u16			rep_pcifunc;
 	int			rep_cnt;
 	u16			*rep2pfvf_map;
+	u8			rep_mode;
 };
 
 static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
@@ -1025,7 +1026,7 @@  int rvu_ndc_fix_locked_cacheline(struct rvu *rvu, int blkaddr);
 /* RVU Switch */
 void rvu_switch_enable(struct rvu *rvu);
 void rvu_switch_disable(struct rvu *rvu);
-void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc);
+void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
 void rvu_switch_enable_lbk_link(struct rvu *rvu, u16 pcifunc, bool ena);
 
 int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
@@ -1039,4 +1040,8 @@  int rvu_mcs_flr_handler(struct rvu *rvu, u16 pcifunc);
 void rvu_mcs_ptp_cfg(struct rvu *rvu, u8 rpm_id, u8 lmac_id, bool ena);
 void rvu_mcs_exit(struct rvu *rvu);
 
+/* Representor APIs */
+int rvu_rep_pf_init(struct rvu *rvu);
+int rvu_rep_install_mcam_rules(struct rvu *rvu);
+void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
 #endif /* RVU_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
index 96c04f7d93f8..8a3b7fb61883 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
@@ -1464,6 +1464,9 @@  static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
 	struct rvu *rvu = rvu_dl->rvu;
 	struct rvu_switch *rswitch;
 
+	if (rvu->rep_mode)
+		return -EOPNOTSUPP;
+
 	rswitch = &rvu->rswitch;
 	*mode = rswitch->mode;
 
@@ -1477,6 +1480,9 @@  static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
 	struct rvu *rvu = rvu_dl->rvu;
 	struct rvu_switch *rswitch;
 
+	if (rvu->rep_mode)
+		return -EOPNOTSUPP;
+
 	rswitch = &rvu->rswitch;
 	switch (mode) {
 	case DEVLINK_ESWITCH_MODE_LEGACY:
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index 4ef5bb7b337f..75d5c1bc00e1 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -2738,7 +2738,7 @@  void rvu_nix_tx_tl2_cfg(struct rvu *rvu, int blkaddr, u16 pcifunc,
 	int schq;
 	u64 cfg;
 
-	if (!is_pf_cgxmapped(rvu, pf))
+	if (!is_pf_cgxmapped(rvu, pf) && !is_rep_dev(rvu, pcifunc))
 		return;
 
 	cfg = enable ? (BIT_ULL(12) | RVU_SWITCH_LBK_CHAN) : 0;
@@ -4368,8 +4368,6 @@  int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,
 	if (test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) && from_vf)
 		ether_addr_copy(pfvf->default_mac, req->mac_addr);
 
-	rvu_switch_update_rules(rvu, pcifunc);
-
 	return 0;
 }
 
@@ -5159,7 +5157,7 @@  int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
 	pfvf = rvu_get_pfvf(rvu, pcifunc);
 	set_bit(NIXLF_INITIALIZED, &pfvf->flags);
 
-	rvu_switch_update_rules(rvu, pcifunc);
+	rvu_switch_update_rules(rvu, pcifunc, true);
 
 	return rvu_cgx_start_stop_io(rvu, pcifunc, true);
 }
@@ -5187,6 +5185,7 @@  int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
 	if (err)
 		return err;
 
+	rvu_switch_update_rules(rvu, pcifunc, false);
 	rvu_cgx_tx_enable(rvu, pcifunc, true);
 
 	return 0;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
index d07cb356d3d6..5c015e8dfbbe 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
@@ -13,6 +13,246 @@ 
 #include "rvu.h"
 #include "rvu_reg.h"
 
+static u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc)
+{
+	int id;
+
+	for (id = 0; id < rvu->rep_cnt; id++)
+		if (rvu->rep2pfvf_map[id] == pcifunc)
+			return id;
+	return -ENODEV;
+}
+
+static int rvu_rep_tx_vlan_cfg(struct rvu *rvu,  u16 pcifunc,
+			       u16 vlan_tci, int *vidx)
+{
+	struct nix_vtag_config req = {0};
+	struct nix_vtag_config_rsp rsp = {0};
+	u64 etype = ETH_P_8021Q;
+	int err;
+
+	/* Insert vlan tag */
+	req.hdr.pcifunc = pcifunc;
+	req.vtag_size = VTAGSIZE_T4;
+	req.cfg_type = 0; /* tx vlan cfg */
+	req.tx.cfg_vtag0 = true;
+	req.tx.vtag0 = etype << 48 | ntohs(vlan_tci);
+
+	err = rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp);
+	if (err) {
+		dev_err(rvu->dev, "Tx vlan config failed\n");
+		return err;
+	}
+	*vidx = rsp.vtag0_idx;
+	return 0;
+}
+
+static int rvu_rep_rx_vlan_cfg(struct rvu *rvu, u16 pcifunc)
+{
+	struct nix_vtag_config req = {0};
+	struct nix_vtag_config_rsp rsp;
+
+	/* config strip, capture and size */
+	req.hdr.pcifunc = pcifunc;
+	req.vtag_size = VTAGSIZE_T4;
+	req.cfg_type = 1; /* rx vlan cfg */
+	req.rx.vtag_type = NIX_AF_LFX_RX_VTAG_TYPE0;
+	req.rx.strip_vtag = true;
+	req.rx.capture_vtag = false;
+
+	return rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp);
+}
+
+static int rvu_rep_install_rx_rule(struct rvu *rvu, u16 pcifunc,
+				   u16 entry, bool rte)
+{
+	struct npc_install_flow_req req = { 0 };
+	struct npc_install_flow_rsp rsp = { 0 };
+	struct rvu_pfvf *pfvf;
+	u16 vlan_tci, rep_id;
+
+	pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+	/* To stree the traffic from Representee to Representor */
+	rep_id = (u16)rvu_rep_get_vlan_id(rvu, pcifunc);
+	if (rte) {
+		vlan_tci = rep_id | 0x1ull << 8;
+		req.vf = rvu->rep_pcifunc;
+		req.op = NIX_RX_ACTIONOP_UCAST;
+		req.index = rep_id;
+	} else {
+		vlan_tci = rep_id;
+		req.vf = pcifunc;
+		req.op = NIX_RX_ACTION_DEFAULT;
+	}
+
+	rvu_rep_rx_vlan_cfg(rvu, req.vf);
+	req.entry = entry;
+	req.hdr.pcifunc = 0; /* AF is requester */
+	req.features = BIT_ULL(NPC_OUTER_VID) | BIT_ULL(NPC_VLAN_ETYPE_CTAG);
+	req.vtag0_valid = true;
+	req.vtag0_type = NIX_AF_LFX_RX_VTAG_TYPE0;
+	req.packet.vlan_etype = ETH_P_8021Q;
+	req.mask.vlan_etype = ETH_P_8021Q;
+	req.packet.vlan_tci = vlan_tci;
+	req.mask.vlan_tci = 0xffff;
+
+	req.channel = RVU_SWITCH_LBK_CHAN;
+	req.chan_mask = 0xffff;
+	req.intf = pfvf->nix_rx_intf;
+
+	return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
+}
+
+static int rvu_rep_install_tx_rule(struct rvu *rvu, u16 pcifunc, u16 entry,
+				   bool rte)
+{
+	struct npc_install_flow_req req = { 0 };
+	struct npc_install_flow_rsp rsp = { 0 };
+	struct rvu_pfvf *pfvf;
+	int vidx, err;
+	u16 vlan_tci;
+	u8 lbkid;
+
+	pfvf = rvu_get_pfvf(rvu, pcifunc);
+	vlan_tci = rvu_rep_get_vlan_id(rvu, pcifunc);
+	if (rte)
+		vlan_tci |= 0x1ull << 8;
+
+	err = rvu_rep_tx_vlan_cfg(rvu, pcifunc, vlan_tci, &vidx);
+	if (err)
+		return err;
+
+	lbkid = pfvf->nix_blkaddr == BLKADDR_NIX0 ? 0 : 1;
+	req.hdr.pcifunc = 0; /* AF is requester */
+	if (rte) {
+		req.vf = pcifunc;
+	} else {
+		req.vf = rvu->rep_pcifunc;
+		req.packet.sq_id = vlan_tci;
+		req.mask.sq_id = 0xffff;
+	}
+
+	req.entry = entry;
+	req.intf = pfvf->nix_tx_intf;
+	req.op = NIX_TX_ACTIONOP_UCAST_CHAN;
+	req.index = (lbkid << 8) | RVU_SWITCH_LBK_CHAN;
+	req.set_cntr = 1;
+	req.vtag0_def = vidx;
+	req.vtag0_op = 1;
+	return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
+}
+
+int rvu_rep_install_mcam_rules(struct rvu *rvu)
+{
+	struct rvu_switch *rswitch = &rvu->rswitch;
+	u16 start = rswitch->start_entry;
+	struct rvu_hwinfo *hw = rvu->hw;
+	u16 pcifunc, entry = 0;
+	int pf, vf, numvfs;
+	int err, nixlf, i;
+	u8 rep;
+
+	for (pf = 1; pf < hw->total_pfs; pf++) {
+		if (!is_pf_cgxmapped(rvu, pf))
+			continue;
+
+		pcifunc = pf << RVU_PFVF_PF_SHIFT;
+		rvu_get_nix_blkaddr(rvu, pcifunc);
+		rep = true;
+		for (i = 0; i < 2; i++) {
+			err = rvu_rep_install_rx_rule(rvu, pcifunc, start + entry, rep);
+			if (err)
+				return err;
+			rswitch->entry2pcifunc[entry++] = pcifunc;
+
+			err = rvu_rep_install_tx_rule(rvu, pcifunc, start + entry, rep);
+			if (err)
+				return err;
+			rswitch->entry2pcifunc[entry++] = pcifunc;
+			rep = false;
+		}
+
+		rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
+		for (vf = 0; vf < numvfs; vf++) {
+			pcifunc = pf << RVU_PFVF_PF_SHIFT |
+				  ((vf + 1) & RVU_PFVF_FUNC_MASK);
+			rvu_get_nix_blkaddr(rvu, pcifunc);
+
+			/* Skip installimg rules if nixlf is not attached */
+			err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL);
+			if (err)
+				continue;
+			rep = true;
+			for (i = 0; i < 2; i++) {
+				err = rvu_rep_install_rx_rule(rvu, pcifunc, start + entry, rep);
+				if (err)
+					return err;
+				rswitch->entry2pcifunc[entry++] = pcifunc;
+
+				err = rvu_rep_install_tx_rule(rvu, pcifunc, start + entry, rep);
+				if (err)
+					return err;
+				rswitch->entry2pcifunc[entry++] = pcifunc;
+				rep = false;
+			}
+		}
+	}
+	return 0;
+}
+
+void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena)
+{
+	struct rvu_switch *rswitch = &rvu->rswitch;
+	struct npc_mcam *mcam = &rvu->hw->mcam;
+	u32 max = rswitch->used_entries;
+	int blkaddr;
+	u16 entry;
+
+	if (!rswitch->used_entries)
+		return;
+
+	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
+
+	if (blkaddr < 0)
+		return;
+
+	rvu_switch_enable_lbk_link(rvu, pcifunc, ena);
+	mutex_lock(&mcam->lock);
+	for (entry = 0; entry < max; entry++) {
+		if (rswitch->entry2pcifunc[entry] == pcifunc)
+			npc_enable_mcam_entry(rvu, mcam, blkaddr, entry, ena);
+	}
+	mutex_unlock(&mcam->lock);
+}
+
+int rvu_rep_pf_init(struct rvu *rvu)
+{
+	u16 pcifunc = rvu->rep_pcifunc;
+	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+	set_bit(NIXLF_INITIALIZED, &pfvf->flags);
+	rvu_switch_enable_lbk_link(rvu, pcifunc, true);
+	rvu_rep_rx_vlan_cfg(rvu, pcifunc);
+	return 0;
+}
+
+int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct esw_cfg_req *req,
+			     struct msg_rsp *rsp)
+{
+	if (req->hdr.pcifunc != rvu->rep_pcifunc)
+		return 0;
+
+	rvu->rep_mode = req->ena;
+
+	if (req->ena)
+		rvu_switch_enable(rvu);
+	else
+		rvu_switch_disable(rvu);
+
+	return 0;
+}
+
 int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
 				 struct get_rep_cnt_rsp *rsp)
 {
@@ -45,4 +285,3 @@  int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
 	}
 	return 0;
 }
-
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
index ceb81eebf65e..268efb7c1c15 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
@@ -166,6 +166,8 @@  void rvu_switch_enable(struct rvu *rvu)
 
 	alloc_req.contig = true;
 	alloc_req.count = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs;
+	if (rvu->rep_mode)
+		alloc_req.count = alloc_req.count * 4;
 	ret = rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &alloc_req,
 						    &alloc_rsp);
 	if (ret) {
@@ -189,7 +191,12 @@  void rvu_switch_enable(struct rvu *rvu)
 	rswitch->used_entries = alloc_rsp.count;
 	rswitch->start_entry = alloc_rsp.entry;
 
-	ret = rvu_switch_install_rules(rvu);
+	if (rvu->rep_mode) {
+		rvu_rep_pf_init(rvu);
+		ret = rvu_rep_install_mcam_rules(rvu);
+	} else {
+		ret = rvu_switch_install_rules(rvu);
+	}
 	if (ret)
 		goto uninstall_rules;
 
@@ -222,6 +229,9 @@  void rvu_switch_disable(struct rvu *rvu)
 	if (!rswitch->used_entries)
 		return;
 
+	if (rvu->rep_mode)
+		goto free_ents;
+
 	for (pf = 1; pf < hw->total_pfs; pf++) {
 		if (!is_pf_cgxmapped(rvu, pf))
 			continue;
@@ -249,6 +259,7 @@  void rvu_switch_disable(struct rvu *rvu)
 		}
 	}
 
+free_ents:
 	uninstall_req.start = rswitch->start_entry;
 	uninstall_req.end =  rswitch->start_entry + rswitch->used_entries - 1;
 	free_req.all = 1;
@@ -258,12 +269,15 @@  void rvu_switch_disable(struct rvu *rvu)
 	kfree(rswitch->entry2pcifunc);
 }
 
-void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc)
+void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc, bool ena)
 {
 	struct rvu_switch *rswitch = &rvu->rswitch;
 	u32 max = rswitch->used_entries;
 	u16 entry;
 
+	if (rvu->rep_mode)
+		return rvu_rep_update_rules(rvu, pcifunc, ena);
+
 	if (!rswitch->used_entries)
 		return;
 
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
index 187b00156bcd..1329617f8d6f 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
@@ -28,6 +28,22 @@  MODULE_DESCRIPTION(DRV_STRING);
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, rvu_rep_id_table);
 
+static int rvu_eswitch_config(struct otx2_nic *priv, u8 ena)
+{
+	struct esw_cfg_req *req;
+
+	mutex_lock(&priv->mbox.lock);
+	req = otx2_mbox_alloc_msg_esw_cfg(&priv->mbox);
+	if (!req) {
+		mutex_unlock(&priv->mbox.lock);
+		return -ENOMEM;
+	}
+	req->ena = ena;
+	otx2_sync_mbox_msg(&priv->mbox);
+	mutex_unlock(&priv->mbox.lock);
+	return 0;
+}
+
 static netdev_tx_t rvu_rep_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct rep_dev *rep = netdev_priv(dev);
@@ -170,6 +186,8 @@  static void rvu_rep_free_netdev(struct otx2_nic *priv)
 
 void rvu_rep_destroy(struct otx2_nic *priv)
 {
+	/* Remove mcam rules */
+	rvu_eswitch_config(priv, false);
 	rvu_rep_free_cq_rsrc(priv);
 	rvu_rep_free_netdev(priv);
 }
@@ -221,6 +239,7 @@  int rvu_rep_create(struct otx2_nic *priv)
 	if (err)
 		goto exit;
 
+	rvu_eswitch_config(priv, true);
 	return 0;
 exit:
 	rvu_rep_free_netdev(priv);