Skip to content

Commit

Permalink
octeontx2-pf: Add support for SR-IOV management functions
Browse files Browse the repository at this point in the history
This patch adds support for ndo_set_vf_mac, ndo_set_vf_vlan
and ndo_get_vf_config handlers. The traffic redirection
based on the VF mac address or vlan id is done by installing
MCAM rules. Reserved RX_VTAG_TYPE7 in each NIXLF for VF VLAN
which strips the VLAN tag from ingress VLAN traffic. The NIX PF
allocates two MCAM entries for VF VLAN feature, one used for
ingress VTAG strip and another entry for egress VTAG insertion.

This patch also updates the MAC address in PF installed VF VLAN
rule upon receiving nix_lf_start_rx mbox request for VF since
Administrative Function driver will assign a valid MAC addr
in nix_lf_start_rx function.

Signed-off-by: Naveen Mamindlapalli <[email protected]>
Co-developed-by: Tomasz Duszynski <[email protected]>
Signed-off-by: Tomasz Duszynski <[email protected]>
Signed-off-by: Sunil Goutham <[email protected]>
Signed-off-by: Hariprasad Kelam <[email protected]>
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
Naveen Mamindlapalli authored and kuba-moo committed Nov 17, 2020
1 parent fd9d785 commit f0c2982
Show file tree
Hide file tree
Showing 9 changed files with 420 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/npc.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ struct rvu_npc_mcam_rule {
bool has_cntr;
u8 default_rule;
bool enable;
bool vfvlan_cfg;
};

#endif /* NPC_H */
4 changes: 4 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ struct rvu_pfvf {
u16 maxlen;
u16 minlen;

u8 pf_set_vf_cfg;
u8 mac_addr[ETH_ALEN]; /* MAC address of this PF/VF */

/* Broadcast pkt replication info */
Expand Down Expand Up @@ -596,6 +597,9 @@ void npc_mcam_enable_flows(struct rvu *rvu, u16 target);
void npc_mcam_disable_flows(struct rvu *rvu, u16 target);
void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index, bool enable);
void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, u16 src, struct mcam_entry *entry,
u8 *intf, u8 *ena);

#ifdef CONFIG_DEBUG_FS
void rvu_dbg_init(struct rvu *rvu);
Expand Down
14 changes: 14 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,11 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
/* Disable NPC entries as NIXLF's contexts are not initialized yet */
rvu_npc_disable_default_entries(rvu, pcifunc, nixlf);

/* Configure RX VTAG Type 7 (strip) for vf vlan */
rvu_write64(rvu, blkaddr,
NIX_AF_LFX_RX_VTAG_TYPEX(nixlf, NIX_AF_LFX_RX_VTAG_TYPE7),
VTAGSIZE_T4 | VTAG_STRIP);

goto exit;

free_mem:
Expand Down Expand Up @@ -1988,6 +1993,10 @@ static int nix_rx_vtag_cfg(struct rvu *rvu, int nixlf, int blkaddr,
req->vtag_size > VTAGSIZE_T8)
return -EINVAL;

/* RX VTAG Type 7 reserved for vf vlan */
if (req->rx.vtag_type == NIX_AF_LFX_RX_VTAG_TYPE7)
return NIX_AF_ERR_RX_VTAG_INUSE;

if (req->rx.capture_vtag)
regval |= BIT_ULL(5);
if (req->rx.strip_vtag)
Expand Down Expand Up @@ -2931,6 +2940,7 @@ int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,
struct nix_set_mac_addr *req,
struct msg_rsp *rsp)
{
bool from_vf = req->hdr.pcifunc & RVU_PFVF_FUNC_MASK;
u16 pcifunc = req->hdr.pcifunc;
int blkaddr, nixlf, err;
struct rvu_pfvf *pfvf;
Expand All @@ -2941,6 +2951,10 @@ int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,

pfvf = rvu_get_pfvf(rvu, pcifunc);

/* VF can't overwrite admin(PF) changes */
if (from_vf && pfvf->pf_set_vf_cfg)
return -EPERM;

ether_addr_copy(pfvf->mac_addr, req->mac_addr);

rvu_npc_install_ucast_entry(rvu, pcifunc, nixlf,
Expand Down
88 changes: 88 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,58 @@ static void npc_get_keyword(struct mcam_entry *entry, int idx,
*cam0 = ~*cam1 & kw_mask;
}

static void npc_fill_entryword(struct mcam_entry *entry, int idx,
u64 cam0, u64 cam1)
{
/* Similar to npc_get_keyword, but fills mcam_entry structure from
* CAM registers.
*/
switch (idx) {
case 0:
entry->kw[0] = cam1;
entry->kw_mask[0] = cam1 ^ cam0;
break;
case 1:
entry->kw[1] = cam1;
entry->kw_mask[1] = cam1 ^ cam0;
break;
case 2:
entry->kw[1] |= (cam1 & CAM_MASK(16)) << 48;
entry->kw[2] = (cam1 >> 16) & CAM_MASK(48);
entry->kw_mask[1] |= ((cam1 ^ cam0) & CAM_MASK(16)) << 48;
entry->kw_mask[2] = ((cam1 ^ cam0) >> 16) & CAM_MASK(48);
break;
case 3:
entry->kw[2] |= (cam1 & CAM_MASK(16)) << 48;
entry->kw[3] = (cam1 >> 16) & CAM_MASK(32);
entry->kw_mask[2] |= ((cam1 ^ cam0) & CAM_MASK(16)) << 48;
entry->kw_mask[3] = ((cam1 ^ cam0) >> 16) & CAM_MASK(32);
break;
case 4:
entry->kw[3] |= (cam1 & CAM_MASK(32)) << 32;
entry->kw[4] = (cam1 >> 32) & CAM_MASK(32);
entry->kw_mask[3] |= ((cam1 ^ cam0) & CAM_MASK(32)) << 32;
entry->kw_mask[4] = ((cam1 ^ cam0) >> 32) & CAM_MASK(32);
break;
case 5:
entry->kw[4] |= (cam1 & CAM_MASK(32)) << 32;
entry->kw[5] = (cam1 >> 32) & CAM_MASK(16);
entry->kw_mask[4] |= ((cam1 ^ cam0) & CAM_MASK(32)) << 32;
entry->kw_mask[5] = ((cam1 ^ cam0) >> 32) & CAM_MASK(16);
break;
case 6:
entry->kw[5] |= (cam1 & CAM_MASK(48)) << 16;
entry->kw[6] = (cam1 >> 48) & CAM_MASK(16);
entry->kw_mask[5] |= ((cam1 ^ cam0) & CAM_MASK(48)) << 16;
entry->kw_mask[6] = ((cam1 ^ cam0) >> 48) & CAM_MASK(16);
break;
case 7:
entry->kw[6] |= (cam1 & CAM_MASK(48)) << 16;
entry->kw_mask[6] |= ((cam1 ^ cam0) & CAM_MASK(48)) << 16;
break;
}
}

static void npc_get_default_entry_action(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, int index,
struct mcam_entry *entry)
Expand Down Expand Up @@ -459,6 +511,42 @@ static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
npc_enable_mcam_entry(rvu, mcam, blkaddr, actindex, true);
}

void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, u16 src,
struct mcam_entry *entry, u8 *intf, u8 *ena)
{
int sbank = npc_get_bank(mcam, src);
int bank, kw = 0;
u64 cam0, cam1;

src &= (mcam->banksize - 1);
bank = sbank;

for (; bank < (sbank + mcam->banks_per_entry); bank++, kw = kw + 2) {
cam1 = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_CAMX_W0(src, bank, 1));
cam0 = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_CAMX_W0(src, bank, 0));
npc_fill_entryword(entry, kw, cam0, cam1);

cam1 = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_CAMX_W1(src, bank, 1));
cam0 = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_CAMX_W1(src, bank, 0));
npc_fill_entryword(entry, kw + 1, cam0, cam1);
}

entry->action = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_ACTION(src, sbank));
entry->vtag_action =
rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_TAG_ACT(src, sbank));
*intf = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_CAMX_INTF(src, sbank, 1)) & 3;
*ena = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_CFG(src, sbank)) & 1;
}

static void npc_copy_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
int blkaddr, u16 src, u16 dest)
{
Expand Down
40 changes: 40 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,9 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
if (req->default_rule)
pfvf->def_ucast_rule = rule;

if (pfvf->pf_set_vf_cfg && req->vtag0_type == NIX_AF_LFX_RX_VTAG_TYPE7)
rule->vfvlan_cfg = true;

return 0;
}

Expand Down Expand Up @@ -1113,6 +1116,10 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu,

pfvf = rvu_get_pfvf(rvu, target);

/* PF installing for its VF */
if (req->hdr.pcifunc && !from_vf && req->vf)
pfvf->pf_set_vf_cfg = 1;

/* update req destination mac addr */
if ((req->features & BIT_ULL(NPC_DMAC)) && is_npc_intf_rx(req->intf) &&
is_zero_ether_addr(req->packet.dmac)) {
Expand Down Expand Up @@ -1210,6 +1217,36 @@ int rvu_mbox_handler_npc_delete_flow(struct rvu *rvu,
return 0;
}

static int npc_update_dmac_value(struct rvu *rvu, int npcblkaddr,
struct rvu_npc_mcam_rule *rule,
struct rvu_pfvf *pfvf)
{
struct npc_mcam_write_entry_req write_req = { 0 };
struct mcam_entry *entry = &write_req.entry_data;
struct npc_mcam *mcam = &rvu->hw->mcam;
struct msg_rsp rsp;
u8 intf, enable;
int err;

ether_addr_copy(rule->packet.dmac, pfvf->mac_addr);

npc_read_mcam_entry(rvu, mcam, npcblkaddr, rule->entry,
entry, &intf, &enable);

npc_update_entry(rvu, NPC_DMAC, entry,
ether_addr_to_u64(pfvf->mac_addr), 0,
0xffffffffffffull, 0, intf);

write_req.hdr.pcifunc = rule->owner;
write_req.entry = rule->entry;

mutex_unlock(&mcam->lock);
err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &write_req, &rsp);
mutex_lock(&mcam->lock);

return err;
}

void npc_mcam_enable_flows(struct rvu *rvu, u16 target)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, target);
Expand All @@ -1236,6 +1273,9 @@ void npc_mcam_enable_flows(struct rvu *rvu, u16 target)
continue;
}

if (rule->vfvlan_cfg)
npc_update_dmac_value(rvu, blkaddr, rule, pfvf);

if (rule->rx_action.op == NIX_RX_ACTION_DEFAULT) {
if (!def_ucast_rule)
continue;
Expand Down
11 changes: 11 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -921,4 +921,15 @@ enum nix_vtag_size {
VTAGSIZE_T4 = 0x0,
VTAGSIZE_T8 = 0x1,
};

enum nix_tx_vtag_op {
NOP = 0x0,
VTAG_INSERT = 0x1,
VTAG_REPLACE = 0x2,
};

/* NIX RX VTAG actions */
#define VTAG_STRIP BIT_ULL(4)
#define VTAG_CAPTURE BIT_ULL(5)

#endif /* RVU_STRUCT_H */
9 changes: 9 additions & 0 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ struct otx2_vf_config {
struct otx2_nic *pf;
struct delayed_work link_event_work;
bool intf_down; /* interface was either configured or not */
u8 mac[ETH_ALEN];
u16 vlan;
int tx_vtag_idx;
};

struct flr_work {
Expand Down Expand Up @@ -247,6 +250,10 @@ struct otx2_flow_config {
u32 ntuple_offset;
u32 unicast_offset;
u32 rx_vlan_offset;
u32 vf_vlan_offset;
#define OTX2_PER_VF_VLAN_FLOWS 2 /* rx+tx per VF */
#define OTX2_VF_VLAN_RX_INDEX 0
#define OTX2_VF_VLAN_TX_INDEX 1
u32 ntuple_max_flows;
struct list_head flow_list;
};
Expand All @@ -265,6 +272,8 @@ struct otx2_nic {
#define OTX2_FLAG_NTUPLE_SUPPORT BIT_ULL(4)
#define OTX2_FLAG_UCAST_FLTR_SUPPORT BIT_ULL(5)
#define OTX2_FLAG_RX_VLAN_SUPPORT BIT_ULL(6)
#define OTX2_FLAG_VF_VLAN_SUPPORT BIT_ULL(7)
#define OTX2_FLAG_PF_SHUTDOWN BIT_ULL(8)
#define OTX2_FLAG_RX_PAUSE_ENABLED BIT_ULL(9)
#define OTX2_FLAG_TX_PAUSE_ENABLED BIT_ULL(10)
u64 flags;
Expand Down
9 changes: 7 additions & 2 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
struct npc_mcam_alloc_entry_req *req;
struct npc_mcam_alloc_entry_rsp *rsp;
int vf_vlan_max_flows;
int i;

mutex_lock(&pfvf->mbox.lock);
Expand All @@ -34,8 +35,9 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
return -ENOMEM;
}

vf_vlan_max_flows = pfvf->total_vfs * OTX2_PER_VF_VLAN_FLOWS;
req->contig = false;
req->count = OTX2_MCAM_COUNT;
req->count = OTX2_MCAM_COUNT + vf_vlan_max_flows;

/* Send message to AF */
if (otx2_sync_mbox_msg(&pfvf->mbox)) {
Expand All @@ -55,14 +57,17 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
flow_cfg->ntuple_offset = 0;
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
} else {
flow_cfg->ntuple_offset = 0;
flow_cfg->vf_vlan_offset = 0;
flow_cfg->ntuple_offset = flow_cfg->vf_vlan_offset +
vf_vlan_max_flows;
flow_cfg->unicast_offset = flow_cfg->ntuple_offset +
OTX2_MAX_NTUPLE_FLOWS;
flow_cfg->rx_vlan_offset = flow_cfg->unicast_offset +
OTX2_MAX_UNICAST_FLOWS;
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
pfvf->flags |= OTX2_FLAG_UCAST_FLTR_SUPPORT;
pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;
pfvf->flags |= OTX2_FLAG_VF_VLAN_SUPPORT;
}

for (i = 0; i < rsp->count; i++)
Expand Down
Loading

0 comments on commit f0c2982

Please sign in to comment.