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);
3132static 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+
34146static int
35147rvu_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
372485static 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 );
0 commit comments