@@ -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
5255static 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
330316free_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+
339358static 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}
14441472EXPORT_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