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,
98a795d8dbSAya Levin 	MLX5E_TT_IPV4_IPIP,
99a795d8dbSAya Levin 	MLX5E_TT_IPV6_IPIP,
100a795d8dbSAya Levin 	MLX5E_TT_IPV4_IPV6,
101a795d8dbSAya Levin 	MLX5E_TT_IPV6_IPV6,
10244f68ae0SSaeed Mahameed 	MLX5E_NUM_TUNNEL_TT,
10344f68ae0SSaeed Mahameed };
10444f68ae0SSaeed Mahameed 
105a49e1f31SAya Levin bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev);
106a49e1f31SAya Levin 
10744f68ae0SSaeed Mahameed /* L3/L4 traffic type classifier */
10844f68ae0SSaeed Mahameed struct mlx5e_ttc_table {
10944f68ae0SSaeed Mahameed 	struct mlx5e_flow_table  ft;
11044f68ae0SSaeed Mahameed 	struct mlx5_flow_handle	 *rules[MLX5E_NUM_TT];
11144f68ae0SSaeed Mahameed 	struct mlx5_flow_handle  *tunnel_rules[MLX5E_NUM_TUNNEL_TT];
11244f68ae0SSaeed Mahameed };
11344f68ae0SSaeed Mahameed 
11444f68ae0SSaeed Mahameed /* NIC prio FTS */
11544f68ae0SSaeed Mahameed enum {
11644f68ae0SSaeed Mahameed 	MLX5E_VLAN_FT_LEVEL = 0,
11744f68ae0SSaeed Mahameed 	MLX5E_L2_FT_LEVEL,
11844f68ae0SSaeed Mahameed 	MLX5E_TTC_FT_LEVEL,
11944f68ae0SSaeed Mahameed 	MLX5E_INNER_TTC_FT_LEVEL,
12044f68ae0SSaeed Mahameed #ifdef CONFIG_MLX5_EN_ARFS
12144f68ae0SSaeed Mahameed 	MLX5E_ARFS_FT_LEVEL
12244f68ae0SSaeed Mahameed #endif
12344f68ae0SSaeed Mahameed };
12444f68ae0SSaeed Mahameed 
125fe6d86b3SSaeed Mahameed #ifdef CONFIG_MLX5_EN_RXNFC
126fe6d86b3SSaeed Mahameed 
127fe6d86b3SSaeed Mahameed struct mlx5e_ethtool_table {
128fe6d86b3SSaeed Mahameed 	struct mlx5_flow_table *ft;
129fe6d86b3SSaeed Mahameed 	int                    num_rules;
130fe6d86b3SSaeed Mahameed };
131fe6d86b3SSaeed Mahameed 
132fe6d86b3SSaeed Mahameed #define ETHTOOL_NUM_L3_L4_FTS 7
133fe6d86b3SSaeed Mahameed #define ETHTOOL_NUM_L2_FTS 4
134fe6d86b3SSaeed Mahameed 
135fe6d86b3SSaeed Mahameed struct mlx5e_ethtool_steering {
136fe6d86b3SSaeed Mahameed 	struct mlx5e_ethtool_table      l3_l4_ft[ETHTOOL_NUM_L3_L4_FTS];
137fe6d86b3SSaeed Mahameed 	struct mlx5e_ethtool_table      l2_ft[ETHTOOL_NUM_L2_FTS];
138fe6d86b3SSaeed Mahameed 	struct list_head                rules;
139fe6d86b3SSaeed Mahameed 	int                             tot_num_rules;
140fe6d86b3SSaeed Mahameed };
141fe6d86b3SSaeed Mahameed 
142fe6d86b3SSaeed Mahameed void mlx5e_ethtool_init_steering(struct mlx5e_priv *priv);
143fe6d86b3SSaeed Mahameed void mlx5e_ethtool_cleanup_steering(struct mlx5e_priv *priv);
14479ce39beSSaeed Mahameed int mlx5e_ethtool_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd);
14579ce39beSSaeed Mahameed int mlx5e_ethtool_get_rxnfc(struct net_device *dev,
146fe6d86b3SSaeed Mahameed 			    struct ethtool_rxnfc *info, u32 *rule_locs);
147fe6d86b3SSaeed Mahameed #else
148fe6d86b3SSaeed Mahameed static inline void mlx5e_ethtool_init_steering(struct mlx5e_priv *priv)    { }
149fe6d86b3SSaeed Mahameed static inline void mlx5e_ethtool_cleanup_steering(struct mlx5e_priv *priv) { }
15079ce39beSSaeed Mahameed static inline int mlx5e_ethtool_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
15179ce39beSSaeed Mahameed { return -EOPNOTSUPP; }
15279ce39beSSaeed Mahameed static inline int mlx5e_ethtool_get_rxnfc(struct net_device *dev,
15379ce39beSSaeed Mahameed 					  struct ethtool_rxnfc *info, u32 *rule_locs)
15479ce39beSSaeed Mahameed { return -EOPNOTSUPP; }
155fe6d86b3SSaeed Mahameed #endif /* CONFIG_MLX5_EN_RXNFC */
156fe6d86b3SSaeed Mahameed 
157ec080045SSaeed Mahameed #ifdef CONFIG_MLX5_EN_ARFS
158ec080045SSaeed Mahameed #define ARFS_HASH_SHIFT BITS_PER_BYTE
159ec080045SSaeed Mahameed #define ARFS_HASH_SIZE BIT(BITS_PER_BYTE)
160ec080045SSaeed Mahameed 
161ec080045SSaeed Mahameed struct arfs_table {
162ec080045SSaeed Mahameed 	struct mlx5e_flow_table  ft;
163ec080045SSaeed Mahameed 	struct mlx5_flow_handle	 *default_rule;
164ec080045SSaeed Mahameed 	struct hlist_head	 rules_hash[ARFS_HASH_SIZE];
165ec080045SSaeed Mahameed };
166ec080045SSaeed Mahameed 
167ec080045SSaeed Mahameed enum  arfs_type {
168ec080045SSaeed Mahameed 	ARFS_IPV4_TCP,
169ec080045SSaeed Mahameed 	ARFS_IPV6_TCP,
170ec080045SSaeed Mahameed 	ARFS_IPV4_UDP,
171ec080045SSaeed Mahameed 	ARFS_IPV6_UDP,
172ec080045SSaeed Mahameed 	ARFS_NUM_TYPES,
173ec080045SSaeed Mahameed };
174ec080045SSaeed Mahameed 
175ec080045SSaeed Mahameed struct mlx5e_arfs_tables {
176ec080045SSaeed Mahameed 	struct arfs_table arfs_tables[ARFS_NUM_TYPES];
177ec080045SSaeed Mahameed 	/* Protect aRFS rules list */
178ec080045SSaeed Mahameed 	spinlock_t                     arfs_lock;
179ec080045SSaeed Mahameed 	struct list_head               rules;
180ec080045SSaeed Mahameed 	int                            last_filter_id;
181ec080045SSaeed Mahameed 	struct workqueue_struct        *wq;
182ec080045SSaeed Mahameed };
183ec080045SSaeed Mahameed 
184ec080045SSaeed Mahameed int mlx5e_arfs_create_tables(struct mlx5e_priv *priv);
185ec080045SSaeed Mahameed void mlx5e_arfs_destroy_tables(struct mlx5e_priv *priv);
186ec080045SSaeed Mahameed int mlx5e_arfs_enable(struct mlx5e_priv *priv);
187ec080045SSaeed Mahameed int mlx5e_arfs_disable(struct mlx5e_priv *priv);
188ec080045SSaeed Mahameed int mlx5e_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
189ec080045SSaeed Mahameed 			u16 rxq_index, u32 flow_id);
190ec080045SSaeed Mahameed #else
191ec080045SSaeed Mahameed static inline int mlx5e_arfs_create_tables(struct mlx5e_priv *priv) { return 0; }
192ec080045SSaeed Mahameed static inline void mlx5e_arfs_destroy_tables(struct mlx5e_priv *priv) {}
193ec080045SSaeed Mahameed static inline int mlx5e_arfs_enable(struct mlx5e_priv *priv) { return -EOPNOTSUPP; }
194ec080045SSaeed Mahameed static inline int mlx5e_arfs_disable(struct mlx5e_priv *priv) {	return -EOPNOTSUPP; }
195ec080045SSaeed Mahameed #endif
196ec080045SSaeed Mahameed 
19744f68ae0SSaeed Mahameed struct mlx5e_flow_steering {
19844f68ae0SSaeed Mahameed 	struct mlx5_flow_namespace      *ns;
19944f68ae0SSaeed Mahameed #ifdef CONFIG_MLX5_EN_RXNFC
20044f68ae0SSaeed Mahameed 	struct mlx5e_ethtool_steering   ethtool;
20144f68ae0SSaeed Mahameed #endif
20244f68ae0SSaeed Mahameed 	struct mlx5e_tc_table           tc;
20344f68ae0SSaeed Mahameed 	struct mlx5e_vlan_table         vlan;
20444f68ae0SSaeed Mahameed 	struct mlx5e_l2_table           l2;
20544f68ae0SSaeed Mahameed 	struct mlx5e_ttc_table          ttc;
20644f68ae0SSaeed Mahameed 	struct mlx5e_ttc_table          inner_ttc;
20744f68ae0SSaeed Mahameed #ifdef CONFIG_MLX5_EN_ARFS
20844f68ae0SSaeed Mahameed 	struct mlx5e_arfs_tables        arfs;
20944f68ae0SSaeed Mahameed #endif
21044f68ae0SSaeed Mahameed };
21144f68ae0SSaeed Mahameed 
21244f68ae0SSaeed Mahameed struct ttc_params {
21344f68ae0SSaeed Mahameed 	struct mlx5_flow_table_attr ft_attr;
21444f68ae0SSaeed Mahameed 	u32 any_tt_tirn;
21544f68ae0SSaeed Mahameed 	u32 indir_tirn[MLX5E_NUM_INDIR_TIRS];
21644f68ae0SSaeed Mahameed 	struct mlx5e_ttc_table *inner_ttc;
21744f68ae0SSaeed Mahameed };
21844f68ae0SSaeed Mahameed 
21944f68ae0SSaeed Mahameed void mlx5e_set_ttc_basic_params(struct mlx5e_priv *priv, struct ttc_params *ttc_params);
22044f68ae0SSaeed Mahameed void mlx5e_set_ttc_ft_params(struct ttc_params *ttc_params);
22144f68ae0SSaeed Mahameed void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params);
22244f68ae0SSaeed Mahameed 
22344f68ae0SSaeed Mahameed int mlx5e_create_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params,
22444f68ae0SSaeed Mahameed 			   struct mlx5e_ttc_table *ttc);
22544f68ae0SSaeed Mahameed void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv,
22644f68ae0SSaeed Mahameed 			     struct mlx5e_ttc_table *ttc);
22744f68ae0SSaeed Mahameed 
22844f68ae0SSaeed Mahameed int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params,
22944f68ae0SSaeed Mahameed 				 struct mlx5e_ttc_table *ttc);
23044f68ae0SSaeed Mahameed void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv,
23144f68ae0SSaeed Mahameed 				   struct mlx5e_ttc_table *ttc);
23244f68ae0SSaeed Mahameed 
23344f68ae0SSaeed Mahameed void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft);
23444f68ae0SSaeed Mahameed 
23544f68ae0SSaeed Mahameed void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv);
23644f68ae0SSaeed Mahameed void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv);
23744f68ae0SSaeed Mahameed 
23844f68ae0SSaeed Mahameed int mlx5e_create_flow_steering(struct mlx5e_priv *priv);
23944f68ae0SSaeed Mahameed void mlx5e_destroy_flow_steering(struct mlx5e_priv *priv);
24044f68ae0SSaeed Mahameed 
241e3a53bc5SMarina Varshaver bool mlx5e_tunnel_proto_supported(struct mlx5_core_dev *mdev, u8 proto_type);
242e3a53bc5SMarina Varshaver bool mlx5e_any_tunnel_proto_supported(struct mlx5_core_dev *mdev);
243e3a53bc5SMarina Varshaver 
244fe6d86b3SSaeed Mahameed #endif /* __MLX5E_FLOW_STEER_H__ */
245fe6d86b3SSaeed Mahameed 
246