Skip to content

Commit 6c40ca9

Browse files
Geetha sowjanyadavem330
authored andcommitted
octeontx2-pf: Adds TC offload support
Implements tc offload support for rvu representors. Usage example: - Add tc rule to drop packets with vlan id 3 using port representor(Rpf1vf0). # tc filter add dev Rpf1vf0 protocol 802.1Q parent ffff: flower vlan_id 3 vlan_ethtype ipv4 skip_sw action drop - Redirect packets with vlan id 5 and IPv4 packets to eth1, after stripping vlan header. # tc filter add dev Rpf1vf0 ingress protocol 802.1Q flower vlan_id 5 vlan_ethtype ipv4 skip_sw action vlan pop action mirred ingress redirect dev eth1 Signed-off-by: Geetha sowjanya <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d8dec30 commit 6c40ca9

File tree

7 files changed

+154
-17
lines changed

7 files changed

+154
-17
lines changed

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,7 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu,
13981398
struct npc_install_flow_rsp *rsp)
13991399
{
14001400
bool from_vf = !!(req->hdr.pcifunc & RVU_PFVF_FUNC_MASK);
1401+
bool from_rep_dev = !!is_rep_dev(rvu, req->hdr.pcifunc);
14011402
struct rvu_switch *rswitch = &rvu->rswitch;
14021403
int blkaddr, nixlf, err;
14031404
struct rvu_pfvf *pfvf;
@@ -1454,14 +1455,19 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu,
14541455
/* AF installing for a PF/VF */
14551456
if (!req->hdr.pcifunc)
14561457
target = req->vf;
1458+
14571459
/* PF installing for its VF */
1458-
else if (!from_vf && req->vf) {
1460+
if (!from_vf && req->vf && !from_rep_dev) {
14591461
target = (req->hdr.pcifunc & ~RVU_PFVF_FUNC_MASK) | req->vf;
14601462
pf_set_vfs_mac = req->default_rule &&
14611463
(req->features & BIT_ULL(NPC_DMAC));
14621464
}
1463-
/* msg received from PF/VF */
1465+
1466+
/* Representor device installing for a representee */
1467+
if (from_rep_dev && req->vf)
1468+
target = req->vf;
14641469
else
1470+
/* msg received from PF/VF */
14651471
target = req->hdr.pcifunc;
14661472

14671473
/* ignore chan_mask in case pf func is not AF, revisit later */
@@ -1474,8 +1480,10 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu,
14741480

14751481
pfvf = rvu_get_pfvf(rvu, target);
14761482

1483+
if (from_rep_dev)
1484+
req->channel = pfvf->rx_chan_base;
14771485
/* PF installing for its VF */
1478-
if (req->hdr.pcifunc && !from_vf && req->vf)
1486+
if (req->hdr.pcifunc && !from_vf && req->vf && !from_rep_dev)
14791487
set_bit(PF_SET_VF_CFG, &pfvf->flags);
14801488

14811489
/* update req destination mac addr */

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,10 @@ int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct esw_cfg_req *req,
427427
return 0;
428428

429429
rvu->rep_mode = req->ena;
430+
431+
if (!rvu->rep_mode)
432+
rvu_npc_free_mcam_entries(rvu, req->hdr.pcifunc, -1);
433+
430434
return 0;
431435
}
432436

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,4 +1142,11 @@ int otx2_get_txq_by_classid(struct otx2_nic *pfvf, u16 classid);
11421142
void otx2_qos_config_txschq(struct otx2_nic *pfvf);
11431143
void otx2_clean_qos_queues(struct otx2_nic *pfvf);
11441144
int rvu_event_up_notify(struct otx2_nic *pf, struct rep_event *info);
1145+
int otx2_setup_tc_cls_flower(struct otx2_nic *nic,
1146+
struct flow_cls_offload *cls_flower);
1147+
1148+
static inline int mcam_entry_cmp(const void *a, const void *b)
1149+
{
1150+
return *(u16 *)a - *(u16 *)b;
1151+
}
11451152
#endif /* OTX2_COMMON_H */

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,6 @@ static int otx2_free_ntuple_mcam_entries(struct otx2_nic *pfvf)
6464
return 0;
6565
}
6666

67-
static int mcam_entry_cmp(const void *a, const void *b)
68-
{
69-
return *(u16 *)a - *(u16 *)b;
70-
}
71-
7267
int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count)
7368
{
7469
struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;

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

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic,
443443
struct flow_action_entry *act;
444444
struct net_device *target;
445445
struct otx2_nic *priv;
446+
struct rep_dev *rdev;
446447
u32 burst, mark = 0;
447448
u8 nr_police = 0;
448449
u8 num_intf = 1;
@@ -464,14 +465,18 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic,
464465
return 0;
465466
case FLOW_ACTION_REDIRECT_INGRESS:
466467
target = act->dev;
467-
priv = netdev_priv(target);
468-
/* npc_install_flow_req doesn't support passing a target pcifunc */
469-
if (rvu_get_pf(nic->pcifunc) != rvu_get_pf(priv->pcifunc)) {
470-
NL_SET_ERR_MSG_MOD(extack,
471-
"can't redirect to other pf/vf");
472-
return -EOPNOTSUPP;
468+
if (target->dev.parent) {
469+
priv = netdev_priv(target);
470+
if (rvu_get_pf(nic->pcifunc) != rvu_get_pf(priv->pcifunc)) {
471+
NL_SET_ERR_MSG_MOD(extack,
472+
"can't redirect to other pf/vf");
473+
return -EOPNOTSUPP;
474+
}
475+
req->vf = priv->pcifunc & RVU_PFVF_FUNC_MASK;
476+
} else {
477+
rdev = netdev_priv(target);
478+
req->vf = rdev->pcifunc & RVU_PFVF_FUNC_MASK;
473479
}
474-
req->vf = priv->pcifunc & RVU_PFVF_FUNC_MASK;
475480

476481
/* if op is already set; avoid overwriting the same */
477482
if (!req->op)
@@ -1300,6 +1305,7 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,
13001305
req->channel = nic->hw.rx_chan_base;
13011306
req->entry = flow_cfg->flow_ent[mcam_idx];
13021307
req->intf = NIX_INTF_RX;
1308+
req->vf = nic->pcifunc;
13031309
req->set_cntr = 1;
13041310
new_node->entry = req->entry;
13051311

@@ -1400,8 +1406,8 @@ static int otx2_tc_get_flow_stats(struct otx2_nic *nic,
14001406
return 0;
14011407
}
14021408

1403-
static int otx2_setup_tc_cls_flower(struct otx2_nic *nic,
1404-
struct flow_cls_offload *cls_flower)
1409+
int otx2_setup_tc_cls_flower(struct otx2_nic *nic,
1410+
struct flow_cls_offload *cls_flower)
14051411
{
14061412
switch (cls_flower->command) {
14071413
case FLOW_CLS_REPLACE:
@@ -1414,6 +1420,7 @@ static int otx2_setup_tc_cls_flower(struct otx2_nic *nic,
14141420
return -EOPNOTSUPP;
14151421
}
14161422
}
1423+
EXPORT_SYMBOL(otx2_setup_tc_cls_flower);
14171424

14181425
static int otx2_tc_ingress_matchall_install(struct otx2_nic *nic,
14191426
struct tc_cls_matchall_offload *cls)

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

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/module.h>
1010
#include <linux/pci.h>
1111
#include <linux/net_tstamp.h>
12+
#include <linux/sort.h>
1213

1314
#include "otx2_common.h"
1415
#include "cn10k.h"
@@ -31,6 +32,117 @@ MODULE_DEVICE_TABLE(pci, rvu_rep_id_table);
3132
static int rvu_rep_notify_pfvf(struct otx2_nic *priv, u16 event,
3233
struct rep_event *data);
3334

35+
static int rvu_rep_mcam_flow_init(struct rep_dev *rep)
36+
{
37+
struct npc_mcam_alloc_entry_req *req;
38+
struct npc_mcam_alloc_entry_rsp *rsp;
39+
struct otx2_nic *priv = rep->mdev;
40+
int ent, allocated = 0;
41+
int count;
42+
43+
rep->flow_cfg = kcalloc(1, sizeof(struct otx2_flow_config), GFP_KERNEL);
44+
45+
if (!rep->flow_cfg)
46+
return -ENOMEM;
47+
48+
count = OTX2_DEFAULT_FLOWCOUNT;
49+
50+
rep->flow_cfg->flow_ent = kcalloc(count, sizeof(u16), GFP_KERNEL);
51+
if (!rep->flow_cfg->flow_ent)
52+
return -ENOMEM;
53+
54+
while (allocated < count) {
55+
req = otx2_mbox_alloc_msg_npc_mcam_alloc_entry(&priv->mbox);
56+
if (!req)
57+
goto exit;
58+
59+
req->hdr.pcifunc = rep->pcifunc;
60+
req->contig = false;
61+
req->ref_entry = 0;
62+
req->count = (count - allocated) > NPC_MAX_NONCONTIG_ENTRIES ?
63+
NPC_MAX_NONCONTIG_ENTRIES : count - allocated;
64+
65+
if (otx2_sync_mbox_msg(&priv->mbox))
66+
goto exit;
67+
68+
rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp
69+
(&priv->mbox.mbox, 0, &req->hdr);
70+
71+
for (ent = 0; ent < rsp->count; ent++)
72+
rep->flow_cfg->flow_ent[ent + allocated] = rsp->entry_list[ent];
73+
74+
allocated += rsp->count;
75+
76+
if (rsp->count != req->count)
77+
break;
78+
}
79+
exit:
80+
/* Multiple MCAM entry alloc requests could result in non-sequential
81+
* MCAM entries in the flow_ent[] array. Sort them in an ascending
82+
* order, otherwise user installed ntuple filter index and MCAM entry
83+
* index will not be in sync.
84+
*/
85+
if (allocated)
86+
sort(&rep->flow_cfg->flow_ent[0], allocated,
87+
sizeof(rep->flow_cfg->flow_ent[0]), mcam_entry_cmp, NULL);
88+
89+
mutex_unlock(&priv->mbox.lock);
90+
91+
rep->flow_cfg->max_flows = allocated;
92+
93+
if (allocated) {
94+
rep->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;
95+
rep->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
96+
rep->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT;
97+
}
98+
99+
INIT_LIST_HEAD(&rep->flow_cfg->flow_list);
100+
INIT_LIST_HEAD(&rep->flow_cfg->flow_list_tc);
101+
return 0;
102+
}
103+
104+
static int rvu_rep_setup_tc_cb(enum tc_setup_type type,
105+
void *type_data, void *cb_priv)
106+
{
107+
struct rep_dev *rep = cb_priv;
108+
struct otx2_nic *priv = rep->mdev;
109+
110+
if (!(rep->flags & RVU_REP_VF_INITIALIZED))
111+
return -EINVAL;
112+
113+
if (!(rep->flags & OTX2_FLAG_TC_FLOWER_SUPPORT))
114+
rvu_rep_mcam_flow_init(rep);
115+
116+
priv->netdev = rep->netdev;
117+
priv->flags = rep->flags;
118+
priv->pcifunc = rep->pcifunc;
119+
priv->flow_cfg = rep->flow_cfg;
120+
121+
switch (type) {
122+
case TC_SETUP_CLSFLOWER:
123+
return otx2_setup_tc_cls_flower(priv, type_data);
124+
default:
125+
return -EOPNOTSUPP;
126+
}
127+
}
128+
129+
static LIST_HEAD(rvu_rep_block_cb_list);
130+
static int rvu_rep_setup_tc(struct net_device *netdev, enum tc_setup_type type,
131+
void *type_data)
132+
{
133+
struct rvu_rep *rep = netdev_priv(netdev);
134+
135+
switch (type) {
136+
case TC_SETUP_BLOCK:
137+
return flow_block_cb_setup_simple(type_data,
138+
&rvu_rep_block_cb_list,
139+
rvu_rep_setup_tc_cb,
140+
rep, rep, true);
141+
default:
142+
return -EOPNOTSUPP;
143+
}
144+
}
145+
34146
static int
35147
rvu_rep_sp_stats64(const struct net_device *dev,
36148
struct rtnl_link_stats64 *stats)
@@ -367,6 +479,7 @@ static const struct net_device_ops rvu_rep_netdev_ops = {
367479
.ndo_change_mtu = rvu_rep_change_mtu,
368480
.ndo_has_offload_stats = rvu_rep_has_offload_stats,
369481
.ndo_get_offload_stats = rvu_rep_get_offload_stats,
482+
.ndo_setup_tc = rvu_rep_setup_tc,
370483
};
371484

372485
static int rvu_rep_napi_init(struct otx2_nic *priv,
@@ -512,6 +625,7 @@ void rvu_rep_destroy(struct otx2_nic *priv)
512625
unregister_netdev(rep->netdev);
513626
rvu_rep_devlink_port_unregister(rep);
514627
free_netdev(rep->netdev);
628+
kfree(rep->flow_cfg);
515629
}
516630
kfree(priv->reps);
517631
rvu_rep_rsrc_free(priv);
@@ -562,6 +676,7 @@ int rvu_rep_create(struct otx2_nic *priv, struct netlink_ext_ack *extack)
562676
NETIF_F_IPV6_CSUM | NETIF_F_RXHASH |
563677
NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6);
564678

679+
ndev->hw_features |= NETIF_F_HW_TC;
565680
ndev->features |= ndev->hw_features;
566681
eth_hw_addr_random(ndev);
567682
err = rvu_rep_devlink_port_register(rep);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct rep_dev {
3535
struct rep_stats stats;
3636
struct delayed_work stats_wrk;
3737
struct devlink_port dl_port;
38+
struct otx2_flow_config *flow_cfg;
3839
#define RVU_REP_VF_INITIALIZED BIT_ULL(0)
3940
u64 flags;
4041
u16 rep_id;

0 commit comments

Comments
 (0)