Skip to content

Commit

Permalink
octeontx2-af: Introduce internal packet switching
Browse files Browse the repository at this point in the history
As of now any communication between CGXs PFs and
their VFs within the system is possible only by
external switches sending packets back to the
system. This patch adds internal switching support.
Broadcast packet replication is not covered here.
RVU admin function (AF) maintains MAC addresses
of all interfaces in the system. When switching is
enabled, MCAM entries are allocated to install rules
such that packets with DMAC matching any of the
internal interface MAC addresses is punted back
into the system via the loopback channel.
On the receive side the default unicast rules
are modified to not check for ingress channel.
So any packet with matching DMAC irrespective of
which interface it is coming from will be forwarded
to the respective PF/VF interface.
The transmit side rules and default unicast rules
are updated if user changes MAC address of an interface.

Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Subbaraya Sundeep authored and David S. Miller committed Jul 19, 2021
1 parent cb7a6b3 commit 23109f8
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 11 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/octeontx2/af/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ obj-$(CONFIG_OCTEONTX2_AF) += rvu_af.o
rvu_mbox-y := mbox.o rvu_trace.o
rvu_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \
rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o \
rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o
rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o rvu_switch.o
4 changes: 3 additions & 1 deletion drivers/net/ethernet/marvell/octeontx2/af/rvu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1314,7 +1314,7 @@ int rvu_mbox_handler_detach_resources(struct rvu *rvu,
return rvu_detach_rsrcs(rvu, detach, detach->hdr.pcifunc);
}

static int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
int blkaddr = BLKADDR_NIX0, vf;
Expand Down Expand Up @@ -3007,6 +3007,8 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* Initialize debugfs */
rvu_dbg_init(rvu);

mutex_init(&rvu->rswitch.switch_lock);

return 0;
err_dl:
rvu_unregister_dl(rvu);
Expand Down
19 changes: 19 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu.h
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,14 @@ struct npc_kpu_profile_adapter {

#define RVU_SWITCH_LBK_CHAN 63

struct rvu_switch {
struct mutex switch_lock; /* Serialize flow installation */
u32 used_entries;
u16 *entry2pcifunc;
u16 mode;
u16 start_entry;
};

struct rvu {
void __iomem *afreg_base;
void __iomem *pfreg_base;
Expand Down Expand Up @@ -447,6 +455,7 @@ struct rvu {

/* CGX */
#define PF_CGXMAP_BASE 1 /* PF 0 is reserved for RVU PF */
u16 cgx_mapped_vfs; /* maximum CGX mapped VFs */
u8 cgx_mapped_pfs;
u8 cgx_cnt_max; /* CGX port count max */
u8 *pf2cgxlmac_map; /* pf to cgx_lmac map */
Expand Down Expand Up @@ -479,6 +488,9 @@ struct rvu {
struct rvu_debugfs rvu_dbg;
#endif
struct rvu_devlink *rvu_dl;

/* RVU switch implementation over NPC with DMAC rules */
struct rvu_switch rswitch;
};

static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
Expand Down Expand Up @@ -693,6 +705,7 @@ int nix_aq_context_read(struct rvu *rvu, struct nix_hw *nix_hw,
struct nix_cn10k_aq_enq_req *aq_req,
struct nix_cn10k_aq_enq_rsp *aq_rsp,
u16 pcifunc, u8 ctype, u32 qidx);
int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc);

/* NPC APIs */
int rvu_npc_init(struct rvu *rvu);
Expand Down Expand Up @@ -770,4 +783,10 @@ void rvu_dbg_exit(struct rvu *rvu);
static inline void rvu_dbg_init(struct rvu *rvu) {}
static inline void rvu_dbg_exit(struct rvu *rvu) {}
#endif

/* 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);

#endif /* RVU_H */
3 changes: 3 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu)
unsigned long lmac_bmap;
int size, free_pkind;
int cgx, lmac, iter;
int numvfs, hwvfs;

if (!cgx_cnt_max)
return 0;
Expand Down Expand Up @@ -166,6 +167,8 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu)
pkind->pfchan_map[free_pkind] = ((pf) & 0x3F) << 16;
rvu_map_cgx_nix_block(rvu, pf, cgx, lmac);
rvu->cgx_mapped_pfs++;
rvu_get_pf_numvfs(rvu, pf, &numvfs, &hwvfs);
rvu->cgx_mapped_vfs += numvfs;
pf++;
}
}
Expand Down
48 changes: 41 additions & 7 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,44 @@ static void rvu_health_reporters_destroy(struct rvu *rvu)
rvu_nix_health_reporters_destroy(rvu_dl);
}

static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
{
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
struct rvu *rvu = rvu_dl->rvu;
struct rvu_switch *rswitch;

rswitch = &rvu->rswitch;
*mode = rswitch->mode;

return 0;
}

static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
struct netlink_ext_ack *extack)
{
struct rvu_devlink *rvu_dl = devlink_priv(devlink);
struct rvu *rvu = rvu_dl->rvu;
struct rvu_switch *rswitch;

rswitch = &rvu->rswitch;
switch (mode) {
case DEVLINK_ESWITCH_MODE_LEGACY:
case DEVLINK_ESWITCH_MODE_SWITCHDEV:
if (rswitch->mode == mode)
return 0;
rswitch->mode = mode;
if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV)
rvu_switch_enable(rvu);
else
rvu_switch_disable(rvu);
break;
default:
return -EINVAL;
}

return 0;
}

static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
struct netlink_ext_ack *extack)
{
Expand All @@ -1372,6 +1410,8 @@ static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req

static const struct devlink_ops rvu_devlink_ops = {
.info_get = rvu_devlink_info_get,
.eswitch_mode_get = rvu_devlink_eswitch_mode_get,
.eswitch_mode_set = rvu_devlink_eswitch_mode_set,
};

int rvu_register_dl(struct rvu *rvu)
Expand All @@ -1380,25 +1420,20 @@ int rvu_register_dl(struct rvu *rvu)
struct devlink *dl;
int err;

rvu_dl = kzalloc(sizeof(*rvu_dl), GFP_KERNEL);
if (!rvu_dl)
return -ENOMEM;

dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink));
if (!dl) {
dev_warn(rvu->dev, "devlink_alloc failed\n");
kfree(rvu_dl);
return -ENOMEM;
}

err = devlink_register(dl, rvu->dev);
if (err) {
dev_err(rvu->dev, "devlink register failed with error %d\n", err);
devlink_free(dl);
kfree(rvu_dl);
return err;
}

rvu_dl = devlink_priv(dl);
rvu_dl->dl = dl;
rvu_dl->rvu = rvu;
rvu->rvu_dl = rvu_dl;
Expand All @@ -1417,5 +1452,4 @@ void rvu_unregister_dl(struct rvu *rvu)
rvu_health_reporters_destroy(rvu);
devlink_unregister(dl);
devlink_free(dl);
kfree(rvu_dl);
}
4 changes: 4 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
Original file line number Diff line number Diff line change
Expand Up @@ -3212,6 +3212,8 @@ 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;
}

Expand Down Expand Up @@ -3881,6 +3883,8 @@ 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);

return rvu_cgx_start_stop_io(rvu, pcifunc, true);
}

Expand Down
9 changes: 7 additions & 2 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -910,10 +910,15 @@ static void rvu_mcam_add_counter_to_rule(struct rvu *rvu, u16 pcifunc,

static void npc_update_rx_entry(struct rvu *rvu, struct rvu_pfvf *pfvf,
struct mcam_entry *entry,
struct npc_install_flow_req *req, u16 target)
struct npc_install_flow_req *req,
u16 target, bool pf_set_vfs_mac)
{
struct rvu_switch *rswitch = &rvu->rswitch;
struct nix_rx_action action;

if (rswitch->mode == DEVLINK_ESWITCH_MODE_SWITCHDEV && pf_set_vfs_mac)
req->chan_mask = 0x0; /* Do not care channel */

npc_update_entry(rvu, NPC_CHAN, entry, req->channel, 0, req->chan_mask,
0, NIX_INTF_RX);

Expand Down Expand Up @@ -1007,7 +1012,7 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
req->intf);

if (is_npc_intf_rx(req->intf))
npc_update_rx_entry(rvu, pfvf, entry, req, target);
npc_update_rx_entry(rvu, pfvf, entry, req, target, pf_set_vfs_mac);
else
npc_update_tx_entry(rvu, pfvf, entry, req, target);

Expand Down
Loading

0 comments on commit 23109f8

Please sign in to comment.