Skip to content

Commit fd7f98b

Browse files
Subbaraya SundeepPaolo Abeni
authored andcommitted
octeontx2-pf: Restore TC ingress police rules when interface is up
TC ingress policer rules depends on interface receive queue contexts since the bandwidth profiles are attached to RQ contexts. When an interface is brought down all the queue contexts are freed. This in turn frees bandwidth profiles in hardware causing ingress police rules non-functional after the interface is brought up. Fix this by applying all the ingress police rules config to hardware in otx2_open. Also allow adding ingress rules only when interface is running since no contexts exist for the interface when it is down. Fixes: 68fbff6 ("octeontx2-pf: Add police action for TC flower") Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com> Link: https://lore.kernel.org/r/1700930217-5707-1-git-send-email-sbhatta@marvell.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 5159721 commit fd7f98b

4 files changed

Lines changed: 102 additions & 25 deletions

File tree

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,9 @@ int cn10k_set_ipolicer_rate(struct otx2_nic *pfvf, u16 profile,
450450
aq->prof.pebs_mantissa = 0;
451451
aq->prof_mask.pebs_mantissa = 0xFF;
452452

453+
aq->prof.hl_en = 0;
454+
aq->prof_mask.hl_en = 1;
455+
453456
/* Fill AQ info */
454457
aq->qidx = profile;
455458
aq->ctype = NIX_AQ_CTYPE_BANDPROF;

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,8 @@ int otx2_init_tc(struct otx2_nic *nic);
10701070
void otx2_shutdown_tc(struct otx2_nic *nic);
10711071
int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type,
10721072
void *type_data);
1073+
void otx2_tc_apply_ingress_police_rules(struct otx2_nic *nic);
1074+
10731075
/* CGX/RPM DMAC filters support */
10741076
int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf);
10751077
int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u32 bit_pos);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,8 @@ int otx2_open(struct net_device *netdev)
18731873
if (pf->flags & OTX2_FLAG_DMACFLTR_SUPPORT)
18741874
otx2_dmacflt_reinstall_flows(pf);
18751875

1876+
otx2_tc_apply_ingress_police_rules(pf);
1877+
18761878
err = otx2_rxtx_enable(pf, true);
18771879
/* If a mbox communication error happens at this point then interface
18781880
* will end up in a state such that it is in down state but hardware

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

Lines changed: 95 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ struct otx2_tc_flow {
4747
bool is_act_police;
4848
u32 prio;
4949
struct npc_install_flow_req req;
50+
u64 rate;
51+
u32 burst;
52+
bool is_pps;
5053
};
5154

5255
static void otx2_get_egress_burst_cfg(struct otx2_nic *nic, u32 burst,
@@ -284,21 +287,10 @@ static int otx2_tc_egress_matchall_delete(struct otx2_nic *nic,
284287
return err;
285288
}
286289

287-
static int otx2_tc_act_set_police(struct otx2_nic *nic,
288-
struct otx2_tc_flow *node,
289-
struct flow_cls_offload *f,
290-
u64 rate, u32 burst, u32 mark,
291-
struct npc_install_flow_req *req, bool pps)
290+
static int otx2_tc_act_set_hw_police(struct otx2_nic *nic,
291+
struct otx2_tc_flow *node)
292292
{
293-
struct netlink_ext_ack *extack = f->common.extack;
294-
struct otx2_hw *hw = &nic->hw;
295-
int rq_idx, rc;
296-
297-
rq_idx = find_first_zero_bit(&nic->rq_bmap, hw->rx_queues);
298-
if (rq_idx >= hw->rx_queues) {
299-
NL_SET_ERR_MSG_MOD(extack, "Police action rules exceeded");
300-
return -EINVAL;
301-
}
293+
int rc;
302294

303295
mutex_lock(&nic->mbox.lock);
304296

@@ -308,23 +300,17 @@ static int otx2_tc_act_set_police(struct otx2_nic *nic,
308300
return rc;
309301
}
310302

311-
rc = cn10k_set_ipolicer_rate(nic, node->leaf_profile, burst, rate, pps);
303+
rc = cn10k_set_ipolicer_rate(nic, node->leaf_profile,
304+
node->burst, node->rate, node->is_pps);
312305
if (rc)
313306
goto free_leaf;
314307

315-
rc = cn10k_map_unmap_rq_policer(nic, rq_idx, node->leaf_profile, true);
308+
rc = cn10k_map_unmap_rq_policer(nic, node->rq, node->leaf_profile, true);
316309
if (rc)
317310
goto free_leaf;
318311

319312
mutex_unlock(&nic->mbox.lock);
320313

321-
req->match_id = mark & 0xFFFFULL;
322-
req->index = rq_idx;
323-
req->op = NIX_RX_ACTIONOP_UCAST;
324-
set_bit(rq_idx, &nic->rq_bmap);
325-
node->is_act_police = true;
326-
node->rq = rq_idx;
327-
328314
return 0;
329315

330316
free_leaf:
@@ -336,6 +322,39 @@ static int otx2_tc_act_set_police(struct otx2_nic *nic,
336322
return rc;
337323
}
338324

325+
static int otx2_tc_act_set_police(struct otx2_nic *nic,
326+
struct otx2_tc_flow *node,
327+
struct flow_cls_offload *f,
328+
u64 rate, u32 burst, u32 mark,
329+
struct npc_install_flow_req *req, bool pps)
330+
{
331+
struct netlink_ext_ack *extack = f->common.extack;
332+
struct otx2_hw *hw = &nic->hw;
333+
int rq_idx, rc;
334+
335+
rq_idx = find_first_zero_bit(&nic->rq_bmap, hw->rx_queues);
336+
if (rq_idx >= hw->rx_queues) {
337+
NL_SET_ERR_MSG_MOD(extack, "Police action rules exceeded");
338+
return -EINVAL;
339+
}
340+
341+
req->match_id = mark & 0xFFFFULL;
342+
req->index = rq_idx;
343+
req->op = NIX_RX_ACTIONOP_UCAST;
344+
345+
node->is_act_police = true;
346+
node->rq = rq_idx;
347+
node->burst = burst;
348+
node->rate = rate;
349+
node->is_pps = pps;
350+
351+
rc = otx2_tc_act_set_hw_police(nic, node);
352+
if (!rc)
353+
set_bit(rq_idx, &nic->rq_bmap);
354+
355+
return rc;
356+
}
357+
339358
static int otx2_tc_parse_actions(struct otx2_nic *nic,
340359
struct flow_action *flow_action,
341360
struct npc_install_flow_req *req,
@@ -1044,6 +1063,11 @@ static int otx2_tc_del_flow(struct otx2_nic *nic,
10441063
}
10451064

10461065
if (flow_node->is_act_police) {
1066+
__clear_bit(flow_node->rq, &nic->rq_bmap);
1067+
1068+
if (nic->flags & OTX2_FLAG_INTF_DOWN)
1069+
goto free_mcam_flow;
1070+
10471071
mutex_lock(&nic->mbox.lock);
10481072

10491073
err = cn10k_map_unmap_rq_policer(nic, flow_node->rq,
@@ -1059,11 +1083,10 @@ static int otx2_tc_del_flow(struct otx2_nic *nic,
10591083
"Unable to free leaf bandwidth profile(%d)\n",
10601084
flow_node->leaf_profile);
10611085

1062-
__clear_bit(flow_node->rq, &nic->rq_bmap);
1063-
10641086
mutex_unlock(&nic->mbox.lock);
10651087
}
10661088

1089+
free_mcam_flow:
10671090
otx2_del_mcam_flow_entry(nic, flow_node->entry, NULL);
10681091
otx2_tc_update_mcam_table(nic, flow_cfg, flow_node, false);
10691092
kfree_rcu(flow_node, rcu);
@@ -1083,6 +1106,11 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,
10831106
if (!(nic->flags & OTX2_FLAG_TC_FLOWER_SUPPORT))
10841107
return -ENOMEM;
10851108

1109+
if (nic->flags & OTX2_FLAG_INTF_DOWN) {
1110+
NL_SET_ERR_MSG_MOD(extack, "Interface not initialized");
1111+
return -EINVAL;
1112+
}
1113+
10861114
if (flow_cfg->nr_flows == flow_cfg->max_flows) {
10871115
NL_SET_ERR_MSG_MOD(extack,
10881116
"Free MCAM entry not available to add the flow");
@@ -1442,3 +1470,45 @@ void otx2_shutdown_tc(struct otx2_nic *nic)
14421470
otx2_destroy_tc_flow_list(nic);
14431471
}
14441472
EXPORT_SYMBOL(otx2_shutdown_tc);
1473+
1474+
static void otx2_tc_config_ingress_rule(struct otx2_nic *nic,
1475+
struct otx2_tc_flow *node)
1476+
{
1477+
struct npc_install_flow_req *req;
1478+
1479+
if (otx2_tc_act_set_hw_police(nic, node))
1480+
return;
1481+
1482+
mutex_lock(&nic->mbox.lock);
1483+
1484+
req = otx2_mbox_alloc_msg_npc_install_flow(&nic->mbox);
1485+
if (!req)
1486+
goto err;
1487+
1488+
memcpy(req, &node->req, sizeof(struct npc_install_flow_req));
1489+
1490+
if (otx2_sync_mbox_msg(&nic->mbox))
1491+
netdev_err(nic->netdev,
1492+
"Failed to install MCAM flow entry for ingress rule");
1493+
err:
1494+
mutex_unlock(&nic->mbox.lock);
1495+
}
1496+
1497+
void otx2_tc_apply_ingress_police_rules(struct otx2_nic *nic)
1498+
{
1499+
struct otx2_flow_config *flow_cfg = nic->flow_cfg;
1500+
struct otx2_tc_flow *node;
1501+
1502+
/* If any ingress policer rules exist for the interface then
1503+
* apply those rules. Ingress policer rules depend on bandwidth
1504+
* profiles linked to the receive queues. Since no receive queues
1505+
* exist when interface is down, ingress policer rules are stored
1506+
* and configured in hardware after all receive queues are allocated
1507+
* in otx2_open.
1508+
*/
1509+
list_for_each_entry(node, &flow_cfg->flow_list_tc, list) {
1510+
if (node->is_act_police)
1511+
otx2_tc_config_ingress_rule(nic, node);
1512+
}
1513+
}
1514+
EXPORT_SYMBOL(otx2_tc_apply_ingress_police_rules);

0 commit comments

Comments
 (0)