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