Skip to content

Commit fd9d785

Browse files
Hariprasad Kelamkuba-moo
authored andcommitted
octeontx2-pf: Implement ingress/egress VLAN offload
This patch implements egress VLAN offload by appending NIX_SEND_EXT_S header to NIX_SEND_HDR_S. The VLAN TCI information is specified in the NIX_SEND_EXT_S. The VLAN offload in the ingress path is implemented by configuring the NIX_RX_VTAG_ACTION_S to strip and capture the outer vlan fields. The NIX PF allocates one MCAM entry for Rx VLAN offload. Signed-off-by: Hariprasad Kelam <[email protected]> Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: Naveen Mamindlapalli <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 9a946de commit fd9d785

File tree

8 files changed

+167
-4
lines changed

8 files changed

+167
-4
lines changed

drivers/net/ethernet/marvell/octeontx2/af/mbox.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,19 @@ enum nix_af_status {
479479
NIX_AF_INVAL_NPA_PF_FUNC = -419,
480480
NIX_AF_INVAL_SSO_PF_FUNC = -420,
481481
NIX_AF_ERR_TX_VTAG_NOSPC = -421,
482+
NIX_AF_ERR_RX_VTAG_INUSE = -422,
483+
};
484+
485+
/* For NIX RX vtag action */
486+
enum nix_rx_vtag0_type {
487+
NIX_AF_LFX_RX_VTAG_TYPE0, /* reserved for rx vlan offload */
488+
NIX_AF_LFX_RX_VTAG_TYPE1,
489+
NIX_AF_LFX_RX_VTAG_TYPE2,
490+
NIX_AF_LFX_RX_VTAG_TYPE3,
491+
NIX_AF_LFX_RX_VTAG_TYPE4,
492+
NIX_AF_LFX_RX_VTAG_TYPE5,
493+
NIX_AF_LFX_RX_VTAG_TYPE6,
494+
NIX_AF_LFX_RX_VTAG_TYPE7,
482495
};
483496

484497
/* For NIX LF context alloc and init */

drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1984,7 +1984,8 @@ static int nix_rx_vtag_cfg(struct rvu *rvu, int nixlf, int blkaddr,
19841984
{
19851985
u64 regval = req->vtag_size;
19861986

1987-
if (req->rx.vtag_type > 7 || req->vtag_size > VTAGSIZE_T8)
1987+
if (req->rx.vtag_type > NIX_AF_LFX_RX_VTAG_TYPE7 ||
1988+
req->vtag_size > VTAGSIZE_T8)
19881989
return -EINVAL;
19891990

19901991
if (req->rx.capture_vtag)

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,14 @@ int otx2_set_mac_address(struct net_device *netdev, void *p)
191191
if (!is_valid_ether_addr(addr->sa_data))
192192
return -EADDRNOTAVAIL;
193193

194-
if (!otx2_hw_set_mac_addr(pfvf, addr->sa_data))
194+
if (!otx2_hw_set_mac_addr(pfvf, addr->sa_data)) {
195195
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
196-
else
196+
/* update dmac field in vlan offload rule */
197+
if (pfvf->flags & OTX2_FLAG_RX_VLAN_SUPPORT)
198+
otx2_install_rxvlan_offload_flow(pfvf);
199+
} else {
197200
return -EPERM;
201+
}
198202

199203
return 0;
200204
}

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,13 @@ struct otx2_flow_config {
240240
u32 nr_flows;
241241
#define OTX2_MAX_NTUPLE_FLOWS 32
242242
#define OTX2_MAX_UNICAST_FLOWS 8
243+
#define OTX2_MAX_VLAN_FLOWS 1
243244
#define OTX2_MCAM_COUNT (OTX2_MAX_NTUPLE_FLOWS + \
244-
OTX2_MAX_UNICAST_FLOWS)
245+
OTX2_MAX_UNICAST_FLOWS + \
246+
OTX2_MAX_VLAN_FLOWS)
245247
u32 ntuple_offset;
246248
u32 unicast_offset;
249+
u32 rx_vlan_offset;
247250
u32 ntuple_max_flows;
248251
struct list_head flow_list;
249252
};
@@ -261,6 +264,7 @@ struct otx2_nic {
261264
#define OTX2_FLAG_MCAM_ENTRIES_ALLOC BIT_ULL(3)
262265
#define OTX2_FLAG_NTUPLE_SUPPORT BIT_ULL(4)
263266
#define OTX2_FLAG_UCAST_FLTR_SUPPORT BIT_ULL(5)
267+
#define OTX2_FLAG_RX_VLAN_SUPPORT BIT_ULL(6)
264268
#define OTX2_FLAG_RX_PAUSE_ENABLED BIT_ULL(9)
265269
#define OTX2_FLAG_TX_PAUSE_ENABLED BIT_ULL(10)
266270
u64 flags;
@@ -687,5 +691,7 @@ int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
687691
struct npc_install_flow_req *req);
688692
int otx2_del_macfilter(struct net_device *netdev, const u8 *mac);
689693
int otx2_add_macfilter(struct net_device *netdev, const u8 *mac);
694+
int otx2_enable_rxvlan(struct otx2_nic *pf, bool enable);
695+
int otx2_install_rxvlan_offload_flow(struct otx2_nic *pfvf);
690696

691697
#endif /* OTX2_COMMON_H */

drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,11 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
5858
flow_cfg->ntuple_offset = 0;
5959
flow_cfg->unicast_offset = flow_cfg->ntuple_offset +
6060
OTX2_MAX_NTUPLE_FLOWS;
61+
flow_cfg->rx_vlan_offset = flow_cfg->unicast_offset +
62+
OTX2_MAX_UNICAST_FLOWS;
6163
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
6264
pfvf->flags |= OTX2_FLAG_UCAST_FLTR_SUPPORT;
65+
pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;
6366
}
6467

6568
for (i = 0; i < rsp->count; i++)
@@ -711,3 +714,102 @@ int otx2_destroy_mcam_flows(struct otx2_nic *pfvf)
711714

712715
return 0;
713716
}
717+
718+
int otx2_install_rxvlan_offload_flow(struct otx2_nic *pfvf)
719+
{
720+
struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
721+
struct npc_install_flow_req *req;
722+
int err;
723+
724+
mutex_lock(&pfvf->mbox.lock);
725+
req = otx2_mbox_alloc_msg_npc_install_flow(&pfvf->mbox);
726+
if (!req) {
727+
mutex_unlock(&pfvf->mbox.lock);
728+
return -ENOMEM;
729+
}
730+
731+
req->entry = flow_cfg->entry[flow_cfg->rx_vlan_offset];
732+
req->intf = NIX_INTF_RX;
733+
ether_addr_copy(req->packet.dmac, pfvf->netdev->dev_addr);
734+
eth_broadcast_addr((u8 *)&req->mask.dmac);
735+
req->channel = pfvf->hw.rx_chan_base;
736+
req->op = NIX_RX_ACTION_DEFAULT;
737+
req->features = BIT_ULL(NPC_OUTER_VID) | BIT_ULL(NPC_DMAC);
738+
req->vtag0_valid = true;
739+
req->vtag0_type = NIX_AF_LFX_RX_VTAG_TYPE0;
740+
741+
/* Send message to AF */
742+
err = otx2_sync_mbox_msg(&pfvf->mbox);
743+
mutex_unlock(&pfvf->mbox.lock);
744+
return err;
745+
}
746+
747+
static int otx2_delete_rxvlan_offload_flow(struct otx2_nic *pfvf)
748+
{
749+
struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
750+
struct npc_delete_flow_req *req;
751+
int err;
752+
753+
mutex_lock(&pfvf->mbox.lock);
754+
req = otx2_mbox_alloc_msg_npc_delete_flow(&pfvf->mbox);
755+
if (!req) {
756+
mutex_unlock(&pfvf->mbox.lock);
757+
return -ENOMEM;
758+
}
759+
760+
req->entry = flow_cfg->entry[flow_cfg->rx_vlan_offset];
761+
/* Send message to AF */
762+
err = otx2_sync_mbox_msg(&pfvf->mbox);
763+
mutex_unlock(&pfvf->mbox.lock);
764+
return err;
765+
}
766+
767+
int otx2_enable_rxvlan(struct otx2_nic *pf, bool enable)
768+
{
769+
struct nix_vtag_config *req;
770+
struct mbox_msghdr *rsp_hdr;
771+
int err;
772+
773+
/* Dont have enough mcam entries */
774+
if (!(pf->flags & OTX2_FLAG_RX_VLAN_SUPPORT))
775+
return -ENOMEM;
776+
777+
if (enable) {
778+
err = otx2_install_rxvlan_offload_flow(pf);
779+
if (err)
780+
return err;
781+
} else {
782+
err = otx2_delete_rxvlan_offload_flow(pf);
783+
if (err)
784+
return err;
785+
}
786+
787+
mutex_lock(&pf->mbox.lock);
788+
req = otx2_mbox_alloc_msg_nix_vtag_cfg(&pf->mbox);
789+
if (!req) {
790+
mutex_unlock(&pf->mbox.lock);
791+
return -ENOMEM;
792+
}
793+
794+
/* config strip, capture and size */
795+
req->vtag_size = VTAGSIZE_T4;
796+
req->cfg_type = 1; /* rx vlan cfg */
797+
req->rx.vtag_type = NIX_AF_LFX_RX_VTAG_TYPE0;
798+
req->rx.strip_vtag = enable;
799+
req->rx.capture_vtag = enable;
800+
801+
err = otx2_sync_mbox_msg(&pf->mbox);
802+
if (err) {
803+
mutex_unlock(&pf->mbox.lock);
804+
return err;
805+
}
806+
807+
rsp_hdr = otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
808+
if (IS_ERR(rsp_hdr)) {
809+
mutex_unlock(&pf->mbox.lock);
810+
return PTR_ERR(rsp_hdr);
811+
}
812+
813+
mutex_unlock(&pf->mbox.lock);
814+
return rsp_hdr->rc;
815+
}

drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,9 @@ int otx2_open(struct net_device *netdev)
15661566

15671567
otx2_set_cints_affinity(pf);
15681568

1569+
if (pf->flags & OTX2_FLAG_RX_VLAN_SUPPORT)
1570+
otx2_enable_rxvlan(pf, true);
1571+
15691572
/* When reinitializing enable time stamping if it is enabled before */
15701573
if (pf->flags & OTX2_FLAG_TX_TSTAMP_ENABLED) {
15711574
pf->flags &= ~OTX2_FLAG_TX_TSTAMP_ENABLED;
@@ -1763,6 +1766,10 @@ static int otx2_set_features(struct net_device *netdev,
17631766
return otx2_cgx_config_loopback(pf,
17641767
features & NETIF_F_LOOPBACK);
17651768

1769+
if ((changed & NETIF_F_HW_VLAN_CTAG_RX) && netif_running(netdev))
1770+
return otx2_enable_rxvlan(pf,
1771+
features & NETIF_F_HW_VLAN_CTAG_RX);
1772+
17661773
if ((changed & NETIF_F_NTUPLE) && !ntuple)
17671774
otx2_destroy_ntuple_flows(pf);
17681775

@@ -2138,6 +2145,15 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
21382145
if (pf->flags & OTX2_FLAG_UCAST_FLTR_SUPPORT)
21392146
netdev->priv_flags |= IFF_UNICAST_FLT;
21402147

2148+
/* Support TSO on tag interface */
2149+
netdev->vlan_features |= netdev->features;
2150+
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
2151+
NETIF_F_HW_VLAN_STAG_TX;
2152+
if (pf->flags & OTX2_FLAG_RX_VLAN_SUPPORT)
2153+
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX |
2154+
NETIF_F_HW_VLAN_STAG_RX;
2155+
netdev->features |= netdev->hw_features;
2156+
21412157
netdev->gso_max_segs = OTX2_MAX_GSO_SEGS;
21422158
netdev->watchdog_timeo = OTX2_TX_TIMEOUT;
21432159

drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,19 @@ static void otx2_sqe_add_ext(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
556556
ext->tstmp = 1;
557557
}
558558

559+
#define OTX2_VLAN_PTR_OFFSET (ETH_HLEN - ETH_TLEN)
560+
if (skb_vlan_tag_present(skb)) {
561+
if (skb->vlan_proto == htons(ETH_P_8021Q)) {
562+
ext->vlan1_ins_ena = 1;
563+
ext->vlan1_ins_ptr = OTX2_VLAN_PTR_OFFSET;
564+
ext->vlan1_ins_tci = skb_vlan_tag_get(skb);
565+
} else if (skb->vlan_proto == htons(ETH_P_8021AD)) {
566+
ext->vlan0_ins_ena = 1;
567+
ext->vlan0_ins_ptr = OTX2_VLAN_PTR_OFFSET;
568+
ext->vlan0_ins_tci = skb_vlan_tag_get(skb);
569+
}
570+
}
571+
559572
*offset += sizeof(*ext);
560573
}
561574

@@ -871,6 +884,9 @@ bool otx2_sq_append_skb(struct net_device *netdev, struct otx2_snd_queue *sq,
871884
}
872885

873886
if (skb_shinfo(skb)->gso_size && !is_hw_tso_supported(pfvf, skb)) {
887+
/* Insert vlan tag before giving pkt to tso */
888+
if (skb_vlan_tag_present(skb))
889+
skb = __vlan_hwaccel_push_inside(skb);
874890
otx2_sq_append_tso(pfvf, sq, skb, qidx);
875891
return true;
876892
}

drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,11 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
558558
NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
559559
NETIF_F_GSO_UDP_L4;
560560
netdev->features = netdev->hw_features;
561+
/* Support TSO on tag interface */
562+
netdev->vlan_features |= netdev->features;
563+
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
564+
NETIF_F_HW_VLAN_STAG_TX;
565+
netdev->features |= netdev->hw_features;
561566

562567
netdev->gso_max_segs = OTX2_MAX_GSO_SEGS;
563568
netdev->watchdog_timeo = OTX2_TX_TIMEOUT;

0 commit comments

Comments
 (0)