Skip to content

Commit 1d4d9e4

Browse files
Naveen Mamindlapallidavem330
authored andcommitted
octeontx2-pf: Add tc flower hardware offload on ingress traffic
This patch adds support for tc flower hardware offload on ingress traffic. Since the tc-flower filter rules use the same set of MCAM rules as the n-tuple filters, the n-tuple filters and tc flower rules are mutually exclusive. When one of the feature is enabled using ethtool, the other feature is disabled in the driver. By default the driver enables n-tuple filters during initialization. The following flow keys are supported. -> Ethernet: dst_mac -> L2 proto: all protocols -> VLAN (802.1q): vlan_id/vlan_prio -> IPv4: dst_ip/src_ip/ip_proto{tcp|udp|sctp|icmp}/ip_tos -> IPv6: ip_proto{icmpv6} -> L4(tcp/udp/sctp): dst_port/src_port The following flow actions are supported. -> drop -> accept -> redirect -> vlan pop The flow action supports multiple actions when vlan pop is specified as the first action. The redirect action supports redirecting to the PF/VF of same PCI device. Redirecting to other PCI NIX devices is not supported. Example #1: Add a tc filter rule to drop UDP traffic with dest port 80 # ethtool -K eth0 hw-tc-offload on # tc qdisc add dev eth0 ingress # tc filter add dev eth0 protocol ip parent ffff: flower ip_proto \ udp dst_port 80 action drop Example #2: Add a tc filter rule to redirect ingress traffic on eth0 with vlan id 3 to eth6 (ex: eth0 vf0) after stripping the vlan hdr. # ethtool -K eth0 hw-tc-offload on # tc qdisc add dev eth0 ingress # tc filter add dev eth0 parent ffff: protocol 802.1Q flower \ vlan_id 3 vlan_ethtype ipv4 action vlan pop action mirred \ ingress redirect dev eth6 Example #3: List the ingress filter rules # tc -s filter show dev eth4 ingress Example #4: Delete tc flower filter rule with handle 0x1 # tc filter del dev eth0 ingress protocol ip pref 49152 \ handle 1 flower Signed-off-by: Naveen Mamindlapalli <naveenm@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2b9cef6 commit 1d4d9e4

File tree

6 files changed

+551
-2
lines changed

6 files changed

+551
-2
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2002,7 +2002,7 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s,
20022002
seq_printf(s, "mask 0x%x\n", ntohs(rule->mask.etype));
20032003
break;
20042004
case NPC_OUTER_VID:
2005-
seq_printf(s, "%d ", ntohs(rule->packet.vlan_tci));
2005+
seq_printf(s, "0x%x ", ntohs(rule->packet.vlan_tci));
20062006
seq_printf(s, "mask 0x%x\n",
20072007
ntohs(rule->mask.vlan_tci));
20082008
break;

drivers/net/ethernet/marvell/octeontx2/nic/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ obj-$(CONFIG_OCTEONTX2_PF) += rvu_nicpf.o
77
obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o
88

99
rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \
10-
otx2_ptp.o otx2_flows.o cn10k.o
10+
otx2_ptp.o otx2_flows.o otx2_tc.o cn10k.o
1111
rvu_nicvf-y := otx2_vf.o
1212

1313
ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/ptp_clock_kernel.h>
1919
#include <linux/timecounter.h>
2020
#include <linux/soc/marvell/octeontx2/asm.h>
21+
#include <net/pkt_cls.h>
2122

2223
#include <mbox.h>
2324
#include <npc.h>
@@ -264,6 +265,7 @@ struct otx2_flow_config {
264265
#define OTX2_MAX_NTUPLE_FLOWS 32
265266
#define OTX2_MAX_UNICAST_FLOWS 8
266267
#define OTX2_MAX_VLAN_FLOWS 1
268+
#define OTX2_MAX_TC_FLOWS OTX2_MAX_NTUPLE_FLOWS
267269
#define OTX2_MCAM_COUNT (OTX2_MAX_NTUPLE_FLOWS + \
268270
OTX2_MAX_UNICAST_FLOWS + \
269271
OTX2_MAX_VLAN_FLOWS)
@@ -274,10 +276,20 @@ struct otx2_flow_config {
274276
#define OTX2_PER_VF_VLAN_FLOWS 2 /* rx+tx per VF */
275277
#define OTX2_VF_VLAN_RX_INDEX 0
276278
#define OTX2_VF_VLAN_TX_INDEX 1
279+
u32 tc_flower_offset;
277280
u32 ntuple_max_flows;
281+
u32 tc_max_flows;
278282
struct list_head flow_list;
279283
};
280284

285+
struct otx2_tc_info {
286+
/* hash table to store TC offloaded flows */
287+
struct rhashtable flow_table;
288+
struct rhashtable_params flow_ht_params;
289+
DECLARE_BITMAP(tc_entries_bitmap, OTX2_MAX_TC_FLOWS);
290+
unsigned long num_entries;
291+
};
292+
281293
struct dev_hw_ops {
282294
int (*sq_aq_init)(void *dev, u16 qidx, u16 sqb_aura);
283295
void (*sqe_flush)(void *dev, struct otx2_snd_queue *sq,
@@ -305,6 +317,7 @@ struct otx2_nic {
305317
#define OTX2_FLAG_PF_SHUTDOWN BIT_ULL(8)
306318
#define OTX2_FLAG_RX_PAUSE_ENABLED BIT_ULL(9)
307319
#define OTX2_FLAG_TX_PAUSE_ENABLED BIT_ULL(10)
320+
#define OTX2_FLAG_TC_FLOWER_SUPPORT BIT_ULL(11)
308321
u64 flags;
309322

310323
struct otx2_qset qset;
@@ -347,6 +360,7 @@ struct otx2_nic {
347360
struct hwtstamp_config tstamp;
348361

349362
struct otx2_flow_config *flow_cfg;
363+
struct otx2_tc_info tc_info;
350364
};
351365

352366
static inline bool is_otx2_lbkvf(struct pci_dev *pdev)
@@ -802,4 +816,9 @@ int otx2_add_macfilter(struct net_device *netdev, const u8 *mac);
802816
int otx2_enable_rxvlan(struct otx2_nic *pf, bool enable);
803817
int otx2_install_rxvlan_offload_flow(struct otx2_nic *pfvf);
804818
u16 otx2_get_max_mtu(struct otx2_nic *pfvf);
819+
/* tc support */
820+
int otx2_init_tc(struct otx2_nic *nic);
821+
void otx2_shutdown_tc(struct otx2_nic *nic);
822+
int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type,
823+
void *type_data);
805824
#endif /* OTX2_COMMON_H */

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,13 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
5757
flow_cfg->ntuple_max_flows = rsp->count;
5858
flow_cfg->ntuple_offset = 0;
5959
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
60+
flow_cfg->tc_max_flows = flow_cfg->ntuple_max_flows;
61+
pfvf->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT;
6062
} else {
6163
flow_cfg->vf_vlan_offset = 0;
6264
flow_cfg->ntuple_offset = flow_cfg->vf_vlan_offset +
6365
vf_vlan_max_flows;
66+
flow_cfg->tc_flower_offset = flow_cfg->ntuple_offset;
6467
flow_cfg->unicast_offset = flow_cfg->ntuple_offset +
6568
OTX2_MAX_NTUPLE_FLOWS;
6669
flow_cfg->rx_vlan_offset = flow_cfg->unicast_offset +
@@ -69,6 +72,7 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
6972
pfvf->flags |= OTX2_FLAG_UCAST_FLTR_SUPPORT;
7073
pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;
7174
pfvf->flags |= OTX2_FLAG_VF_VLAN_SUPPORT;
75+
pfvf->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT;
7276
}
7377

7478
for (i = 0; i < rsp->count; i++)
@@ -93,6 +97,7 @@ int otx2_mcam_flow_init(struct otx2_nic *pf)
9397
INIT_LIST_HEAD(&pf->flow_cfg->flow_list);
9498

9599
pf->flow_cfg->ntuple_max_flows = OTX2_MAX_NTUPLE_FLOWS;
100+
pf->flow_cfg->tc_max_flows = pf->flow_cfg->ntuple_max_flows;
96101

97102
err = otx2_alloc_mcam_entries(pf);
98103
if (err)

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,24 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
17601760
return NETDEV_TX_OK;
17611761
}
17621762

1763+
static netdev_features_t otx2_fix_features(struct net_device *dev,
1764+
netdev_features_t features)
1765+
{
1766+
/* check if n-tuple filters are ON */
1767+
if ((features & NETIF_F_HW_TC) && (dev->features & NETIF_F_NTUPLE)) {
1768+
netdev_info(dev, "Disabling n-tuple filters\n");
1769+
features &= ~NETIF_F_NTUPLE;
1770+
}
1771+
1772+
/* check if tc hw offload is ON */
1773+
if ((features & NETIF_F_NTUPLE) && (dev->features & NETIF_F_HW_TC)) {
1774+
netdev_info(dev, "Disabling TC hardware offload\n");
1775+
features &= ~NETIF_F_HW_TC;
1776+
}
1777+
1778+
return features;
1779+
}
1780+
17631781
static void otx2_set_rx_mode(struct net_device *netdev)
17641782
{
17651783
struct otx2_nic *pf = netdev_priv(netdev);
@@ -1822,6 +1840,12 @@ static int otx2_set_features(struct net_device *netdev,
18221840
if ((changed & NETIF_F_NTUPLE) && !ntuple)
18231841
otx2_destroy_ntuple_flows(pf);
18241842

1843+
if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
1844+
pf->tc_info.num_entries) {
1845+
netdev_err(netdev, "Can't disable TC hardware offload while flows are active\n");
1846+
return -EBUSY;
1847+
}
1848+
18251849
return 0;
18261850
}
18271851

@@ -2220,6 +2244,7 @@ static const struct net_device_ops otx2_netdev_ops = {
22202244
.ndo_open = otx2_open,
22212245
.ndo_stop = otx2_stop,
22222246
.ndo_start_xmit = otx2_xmit,
2247+
.ndo_fix_features = otx2_fix_features,
22232248
.ndo_set_mac_address = otx2_set_mac_address,
22242249
.ndo_change_mtu = otx2_change_mtu,
22252250
.ndo_set_rx_mode = otx2_set_rx_mode,
@@ -2230,6 +2255,7 @@ static const struct net_device_ops otx2_netdev_ops = {
22302255
.ndo_set_vf_mac = otx2_set_vf_mac,
22312256
.ndo_set_vf_vlan = otx2_set_vf_vlan,
22322257
.ndo_get_vf_config = otx2_get_vf_config,
2258+
.ndo_setup_tc = otx2_setup_tc,
22332259
};
22342260

22352261
static int otx2_wq_init(struct otx2_nic *pf)
@@ -2449,6 +2475,10 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
24492475
NETIF_F_HW_VLAN_STAG_RX;
24502476
netdev->features |= netdev->hw_features;
24512477

2478+
/* HW supports tc offload but mutually exclusive with n-tuple filters */
2479+
if (pf->flags & OTX2_FLAG_TC_FLOWER_SUPPORT)
2480+
netdev->hw_features |= NETIF_F_HW_TC;
2481+
24522482
netdev->gso_max_segs = OTX2_MAX_GSO_SEGS;
24532483
netdev->watchdog_timeo = OTX2_TX_TIMEOUT;
24542484

@@ -2470,6 +2500,10 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
24702500

24712501
otx2_set_ethtool_ops(netdev);
24722502

2503+
err = otx2_init_tc(pf);
2504+
if (err)
2505+
goto err_mcam_flow_del;
2506+
24732507
/* Enable link notifications */
24742508
otx2_cgx_config_linkevents(pf, true);
24752509

@@ -2479,6 +2513,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
24792513

24802514
return 0;
24812515

2516+
err_mcam_flow_del:
2517+
otx2_mcam_flow_del(pf);
24822518
err_unreg_netdev:
24832519
unregister_netdev(netdev);
24842520
err_del_mcam_entries:
@@ -2646,6 +2682,7 @@ static void otx2_remove(struct pci_dev *pdev)
26462682

26472683
otx2_ptp_destroy(pf);
26482684
otx2_mcam_flow_del(pf);
2685+
otx2_shutdown_tc(pf);
26492686
otx2_detach_resources(&pf->mbox);
26502687
if (pf->hw.lmt_base)
26512688
iounmap(pf->hw.lmt_base);

0 commit comments

Comments
 (0)