1fe6d86b3SSaeed Mahameed /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2fe6d86b3SSaeed Mahameed /* Copyright (c) 2018 Mellanox Technologies. */
3fe6d86b3SSaeed Mahameed 
4fe6d86b3SSaeed Mahameed #ifndef __MLX5E_FLOW_STEER_H__
5fe6d86b3SSaeed Mahameed #define __MLX5E_FLOW_STEER_H__
6fe6d86b3SSaeed Mahameed 
744f68ae0SSaeed Mahameed enum {
844f68ae0SSaeed Mahameed 	MLX5E_TC_FT_LEVEL = 0,
944f68ae0SSaeed Mahameed 	MLX5E_TC_TTC_FT_LEVEL,
1044f68ae0SSaeed Mahameed };
1144f68ae0SSaeed Mahameed 
1244f68ae0SSaeed Mahameed struct mlx5e_tc_table {
13b6fac0b4SVlad Buslov 	/* protects flow table */
14b6fac0b4SVlad Buslov 	struct mutex			t_lock;
1544f68ae0SSaeed Mahameed 	struct mlx5_flow_table		*t;
1644f68ae0SSaeed Mahameed 
1744f68ae0SSaeed Mahameed 	struct rhashtable               ht;
1844f68ae0SSaeed Mahameed 
19dd58edc3SVlad Buslov 	struct mod_hdr_tbl mod_hdr;
20b32accdaSVlad Buslov 	struct mutex hairpin_tbl_lock; /* protects hairpin_tbl */
2144f68ae0SSaeed Mahameed 	DECLARE_HASHTABLE(hairpin_tbl, 8);
224d8fcf21SAlaa Hleihel 
234d8fcf21SAlaa Hleihel 	struct notifier_block     netdevice_nb;
2444f68ae0SSaeed Mahameed };
2544f68ae0SSaeed Mahameed 
26ec080045SSaeed Mahameed struct mlx5e_flow_table {
27ec080045SSaeed Mahameed 	int num_groups;
28ec080045SSaeed Mahameed 	struct mlx5_flow_table *t;
29ec080045SSaeed Mahameed 	struct mlx5_flow_group **g;
30ec080045SSaeed Mahameed };
31ec080045SSaeed Mahameed 
3244f68ae0SSaeed Mahameed struct mlx5e_l2_rule {
3344f68ae0SSaeed Mahameed 	u8  addr[ETH_ALEN + 2];
3444f68ae0SSaeed Mahameed 	struct mlx5_flow_handle *rule;
3544f68ae0SSaeed Mahameed };
3644f68ae0SSaeed Mahameed 
3744f68ae0SSaeed Mahameed #define MLX5E_L2_ADDR_HASH_SIZE BIT(BITS_PER_BYTE)
3844f68ae0SSaeed Mahameed 
3944f68ae0SSaeed Mahameed struct mlx5e_vlan_table {
4044f68ae0SSaeed Mahameed 	struct mlx5e_flow_table		ft;
4144f68ae0SSaeed Mahameed 	DECLARE_BITMAP(active_cvlans, VLAN_N_VID);
4244f68ae0SSaeed Mahameed 	DECLARE_BITMAP(active_svlans, VLAN_N_VID);
4344f68ae0SSaeed Mahameed 	struct mlx5_flow_handle	*active_cvlans_rule[VLAN_N_VID];
4444f68ae0SSaeed Mahameed 	struct mlx5_flow_handle	*active_svlans_rule[VLAN_N_VID];
4544f68ae0SSaeed Mahameed 	struct mlx5_flow_handle	*untagged_rule;
4644f68ae0SSaeed Mahameed 	struct mlx5_flow_handle	*any_cvlan_rule;
4744f68ae0SSaeed Mahameed 	struct mlx5_flow_handle	*any_svlan_rule;
4844f68ae0SSaeed Mahameed 	bool			cvlan_filter_disabled;
4944f68ae0SSaeed Mahameed };
5044f68ae0SSaeed Mahameed 
5144f68ae0SSaeed Mahameed struct mlx5e_l2_table {
5244f68ae0SSaeed Mahameed 	struct mlx5e_flow_table    ft;
5344f68ae0SSaeed Mahameed 	struct hlist_head          netdev_uc[MLX5E_L2_ADDR_HASH_SIZE];
5444f68ae0SSaeed Mahameed 	struct hlist_head          netdev_mc[MLX5E_L2_ADDR_HASH_SIZE];
5544f68ae0SSaeed Mahameed 	struct mlx5e_l2_rule	   broadcast;
5644f68ae0SSaeed Mahameed 	struct mlx5e_l2_rule	   allmulti;
5744f68ae0SSaeed Mahameed 	struct mlx5e_l2_rule	   promisc;
5844f68ae0SSaeed Mahameed 	bool                       broadcast_enabled;
5944f68ae0SSaeed Mahameed 	bool                       allmulti_enabled;
6044f68ae0SSaeed Mahameed 	bool                       promisc_enabled;
6144f68ae0SSaeed Mahameed };
6244f68ae0SSaeed Mahameed 
6344f68ae0SSaeed Mahameed enum mlx5e_traffic_types {
6444f68ae0SSaeed Mahameed 	MLX5E_TT_IPV4_TCP,
6544f68ae0SSaeed Mahameed 	MLX5E_TT_IPV6_TCP,
6644f68ae0SSaeed Mahameed 	MLX5E_TT_IPV4_UDP,
6744f68ae0SSaeed Mahameed 	MLX5E_TT_IPV6_UDP,
6844f68ae0SSaeed Mahameed 	MLX5E_TT_IPV4_IPSEC_AH,
6944f68ae0SSaeed Mahameed 	MLX5E_TT_IPV6_IPSEC_AH,
7044f68ae0SSaeed Mahameed 	MLX5E_TT_IPV4_IPSEC_ESP,
7144f68ae0SSaeed Mahameed 	MLX5E_TT_IPV6_IPSEC_ESP,
7244f68ae0SSaeed Mahameed 	MLX5E_TT_IPV4,
7344f68ae0SSaeed Mahameed 	MLX5E_TT_IPV6,
7444f68ae0SSaeed Mahameed 	MLX5E_TT_ANY,
7544f68ae0SSaeed Mahameed 	MLX5E_NUM_TT,
7644f68ae0SSaeed Mahameed 	MLX5E_NUM_INDIR_TIRS = MLX5E_TT_ANY,
7744f68ae0SSaeed Mahameed };
7844f68ae0SSaeed Mahameed 
79d930ac79SAya Levin struct mlx5e_tirc_config {
80d930ac79SAya Levin 	u8 l3_prot_type;
81d930ac79SAya Levin 	u8 l4_prot_type;
82d930ac79SAya Levin 	u32 rx_hash_fields;
83d930ac79SAya Levin };
84d930ac79SAya Levin 
85d930ac79SAya Levin #define MLX5_HASH_IP		(MLX5_HASH_FIELD_SEL_SRC_IP   |\
86d930ac79SAya Levin 				 MLX5_HASH_FIELD_SEL_DST_IP)
87d930ac79SAya Levin #define MLX5_HASH_IP_L4PORTS	(MLX5_HASH_FIELD_SEL_SRC_IP   |\
88d930ac79SAya Levin 				 MLX5_HASH_FIELD_SEL_DST_IP   |\
89d930ac79SAya Levin 				 MLX5_HASH_FIELD_SEL_L4_SPORT |\
90d930ac79SAya Levin 				 MLX5_HASH_FIELD_SEL_L4_DPORT)
91d930ac79SAya Levin #define MLX5_HASH_IP_IPSEC_SPI	(MLX5_HASH_FIELD_SEL_SRC_IP   |\
92d930ac79SAya Levin 				 MLX5_HASH_FIELD_SEL_DST_IP   |\
93d930ac79SAya Levin 				 MLX5_HASH_FIELD_SEL_IPSEC_SPI)
94d930ac79SAya Levin 
9544f68ae0SSaeed Mahameed enum mlx5e_tunnel_types {
9644f68ae0SSaeed Mahameed 	MLX5E_TT_IPV4_GRE,
9744f68ae0SSaeed Mahameed 	MLX5E_TT_IPV6_GRE,
9844f68ae0SSaeed Mahameed 	MLX5E_NUM_TUNNEL_TT,
9944f68ae0SSaeed Mahameed };
10044f68ae0SSaeed Mahameed 
10144f68ae0SSaeed Mahameed /* L3/L4 traffic type classifier */
10244f68ae0SSaeed Mahameed struct mlx5e_ttc_table {
10344f68ae0SSaeed Mahameed 	struct mlx5e_flow_table  ft;
10444f68ae0SSaeed Mahameed 	struct mlx5_flow_handle	 *rules[MLX5E_NUM_TT];
10544f68ae0SSaeed Mahameed 	struct mlx5_flow_handle  *tunnel_rules[MLX5E_NUM_TUNNEL_TT];
10644f68ae0SSaeed Mahameed };
10744f68ae0SSaeed Mahameed 
10844f68ae0SSaeed Mahameed /* NIC prio FTS */
10944f68ae0SSaeed Mahameed enum {
11044f68ae0SSaeed Mahameed 	MLX5E_VLAN_FT_LEVEL = 0,
11144f68ae0SSaeed Mahameed 	MLX5E_L2_FT_LEVEL,
11244f68ae0SSaeed Mahameed 	MLX5E_TTC_FT_LEVEL,
11344f68ae0SSaeed Mahameed 	MLX5E_INNER_TTC_FT_LEVEL,
11444f68ae0SSaeed Mahameed #ifdef CONFIG_MLX5_EN_ARFS
11544f68ae0SSaeed Mahameed 	MLX5E_ARFS_FT_LEVEL
11644f68ae0SSaeed Mahameed #endif
11744f68ae0SSaeed Mahameed };
11844f68ae0SSaeed Mahameed 
119fe6d86b3SSaeed Mahameed #ifdef CONFIG_MLX5_EN_RXNFC
120fe6d86b3SSaeed Mahameed 
121fe6d86b3SSaeed Mahameed struct mlx5e_ethtool_table {
122fe6d86b3SSaeed Mahameed 	struct mlx5_flow_table *ft;
123fe6d86b3SSaeed Mahameed 	int                    num_rules;
124fe6d86b3SSaeed Mahameed };
125fe6d86b3SSaeed Mahameed 
126fe6d86b3SSaeed Mahameed #define ETHTOOL_NUM_L3_L4_FTS 7
127fe6d86b3SSaeed Mahameed #define ETHTOOL_NUM_L2_FTS 4
128fe6d86b3SSaeed Mahameed 
129fe6d86b3SSaeed Mahameed struct mlx5e_ethtool_steering {
130fe6d86b3SSaeed Mahameed 	struct mlx5e_ethtool_table      l3_l4_ft[ETHTOOL_NUM_L3_L4_FTS];
131fe6d86b3SSaeed Mahameed 	struct mlx5e_ethtool_table      l2_ft[ETHTOOL_NUM_L2_FTS];
132fe6d86b3SSaeed Mahameed 	struct list_head                rules;
133fe6d86b3SSaeed Mahameed 	int                             tot_num_rules;
134fe6d86b3SSaeed Mahameed };
135fe6d86b3SSaeed Mahameed 
136fe6d86b3SSaeed Mahameed void mlx5e_ethtool_init_steering(struct mlx5e_priv *priv);
137fe6d86b3SSaeed Mahameed void mlx5e_ethtool_cleanup_steering(struct mlx5e_priv *priv);
13879ce39beSSaeed Mahameed int mlx5e_ethtool_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd);
13979ce39beSSaeed Mahameed int mlx5e_ethtool_get_rxnfc(struct net_device *dev,
140fe6d86b3SSaeed Mahameed 			    struct ethtool_rxnfc *info, u32 *rule_locs);
141fe6d86b3SSaeed Mahameed #else
142fe6d86b3SSaeed Mahameed static inline void mlx5e_ethtool_init_steering(struct mlx5e_priv *priv)    { }
143fe6d86b3SSaeed Mahameed static inline void mlx5e_ethtool_cleanup_steering(struct mlx5e_priv *priv) { }
14479ce39beSSaeed Mahameed static inline int mlx5e_ethtool_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
14579ce39beSSaeed Mahameed { return -EOPNOTSUPP; }
14679ce39beSSaeed Mahameed static inline int mlx5e_ethtool_get_rxnfc(struct net_device *dev,
14779ce39beSSaeed Mahameed 					  struct ethtool_rxnfc *info, u32 *rule_locs)
14879ce39beSSaeed Mahameed { return -EOPNOTSUPP; }
149fe6d86b3SSaeed Mahameed #endif /* CONFIG_MLX5_EN_RXNFC */
150fe6d86b3SSaeed Mahameed 
151ec080045SSaeed Mahameed #ifdef CONFIG_MLX5_EN_ARFS
152ec080045SSaeed Mahameed #define ARFS_HASH_SHIFT BITS_PER_BYTE
153ec080045SSaeed Mahameed #define ARFS_HASH_SIZE BIT(BITS_PER_BYTE)
154ec080045SSaeed Mahameed 
155ec080045SSaeed Mahameed struct arfs_table {
156ec080045SSaeed Mahameed 	struct mlx5e_flow_table  ft;
157ec080045SSaeed Mahameed 	struct mlx5_flow_handle	 *default_rule;
158ec080045SSaeed Mahameed 	struct hlist_head	 rules_hash[ARFS_HASH_SIZE];
159ec080045SSaeed Mahameed };
160ec080045SSaeed Mahameed 
161ec080045SSaeed Mahameed enum  arfs_type {
162ec080045SSaeed Mahameed 	ARFS_IPV4_TCP,
163ec080045SSaeed Mahameed 	ARFS_IPV6_TCP,
164ec080045SSaeed Mahameed 	ARFS_IPV4_UDP,
165ec080045SSaeed Mahameed 	ARFS_IPV6_UDP,
166ec080045SSaeed Mahameed 	ARFS_NUM_TYPES,
167ec080045SSaeed Mahameed };
168ec080045SSaeed Mahameed 
169ec080045SSaeed Mahameed struct mlx5e_arfs_tables {
170ec080045SSaeed Mahameed 	struct arfs_table arfs_tables[ARFS_NUM_TYPES];
171ec080045SSaeed Mahameed 	/* Protect aRFS rules list */
172ec080045SSaeed Mahameed 	spinlock_t                     arfs_lock;
173ec080045SSaeed Mahameed 	struct list_head               rules;
174ec080045SSaeed Mahameed 	int                            last_filter_id;
175ec080045SSaeed Mahameed 	struct workqueue_struct        *wq;
176ec080045SSaeed Mahameed };
177ec080045SSaeed Mahameed 
178ec080045SSaeed Mahameed int mlx5e_arfs_create_tables(struct mlx5e_priv *priv);
179ec080045SSaeed Mahameed void mlx5e_arfs_destroy_tables(struct mlx5e_priv *priv);
180ec080045SSaeed Mahameed int mlx5e_arfs_enable(struct mlx5e_priv *priv);
181ec080045SSaeed Mahameed int mlx5e_arfs_disable(struct mlx5e_priv *priv);
182ec080045SSaeed Mahameed int mlx5e_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
183ec080045SSaeed Mahameed 			u16 rxq_index, u32 flow_id);
184ec080045SSaeed Mahameed #else
185ec080045SSaeed Mahameed static inline int mlx5e_arfs_create_tables(struct mlx5e_priv *priv) { return 0; }
186ec080045SSaeed Mahameed static inline void mlx5e_arfs_destroy_tables(struct mlx5e_priv *priv) {}
187ec080045SSaeed Mahameed static inline int mlx5e_arfs_enable(struct mlx5e_priv *priv) { return -EOPNOTSUPP; }
188ec080045SSaeed Mahameed static inline int mlx5e_arfs_disable(struct mlx5e_priv *priv) {	return -EOPNOTSUPP; }
189ec080045SSaeed Mahameed #endif
190ec080045SSaeed Mahameed 
19144f68ae0SSaeed Mahameed struct mlx5e_flow_steering {
19244f68ae0SSaeed Mahameed 	struct mlx5_flow_namespace      *ns;
19344f68ae0SSaeed Mahameed #ifdef CONFIG_MLX5_EN_RXNFC
19444f68ae0SSaeed Mahameed 	struct mlx5e_ethtool_steering   ethtool;
19544f68ae0SSaeed Mahameed #endif
19644f68ae0SSaeed Mahameed 	struct mlx5e_tc_table           tc;
19744f68ae0SSaeed Mahameed 	struct mlx5e_vlan_table         vlan;
19844f68ae0SSaeed Mahameed 	struct mlx5e_l2_table           l2;
19944f68ae0SSaeed Mahameed 	struct mlx5e_ttc_table          ttc;
20044f68ae0SSaeed Mahameed 	struct mlx5e_ttc_table          inner_ttc;
20144f68ae0SSaeed Mahameed #ifdef CONFIG_MLX5_EN_ARFS
20244f68ae0SSaeed Mahameed 	struct mlx5e_arfs_tables        arfs;
20344f68ae0SSaeed Mahameed #endif
20444f68ae0SSaeed Mahameed };
20544f68ae0SSaeed Mahameed 
20644f68ae0SSaeed Mahameed struct ttc_params {
20744f68ae0SSaeed Mahameed 	struct mlx5_flow_table_attr ft_attr;
20844f68ae0SSaeed Mahameed 	u32 any_tt_tirn;
20944f68ae0SSaeed Mahameed 	u32 indir_tirn[MLX5E_NUM_INDIR_TIRS];
21044f68ae0SSaeed Mahameed 	struct mlx5e_ttc_table *inner_ttc;
21144f68ae0SSaeed Mahameed };
21244f68ae0SSaeed Mahameed 
21344f68ae0SSaeed Mahameed void mlx5e_set_ttc_basic_params(struct mlx5e_priv *priv, struct ttc_params *ttc_params);
21444f68ae0SSaeed Mahameed void mlx5e_set_ttc_ft_params(struct ttc_params *ttc_params);
21544f68ae0SSaeed Mahameed void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params);
21644f68ae0SSaeed Mahameed 
21744f68ae0SSaeed Mahameed int mlx5e_create_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params,
21844f68ae0SSaeed Mahameed 			   struct mlx5e_ttc_table *ttc);
21944f68ae0SSaeed Mahameed void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv,
22044f68ae0SSaeed Mahameed 			     struct mlx5e_ttc_table *ttc);
22144f68ae0SSaeed Mahameed 
22244f68ae0SSaeed Mahameed int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params,
22344f68ae0SSaeed Mahameed 				 struct mlx5e_ttc_table *ttc);
22444f68ae0SSaeed Mahameed void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv,
22544f68ae0SSaeed Mahameed 				   struct mlx5e_ttc_table *ttc);
22644f68ae0SSaeed Mahameed 
22744f68ae0SSaeed Mahameed void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft);
22844f68ae0SSaeed Mahameed 
22944f68ae0SSaeed Mahameed void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv);
23044f68ae0SSaeed Mahameed void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv);
23144f68ae0SSaeed Mahameed 
23244f68ae0SSaeed Mahameed int mlx5e_create_flow_steering(struct mlx5e_priv *priv);
23344f68ae0SSaeed Mahameed void mlx5e_destroy_flow_steering(struct mlx5e_priv *priv);
23444f68ae0SSaeed Mahameed 
235fe6d86b3SSaeed Mahameed #endif /* __MLX5E_FLOW_STEER_H__ */
236fe6d86b3SSaeed Mahameed 
237