xref: /dpdk/drivers/net/i40e/i40e_ethdev.c (revision 4113ddd4)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2017 Intel Corporation
3  */
4 
5 #include <stdio.h>
6 #include <errno.h>
7 #include <stdint.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <stdarg.h>
11 #include <inttypes.h>
12 #include <assert.h>
13 
14 #include <rte_common.h>
15 #include <rte_eal.h>
16 #include <rte_string_fns.h>
17 #include <rte_pci.h>
18 #include <rte_bus_pci.h>
19 #include <rte_ether.h>
20 #include <ethdev_driver.h>
21 #include <ethdev_pci.h>
22 #include <rte_memzone.h>
23 #include <rte_malloc.h>
24 #include <rte_memcpy.h>
25 #include <rte_alarm.h>
26 #include <rte_dev.h>
27 #include <rte_tailq.h>
28 #include <rte_hash_crc.h>
29 #include <rte_bitmap.h>
30 
31 #include "i40e_logs.h"
32 #include "base/i40e_prototype.h"
33 #include "base/i40e_adminq_cmd.h"
34 #include "base/i40e_type.h"
35 #include "base/i40e_register.h"
36 #include "base/i40e_dcb.h"
37 #include "i40e_ethdev.h"
38 #include "i40e_rxtx.h"
39 #include "i40e_pf.h"
40 #include "i40e_regs.h"
41 #include "rte_pmd_i40e.h"
42 #include "i40e_hash.h"
43 
44 #define ETH_I40E_FLOATING_VEB_ARG	"enable_floating_veb"
45 #define ETH_I40E_FLOATING_VEB_LIST_ARG	"floating_veb_list"
46 #define ETH_I40E_SUPPORT_MULTI_DRIVER	"support-multi-driver"
47 #define ETH_I40E_QUEUE_NUM_PER_VF_ARG	"queue-num-per-vf"
48 #define ETH_I40E_VF_MSG_CFG		"vf_msg_cfg"
49 
50 #define I40E_CLEAR_PXE_WAIT_MS     200
51 #define I40E_VSI_TSR_QINQ_STRIP		0x4010
52 #define I40E_VSI_TSR(_i)	(0x00050800 + ((_i) * 4))
53 
54 /* Maximun number of capability elements */
55 #define I40E_MAX_CAP_ELE_NUM       128
56 
57 /* Wait count and interval */
58 #define I40E_CHK_Q_ENA_COUNT       1000
59 #define I40E_CHK_Q_ENA_INTERVAL_US 1000
60 
61 /* Maximun number of VSI */
62 #define I40E_MAX_NUM_VSIS          (384UL)
63 
64 #define I40E_PRE_TX_Q_CFG_WAIT_US       10 /* 10 us */
65 
66 /* Flow control default timer */
67 #define I40E_DEFAULT_PAUSE_TIME 0xFFFFU
68 
69 /* Flow control enable fwd bit */
70 #define I40E_PRTMAC_FWD_CTRL   0x00000001
71 
72 /* Receive Packet Buffer size */
73 #define I40E_RXPBSIZE (968 * 1024)
74 
75 /* Kilobytes shift */
76 #define I40E_KILOSHIFT 10
77 
78 /* Flow control default high water */
79 #define I40E_DEFAULT_HIGH_WATER (0xF2000 >> I40E_KILOSHIFT)
80 
81 /* Flow control default low water */
82 #define I40E_DEFAULT_LOW_WATER  (0xF2000 >> I40E_KILOSHIFT)
83 
84 /* Receive Average Packet Size in Byte*/
85 #define I40E_PACKET_AVERAGE_SIZE 128
86 
87 /* Mask of PF interrupt causes */
88 #define I40E_PFINT_ICR0_ENA_MASK ( \
89 		I40E_PFINT_ICR0_ENA_ECC_ERR_MASK | \
90 		I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK | \
91 		I40E_PFINT_ICR0_ENA_GRST_MASK | \
92 		I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK | \
93 		I40E_PFINT_ICR0_ENA_STORM_DETECT_MASK | \
94 		I40E_PFINT_ICR0_ENA_HMC_ERR_MASK | \
95 		I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK | \
96 		I40E_PFINT_ICR0_ENA_VFLR_MASK | \
97 		I40E_PFINT_ICR0_ENA_ADMINQ_MASK)
98 
99 #define I40E_FLOW_TYPES ( \
100 	(1UL << RTE_ETH_FLOW_FRAG_IPV4) | \
101 	(1UL << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
102 	(1UL << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
103 	(1UL << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
104 	(1UL << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
105 	(1UL << RTE_ETH_FLOW_FRAG_IPV6) | \
106 	(1UL << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
107 	(1UL << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
108 	(1UL << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
109 	(1UL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER) | \
110 	(1UL << RTE_ETH_FLOW_L2_PAYLOAD))
111 
112 /* Additional timesync values. */
113 #define I40E_PTP_40GB_INCVAL     0x0199999999ULL
114 #define I40E_PTP_10GB_INCVAL     0x0333333333ULL
115 #define I40E_PTP_1GB_INCVAL      0x2000000000ULL
116 #define I40E_PRTTSYN_TSYNENA     0x80000000
117 #define I40E_PRTTSYN_TSYNTYPE    0x0e000000
118 #define I40E_CYCLECOUNTER_MASK   0xffffffffffffffffULL
119 
120 /**
121  * Below are values for writing un-exposed registers suggested
122  * by silicon experts
123  */
124 /* Destination MAC address */
125 #define I40E_REG_INSET_L2_DMAC                   0xE000000000000000ULL
126 /* Source MAC address */
127 #define I40E_REG_INSET_L2_SMAC                   0x1C00000000000000ULL
128 /* Outer (S-Tag) VLAN tag in the outer L2 header */
129 #define I40E_REG_INSET_L2_OUTER_VLAN             0x0000000004000000ULL
130 /* Inner (C-Tag) or single VLAN tag in the outer L2 header */
131 #define I40E_REG_INSET_L2_INNER_VLAN             0x0080000000000000ULL
132 /* Single VLAN tag in the inner L2 header */
133 #define I40E_REG_INSET_TUNNEL_VLAN               0x0100000000000000ULL
134 /* Source IPv4 address */
135 #define I40E_REG_INSET_L3_SRC_IP4                0x0001800000000000ULL
136 /* Destination IPv4 address */
137 #define I40E_REG_INSET_L3_DST_IP4                0x0000001800000000ULL
138 /* Source IPv4 address for X722 */
139 #define I40E_X722_REG_INSET_L3_SRC_IP4           0x0006000000000000ULL
140 /* Destination IPv4 address for X722 */
141 #define I40E_X722_REG_INSET_L3_DST_IP4           0x0000060000000000ULL
142 /* IPv4 Protocol for X722 */
143 #define I40E_X722_REG_INSET_L3_IP4_PROTO         0x0010000000000000ULL
144 /* IPv4 Time to Live for X722 */
145 #define I40E_X722_REG_INSET_L3_IP4_TTL           0x0010000000000000ULL
146 /* IPv4 Type of Service (TOS) */
147 #define I40E_REG_INSET_L3_IP4_TOS                0x0040000000000000ULL
148 /* IPv4 Protocol */
149 #define I40E_REG_INSET_L3_IP4_PROTO              0x0004000000000000ULL
150 /* IPv4 Time to Live */
151 #define I40E_REG_INSET_L3_IP4_TTL                0x0004000000000000ULL
152 /* Source IPv6 address */
153 #define I40E_REG_INSET_L3_SRC_IP6                0x0007F80000000000ULL
154 /* Destination IPv6 address */
155 #define I40E_REG_INSET_L3_DST_IP6                0x000007F800000000ULL
156 /* IPv6 Traffic Class (TC) */
157 #define I40E_REG_INSET_L3_IP6_TC                 0x0040000000000000ULL
158 /* IPv6 Next Header */
159 #define I40E_REG_INSET_L3_IP6_NEXT_HDR           0x0008000000000000ULL
160 /* IPv6 Hop Limit */
161 #define I40E_REG_INSET_L3_IP6_HOP_LIMIT          0x0008000000000000ULL
162 /* Source L4 port */
163 #define I40E_REG_INSET_L4_SRC_PORT               0x0000000400000000ULL
164 /* Destination L4 port */
165 #define I40E_REG_INSET_L4_DST_PORT               0x0000000200000000ULL
166 /* SCTP verification tag */
167 #define I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG  0x0000000180000000ULL
168 /* Inner destination MAC address (MAC-in-UDP/MAC-in-GRE)*/
169 #define I40E_REG_INSET_TUNNEL_L2_INNER_DST_MAC   0x0000000001C00000ULL
170 /* Source port of tunneling UDP */
171 #define I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT    0x0000000000200000ULL
172 /* Destination port of tunneling UDP */
173 #define I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT    0x0000000000100000ULL
174 /* UDP Tunneling ID, NVGRE/GRE key */
175 #define I40E_REG_INSET_TUNNEL_ID                 0x00000000000C0000ULL
176 /* Last ether type */
177 #define I40E_REG_INSET_LAST_ETHER_TYPE           0x0000000000004000ULL
178 /* Tunneling outer destination IPv4 address */
179 #define I40E_REG_INSET_TUNNEL_L3_DST_IP4         0x00000000000000C0ULL
180 /* Tunneling outer destination IPv6 address */
181 #define I40E_REG_INSET_TUNNEL_L3_DST_IP6         0x0000000000003FC0ULL
182 /* 1st word of flex payload */
183 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD1        0x0000000000002000ULL
184 /* 2nd word of flex payload */
185 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD2        0x0000000000001000ULL
186 /* 3rd word of flex payload */
187 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD3        0x0000000000000800ULL
188 /* 4th word of flex payload */
189 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD4        0x0000000000000400ULL
190 /* 5th word of flex payload */
191 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD5        0x0000000000000200ULL
192 /* 6th word of flex payload */
193 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD6        0x0000000000000100ULL
194 /* 7th word of flex payload */
195 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7        0x0000000000000080ULL
196 /* 8th word of flex payload */
197 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8        0x0000000000000040ULL
198 /* all 8 words flex payload */
199 #define I40E_REG_INSET_FLEX_PAYLOAD_WORDS        0x0000000000003FC0ULL
200 #define I40E_REG_INSET_MASK_DEFAULT              0x0000000000000000ULL
201 
202 #define I40E_TRANSLATE_INSET 0
203 #define I40E_TRANSLATE_REG   1
204 
205 #define I40E_INSET_IPV4_TOS_MASK        0x0000FF00UL
206 #define I40E_INSET_IPV4_TTL_MASK        0x000000FFUL
207 #define I40E_INSET_IPV4_PROTO_MASK      0x0000FF00UL
208 #define I40E_INSET_IPV6_TC_MASK         0x0000F00FUL
209 #define I40E_INSET_IPV6_HOP_LIMIT_MASK  0x0000FF00UL
210 #define I40E_INSET_IPV6_NEXT_HDR_MASK   0x000000FFUL
211 
212 /* PCI offset for querying capability */
213 #define PCI_DEV_CAP_REG            0xA4
214 /* PCI offset for enabling/disabling Extended Tag */
215 #define PCI_DEV_CTRL_REG           0xA8
216 /* Bit mask of Extended Tag capability */
217 #define PCI_DEV_CAP_EXT_TAG_MASK   0x20
218 /* Bit shift of Extended Tag enable/disable */
219 #define PCI_DEV_CTRL_EXT_TAG_SHIFT 8
220 /* Bit mask of Extended Tag enable/disable */
221 #define PCI_DEV_CTRL_EXT_TAG_MASK  (1 << PCI_DEV_CTRL_EXT_TAG_SHIFT)
222 
223 #define I40E_GLQF_PIT_IPV4_START	2
224 #define I40E_GLQF_PIT_IPV4_COUNT	2
225 #define I40E_GLQF_PIT_IPV6_START	4
226 #define I40E_GLQF_PIT_IPV6_COUNT	2
227 
228 #define I40E_GLQF_PIT_SOURCE_OFF_GET(a)	\
229 				(((a) & I40E_GLQF_PIT_SOURCE_OFF_MASK) >> \
230 				 I40E_GLQF_PIT_SOURCE_OFF_SHIFT)
231 
232 #define I40E_GLQF_PIT_DEST_OFF_GET(a) \
233 				(((a) & I40E_GLQF_PIT_DEST_OFF_MASK) >> \
234 				 I40E_GLQF_PIT_DEST_OFF_SHIFT)
235 
236 #define I40E_GLQF_PIT_FSIZE_GET(a)	(((a) & I40E_GLQF_PIT_FSIZE_MASK) >> \
237 					 I40E_GLQF_PIT_FSIZE_SHIFT)
238 
239 #define I40E_GLQF_PIT_BUILD(off, mask)	(((off) << 16) | (mask))
240 #define I40E_FDIR_FIELD_OFFSET(a)	((a) >> 1)
241 
242 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev, void *init_params);
243 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
244 static int i40e_dev_configure(struct rte_eth_dev *dev);
245 static int i40e_dev_start(struct rte_eth_dev *dev);
246 static int i40e_dev_stop(struct rte_eth_dev *dev);
247 static int i40e_dev_close(struct rte_eth_dev *dev);
248 static int  i40e_dev_reset(struct rte_eth_dev *dev);
249 static int i40e_dev_promiscuous_enable(struct rte_eth_dev *dev);
250 static int i40e_dev_promiscuous_disable(struct rte_eth_dev *dev);
251 static int i40e_dev_allmulticast_enable(struct rte_eth_dev *dev);
252 static int i40e_dev_allmulticast_disable(struct rte_eth_dev *dev);
253 static int i40e_dev_set_link_up(struct rte_eth_dev *dev);
254 static int i40e_dev_set_link_down(struct rte_eth_dev *dev);
255 static int i40e_dev_stats_get(struct rte_eth_dev *dev,
256 			       struct rte_eth_stats *stats);
257 static int i40e_dev_xstats_get(struct rte_eth_dev *dev,
258 			       struct rte_eth_xstat *xstats, unsigned n);
259 static int i40e_dev_xstats_get_names(struct rte_eth_dev *dev,
260 				     struct rte_eth_xstat_name *xstats_names,
261 				     unsigned limit);
262 static int i40e_dev_stats_reset(struct rte_eth_dev *dev);
263 static int i40e_fw_version_get(struct rte_eth_dev *dev,
264 				char *fw_version, size_t fw_size);
265 static int i40e_dev_info_get(struct rte_eth_dev *dev,
266 			     struct rte_eth_dev_info *dev_info);
267 static int i40e_vlan_filter_set(struct rte_eth_dev *dev,
268 				uint16_t vlan_id,
269 				int on);
270 static int i40e_vlan_tpid_set(struct rte_eth_dev *dev,
271 			      enum rte_vlan_type vlan_type,
272 			      uint16_t tpid);
273 static int i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask);
274 static void i40e_vlan_strip_queue_set(struct rte_eth_dev *dev,
275 				      uint16_t queue,
276 				      int on);
277 static int i40e_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on);
278 static int i40e_dev_led_on(struct rte_eth_dev *dev);
279 static int i40e_dev_led_off(struct rte_eth_dev *dev);
280 static int i40e_flow_ctrl_get(struct rte_eth_dev *dev,
281 			      struct rte_eth_fc_conf *fc_conf);
282 static int i40e_flow_ctrl_set(struct rte_eth_dev *dev,
283 			      struct rte_eth_fc_conf *fc_conf);
284 static int i40e_priority_flow_ctrl_set(struct rte_eth_dev *dev,
285 				       struct rte_eth_pfc_conf *pfc_conf);
286 static int i40e_macaddr_add(struct rte_eth_dev *dev,
287 			    struct rte_ether_addr *mac_addr,
288 			    uint32_t index,
289 			    uint32_t pool);
290 static void i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index);
291 static int i40e_dev_rss_reta_update(struct rte_eth_dev *dev,
292 				    struct rte_eth_rss_reta_entry64 *reta_conf,
293 				    uint16_t reta_size);
294 static int i40e_dev_rss_reta_query(struct rte_eth_dev *dev,
295 				   struct rte_eth_rss_reta_entry64 *reta_conf,
296 				   uint16_t reta_size);
297 
298 static int i40e_get_cap(struct i40e_hw *hw);
299 static int i40e_pf_parameter_init(struct rte_eth_dev *dev);
300 static int i40e_pf_setup(struct i40e_pf *pf);
301 static int i40e_dev_rxtx_init(struct i40e_pf *pf);
302 static int i40e_vmdq_setup(struct rte_eth_dev *dev);
303 static int i40e_dcb_setup(struct rte_eth_dev *dev);
304 static void i40e_stat_update_32(struct i40e_hw *hw, uint32_t reg,
305 		bool offset_loaded, uint64_t *offset, uint64_t *stat);
306 static void i40e_stat_update_48(struct i40e_hw *hw,
307 			       uint32_t hireg,
308 			       uint32_t loreg,
309 			       bool offset_loaded,
310 			       uint64_t *offset,
311 			       uint64_t *stat);
312 static void i40e_pf_config_irq0(struct i40e_hw *hw, bool no_queue);
313 static void i40e_dev_interrupt_handler(void *param);
314 static void i40e_dev_alarm_handler(void *param);
315 static int i40e_res_pool_init(struct i40e_res_pool_info *pool,
316 				uint32_t base, uint32_t num);
317 static void i40e_res_pool_destroy(struct i40e_res_pool_info *pool);
318 static int i40e_res_pool_free(struct i40e_res_pool_info *pool,
319 			uint32_t base);
320 static int i40e_res_pool_alloc(struct i40e_res_pool_info *pool,
321 			uint16_t num);
322 static int i40e_dev_init_vlan(struct rte_eth_dev *dev);
323 static int i40e_veb_release(struct i40e_veb *veb);
324 static struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf,
325 						struct i40e_vsi *vsi);
326 static int i40e_vsi_config_double_vlan(struct i40e_vsi *vsi, int on);
327 static inline int i40e_find_all_mac_for_vlan(struct i40e_vsi *vsi,
328 					     struct i40e_macvlan_filter *mv_f,
329 					     int num,
330 					     uint16_t vlan);
331 static int i40e_vsi_remove_all_macvlan_filter(struct i40e_vsi *vsi);
332 static int i40e_dev_rss_hash_update(struct rte_eth_dev *dev,
333 				    struct rte_eth_rss_conf *rss_conf);
334 static int i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
335 				      struct rte_eth_rss_conf *rss_conf);
336 static int i40e_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
337 					struct rte_eth_udp_tunnel *udp_tunnel);
338 static int i40e_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
339 					struct rte_eth_udp_tunnel *udp_tunnel);
340 static void i40e_filter_input_set_init(struct i40e_pf *pf);
341 static int i40e_dev_flow_ops_get(struct rte_eth_dev *dev,
342 				 const struct rte_flow_ops **ops);
343 static int i40e_dev_get_dcb_info(struct rte_eth_dev *dev,
344 				  struct rte_eth_dcb_info *dcb_info);
345 static int i40e_dev_sync_phy_type(struct i40e_hw *hw);
346 static void i40e_configure_registers(struct i40e_hw *hw);
347 static void i40e_hw_init(struct rte_eth_dev *dev);
348 static int i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi);
349 static enum i40e_status_code i40e_aq_del_mirror_rule(struct i40e_hw *hw,
350 						     uint16_t seid,
351 						     uint16_t rule_type,
352 						     uint16_t *entries,
353 						     uint16_t count,
354 						     uint16_t rule_id);
355 static int i40e_mirror_rule_set(struct rte_eth_dev *dev,
356 			struct rte_eth_mirror_conf *mirror_conf,
357 			uint8_t sw_id, uint8_t on);
358 static int i40e_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t sw_id);
359 
360 static int i40e_timesync_enable(struct rte_eth_dev *dev);
361 static int i40e_timesync_disable(struct rte_eth_dev *dev);
362 static int i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
363 					   struct timespec *timestamp,
364 					   uint32_t flags);
365 static int i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
366 					   struct timespec *timestamp);
367 static void i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw);
368 
369 static int i40e_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta);
370 
371 static int i40e_timesync_read_time(struct rte_eth_dev *dev,
372 				   struct timespec *timestamp);
373 static int i40e_timesync_write_time(struct rte_eth_dev *dev,
374 				    const struct timespec *timestamp);
375 
376 static int i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
377 					 uint16_t queue_id);
378 static int i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev,
379 					  uint16_t queue_id);
380 
381 static int i40e_get_regs(struct rte_eth_dev *dev,
382 			 struct rte_dev_reg_info *regs);
383 
384 static int i40e_get_eeprom_length(struct rte_eth_dev *dev);
385 
386 static int i40e_get_eeprom(struct rte_eth_dev *dev,
387 			   struct rte_dev_eeprom_info *eeprom);
388 
389 static int i40e_get_module_info(struct rte_eth_dev *dev,
390 				struct rte_eth_dev_module_info *modinfo);
391 static int i40e_get_module_eeprom(struct rte_eth_dev *dev,
392 				  struct rte_dev_eeprom_info *info);
393 
394 static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
395 				      struct rte_ether_addr *mac_addr);
396 
397 static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
398 
399 static int i40e_ethertype_filter_convert(
400 	const struct rte_eth_ethertype_filter *input,
401 	struct i40e_ethertype_filter *filter);
402 static int i40e_sw_ethertype_filter_insert(struct i40e_pf *pf,
403 				   struct i40e_ethertype_filter *filter);
404 
405 static int i40e_tunnel_filter_convert(
406 	struct i40e_aqc_cloud_filters_element_bb *cld_filter,
407 	struct i40e_tunnel_filter *tunnel_filter);
408 static int i40e_sw_tunnel_filter_insert(struct i40e_pf *pf,
409 				struct i40e_tunnel_filter *tunnel_filter);
410 static int i40e_cloud_filter_qinq_create(struct i40e_pf *pf);
411 
412 static void i40e_ethertype_filter_restore(struct i40e_pf *pf);
413 static void i40e_tunnel_filter_restore(struct i40e_pf *pf);
414 static void i40e_filter_restore(struct i40e_pf *pf);
415 static void i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev);
416 
417 static const char *const valid_keys[] = {
418 	ETH_I40E_FLOATING_VEB_ARG,
419 	ETH_I40E_FLOATING_VEB_LIST_ARG,
420 	ETH_I40E_SUPPORT_MULTI_DRIVER,
421 	ETH_I40E_QUEUE_NUM_PER_VF_ARG,
422 	ETH_I40E_VF_MSG_CFG,
423 	NULL};
424 
425 static const struct rte_pci_id pci_id_i40e_map[] = {
426 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_XL710) },
427 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QEMU) },
428 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_B) },
429 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_C) },
430 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_A) },
431 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_B) },
432 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_C) },
433 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T) },
434 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_20G_KR2) },
435 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_20G_KR2_A) },
436 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T4) },
437 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_25G_B) },
438 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_25G_SFP28) },
439 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X722_A0) },
440 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_X722) },
441 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_X722) },
442 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_X722) },
443 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_1G_BASE_T_X722) },
444 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_X722) },
445 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_I_X722) },
446 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X710_N3000) },
447 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_XXV710_N3000) },
448 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_BC) },
449 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_5G_BASE_T_BC) },
450 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_B) },
451 	{ RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_SFP) },
452 	{ .vendor_id = 0, /* sentinel */ },
453 };
454 
455 static const struct eth_dev_ops i40e_eth_dev_ops = {
456 	.dev_configure                = i40e_dev_configure,
457 	.dev_start                    = i40e_dev_start,
458 	.dev_stop                     = i40e_dev_stop,
459 	.dev_close                    = i40e_dev_close,
460 	.dev_reset		      = i40e_dev_reset,
461 	.promiscuous_enable           = i40e_dev_promiscuous_enable,
462 	.promiscuous_disable          = i40e_dev_promiscuous_disable,
463 	.allmulticast_enable          = i40e_dev_allmulticast_enable,
464 	.allmulticast_disable         = i40e_dev_allmulticast_disable,
465 	.dev_set_link_up              = i40e_dev_set_link_up,
466 	.dev_set_link_down            = i40e_dev_set_link_down,
467 	.link_update                  = i40e_dev_link_update,
468 	.stats_get                    = i40e_dev_stats_get,
469 	.xstats_get                   = i40e_dev_xstats_get,
470 	.xstats_get_names             = i40e_dev_xstats_get_names,
471 	.stats_reset                  = i40e_dev_stats_reset,
472 	.xstats_reset                 = i40e_dev_stats_reset,
473 	.fw_version_get               = i40e_fw_version_get,
474 	.dev_infos_get                = i40e_dev_info_get,
475 	.dev_supported_ptypes_get     = i40e_dev_supported_ptypes_get,
476 	.vlan_filter_set              = i40e_vlan_filter_set,
477 	.vlan_tpid_set                = i40e_vlan_tpid_set,
478 	.vlan_offload_set             = i40e_vlan_offload_set,
479 	.vlan_strip_queue_set         = i40e_vlan_strip_queue_set,
480 	.vlan_pvid_set                = i40e_vlan_pvid_set,
481 	.rx_queue_start               = i40e_dev_rx_queue_start,
482 	.rx_queue_stop                = i40e_dev_rx_queue_stop,
483 	.tx_queue_start               = i40e_dev_tx_queue_start,
484 	.tx_queue_stop                = i40e_dev_tx_queue_stop,
485 	.rx_queue_setup               = i40e_dev_rx_queue_setup,
486 	.rx_queue_intr_enable         = i40e_dev_rx_queue_intr_enable,
487 	.rx_queue_intr_disable        = i40e_dev_rx_queue_intr_disable,
488 	.rx_queue_release             = i40e_dev_rx_queue_release,
489 	.tx_queue_setup               = i40e_dev_tx_queue_setup,
490 	.tx_queue_release             = i40e_dev_tx_queue_release,
491 	.dev_led_on                   = i40e_dev_led_on,
492 	.dev_led_off                  = i40e_dev_led_off,
493 	.flow_ctrl_get                = i40e_flow_ctrl_get,
494 	.flow_ctrl_set                = i40e_flow_ctrl_set,
495 	.priority_flow_ctrl_set       = i40e_priority_flow_ctrl_set,
496 	.mac_addr_add                 = i40e_macaddr_add,
497 	.mac_addr_remove              = i40e_macaddr_remove,
498 	.reta_update                  = i40e_dev_rss_reta_update,
499 	.reta_query                   = i40e_dev_rss_reta_query,
500 	.rss_hash_update              = i40e_dev_rss_hash_update,
501 	.rss_hash_conf_get            = i40e_dev_rss_hash_conf_get,
502 	.udp_tunnel_port_add          = i40e_dev_udp_tunnel_port_add,
503 	.udp_tunnel_port_del          = i40e_dev_udp_tunnel_port_del,
504 	.flow_ops_get                 = i40e_dev_flow_ops_get,
505 	.rxq_info_get                 = i40e_rxq_info_get,
506 	.txq_info_get                 = i40e_txq_info_get,
507 	.rx_burst_mode_get            = i40e_rx_burst_mode_get,
508 	.tx_burst_mode_get            = i40e_tx_burst_mode_get,
509 	.mirror_rule_set              = i40e_mirror_rule_set,
510 	.mirror_rule_reset            = i40e_mirror_rule_reset,
511 	.timesync_enable              = i40e_timesync_enable,
512 	.timesync_disable             = i40e_timesync_disable,
513 	.timesync_read_rx_timestamp   = i40e_timesync_read_rx_timestamp,
514 	.timesync_read_tx_timestamp   = i40e_timesync_read_tx_timestamp,
515 	.get_dcb_info                 = i40e_dev_get_dcb_info,
516 	.timesync_adjust_time         = i40e_timesync_adjust_time,
517 	.timesync_read_time           = i40e_timesync_read_time,
518 	.timesync_write_time          = i40e_timesync_write_time,
519 	.get_reg                      = i40e_get_regs,
520 	.get_eeprom_length            = i40e_get_eeprom_length,
521 	.get_eeprom                   = i40e_get_eeprom,
522 	.get_module_info              = i40e_get_module_info,
523 	.get_module_eeprom            = i40e_get_module_eeprom,
524 	.mac_addr_set                 = i40e_set_default_mac_addr,
525 	.mtu_set                      = i40e_dev_mtu_set,
526 	.tm_ops_get                   = i40e_tm_ops_get,
527 	.tx_done_cleanup              = i40e_tx_done_cleanup,
528 	.get_monitor_addr             = i40e_get_monitor_addr,
529 };
530 
531 /* store statistics names and its offset in stats structure */
532 struct rte_i40e_xstats_name_off {
533 	char name[RTE_ETH_XSTATS_NAME_SIZE];
534 	unsigned offset;
535 };
536 
537 static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = {
538 	{"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
539 	{"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
540 	{"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
541 	{"rx_dropped_packets", offsetof(struct i40e_eth_stats, rx_discards)},
542 	{"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
543 		rx_unknown_protocol)},
544 	{"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_unicast)},
545 	{"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_multicast)},
546 	{"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_broadcast)},
547 	{"tx_dropped_packets", offsetof(struct i40e_eth_stats, tx_discards)},
548 };
549 
550 #define I40E_NB_ETH_XSTATS (sizeof(rte_i40e_stats_strings) / \
551 		sizeof(rte_i40e_stats_strings[0]))
552 
553 static const struct rte_i40e_xstats_name_off rte_i40e_hw_port_strings[] = {
554 	{"tx_link_down_dropped", offsetof(struct i40e_hw_port_stats,
555 		tx_dropped_link_down)},
556 	{"rx_crc_errors", offsetof(struct i40e_hw_port_stats, crc_errors)},
557 	{"rx_illegal_byte_errors", offsetof(struct i40e_hw_port_stats,
558 		illegal_bytes)},
559 	{"rx_error_bytes", offsetof(struct i40e_hw_port_stats, error_bytes)},
560 	{"mac_local_errors", offsetof(struct i40e_hw_port_stats,
561 		mac_local_faults)},
562 	{"mac_remote_errors", offsetof(struct i40e_hw_port_stats,
563 		mac_remote_faults)},
564 	{"rx_length_errors", offsetof(struct i40e_hw_port_stats,
565 		rx_length_errors)},
566 	{"tx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_tx)},
567 	{"rx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_rx)},
568 	{"tx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_tx)},
569 	{"rx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_rx)},
570 	{"rx_size_64_packets", offsetof(struct i40e_hw_port_stats, rx_size_64)},
571 	{"rx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
572 		rx_size_127)},
573 	{"rx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
574 		rx_size_255)},
575 	{"rx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
576 		rx_size_511)},
577 	{"rx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
578 		rx_size_1023)},
579 	{"rx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
580 		rx_size_1522)},
581 	{"rx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
582 		rx_size_big)},
583 	{"rx_undersized_errors", offsetof(struct i40e_hw_port_stats,
584 		rx_undersize)},
585 	{"rx_oversize_errors", offsetof(struct i40e_hw_port_stats,
586 		rx_oversize)},
587 	{"rx_mac_short_dropped", offsetof(struct i40e_hw_port_stats,
588 		mac_short_packet_dropped)},
589 	{"rx_fragmented_errors", offsetof(struct i40e_hw_port_stats,
590 		rx_fragments)},
591 	{"rx_jabber_errors", offsetof(struct i40e_hw_port_stats, rx_jabber)},
592 	{"tx_size_64_packets", offsetof(struct i40e_hw_port_stats, tx_size_64)},
593 	{"tx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
594 		tx_size_127)},
595 	{"tx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
596 		tx_size_255)},
597 	{"tx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
598 		tx_size_511)},
599 	{"tx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
600 		tx_size_1023)},
601 	{"tx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
602 		tx_size_1522)},
603 	{"tx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
604 		tx_size_big)},
605 	{"rx_flow_director_atr_match_packets",
606 		offsetof(struct i40e_hw_port_stats, fd_atr_match)},
607 	{"rx_flow_director_sb_match_packets",
608 		offsetof(struct i40e_hw_port_stats, fd_sb_match)},
609 	{"tx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
610 		tx_lpi_status)},
611 	{"rx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
612 		rx_lpi_status)},
613 	{"tx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
614 		tx_lpi_count)},
615 	{"rx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
616 		rx_lpi_count)},
617 };
618 
619 #define I40E_NB_HW_PORT_XSTATS (sizeof(rte_i40e_hw_port_strings) / \
620 		sizeof(rte_i40e_hw_port_strings[0]))
621 
622 static const struct rte_i40e_xstats_name_off rte_i40e_rxq_prio_strings[] = {
623 	{"xon_packets", offsetof(struct i40e_hw_port_stats,
624 		priority_xon_rx)},
625 	{"xoff_packets", offsetof(struct i40e_hw_port_stats,
626 		priority_xoff_rx)},
627 };
628 
629 #define I40E_NB_RXQ_PRIO_XSTATS (sizeof(rte_i40e_rxq_prio_strings) / \
630 		sizeof(rte_i40e_rxq_prio_strings[0]))
631 
632 static const struct rte_i40e_xstats_name_off rte_i40e_txq_prio_strings[] = {
633 	{"xon_packets", offsetof(struct i40e_hw_port_stats,
634 		priority_xon_tx)},
635 	{"xoff_packets", offsetof(struct i40e_hw_port_stats,
636 		priority_xoff_tx)},
637 	{"xon_to_xoff_packets", offsetof(struct i40e_hw_port_stats,
638 		priority_xon_2_xoff)},
639 };
640 
641 #define I40E_NB_TXQ_PRIO_XSTATS (sizeof(rte_i40e_txq_prio_strings) / \
642 		sizeof(rte_i40e_txq_prio_strings[0]))
643 
644 static int
645 eth_i40e_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
646 	struct rte_pci_device *pci_dev)
647 {
648 	char name[RTE_ETH_NAME_MAX_LEN];
649 	struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 };
650 	int i, retval;
651 
652 	if (pci_dev->device.devargs) {
653 		retval = rte_eth_devargs_parse(pci_dev->device.devargs->args,
654 				&eth_da);
655 		if (retval)
656 			return retval;
657 	}
658 
659 	if (eth_da.nb_representor_ports > 0 &&
660 	    eth_da.type != RTE_ETH_REPRESENTOR_VF) {
661 		PMD_DRV_LOG(ERR, "unsupported representor type: %s\n",
662 			    pci_dev->device.devargs->args);
663 		return -ENOTSUP;
664 	}
665 
666 	retval = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
667 		sizeof(struct i40e_adapter),
668 		eth_dev_pci_specific_init, pci_dev,
669 		eth_i40e_dev_init, NULL);
670 
671 	if (retval || eth_da.nb_representor_ports < 1)
672 		return retval;
673 
674 	/* probe VF representor ports */
675 	struct rte_eth_dev *pf_ethdev = rte_eth_dev_allocated(
676 		pci_dev->device.name);
677 
678 	if (pf_ethdev == NULL)
679 		return -ENODEV;
680 
681 	for (i = 0; i < eth_da.nb_representor_ports; i++) {
682 		struct i40e_vf_representor representor = {
683 			.vf_id = eth_da.representor_ports[i],
684 			.switch_domain_id = I40E_DEV_PRIVATE_TO_PF(
685 				pf_ethdev->data->dev_private)->switch_domain_id,
686 			.adapter = I40E_DEV_PRIVATE_TO_ADAPTER(
687 				pf_ethdev->data->dev_private)
688 		};
689 
690 		/* representor port net_bdf_port */
691 		snprintf(name, sizeof(name), "net_%s_representor_%d",
692 			pci_dev->device.name, eth_da.representor_ports[i]);
693 
694 		retval = rte_eth_dev_create(&pci_dev->device, name,
695 			sizeof(struct i40e_vf_representor), NULL, NULL,
696 			i40e_vf_representor_init, &representor);
697 
698 		if (retval)
699 			PMD_DRV_LOG(ERR, "failed to create i40e vf "
700 				"representor %s.", name);
701 	}
702 
703 	return 0;
704 }
705 
706 static int eth_i40e_pci_remove(struct rte_pci_device *pci_dev)
707 {
708 	struct rte_eth_dev *ethdev;
709 
710 	ethdev = rte_eth_dev_allocated(pci_dev->device.name);
711 	if (!ethdev)
712 		return 0;
713 
714 	if (ethdev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)
715 		return rte_eth_dev_pci_generic_remove(pci_dev,
716 					i40e_vf_representor_uninit);
717 	else
718 		return rte_eth_dev_pci_generic_remove(pci_dev,
719 						eth_i40e_dev_uninit);
720 }
721 
722 static struct rte_pci_driver rte_i40e_pmd = {
723 	.id_table = pci_id_i40e_map,
724 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
725 	.probe = eth_i40e_pci_probe,
726 	.remove = eth_i40e_pci_remove,
727 };
728 
729 static inline void
730 i40e_write_global_rx_ctl(struct i40e_hw *hw, uint32_t reg_addr,
731 			 uint32_t reg_val)
732 {
733 	uint32_t ori_reg_val;
734 	struct rte_eth_dev *dev;
735 
736 	ori_reg_val = i40e_read_rx_ctl(hw, reg_addr);
737 	dev = ((struct i40e_adapter *)hw->back)->eth_dev;
738 	i40e_write_rx_ctl(hw, reg_addr, reg_val);
739 	if (ori_reg_val != reg_val)
740 		PMD_DRV_LOG(WARNING,
741 			    "i40e device %s changed global register [0x%08x]."
742 			    " original: 0x%08x, new: 0x%08x",
743 			    dev->device->name, reg_addr, ori_reg_val, reg_val);
744 }
745 
746 RTE_PMD_REGISTER_PCI(net_i40e, rte_i40e_pmd);
747 RTE_PMD_REGISTER_PCI_TABLE(net_i40e, pci_id_i40e_map);
748 RTE_PMD_REGISTER_KMOD_DEP(net_i40e, "* igb_uio | uio_pci_generic | vfio-pci");
749 
750 #ifndef I40E_GLQF_ORT
751 #define I40E_GLQF_ORT(_i)    (0x00268900 + ((_i) * 4))
752 #endif
753 #ifndef I40E_GLQF_PIT
754 #define I40E_GLQF_PIT(_i)    (0x00268C80 + ((_i) * 4))
755 #endif
756 #ifndef I40E_GLQF_L3_MAP
757 #define I40E_GLQF_L3_MAP(_i) (0x0026C700 + ((_i) * 4))
758 #endif
759 
760 static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
761 {
762 	/*
763 	 * Initialize registers for parsing packet type of QinQ
764 	 * This should be removed from code once proper
765 	 * configuration API is added to avoid configuration conflicts
766 	 * between ports of the same device.
767 	 */
768 	I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(40), 0x00000029);
769 	I40E_WRITE_GLB_REG(hw, I40E_GLQF_PIT(9), 0x00009420);
770 }
771 
772 static inline void i40e_config_automask(struct i40e_pf *pf)
773 {
774 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
775 	uint32_t val;
776 
777 	/* INTENA flag is not auto-cleared for interrupt */
778 	val = I40E_READ_REG(hw, I40E_GLINT_CTL);
779 	val |= I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK |
780 		I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK;
781 
782 	/* If support multi-driver, PF will use INT0. */
783 	if (!pf->support_multi_driver)
784 		val |= I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK;
785 
786 	I40E_WRITE_REG(hw, I40E_GLINT_CTL, val);
787 }
788 
789 static inline void i40e_clear_automask(struct i40e_pf *pf)
790 {
791 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
792 	uint32_t val;
793 
794 	val = I40E_READ_REG(hw, I40E_GLINT_CTL);
795 	val &= ~(I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK |
796 		 I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK);
797 
798 	if (!pf->support_multi_driver)
799 		val &= ~I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK;
800 
801 	I40E_WRITE_REG(hw, I40E_GLINT_CTL, val);
802 }
803 
804 #define I40E_FLOW_CONTROL_ETHERTYPE  0x8808
805 
806 /*
807  * Add a ethertype filter to drop all flow control frames transmitted
808  * from VSIs.
809 */
810 static void
811 i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
812 {
813 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
814 	uint16_t flags = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
815 			I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
816 			I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
817 	int ret;
818 
819 	ret = i40e_aq_add_rem_control_packet_filter(hw, NULL,
820 				I40E_FLOW_CONTROL_ETHERTYPE, flags,
821 				pf->main_vsi_seid, 0,
822 				TRUE, NULL, NULL);
823 	if (ret)
824 		PMD_INIT_LOG(ERR,
825 			"Failed to add filter to drop flow control frames from VSIs.");
826 }
827 
828 static int
829 floating_veb_list_handler(__rte_unused const char *key,
830 			  const char *floating_veb_value,
831 			  void *opaque)
832 {
833 	int idx = 0;
834 	unsigned int count = 0;
835 	char *end = NULL;
836 	int min, max;
837 	bool *vf_floating_veb = opaque;
838 
839 	while (isblank(*floating_veb_value))
840 		floating_veb_value++;
841 
842 	/* Reset floating VEB configuration for VFs */
843 	for (idx = 0; idx < I40E_MAX_VF; idx++)
844 		vf_floating_veb[idx] = false;
845 
846 	min = I40E_MAX_VF;
847 	do {
848 		while (isblank(*floating_veb_value))
849 			floating_veb_value++;
850 		if (*floating_veb_value == '\0')
851 			return -1;
852 		errno = 0;
853 		idx = strtoul(floating_veb_value, &end, 10);
854 		if (errno || end == NULL)
855 			return -1;
856 		while (isblank(*end))
857 			end++;
858 		if (*end == '-') {
859 			min = idx;
860 		} else if ((*end == ';') || (*end == '\0')) {
861 			max = idx;
862 			if (min == I40E_MAX_VF)
863 				min = idx;
864 			if (max >= I40E_MAX_VF)
865 				max = I40E_MAX_VF - 1;
866 			for (idx = min; idx <= max; idx++) {
867 				vf_floating_veb[idx] = true;
868 				count++;
869 			}
870 			min = I40E_MAX_VF;
871 		} else {
872 			return -1;
873 		}
874 		floating_veb_value = end + 1;
875 	} while (*end != '\0');
876 
877 	if (count == 0)
878 		return -1;
879 
880 	return 0;
881 }
882 
883 static void
884 config_vf_floating_veb(struct rte_devargs *devargs,
885 		       uint16_t floating_veb,
886 		       bool *vf_floating_veb)
887 {
888 	struct rte_kvargs *kvlist;
889 	int i;
890 	const char *floating_veb_list = ETH_I40E_FLOATING_VEB_LIST_ARG;
891 
892 	if (!floating_veb)
893 		return;
894 	/* All the VFs attach to the floating VEB by default
895 	 * when the floating VEB is enabled.
896 	 */
897 	for (i = 0; i < I40E_MAX_VF; i++)
898 		vf_floating_veb[i] = true;
899 
900 	if (devargs == NULL)
901 		return;
902 
903 	kvlist = rte_kvargs_parse(devargs->args, valid_keys);
904 	if (kvlist == NULL)
905 		return;
906 
907 	if (!rte_kvargs_count(kvlist, floating_veb_list)) {
908 		rte_kvargs_free(kvlist);
909 		return;
910 	}
911 	/* When the floating_veb_list parameter exists, all the VFs
912 	 * will attach to the legacy VEB firstly, then configure VFs
913 	 * to the floating VEB according to the floating_veb_list.
914 	 */
915 	if (rte_kvargs_process(kvlist, floating_veb_list,
916 			       floating_veb_list_handler,
917 			       vf_floating_veb) < 0) {
918 		rte_kvargs_free(kvlist);
919 		return;
920 	}
921 	rte_kvargs_free(kvlist);
922 }
923 
924 static int
925 i40e_check_floating_handler(__rte_unused const char *key,
926 			    const char *value,
927 			    __rte_unused void *opaque)
928 {
929 	if (strcmp(value, "1"))
930 		return -1;
931 
932 	return 0;
933 }
934 
935 static int
936 is_floating_veb_supported(struct rte_devargs *devargs)
937 {
938 	struct rte_kvargs *kvlist;
939 	const char *floating_veb_key = ETH_I40E_FLOATING_VEB_ARG;
940 
941 	if (devargs == NULL)
942 		return 0;
943 
944 	kvlist = rte_kvargs_parse(devargs->args, valid_keys);
945 	if (kvlist == NULL)
946 		return 0;
947 
948 	if (!rte_kvargs_count(kvlist, floating_veb_key)) {
949 		rte_kvargs_free(kvlist);
950 		return 0;
951 	}
952 	/* Floating VEB is enabled when there's key-value:
953 	 * enable_floating_veb=1
954 	 */
955 	if (rte_kvargs_process(kvlist, floating_veb_key,
956 			       i40e_check_floating_handler, NULL) < 0) {
957 		rte_kvargs_free(kvlist);
958 		return 0;
959 	}
960 	rte_kvargs_free(kvlist);
961 
962 	return 1;
963 }
964 
965 static void
966 config_floating_veb(struct rte_eth_dev *dev)
967 {
968 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
969 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
970 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
971 
972 	memset(pf->floating_veb_list, 0, sizeof(pf->floating_veb_list));
973 
974 	if (hw->aq.fw_maj_ver >= FLOATING_VEB_SUPPORTED_FW_MAJ) {
975 		pf->floating_veb =
976 			is_floating_veb_supported(pci_dev->device.devargs);
977 		config_vf_floating_veb(pci_dev->device.devargs,
978 				       pf->floating_veb,
979 				       pf->floating_veb_list);
980 	} else {
981 		pf->floating_veb = false;
982 	}
983 }
984 
985 #define I40E_L2_TAGS_S_TAG_SHIFT 1
986 #define I40E_L2_TAGS_S_TAG_MASK I40E_MASK(0x1, I40E_L2_TAGS_S_TAG_SHIFT)
987 
988 static int
989 i40e_init_ethtype_filter_list(struct rte_eth_dev *dev)
990 {
991 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
992 	struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
993 	char ethertype_hash_name[RTE_HASH_NAMESIZE];
994 	int ret;
995 
996 	struct rte_hash_parameters ethertype_hash_params = {
997 		.name = ethertype_hash_name,
998 		.entries = I40E_MAX_ETHERTYPE_FILTER_NUM,
999 		.key_len = sizeof(struct i40e_ethertype_filter_input),
1000 		.hash_func = rte_hash_crc,
1001 		.hash_func_init_val = 0,
1002 		.socket_id = rte_socket_id(),
1003 	};
1004 
1005 	/* Initialize ethertype filter rule list and hash */
1006 	TAILQ_INIT(&ethertype_rule->ethertype_list);
1007 	snprintf(ethertype_hash_name, RTE_HASH_NAMESIZE,
1008 		 "ethertype_%s", dev->device->name);
1009 	ethertype_rule->hash_table = rte_hash_create(&ethertype_hash_params);
1010 	if (!ethertype_rule->hash_table) {
1011 		PMD_INIT_LOG(ERR, "Failed to create ethertype hash table!");
1012 		return -EINVAL;
1013 	}
1014 	ethertype_rule->hash_map = rte_zmalloc("i40e_ethertype_hash_map",
1015 				       sizeof(struct i40e_ethertype_filter *) *
1016 				       I40E_MAX_ETHERTYPE_FILTER_NUM,
1017 				       0);
1018 	if (!ethertype_rule->hash_map) {
1019 		PMD_INIT_LOG(ERR,
1020 			     "Failed to allocate memory for ethertype hash map!");
1021 		ret = -ENOMEM;
1022 		goto err_ethertype_hash_map_alloc;
1023 	}
1024 
1025 	return 0;
1026 
1027 err_ethertype_hash_map_alloc:
1028 	rte_hash_free(ethertype_rule->hash_table);
1029 
1030 	return ret;
1031 }
1032 
1033 static int
1034 i40e_init_tunnel_filter_list(struct rte_eth_dev *dev)
1035 {
1036 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1037 	struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
1038 	char tunnel_hash_name[RTE_HASH_NAMESIZE];
1039 	int ret;
1040 
1041 	struct rte_hash_parameters tunnel_hash_params = {
1042 		.name = tunnel_hash_name,
1043 		.entries = I40E_MAX_TUNNEL_FILTER_NUM,
1044 		.key_len = sizeof(struct i40e_tunnel_filter_input),
1045 		.hash_func = rte_hash_crc,
1046 		.hash_func_init_val = 0,
1047 		.socket_id = rte_socket_id(),
1048 	};
1049 
1050 	/* Initialize tunnel filter rule list and hash */
1051 	TAILQ_INIT(&tunnel_rule->tunnel_list);
1052 	snprintf(tunnel_hash_name, RTE_HASH_NAMESIZE,
1053 		 "tunnel_%s", dev->device->name);
1054 	tunnel_rule->hash_table = rte_hash_create(&tunnel_hash_params);
1055 	if (!tunnel_rule->hash_table) {
1056 		PMD_INIT_LOG(ERR, "Failed to create tunnel hash table!");
1057 		return -EINVAL;
1058 	}
1059 	tunnel_rule->hash_map = rte_zmalloc("i40e_tunnel_hash_map",
1060 				    sizeof(struct i40e_tunnel_filter *) *
1061 				    I40E_MAX_TUNNEL_FILTER_NUM,
1062 				    0);
1063 	if (!tunnel_rule->hash_map) {
1064 		PMD_INIT_LOG(ERR,
1065 			     "Failed to allocate memory for tunnel hash map!");
1066 		ret = -ENOMEM;
1067 		goto err_tunnel_hash_map_alloc;
1068 	}
1069 
1070 	return 0;
1071 
1072 err_tunnel_hash_map_alloc:
1073 	rte_hash_free(tunnel_rule->hash_table);
1074 
1075 	return ret;
1076 }
1077 
1078 static int
1079 i40e_init_fdir_filter_list(struct rte_eth_dev *dev)
1080 {
1081 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1082 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
1083 	struct i40e_fdir_info *fdir_info = &pf->fdir;
1084 	char fdir_hash_name[RTE_HASH_NAMESIZE];
1085 	uint32_t alloc = hw->func_caps.fd_filters_guaranteed;
1086 	uint32_t best = hw->func_caps.fd_filters_best_effort;
1087 	struct rte_bitmap *bmp = NULL;
1088 	uint32_t bmp_size;
1089 	void *mem = NULL;
1090 	uint32_t i = 0;
1091 	int ret;
1092 
1093 	struct rte_hash_parameters fdir_hash_params = {
1094 		.name = fdir_hash_name,
1095 		.entries = I40E_MAX_FDIR_FILTER_NUM,
1096 		.key_len = sizeof(struct i40e_fdir_input),
1097 		.hash_func = rte_hash_crc,
1098 		.hash_func_init_val = 0,
1099 		.socket_id = rte_socket_id(),
1100 	};
1101 
1102 	/* Initialize flow director filter rule list and hash */
1103 	TAILQ_INIT(&fdir_info->fdir_list);
1104 	snprintf(fdir_hash_name, RTE_HASH_NAMESIZE,
1105 		 "fdir_%s", dev->device->name);
1106 	fdir_info->hash_table = rte_hash_create(&fdir_hash_params);
1107 	if (!fdir_info->hash_table) {
1108 		PMD_INIT_LOG(ERR, "Failed to create fdir hash table!");
1109 		return -EINVAL;
1110 	}
1111 
1112 	fdir_info->hash_map = rte_zmalloc("i40e_fdir_hash_map",
1113 					  sizeof(struct i40e_fdir_filter *) *
1114 					  I40E_MAX_FDIR_FILTER_NUM,
1115 					  0);
1116 	if (!fdir_info->hash_map) {
1117 		PMD_INIT_LOG(ERR,
1118 			     "Failed to allocate memory for fdir hash map!");
1119 		ret = -ENOMEM;
1120 		goto err_fdir_hash_map_alloc;
1121 	}
1122 
1123 	fdir_info->fdir_filter_array = rte_zmalloc("fdir_filter",
1124 			sizeof(struct i40e_fdir_filter) *
1125 			I40E_MAX_FDIR_FILTER_NUM,
1126 			0);
1127 
1128 	if (!fdir_info->fdir_filter_array) {
1129 		PMD_INIT_LOG(ERR,
1130 			     "Failed to allocate memory for fdir filter array!");
1131 		ret = -ENOMEM;
1132 		goto err_fdir_filter_array_alloc;
1133 	}
1134 
1135 	fdir_info->fdir_space_size = alloc + best;
1136 	fdir_info->fdir_actual_cnt = 0;
1137 	fdir_info->fdir_guarantee_total_space = alloc;
1138 	fdir_info->fdir_guarantee_free_space =
1139 		fdir_info->fdir_guarantee_total_space;
1140 
1141 	PMD_DRV_LOG(INFO, "FDIR guarantee space: %u, best_effort space %u.", alloc, best);
1142 
1143 	fdir_info->fdir_flow_pool.pool =
1144 			rte_zmalloc("i40e_fdir_entry",
1145 				sizeof(struct i40e_fdir_entry) *
1146 				fdir_info->fdir_space_size,
1147 				0);
1148 
1149 	if (!fdir_info->fdir_flow_pool.pool) {
1150 		PMD_INIT_LOG(ERR,
1151 			     "Failed to allocate memory for bitmap flow!");
1152 		ret = -ENOMEM;
1153 		goto err_fdir_bitmap_flow_alloc;
1154 	}
1155 
1156 	for (i = 0; i < fdir_info->fdir_space_size; i++)
1157 		fdir_info->fdir_flow_pool.pool[i].idx = i;
1158 
1159 	bmp_size =
1160 		rte_bitmap_get_memory_footprint(fdir_info->fdir_space_size);
1161 	mem = rte_zmalloc("fdir_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
1162 	if (mem == NULL) {
1163 		PMD_INIT_LOG(ERR,
1164 			     "Failed to allocate memory for fdir bitmap!");
1165 		ret = -ENOMEM;
1166 		goto err_fdir_mem_alloc;
1167 	}
1168 	bmp = rte_bitmap_init(fdir_info->fdir_space_size, mem, bmp_size);
1169 	if (bmp == NULL) {
1170 		PMD_INIT_LOG(ERR,
1171 			     "Failed to initialization fdir bitmap!");
1172 		ret = -ENOMEM;
1173 		goto err_fdir_bmp_alloc;
1174 	}
1175 	for (i = 0; i < fdir_info->fdir_space_size; i++)
1176 		rte_bitmap_set(bmp, i);
1177 
1178 	fdir_info->fdir_flow_pool.bitmap = bmp;
1179 
1180 	return 0;
1181 
1182 err_fdir_bmp_alloc:
1183 	rte_free(mem);
1184 err_fdir_mem_alloc:
1185 	rte_free(fdir_info->fdir_flow_pool.pool);
1186 err_fdir_bitmap_flow_alloc:
1187 	rte_free(fdir_info->fdir_filter_array);
1188 err_fdir_filter_array_alloc:
1189 	rte_free(fdir_info->hash_map);
1190 err_fdir_hash_map_alloc:
1191 	rte_hash_free(fdir_info->hash_table);
1192 
1193 	return ret;
1194 }
1195 
1196 static void
1197 i40e_init_customized_info(struct i40e_pf *pf)
1198 {
1199 	int i;
1200 
1201 	/* Initialize customized pctype */
1202 	for (i = I40E_CUSTOMIZED_GTPC; i < I40E_CUSTOMIZED_MAX; i++) {
1203 		pf->customized_pctype[i].index = i;
1204 		pf->customized_pctype[i].pctype = I40E_FILTER_PCTYPE_INVALID;
1205 		pf->customized_pctype[i].valid = false;
1206 	}
1207 
1208 	pf->gtp_support = false;
1209 	pf->esp_support = false;
1210 }
1211 
1212 static void
1213 i40e_init_filter_invalidation(struct i40e_pf *pf)
1214 {
1215 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
1216 	struct i40e_fdir_info *fdir_info = &pf->fdir;
1217 	uint32_t glqf_ctl_reg = 0;
1218 
1219 	glqf_ctl_reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL);
1220 	if (!pf->support_multi_driver) {
1221 		fdir_info->fdir_invalprio = 1;
1222 		glqf_ctl_reg |= I40E_GLQF_CTL_INVALPRIO_MASK;
1223 		PMD_DRV_LOG(INFO, "FDIR INVALPRIO set to guaranteed first");
1224 		i40e_write_rx_ctl(hw, I40E_GLQF_CTL, glqf_ctl_reg);
1225 	} else {
1226 		if (glqf_ctl_reg & I40E_GLQF_CTL_INVALPRIO_MASK) {
1227 			fdir_info->fdir_invalprio = 1;
1228 			PMD_DRV_LOG(INFO, "FDIR INVALPRIO is: guaranteed first");
1229 		} else {
1230 			fdir_info->fdir_invalprio = 0;
1231 			PMD_DRV_LOG(INFO, "FDIR INVALPRIO is: shared first");
1232 		}
1233 	}
1234 }
1235 
1236 void
1237 i40e_init_queue_region_conf(struct rte_eth_dev *dev)
1238 {
1239 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1240 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1241 	struct i40e_queue_regions *info = &pf->queue_region;
1242 	uint16_t i;
1243 
1244 	for (i = 0; i < I40E_PFQF_HREGION_MAX_INDEX; i++)
1245 		i40e_write_rx_ctl(hw, I40E_PFQF_HREGION(i), 0);
1246 
1247 	memset(info, 0, sizeof(struct i40e_queue_regions));
1248 }
1249 
1250 static int
1251 i40e_parse_multi_drv_handler(__rte_unused const char *key,
1252 			       const char *value,
1253 			       void *opaque)
1254 {
1255 	struct i40e_pf *pf;
1256 	unsigned long support_multi_driver;
1257 	char *end;
1258 
1259 	pf = (struct i40e_pf *)opaque;
1260 
1261 	errno = 0;
1262 	support_multi_driver = strtoul(value, &end, 10);
1263 	if (errno != 0 || end == value || *end != 0) {
1264 		PMD_DRV_LOG(WARNING, "Wrong global configuration");
1265 		return -(EINVAL);
1266 	}
1267 
1268 	if (support_multi_driver == 1 || support_multi_driver == 0)
1269 		pf->support_multi_driver = (bool)support_multi_driver;
1270 	else
1271 		PMD_DRV_LOG(WARNING, "%s must be 1 or 0,",
1272 			    "enable global configuration by default."
1273 			    ETH_I40E_SUPPORT_MULTI_DRIVER);
1274 	return 0;
1275 }
1276 
1277 static int
1278 i40e_support_multi_driver(struct rte_eth_dev *dev)
1279 {
1280 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1281 	struct rte_kvargs *kvlist;
1282 	int kvargs_count;
1283 
1284 	/* Enable global configuration by default */
1285 	pf->support_multi_driver = false;
1286 
1287 	if (!dev->device->devargs)
1288 		return 0;
1289 
1290 	kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);
1291 	if (!kvlist)
1292 		return -EINVAL;
1293 
1294 	kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER);
1295 	if (!kvargs_count) {
1296 		rte_kvargs_free(kvlist);
1297 		return 0;
1298 	}
1299 
1300 	if (kvargs_count > 1)
1301 		PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
1302 			    "the first invalid or last valid one is used !",
1303 			    ETH_I40E_SUPPORT_MULTI_DRIVER);
1304 
1305 	if (rte_kvargs_process(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER,
1306 			       i40e_parse_multi_drv_handler, pf) < 0) {
1307 		rte_kvargs_free(kvlist);
1308 		return -EINVAL;
1309 	}
1310 
1311 	rte_kvargs_free(kvlist);
1312 	return 0;
1313 }
1314 
1315 static int
1316 i40e_aq_debug_write_global_register(struct i40e_hw *hw,
1317 				    uint32_t reg_addr, uint64_t reg_val,
1318 				    struct i40e_asq_cmd_details *cmd_details)
1319 {
1320 	uint64_t ori_reg_val;
1321 	struct rte_eth_dev *dev;
1322 	int ret;
1323 
1324 	ret = i40e_aq_debug_read_register(hw, reg_addr, &ori_reg_val, NULL);
1325 	if (ret != I40E_SUCCESS) {
1326 		PMD_DRV_LOG(ERR,
1327 			    "Fail to debug read from 0x%08x",
1328 			    reg_addr);
1329 		return -EIO;
1330 	}
1331 	dev = ((struct i40e_adapter *)hw->back)->eth_dev;
1332 
1333 	if (ori_reg_val != reg_val)
1334 		PMD_DRV_LOG(WARNING,
1335 			    "i40e device %s changed global register [0x%08x]."
1336 			    " original: 0x%"PRIx64", after: 0x%"PRIx64,
1337 			    dev->device->name, reg_addr, ori_reg_val, reg_val);
1338 
1339 	return i40e_aq_debug_write_register(hw, reg_addr, reg_val, cmd_details);
1340 }
1341 
1342 static int
1343 read_vf_msg_config(__rte_unused const char *key,
1344 			       const char *value,
1345 			       void *opaque)
1346 {
1347 	struct i40e_vf_msg_cfg *cfg = opaque;
1348 
1349 	if (sscanf(value, "%u@%u:%u", &cfg->max_msg, &cfg->period,
1350 			&cfg->ignore_second) != 3) {
1351 		memset(cfg, 0, sizeof(*cfg));
1352 		PMD_DRV_LOG(ERR, "format error! example: "
1353 				"%s=60@120:180", ETH_I40E_VF_MSG_CFG);
1354 		return -EINVAL;
1355 	}
1356 
1357 	/*
1358 	 * If the message validation function been enabled, the 'period'
1359 	 * and 'ignore_second' must greater than 0.
1360 	 */
1361 	if (cfg->max_msg && (!cfg->period || !cfg->ignore_second)) {
1362 		memset(cfg, 0, sizeof(*cfg));
1363 		PMD_DRV_LOG(ERR, "%s error! the second and third"
1364 				" number must be greater than 0!",
1365 				ETH_I40E_VF_MSG_CFG);
1366 		return -EINVAL;
1367 	}
1368 
1369 	return 0;
1370 }
1371 
1372 static int
1373 i40e_parse_vf_msg_config(struct rte_eth_dev *dev,
1374 		struct i40e_vf_msg_cfg *msg_cfg)
1375 {
1376 	struct rte_kvargs *kvlist;
1377 	int kvargs_count;
1378 	int ret = 0;
1379 
1380 	memset(msg_cfg, 0, sizeof(*msg_cfg));
1381 
1382 	if (!dev->device->devargs)
1383 		return ret;
1384 
1385 	kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);
1386 	if (!kvlist)
1387 		return -EINVAL;
1388 
1389 	kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_VF_MSG_CFG);
1390 	if (!kvargs_count)
1391 		goto free_end;
1392 
1393 	if (kvargs_count > 1) {
1394 		PMD_DRV_LOG(ERR, "More than one argument \"%s\"!",
1395 				ETH_I40E_VF_MSG_CFG);
1396 		ret = -EINVAL;
1397 		goto free_end;
1398 	}
1399 
1400 	if (rte_kvargs_process(kvlist, ETH_I40E_VF_MSG_CFG,
1401 			read_vf_msg_config, msg_cfg) < 0)
1402 		ret = -EINVAL;
1403 
1404 free_end:
1405 	rte_kvargs_free(kvlist);
1406 	return ret;
1407 }
1408 
1409 #define I40E_ALARM_INTERVAL 50000 /* us */
1410 
1411 static int
1412 eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
1413 {
1414 	struct rte_pci_device *pci_dev;
1415 	struct rte_intr_handle *intr_handle;
1416 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1417 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1418 	struct i40e_vsi *vsi;
1419 	int ret;
1420 	uint32_t len, val;
1421 	uint8_t aq_fail = 0;
1422 
1423 	PMD_INIT_FUNC_TRACE();
1424 
1425 	dev->dev_ops = &i40e_eth_dev_ops;
1426 	dev->rx_queue_count = i40e_dev_rx_queue_count;
1427 	dev->rx_descriptor_done = i40e_dev_rx_descriptor_done;
1428 	dev->rx_descriptor_status = i40e_dev_rx_descriptor_status;
1429 	dev->tx_descriptor_status = i40e_dev_tx_descriptor_status;
1430 	dev->rx_pkt_burst = i40e_recv_pkts;
1431 	dev->tx_pkt_burst = i40e_xmit_pkts;
1432 	dev->tx_pkt_prepare = i40e_prep_pkts;
1433 
1434 	/* for secondary processes, we don't initialise any further as primary
1435 	 * has already done this work. Only check we don't need a different
1436 	 * RX function */
1437 	if (rte_eal_process_type() != RTE_PROC_PRIMARY){
1438 		i40e_set_rx_function(dev);
1439 		i40e_set_tx_function(dev);
1440 		return 0;
1441 	}
1442 	i40e_set_default_ptype_table(dev);
1443 	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1444 	intr_handle = &pci_dev->intr_handle;
1445 
1446 	rte_eth_copy_pci_info(dev, pci_dev);
1447 	dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
1448 
1449 	pf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1450 	pf->adapter->eth_dev = dev;
1451 	pf->dev_data = dev->data;
1452 
1453 	hw->back = I40E_PF_TO_ADAPTER(pf);
1454 	hw->hw_addr = (uint8_t *)(pci_dev->mem_resource[0].addr);
1455 	if (!hw->hw_addr) {
1456 		PMD_INIT_LOG(ERR,
1457 			"Hardware is not available, as address is NULL");
1458 		return -ENODEV;
1459 	}
1460 
1461 	hw->vendor_id = pci_dev->id.vendor_id;
1462 	hw->device_id = pci_dev->id.device_id;
1463 	hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
1464 	hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
1465 	hw->bus.device = pci_dev->addr.devid;
1466 	hw->bus.func = pci_dev->addr.function;
1467 	hw->adapter_stopped = 0;
1468 	hw->adapter_closed = 0;
1469 
1470 	/* Init switch device pointer */
1471 	hw->switch_dev = NULL;
1472 
1473 	/*
1474 	 * Switch Tag value should not be identical to either the First Tag
1475 	 * or Second Tag values. So set something other than common Ethertype
1476 	 * for internal switching.
1477 	 */
1478 	hw->switch_tag = 0xffff;
1479 
1480 	val = I40E_READ_REG(hw, I40E_GL_FWSTS);
1481 	if (val & I40E_GL_FWSTS_FWS1B_MASK) {
1482 		PMD_INIT_LOG(ERR, "\nERROR: "
1483 			"Firmware recovery mode detected. Limiting functionality.\n"
1484 			"Refer to the Intel(R) Ethernet Adapters and Devices "
1485 			"User Guide for details on firmware recovery mode.");
1486 		return -EIO;
1487 	}
1488 
1489 	i40e_parse_vf_msg_config(dev, &pf->vf_msg_cfg);
1490 	/* Check if need to support multi-driver */
1491 	i40e_support_multi_driver(dev);
1492 
1493 	/* Make sure all is clean before doing PF reset */
1494 	i40e_clear_hw(hw);
1495 
1496 	/* Reset here to make sure all is clean for each PF */
1497 	ret = i40e_pf_reset(hw);
1498 	if (ret) {
1499 		PMD_INIT_LOG(ERR, "Failed to reset pf: %d", ret);
1500 		return ret;
1501 	}
1502 
1503 	/* Initialize the shared code (base driver) */
1504 	ret = i40e_init_shared_code(hw);
1505 	if (ret) {
1506 		PMD_INIT_LOG(ERR, "Failed to init shared code (base driver): %d", ret);
1507 		return ret;
1508 	}
1509 
1510 	/* Initialize the parameters for adminq */
1511 	i40e_init_adminq_parameter(hw);
1512 	ret = i40e_init_adminq(hw);
1513 	if (ret != I40E_SUCCESS) {
1514 		PMD_INIT_LOG(ERR, "Failed to init adminq: %d", ret);
1515 		return -EIO;
1516 	}
1517 	/* Firmware of SFP x722 does not support 802.1ad frames ability */
1518 	if (hw->device_id == I40E_DEV_ID_SFP_X722 ||
1519 		hw->device_id == I40E_DEV_ID_SFP_I_X722)
1520 		hw->flags &= ~I40E_HW_FLAG_802_1AD_CAPABLE;
1521 
1522 	PMD_INIT_LOG(INFO, "FW %d.%d API %d.%d NVM %02d.%02d.%02d eetrack %04x",
1523 		     hw->aq.fw_maj_ver, hw->aq.fw_min_ver,
1524 		     hw->aq.api_maj_ver, hw->aq.api_min_ver,
1525 		     ((hw->nvm.version >> 12) & 0xf),
1526 		     ((hw->nvm.version >> 4) & 0xff),
1527 		     (hw->nvm.version & 0xf), hw->nvm.eetrack);
1528 
1529 	/* Initialize the hardware */
1530 	i40e_hw_init(dev);
1531 
1532 	i40e_config_automask(pf);
1533 
1534 	i40e_set_default_pctype_table(dev);
1535 
1536 	/*
1537 	 * To work around the NVM issue, initialize registers
1538 	 * for packet type of QinQ by software.
1539 	 * It should be removed once issues are fixed in NVM.
1540 	 */
1541 	if (!pf->support_multi_driver)
1542 		i40e_GLQF_reg_init(hw);
1543 
1544 	/* Initialize the input set for filters (hash and fd) to default value */
1545 	i40e_filter_input_set_init(pf);
1546 
1547 	/* initialise the L3_MAP register */
1548 	if (!pf->support_multi_driver) {
1549 		ret = i40e_aq_debug_write_global_register(hw,
1550 						   I40E_GLQF_L3_MAP(40),
1551 						   0x00000028,	NULL);
1552 		if (ret)
1553 			PMD_INIT_LOG(ERR, "Failed to write L3 MAP register %d",
1554 				     ret);
1555 		PMD_INIT_LOG(DEBUG,
1556 			     "Global register 0x%08x is changed with 0x28",
1557 			     I40E_GLQF_L3_MAP(40));
1558 	}
1559 
1560 	/* Need the special FW version to support floating VEB */
1561 	config_floating_veb(dev);
1562 	/* Clear PXE mode */
1563 	i40e_clear_pxe_mode(hw);
1564 	i40e_dev_sync_phy_type(hw);
1565 
1566 	/*
1567 	 * On X710, performance number is far from the expectation on recent
1568 	 * firmware versions. The fix for this issue may not be integrated in
1569 	 * the following firmware version. So the workaround in software driver
1570 	 * is needed. It needs to modify the initial values of 3 internal only
1571 	 * registers. Note that the workaround can be removed when it is fixed
1572 	 * in firmware in the future.
1573 	 */
1574 	i40e_configure_registers(hw);
1575 
1576 	/* Get hw capabilities */
1577 	ret = i40e_get_cap(hw);
1578 	if (ret != I40E_SUCCESS) {
1579 		PMD_INIT_LOG(ERR, "Failed to get capabilities: %d", ret);
1580 		goto err_get_capabilities;
1581 	}
1582 
1583 	/* Initialize parameters for PF */
1584 	ret = i40e_pf_parameter_init(dev);
1585 	if (ret != 0) {
1586 		PMD_INIT_LOG(ERR, "Failed to do parameter init: %d", ret);
1587 		goto err_parameter_init;
1588 	}
1589 
1590 	/* Initialize the queue management */
1591 	ret = i40e_res_pool_init(&pf->qp_pool, 0, hw->func_caps.num_tx_qp);
1592 	if (ret < 0) {
1593 		PMD_INIT_LOG(ERR, "Failed to init queue pool");
1594 		goto err_qp_pool_init;
1595 	}
1596 	ret = i40e_res_pool_init(&pf->msix_pool, 1,
1597 				hw->func_caps.num_msix_vectors - 1);
1598 	if (ret < 0) {
1599 		PMD_INIT_LOG(ERR, "Failed to init MSIX pool");
1600 		goto err_msix_pool_init;
1601 	}
1602 
1603 	/* Initialize lan hmc */
1604 	ret = i40e_init_lan_hmc(hw, hw->func_caps.num_tx_qp,
1605 				hw->func_caps.num_rx_qp, 0, 0);
1606 	if (ret != I40E_SUCCESS) {
1607 		PMD_INIT_LOG(ERR, "Failed to init lan hmc: %d", ret);
1608 		goto err_init_lan_hmc;
1609 	}
1610 
1611 	/* Configure lan hmc */
1612 	ret = i40e_configure_lan_hmc(hw, I40E_HMC_MODEL_DIRECT_ONLY);
1613 	if (ret != I40E_SUCCESS) {
1614 		PMD_INIT_LOG(ERR, "Failed to configure lan hmc: %d", ret);
1615 		goto err_configure_lan_hmc;
1616 	}
1617 
1618 	/* Get and check the mac address */
1619 	i40e_get_mac_addr(hw, hw->mac.addr);
1620 	if (i40e_validate_mac_addr(hw->mac.addr) != I40E_SUCCESS) {
1621 		PMD_INIT_LOG(ERR, "mac address is not valid");
1622 		ret = -EIO;
1623 		goto err_get_mac_addr;
1624 	}
1625 	/* Copy the permanent MAC address */
1626 	rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.addr,
1627 			(struct rte_ether_addr *)hw->mac.perm_addr);
1628 
1629 	/* Disable flow control */
1630 	hw->fc.requested_mode = I40E_FC_NONE;
1631 	i40e_set_fc(hw, &aq_fail, TRUE);
1632 
1633 	/* Set the global registers with default ether type value */
1634 	if (!pf->support_multi_driver) {
1635 		ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER,
1636 					 RTE_ETHER_TYPE_VLAN);
1637 		if (ret != I40E_SUCCESS) {
1638 			PMD_INIT_LOG(ERR,
1639 				     "Failed to set the default outer "
1640 				     "VLAN ether type");
1641 			goto err_setup_pf_switch;
1642 		}
1643 	}
1644 
1645 	/* PF setup, which includes VSI setup */
1646 	ret = i40e_pf_setup(pf);
1647 	if (ret) {
1648 		PMD_INIT_LOG(ERR, "Failed to setup pf switch: %d", ret);
1649 		goto err_setup_pf_switch;
1650 	}
1651 
1652 	vsi = pf->main_vsi;
1653 
1654 	/* Disable double vlan by default */
1655 	i40e_vsi_config_double_vlan(vsi, FALSE);
1656 
1657 	/* Disable S-TAG identification when floating_veb is disabled */
1658 	if (!pf->floating_veb) {
1659 		ret = I40E_READ_REG(hw, I40E_PRT_L2TAGSEN);
1660 		if (ret & I40E_L2_TAGS_S_TAG_MASK) {
1661 			ret &= ~I40E_L2_TAGS_S_TAG_MASK;
1662 			I40E_WRITE_REG(hw, I40E_PRT_L2TAGSEN, ret);
1663 		}
1664 	}
1665 
1666 	if (!vsi->max_macaddrs)
1667 		len = RTE_ETHER_ADDR_LEN;
1668 	else
1669 		len = RTE_ETHER_ADDR_LEN * vsi->max_macaddrs;
1670 
1671 	/* Should be after VSI initialized */
1672 	dev->data->mac_addrs = rte_zmalloc("i40e", len, 0);
1673 	if (!dev->data->mac_addrs) {
1674 		PMD_INIT_LOG(ERR,
1675 			"Failed to allocated memory for storing mac address");
1676 		goto err_mac_alloc;
1677 	}
1678 	rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.perm_addr,
1679 					&dev->data->mac_addrs[0]);
1680 
1681 	/* Init dcb to sw mode by default */
1682 	ret = i40e_dcb_init_configure(dev, TRUE);
1683 	if (ret != I40E_SUCCESS) {
1684 		PMD_INIT_LOG(INFO, "Failed to init dcb.");
1685 		pf->flags &= ~I40E_FLAG_DCB;
1686 	}
1687 	/* Update HW struct after DCB configuration */
1688 	i40e_get_cap(hw);
1689 
1690 	/* initialize pf host driver to setup SRIOV resource if applicable */
1691 	i40e_pf_host_init(dev);
1692 
1693 	/* register callback func to eal lib */
1694 	rte_intr_callback_register(intr_handle,
1695 				   i40e_dev_interrupt_handler, dev);
1696 
1697 	/* configure and enable device interrupt */
1698 	i40e_pf_config_irq0(hw, TRUE);
1699 	i40e_pf_enable_irq0(hw);
1700 
1701 	/* enable uio intr after callback register */
1702 	rte_intr_enable(intr_handle);
1703 
1704 	/* By default disable flexible payload in global configuration */
1705 	if (!pf->support_multi_driver)
1706 		i40e_flex_payload_reg_set_default(hw);
1707 
1708 	/*
1709 	 * Add an ethertype filter to drop all flow control frames transmitted
1710 	 * from VSIs. By doing so, we stop VF from sending out PAUSE or PFC
1711 	 * frames to wire.
1712 	 */
1713 	i40e_add_tx_flow_control_drop_filter(pf);
1714 
1715 	/* Set the max frame size to 0x2600 by default,
1716 	 * in case other drivers changed the default value.
1717 	 */
1718 	i40e_aq_set_mac_config(hw, I40E_FRAME_SIZE_MAX, TRUE, false, 0, NULL);
1719 
1720 	/* initialize mirror rule list */
1721 	TAILQ_INIT(&pf->mirror_list);
1722 
1723 	/* initialize RSS rule list */
1724 	TAILQ_INIT(&pf->rss_config_list);
1725 
1726 	/* initialize Traffic Manager configuration */
1727 	i40e_tm_conf_init(dev);
1728 
1729 	/* Initialize customized information */
1730 	i40e_init_customized_info(pf);
1731 
1732 	/* Initialize the filter invalidation configuration */
1733 	i40e_init_filter_invalidation(pf);
1734 
1735 	ret = i40e_init_ethtype_filter_list(dev);
1736 	if (ret < 0)
1737 		goto err_init_ethtype_filter_list;
1738 	ret = i40e_init_tunnel_filter_list(dev);
1739 	if (ret < 0)
1740 		goto err_init_tunnel_filter_list;
1741 	ret = i40e_init_fdir_filter_list(dev);
1742 	if (ret < 0)
1743 		goto err_init_fdir_filter_list;
1744 
1745 	/* initialize queue region configuration */
1746 	i40e_init_queue_region_conf(dev);
1747 
1748 	/* reset all stats of the device, including pf and main vsi */
1749 	i40e_dev_stats_reset(dev);
1750 
1751 	return 0;
1752 
1753 err_init_fdir_filter_list:
1754 	rte_free(pf->tunnel.hash_table);
1755 	rte_free(pf->tunnel.hash_map);
1756 err_init_tunnel_filter_list:
1757 	rte_free(pf->ethertype.hash_table);
1758 	rte_free(pf->ethertype.hash_map);
1759 err_init_ethtype_filter_list:
1760 	rte_free(dev->data->mac_addrs);
1761 	dev->data->mac_addrs = NULL;
1762 err_mac_alloc:
1763 	i40e_vsi_release(pf->main_vsi);
1764 err_setup_pf_switch:
1765 err_get_mac_addr:
1766 err_configure_lan_hmc:
1767 	(void)i40e_shutdown_lan_hmc(hw);
1768 err_init_lan_hmc:
1769 	i40e_res_pool_destroy(&pf->msix_pool);
1770 err_msix_pool_init:
1771 	i40e_res_pool_destroy(&pf->qp_pool);
1772 err_qp_pool_init:
1773 err_parameter_init:
1774 err_get_capabilities:
1775 	(void)i40e_shutdown_adminq(hw);
1776 
1777 	return ret;
1778 }
1779 
1780 static void
1781 i40e_rm_ethtype_filter_list(struct i40e_pf *pf)
1782 {
1783 	struct i40e_ethertype_filter *p_ethertype;
1784 	struct i40e_ethertype_rule *ethertype_rule;
1785 
1786 	ethertype_rule = &pf->ethertype;
1787 	/* Remove all ethertype filter rules and hash */
1788 	if (ethertype_rule->hash_map)
1789 		rte_free(ethertype_rule->hash_map);
1790 	if (ethertype_rule->hash_table)
1791 		rte_hash_free(ethertype_rule->hash_table);
1792 
1793 	while ((p_ethertype = TAILQ_FIRST(&ethertype_rule->ethertype_list))) {
1794 		TAILQ_REMOVE(&ethertype_rule->ethertype_list,
1795 			     p_ethertype, rules);
1796 		rte_free(p_ethertype);
1797 	}
1798 }
1799 
1800 static void
1801 i40e_rm_tunnel_filter_list(struct i40e_pf *pf)
1802 {
1803 	struct i40e_tunnel_filter *p_tunnel;
1804 	struct i40e_tunnel_rule *tunnel_rule;
1805 
1806 	tunnel_rule = &pf->tunnel;
1807 	/* Remove all tunnel director rules and hash */
1808 	if (tunnel_rule->hash_map)
1809 		rte_free(tunnel_rule->hash_map);
1810 	if (tunnel_rule->hash_table)
1811 		rte_hash_free(tunnel_rule->hash_table);
1812 
1813 	while ((p_tunnel = TAILQ_FIRST(&tunnel_rule->tunnel_list))) {
1814 		TAILQ_REMOVE(&tunnel_rule->tunnel_list, p_tunnel, rules);
1815 		rte_free(p_tunnel);
1816 	}
1817 }
1818 
1819 static void
1820 i40e_rm_fdir_filter_list(struct i40e_pf *pf)
1821 {
1822 	struct i40e_fdir_filter *p_fdir;
1823 	struct i40e_fdir_info *fdir_info;
1824 
1825 	fdir_info = &pf->fdir;
1826 
1827 	/* Remove all flow director rules */
1828 	while ((p_fdir = TAILQ_FIRST(&fdir_info->fdir_list)))
1829 		TAILQ_REMOVE(&fdir_info->fdir_list, p_fdir, rules);
1830 }
1831 
1832 static void
1833 i40e_fdir_memory_cleanup(struct i40e_pf *pf)
1834 {
1835 	struct i40e_fdir_info *fdir_info;
1836 
1837 	fdir_info = &pf->fdir;
1838 
1839 	/* flow director memory cleanup */
1840 	if (fdir_info->hash_map)
1841 		rte_free(fdir_info->hash_map);
1842 	if (fdir_info->hash_table)
1843 		rte_hash_free(fdir_info->hash_table);
1844 	if (fdir_info->fdir_flow_pool.bitmap)
1845 		rte_free(fdir_info->fdir_flow_pool.bitmap);
1846 	if (fdir_info->fdir_flow_pool.pool)
1847 		rte_free(fdir_info->fdir_flow_pool.pool);
1848 	if (fdir_info->fdir_filter_array)
1849 		rte_free(fdir_info->fdir_filter_array);
1850 }
1851 
1852 void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
1853 {
1854 	/*
1855 	 * Disable by default flexible payload
1856 	 * for corresponding L2/L3/L4 layers.
1857 	 */
1858 	I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33), 0x00000000);
1859 	I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(34), 0x00000000);
1860 	I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(35), 0x00000000);
1861 }
1862 
1863 static int
1864 eth_i40e_dev_uninit(struct rte_eth_dev *dev)
1865 {
1866 	struct i40e_hw *hw;
1867 
1868 	PMD_INIT_FUNC_TRACE();
1869 
1870 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1871 		return 0;
1872 
1873 	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1874 
1875 	if (hw->adapter_closed == 0)
1876 		i40e_dev_close(dev);
1877 
1878 	return 0;
1879 }
1880 
1881 static int
1882 i40e_dev_configure(struct rte_eth_dev *dev)
1883 {
1884 	struct i40e_adapter *ad =
1885 		I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
1886 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1887 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1888 	enum rte_eth_rx_mq_mode mq_mode = dev->data->dev_conf.rxmode.mq_mode;
1889 	int i, ret;
1890 
1891 	ret = i40e_dev_sync_phy_type(hw);
1892 	if (ret)
1893 		return ret;
1894 
1895 	/* Initialize to TRUE. If any of Rx queues doesn't meet the
1896 	 * bulk allocation or vector Rx preconditions we will reset it.
1897 	 */
1898 	ad->rx_bulk_alloc_allowed = true;
1899 	ad->rx_vec_allowed = true;
1900 	ad->tx_simple_allowed = true;
1901 	ad->tx_vec_allowed = true;
1902 
1903 	if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
1904 		dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH;
1905 
1906 	/* Only legacy filter API needs the following fdir config. So when the
1907 	 * legacy filter API is deprecated, the following codes should also be
1908 	 * removed.
1909 	 */
1910 	if (dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_PERFECT) {
1911 		ret = i40e_fdir_setup(pf);
1912 		if (ret != I40E_SUCCESS) {
1913 			PMD_DRV_LOG(ERR, "Failed to setup flow director.");
1914 			return -ENOTSUP;
1915 		}
1916 		ret = i40e_fdir_configure(dev);
1917 		if (ret < 0) {
1918 			PMD_DRV_LOG(ERR, "failed to configure fdir.");
1919 			goto err;
1920 		}
1921 	} else
1922 		i40e_fdir_teardown(pf);
1923 
1924 	ret = i40e_dev_init_vlan(dev);
1925 	if (ret < 0)
1926 		goto err;
1927 
1928 	/* VMDQ setup.
1929 	 *  General PMD driver call sequence are NIC init, configure,
1930 	 *  rx/tx_queue_setup and dev_start. In rx/tx_queue_setup() function, it
1931 	 *  will try to lookup the VSI that specific queue belongs to if VMDQ
1932 	 *  applicable. So, VMDQ setting has to be done before
1933 	 *  rx/tx_queue_setup(). This function is good  to place vmdq_setup.
1934 	 *  For RSS setting, it will try to calculate actual configured RX queue
1935 	 *  number, which will be available after rx_queue_setup(). dev_start()
1936 	 *  function is good to place RSS setup.
1937 	 */
1938 	if (mq_mode & ETH_MQ_RX_VMDQ_FLAG) {
1939 		ret = i40e_vmdq_setup(dev);
1940 		if (ret)
1941 			goto err;
1942 	}
1943 
1944 	if (mq_mode & ETH_MQ_RX_DCB_FLAG) {
1945 		ret = i40e_dcb_setup(dev);
1946 		if (ret) {
1947 			PMD_DRV_LOG(ERR, "failed to configure DCB.");
1948 			goto err_dcb;
1949 		}
1950 	}
1951 
1952 	TAILQ_INIT(&pf->flow_list);
1953 
1954 	return 0;
1955 
1956 err_dcb:
1957 	/* need to release vmdq resource if exists */
1958 	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
1959 		i40e_vsi_release(pf->vmdq[i].vsi);
1960 		pf->vmdq[i].vsi = NULL;
1961 	}
1962 	rte_free(pf->vmdq);
1963 	pf->vmdq = NULL;
1964 err:
1965 	/* Need to release fdir resource if exists.
1966 	 * Only legacy filter API needs the following fdir config. So when the
1967 	 * legacy filter API is deprecated, the following code should also be
1968 	 * removed.
1969 	 */
1970 	i40e_fdir_teardown(pf);
1971 	return ret;
1972 }
1973 
1974 void
1975 i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi)
1976 {
1977 	struct rte_eth_dev *dev = vsi->adapter->eth_dev;
1978 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1979 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
1980 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
1981 	uint16_t msix_vect = vsi->msix_intr;
1982 	uint16_t i;
1983 
1984 	for (i = 0; i < vsi->nb_qps; i++) {
1985 		I40E_WRITE_REG(hw, I40E_QINT_TQCTL(vsi->base_queue + i), 0);
1986 		I40E_WRITE_REG(hw, I40E_QINT_RQCTL(vsi->base_queue + i), 0);
1987 		rte_wmb();
1988 	}
1989 
1990 	if (vsi->type != I40E_VSI_SRIOV) {
1991 		if (!rte_intr_allow_others(intr_handle)) {
1992 			I40E_WRITE_REG(hw, I40E_PFINT_LNKLST0,
1993 				       I40E_PFINT_LNKLST0_FIRSTQ_INDX_MASK);
1994 			I40E_WRITE_REG(hw,
1995 				       I40E_PFINT_ITR0(I40E_ITR_INDEX_DEFAULT),
1996 				       0);
1997 		} else {
1998 			I40E_WRITE_REG(hw, I40E_PFINT_LNKLSTN(msix_vect - 1),
1999 				       I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK);
2000 			I40E_WRITE_REG(hw,
2001 				       I40E_PFINT_ITRN(I40E_ITR_INDEX_DEFAULT,
2002 						       msix_vect - 1), 0);
2003 		}
2004 	} else {
2005 		uint32_t reg;
2006 		reg = (hw->func_caps.num_msix_vectors_vf - 1) *
2007 			vsi->user_param + (msix_vect - 1);
2008 
2009 		I40E_WRITE_REG(hw, I40E_VPINT_LNKLSTN(reg),
2010 			       I40E_VPINT_LNKLSTN_FIRSTQ_INDX_MASK);
2011 	}
2012 	I40E_WRITE_FLUSH(hw);
2013 }
2014 
2015 static void
2016 __vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t msix_vect,
2017 		       int base_queue, int nb_queue,
2018 		       uint16_t itr_idx)
2019 {
2020 	int i;
2021 	uint32_t val;
2022 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
2023 	struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
2024 
2025 	/* Bind all RX queues to allocated MSIX interrupt */
2026 	for (i = 0; i < nb_queue; i++) {
2027 		val = (msix_vect << I40E_QINT_RQCTL_MSIX_INDX_SHIFT) |
2028 			itr_idx << I40E_QINT_RQCTL_ITR_INDX_SHIFT |
2029 			((base_queue + i + 1) <<
2030 			 I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT) |
2031 			(0 << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT) |
2032 			I40E_QINT_RQCTL_CAUSE_ENA_MASK;
2033 
2034 		if (i == nb_queue - 1)
2035 			val |= I40E_QINT_RQCTL_NEXTQ_INDX_MASK;
2036 		I40E_WRITE_REG(hw, I40E_QINT_RQCTL(base_queue + i), val);
2037 	}
2038 
2039 	/* Write first RX queue to Link list register as the head element */
2040 	if (vsi->type != I40E_VSI_SRIOV) {
2041 		uint16_t interval =
2042 			i40e_calc_itr_interval(1, pf->support_multi_driver);
2043 
2044 		if (msix_vect == I40E_MISC_VEC_ID) {
2045 			I40E_WRITE_REG(hw, I40E_PFINT_LNKLST0,
2046 				       (base_queue <<
2047 					I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT) |
2048 				       (0x0 <<
2049 					I40E_PFINT_LNKLST0_FIRSTQ_TYPE_SHIFT));
2050 			I40E_WRITE_REG(hw,
2051 				       I40E_PFINT_ITR0(I40E_ITR_INDEX_DEFAULT),
2052 				       interval);
2053 		} else {
2054 			I40E_WRITE_REG(hw, I40E_PFINT_LNKLSTN(msix_vect - 1),
2055 				       (base_queue <<
2056 					I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT) |
2057 				       (0x0 <<
2058 					I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT));
2059 			I40E_WRITE_REG(hw,
2060 				       I40E_PFINT_ITRN(I40E_ITR_INDEX_DEFAULT,
2061 						       msix_vect - 1),
2062 				       interval);
2063 		}
2064 	} else {
2065 		uint32_t reg;
2066 
2067 		if (msix_vect == I40E_MISC_VEC_ID) {
2068 			I40E_WRITE_REG(hw,
2069 				       I40E_VPINT_LNKLST0(vsi->user_param),
2070 				       (base_queue <<
2071 					I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT) |
2072 				       (0x0 <<
2073 					I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT));
2074 		} else {
2075 			/* num_msix_vectors_vf needs to minus irq0 */
2076 			reg = (hw->func_caps.num_msix_vectors_vf - 1) *
2077 				vsi->user_param + (msix_vect - 1);
2078 
2079 			I40E_WRITE_REG(hw, I40E_VPINT_LNKLSTN(reg),
2080 				       (base_queue <<
2081 					I40E_VPINT_LNKLSTN_FIRSTQ_INDX_SHIFT) |
2082 				       (0x0 <<
2083 					I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT));
2084 		}
2085 	}
2086 
2087 	I40E_WRITE_FLUSH(hw);
2088 }
2089 
2090 int
2091 i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx)
2092 {
2093 	struct rte_eth_dev *dev = vsi->adapter->eth_dev;
2094 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
2095 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
2096 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
2097 	uint16_t msix_vect = vsi->msix_intr;
2098 	uint16_t nb_msix = RTE_MIN(vsi->nb_msix, intr_handle->nb_efd);
2099 	uint16_t queue_idx = 0;
2100 	int record = 0;
2101 	int i;
2102 
2103 	for (i = 0; i < vsi->nb_qps; i++) {
2104 		I40E_WRITE_REG(hw, I40E_QINT_TQCTL(vsi->base_queue + i), 0);
2105 		I40E_WRITE_REG(hw, I40E_QINT_RQCTL(vsi->base_queue + i), 0);
2106 	}
2107 
2108 	/* VF bind interrupt */
2109 	if (vsi->type == I40E_VSI_SRIOV) {
2110 		if (vsi->nb_msix == 0) {
2111 			PMD_DRV_LOG(ERR, "No msix resource");
2112 			return -EINVAL;
2113 		}
2114 		__vsi_queues_bind_intr(vsi, msix_vect,
2115 				       vsi->base_queue, vsi->nb_qps,
2116 				       itr_idx);
2117 		return 0;
2118 	}
2119 
2120 	/* PF & VMDq bind interrupt */
2121 	if (rte_intr_dp_is_en(intr_handle)) {
2122 		if (vsi->type == I40E_VSI_MAIN) {
2123 			queue_idx = 0;
2124 			record = 1;
2125 		} else if (vsi->type == I40E_VSI_VMDQ2) {
2126 			struct i40e_vsi *main_vsi =
2127 				I40E_DEV_PRIVATE_TO_MAIN_VSI(vsi->adapter);
2128 			queue_idx = vsi->base_queue - main_vsi->nb_qps;
2129 			record = 1;
2130 		}
2131 	}
2132 
2133 	for (i = 0; i < vsi->nb_used_qps; i++) {
2134 		if (vsi->nb_msix == 0) {
2135 			PMD_DRV_LOG(ERR, "No msix resource");
2136 			return -EINVAL;
2137 		} else if (nb_msix <= 1) {
2138 			if (!rte_intr_allow_others(intr_handle))
2139 				/* allow to share MISC_VEC_ID */
2140 				msix_vect = I40E_MISC_VEC_ID;
2141 
2142 			/* no enough msix_vect, map all to one */
2143 			__vsi_queues_bind_intr(vsi, msix_vect,
2144 					       vsi->base_queue + i,
2145 					       vsi->nb_used_qps - i,
2146 					       itr_idx);
2147 			for (; !!record && i < vsi->nb_used_qps; i++)
2148 				intr_handle->intr_vec[queue_idx + i] =
2149 					msix_vect;
2150 			break;
2151 		}
2152 		/* 1:1 queue/msix_vect mapping */
2153 		__vsi_queues_bind_intr(vsi, msix_vect,
2154 				       vsi->base_queue + i, 1,
2155 				       itr_idx);
2156 		if (!!record)
2157 			intr_handle->intr_vec[queue_idx + i] = msix_vect;
2158 
2159 		msix_vect++;
2160 		nb_msix--;
2161 	}
2162 
2163 	return 0;
2164 }
2165 
2166 void
2167 i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi)
2168 {
2169 	struct rte_eth_dev *dev = vsi->adapter->eth_dev;
2170 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
2171 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
2172 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
2173 	struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
2174 	uint16_t msix_intr, i;
2175 
2176 	if (rte_intr_allow_others(intr_handle) && !pf->support_multi_driver)
2177 		for (i = 0; i < vsi->nb_msix; i++) {
2178 			msix_intr = vsi->msix_intr + i;
2179 			I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTLN(msix_intr - 1),
2180 				I40E_PFINT_DYN_CTLN_INTENA_MASK |
2181 				I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
2182 				I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
2183 		}
2184 	else
2185 		I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
2186 			       I40E_PFINT_DYN_CTL0_INTENA_MASK |
2187 			       I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
2188 			       I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
2189 
2190 	I40E_WRITE_FLUSH(hw);
2191 }
2192 
2193 void
2194 i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
2195 {
2196 	struct rte_eth_dev *dev = vsi->adapter->eth_dev;
2197 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
2198 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
2199 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
2200 	struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
2201 	uint16_t msix_intr, i;
2202 
2203 	if (rte_intr_allow_others(intr_handle) && !pf->support_multi_driver)
2204 		for (i = 0; i < vsi->nb_msix; i++) {
2205 			msix_intr = vsi->msix_intr + i;
2206 			I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTLN(msix_intr - 1),
2207 				       I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
2208 		}
2209 	else
2210 		I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
2211 			       I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
2212 
2213 	I40E_WRITE_FLUSH(hw);
2214 }
2215 
2216 static inline uint8_t
2217 i40e_parse_link_speeds(uint16_t link_speeds)
2218 {
2219 	uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
2220 
2221 	if (link_speeds & ETH_LINK_SPEED_40G)
2222 		link_speed |= I40E_LINK_SPEED_40GB;
2223 	if (link_speeds & ETH_LINK_SPEED_25G)
2224 		link_speed |= I40E_LINK_SPEED_25GB;
2225 	if (link_speeds & ETH_LINK_SPEED_20G)
2226 		link_speed |= I40E_LINK_SPEED_20GB;
2227 	if (link_speeds & ETH_LINK_SPEED_10G)
2228 		link_speed |= I40E_LINK_SPEED_10GB;
2229 	if (link_speeds & ETH_LINK_SPEED_1G)
2230 		link_speed |= I40E_LINK_SPEED_1GB;
2231 	if (link_speeds & ETH_LINK_SPEED_100M)
2232 		link_speed |= I40E_LINK_SPEED_100MB;
2233 
2234 	return link_speed;
2235 }
2236 
2237 static int
2238 i40e_phy_conf_link(struct i40e_hw *hw,
2239 		   uint8_t abilities,
2240 		   uint8_t force_speed,
2241 		   bool is_up)
2242 {
2243 	enum i40e_status_code status;
2244 	struct i40e_aq_get_phy_abilities_resp phy_ab;
2245 	struct i40e_aq_set_phy_config phy_conf;
2246 	enum i40e_aq_phy_type cnt;
2247 	uint8_t avail_speed;
2248 	uint32_t phy_type_mask = 0;
2249 
2250 	const uint8_t mask = I40E_AQ_PHY_FLAG_PAUSE_TX |
2251 			I40E_AQ_PHY_FLAG_PAUSE_RX |
2252 			I40E_AQ_PHY_FLAG_PAUSE_RX |
2253 			I40E_AQ_PHY_FLAG_LOW_POWER;
2254 	int ret = -ENOTSUP;
2255 
2256 	/* To get phy capabilities of available speeds. */
2257 	status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_ab,
2258 					      NULL);
2259 	if (status) {
2260 		PMD_DRV_LOG(ERR, "Failed to get PHY capabilities: %d\n",
2261 				status);
2262 		return ret;
2263 	}
2264 	avail_speed = phy_ab.link_speed;
2265 
2266 	/* To get the current phy config. */
2267 	status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_ab,
2268 					      NULL);
2269 	if (status) {
2270 		PMD_DRV_LOG(ERR, "Failed to get the current PHY config: %d\n",
2271 				status);
2272 		return ret;
2273 	}
2274 
2275 	/* If link needs to go up and it is in autoneg mode the speed is OK,
2276 	 * no need to set up again.
2277 	 */
2278 	if (is_up && phy_ab.phy_type != 0 &&
2279 		     abilities & I40E_AQ_PHY_AN_ENABLED &&
2280 		     phy_ab.link_speed != 0)
2281 		return I40E_SUCCESS;
2282 
2283 	memset(&phy_conf, 0, sizeof(phy_conf));
2284 
2285 	/* bits 0-2 use the values from get_phy_abilities_resp */
2286 	abilities &= ~mask;
2287 	abilities |= phy_ab.abilities & mask;
2288 
2289 	phy_conf.abilities = abilities;
2290 
2291 	/* If link needs to go up, but the force speed is not supported,
2292 	 * Warn users and config the default available speeds.
2293 	 */
2294 	if (is_up && !(force_speed & avail_speed)) {
2295 		PMD_DRV_LOG(WARNING, "Invalid speed setting, set to default!\n");
2296 		phy_conf.link_speed = avail_speed;
2297 	} else {
2298 		phy_conf.link_speed = is_up ? force_speed : avail_speed;
2299 	}
2300 
2301 	/* PHY type mask needs to include each type except PHY type extension */
2302 	for (cnt = I40E_PHY_TYPE_SGMII; cnt < I40E_PHY_TYPE_25GBASE_KR; cnt++)
2303 		phy_type_mask |= 1 << cnt;
2304 
2305 	/* use get_phy_abilities_resp value for the rest */
2306 	phy_conf.phy_type = is_up ? cpu_to_le32(phy_type_mask) : 0;
2307 	phy_conf.phy_type_ext = is_up ? (I40E_AQ_PHY_TYPE_EXT_25G_KR |
2308 		I40E_AQ_PHY_TYPE_EXT_25G_CR | I40E_AQ_PHY_TYPE_EXT_25G_SR |
2309 		I40E_AQ_PHY_TYPE_EXT_25G_LR) : 0;
2310 	phy_conf.fec_config = phy_ab.fec_cfg_curr_mod_ext_info;
2311 	phy_conf.eee_capability = phy_ab.eee_capability;
2312 	phy_conf.eeer = phy_ab.eeer_val;
2313 	phy_conf.low_power_ctrl = phy_ab.d3_lpan;
2314 
2315 	PMD_DRV_LOG(DEBUG, "\tCurrent: abilities %x, link_speed %x",
2316 		    phy_ab.abilities, phy_ab.link_speed);
2317 	PMD_DRV_LOG(DEBUG, "\tConfig:  abilities %x, link_speed %x",
2318 		    phy_conf.abilities, phy_conf.link_speed);
2319 
2320 	status = i40e_aq_set_phy_config(hw, &phy_conf, NULL);
2321 	if (status)
2322 		return ret;
2323 
2324 	return I40E_SUCCESS;
2325 }
2326 
2327 static int
2328 i40e_apply_link_speed(struct rte_eth_dev *dev)
2329 {
2330 	uint8_t speed;
2331 	uint8_t abilities = 0;
2332 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2333 	struct rte_eth_conf *conf = &dev->data->dev_conf;
2334 
2335 	abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK |
2336 		     I40E_AQ_PHY_LINK_ENABLED;
2337 
2338 	if (conf->link_speeds == ETH_LINK_SPEED_AUTONEG) {
2339 		conf->link_speeds = ETH_LINK_SPEED_40G |
2340 				    ETH_LINK_SPEED_25G |
2341 				    ETH_LINK_SPEED_20G |
2342 				    ETH_LINK_SPEED_10G |
2343 				    ETH_LINK_SPEED_1G |
2344 				    ETH_LINK_SPEED_100M;
2345 
2346 		abilities |= I40E_AQ_PHY_AN_ENABLED;
2347 	} else {
2348 		abilities &= ~I40E_AQ_PHY_AN_ENABLED;
2349 	}
2350 	speed = i40e_parse_link_speeds(conf->link_speeds);
2351 
2352 	return i40e_phy_conf_link(hw, abilities, speed, true);
2353 }
2354 
2355 static int
2356 i40e_dev_start(struct rte_eth_dev *dev)
2357 {
2358 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2359 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2360 	struct i40e_vsi *main_vsi = pf->main_vsi;
2361 	int ret, i;
2362 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
2363 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
2364 	uint32_t intr_vector = 0;
2365 	struct i40e_vsi *vsi;
2366 	uint16_t nb_rxq, nb_txq;
2367 
2368 	hw->adapter_stopped = 0;
2369 
2370 	rte_intr_disable(intr_handle);
2371 
2372 	if ((rte_intr_cap_multiple(intr_handle) ||
2373 	     !RTE_ETH_DEV_SRIOV(dev).active) &&
2374 	    dev->data->dev_conf.intr_conf.rxq != 0) {
2375 		intr_vector = dev->data->nb_rx_queues;
2376 		ret = rte_intr_efd_enable(intr_handle, intr_vector);
2377 		if (ret)
2378 			return ret;
2379 	}
2380 
2381 	if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {
2382 		intr_handle->intr_vec =
2383 			rte_zmalloc("intr_vec",
2384 				    dev->data->nb_rx_queues * sizeof(int),
2385 				    0);
2386 		if (!intr_handle->intr_vec) {
2387 			PMD_INIT_LOG(ERR,
2388 				"Failed to allocate %d rx_queues intr_vec",
2389 				dev->data->nb_rx_queues);
2390 			return -ENOMEM;
2391 		}
2392 	}
2393 
2394 	/* Initialize VSI */
2395 	ret = i40e_dev_rxtx_init(pf);
2396 	if (ret != I40E_SUCCESS) {
2397 		PMD_DRV_LOG(ERR, "Failed to init rx/tx queues");
2398 		return ret;
2399 	}
2400 
2401 	/* Map queues with MSIX interrupt */
2402 	main_vsi->nb_used_qps = dev->data->nb_rx_queues -
2403 		pf->nb_cfg_vmdq_vsi * RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM;
2404 	ret = i40e_vsi_queues_bind_intr(main_vsi, I40E_ITR_INDEX_DEFAULT);
2405 	if (ret < 0)
2406 		return ret;
2407 	i40e_vsi_enable_queues_intr(main_vsi);
2408 
2409 	/* Map VMDQ VSI queues with MSIX interrupt */
2410 	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
2411 		pf->vmdq[i].vsi->nb_used_qps = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM;
2412 		ret = i40e_vsi_queues_bind_intr(pf->vmdq[i].vsi,
2413 						I40E_ITR_INDEX_DEFAULT);
2414 		if (ret < 0)
2415 			return ret;
2416 		i40e_vsi_enable_queues_intr(pf->vmdq[i].vsi);
2417 	}
2418 
2419 	/* Enable all queues which have been configured */
2420 	for (nb_rxq = 0; nb_rxq < dev->data->nb_rx_queues; nb_rxq++) {
2421 		ret = i40e_dev_rx_queue_start(dev, nb_rxq);
2422 		if (ret)
2423 			goto rx_err;
2424 	}
2425 
2426 	for (nb_txq = 0; nb_txq < dev->data->nb_tx_queues; nb_txq++) {
2427 		ret = i40e_dev_tx_queue_start(dev, nb_txq);
2428 		if (ret)
2429 			goto tx_err;
2430 	}
2431 
2432 	/* Enable receiving broadcast packets */
2433 	ret = i40e_aq_set_vsi_broadcast(hw, main_vsi->seid, true, NULL);
2434 	if (ret != I40E_SUCCESS)
2435 		PMD_DRV_LOG(INFO, "fail to set vsi broadcast");
2436 
2437 	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
2438 		ret = i40e_aq_set_vsi_broadcast(hw, pf->vmdq[i].vsi->seid,
2439 						true, NULL);
2440 		if (ret != I40E_SUCCESS)
2441 			PMD_DRV_LOG(INFO, "fail to set vsi broadcast");
2442 	}
2443 
2444 	/* Enable the VLAN promiscuous mode. */
2445 	if (pf->vfs) {
2446 		for (i = 0; i < pf->vf_num; i++) {
2447 			vsi = pf->vfs[i].vsi;
2448 			i40e_aq_set_vsi_vlan_promisc(hw, vsi->seid,
2449 						     true, NULL);
2450 		}
2451 	}
2452 
2453 	/* Enable mac loopback mode */
2454 	if (dev->data->dev_conf.lpbk_mode == I40E_AQ_LB_MODE_NONE ||
2455 	    dev->data->dev_conf.lpbk_mode == I40E_AQ_LB_PHY_LOCAL) {
2456 		ret = i40e_aq_set_lb_modes(hw, dev->data->dev_conf.lpbk_mode, NULL);
2457 		if (ret != I40E_SUCCESS) {
2458 			PMD_DRV_LOG(ERR, "fail to set loopback link");
2459 			goto tx_err;
2460 		}
2461 	}
2462 
2463 	/* Apply link configure */
2464 	ret = i40e_apply_link_speed(dev);
2465 	if (I40E_SUCCESS != ret) {
2466 		PMD_DRV_LOG(ERR, "Fail to apply link setting");
2467 		goto tx_err;
2468 	}
2469 
2470 	if (!rte_intr_allow_others(intr_handle)) {
2471 		rte_intr_callback_unregister(intr_handle,
2472 					     i40e_dev_interrupt_handler,
2473 					     (void *)dev);
2474 		/* configure and enable device interrupt */
2475 		i40e_pf_config_irq0(hw, FALSE);
2476 		i40e_pf_enable_irq0(hw);
2477 
2478 		if (dev->data->dev_conf.intr_conf.lsc != 0)
2479 			PMD_INIT_LOG(INFO,
2480 				"lsc won't enable because of no intr multiplex");
2481 	} else {
2482 		ret = i40e_aq_set_phy_int_mask(hw,
2483 					       ~(I40E_AQ_EVENT_LINK_UPDOWN |
2484 					       I40E_AQ_EVENT_MODULE_QUAL_FAIL |
2485 					       I40E_AQ_EVENT_MEDIA_NA), NULL);
2486 		if (ret != I40E_SUCCESS)
2487 			PMD_DRV_LOG(WARNING, "Fail to set phy mask");
2488 
2489 		/* Call get_link_info aq commond to enable/disable LSE */
2490 		i40e_dev_link_update(dev, 0);
2491 	}
2492 
2493 	if (dev->data->dev_conf.intr_conf.rxq == 0) {
2494 		rte_eal_alarm_set(I40E_ALARM_INTERVAL,
2495 				  i40e_dev_alarm_handler, dev);
2496 	} else {
2497 		/* enable uio intr after callback register */
2498 		rte_intr_enable(intr_handle);
2499 	}
2500 
2501 	i40e_filter_restore(pf);
2502 
2503 	if (pf->tm_conf.root && !pf->tm_conf.committed)
2504 		PMD_DRV_LOG(WARNING,
2505 			    "please call hierarchy_commit() "
2506 			    "before starting the port");
2507 
2508 	return I40E_SUCCESS;
2509 
2510 tx_err:
2511 	for (i = 0; i < nb_txq; i++)
2512 		i40e_dev_tx_queue_stop(dev, i);
2513 rx_err:
2514 	for (i = 0; i < nb_rxq; i++)
2515 		i40e_dev_rx_queue_stop(dev, i);
2516 
2517 	return ret;
2518 }
2519 
2520 static int
2521 i40e_dev_stop(struct rte_eth_dev *dev)
2522 {
2523 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2524 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2525 	struct i40e_vsi *main_vsi = pf->main_vsi;
2526 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
2527 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
2528 	int i;
2529 
2530 	if (hw->adapter_stopped == 1)
2531 		return 0;
2532 
2533 	if (dev->data->dev_conf.intr_conf.rxq == 0) {
2534 		rte_eal_alarm_cancel(i40e_dev_alarm_handler, dev);
2535 		rte_intr_enable(intr_handle);
2536 	}
2537 
2538 	/* Disable all queues */
2539 	for (i = 0; i < dev->data->nb_tx_queues; i++)
2540 		i40e_dev_tx_queue_stop(dev, i);
2541 
2542 	for (i = 0; i < dev->data->nb_rx_queues; i++)
2543 		i40e_dev_rx_queue_stop(dev, i);
2544 
2545 	/* un-map queues with interrupt registers */
2546 	i40e_vsi_disable_queues_intr(main_vsi);
2547 	i40e_vsi_queues_unbind_intr(main_vsi);
2548 
2549 	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
2550 		i40e_vsi_disable_queues_intr(pf->vmdq[i].vsi);
2551 		i40e_vsi_queues_unbind_intr(pf->vmdq[i].vsi);
2552 	}
2553 
2554 	/* Clear all queues and release memory */
2555 	i40e_dev_clear_queues(dev);
2556 
2557 	/* Set link down */
2558 	i40e_dev_set_link_down(dev);
2559 
2560 	if (!rte_intr_allow_others(intr_handle))
2561 		/* resume to the default handler */
2562 		rte_intr_callback_register(intr_handle,
2563 					   i40e_dev_interrupt_handler,
2564 					   (void *)dev);
2565 
2566 	/* Clean datapath event and queue/vec mapping */
2567 	rte_intr_efd_disable(intr_handle);
2568 	if (intr_handle->intr_vec) {
2569 		rte_free(intr_handle->intr_vec);
2570 		intr_handle->intr_vec = NULL;
2571 	}
2572 
2573 	/* reset hierarchy commit */
2574 	pf->tm_conf.committed = false;
2575 
2576 	hw->adapter_stopped = 1;
2577 	dev->data->dev_started = 0;
2578 
2579 	pf->adapter->rss_reta_updated = 0;
2580 
2581 	return 0;
2582 }
2583 
2584 static int
2585 i40e_dev_close(struct rte_eth_dev *dev)
2586 {
2587 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2588 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2589 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
2590 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
2591 	struct i40e_mirror_rule *p_mirror;
2592 	struct i40e_filter_control_settings settings;
2593 	struct rte_flow *p_flow;
2594 	uint32_t reg;
2595 	int i;
2596 	int ret;
2597 	uint8_t aq_fail = 0;
2598 	int retries = 0;
2599 
2600 	PMD_INIT_FUNC_TRACE();
2601 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2602 		return 0;
2603 
2604 	ret = rte_eth_switch_domain_free(pf->switch_domain_id);
2605 	if (ret)
2606 		PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret);
2607 
2608 
2609 	ret = i40e_dev_stop(dev);
2610 
2611 	/* Remove all mirror rules */
2612 	while ((p_mirror = TAILQ_FIRST(&pf->mirror_list))) {
2613 		ret = i40e_aq_del_mirror_rule(hw,
2614 					      pf->main_vsi->veb->seid,
2615 					      p_mirror->rule_type,
2616 					      p_mirror->entries,
2617 					      p_mirror->num_entries,
2618 					      p_mirror->id);
2619 		if (ret < 0)
2620 			PMD_DRV_LOG(ERR, "failed to remove mirror rule: "
2621 				    "status = %d, aq_err = %d.", ret,
2622 				    hw->aq.asq_last_status);
2623 
2624 		/* remove mirror software resource anyway */
2625 		TAILQ_REMOVE(&pf->mirror_list, p_mirror, rules);
2626 		rte_free(p_mirror);
2627 		pf->nb_mirror_rule--;
2628 	}
2629 
2630 	i40e_dev_free_queues(dev);
2631 
2632 	/* Disable interrupt */
2633 	i40e_pf_disable_irq0(hw);
2634 	rte_intr_disable(intr_handle);
2635 
2636 	/*
2637 	 * Only legacy filter API needs the following fdir config. So when the
2638 	 * legacy filter API is deprecated, the following code should also be
2639 	 * removed.
2640 	 */
2641 	i40e_fdir_teardown(pf);
2642 
2643 	/* shutdown and destroy the HMC */
2644 	i40e_shutdown_lan_hmc(hw);
2645 
2646 	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
2647 		i40e_vsi_release(pf->vmdq[i].vsi);
2648 		pf->vmdq[i].vsi = NULL;
2649 	}
2650 	rte_free(pf->vmdq);
2651 	pf->vmdq = NULL;
2652 
2653 	/* release all the existing VSIs and VEBs */
2654 	i40e_vsi_release(pf->main_vsi);
2655 
2656 	/* shutdown the adminq */
2657 	i40e_aq_queue_shutdown(hw, true);
2658 	i40e_shutdown_adminq(hw);
2659 
2660 	i40e_res_pool_destroy(&pf->qp_pool);
2661 	i40e_res_pool_destroy(&pf->msix_pool);
2662 
2663 	/* Disable flexible payload in global configuration */
2664 	if (!pf->support_multi_driver)
2665 		i40e_flex_payload_reg_set_default(hw);
2666 
2667 	/* force a PF reset to clean anything leftover */
2668 	reg = I40E_READ_REG(hw, I40E_PFGEN_CTRL);
2669 	I40E_WRITE_REG(hw, I40E_PFGEN_CTRL,
2670 			(reg | I40E_PFGEN_CTRL_PFSWR_MASK));
2671 	I40E_WRITE_FLUSH(hw);
2672 
2673 	/* Clear PXE mode */
2674 	i40e_clear_pxe_mode(hw);
2675 
2676 	/* Unconfigure filter control */
2677 	memset(&settings, 0, sizeof(settings));
2678 	ret = i40e_set_filter_control(hw, &settings);
2679 	if (ret)
2680 		PMD_INIT_LOG(WARNING, "setup_pf_filter_control failed: %d",
2681 					ret);
2682 
2683 	/* Disable flow control */
2684 	hw->fc.requested_mode = I40E_FC_NONE;
2685 	i40e_set_fc(hw, &aq_fail, TRUE);
2686 
2687 	/* uninitialize pf host driver */
2688 	i40e_pf_host_uninit(dev);
2689 
2690 	do {
2691 		ret = rte_intr_callback_unregister(intr_handle,
2692 				i40e_dev_interrupt_handler, dev);
2693 		if (ret >= 0 || ret == -ENOENT) {
2694 			break;
2695 		} else if (ret != -EAGAIN) {
2696 			PMD_INIT_LOG(ERR,
2697 				 "intr callback unregister failed: %d",
2698 				 ret);
2699 		}
2700 		i40e_msec_delay(500);
2701 	} while (retries++ < 5);
2702 
2703 	i40e_rm_ethtype_filter_list(pf);
2704 	i40e_rm_tunnel_filter_list(pf);
2705 	i40e_rm_fdir_filter_list(pf);
2706 
2707 	/* Remove all flows */
2708 	while ((p_flow = TAILQ_FIRST(&pf->flow_list))) {
2709 		TAILQ_REMOVE(&pf->flow_list, p_flow, node);
2710 		/* Do not free FDIR flows since they are static allocated */
2711 		if (p_flow->filter_type != RTE_ETH_FILTER_FDIR)
2712 			rte_free(p_flow);
2713 	}
2714 
2715 	/* release the fdir static allocated memory */
2716 	i40e_fdir_memory_cleanup(pf);
2717 
2718 	/* Remove all Traffic Manager configuration */
2719 	i40e_tm_conf_uninit(dev);
2720 
2721 	i40e_clear_automask(pf);
2722 
2723 	hw->adapter_closed = 1;
2724 	return ret;
2725 }
2726 
2727 /*
2728  * Reset PF device only to re-initialize resources in PMD layer
2729  */
2730 static int
2731 i40e_dev_reset(struct rte_eth_dev *dev)
2732 {
2733 	int ret;
2734 
2735 	/* When a DPDK PMD PF begin to reset PF port, it should notify all
2736 	 * its VF to make them align with it. The detailed notification
2737 	 * mechanism is PMD specific. As to i40e PF, it is rather complex.
2738 	 * To avoid unexpected behavior in VF, currently reset of PF with
2739 	 * SR-IOV activation is not supported. It might be supported later.
2740 	 */
2741 	if (dev->data->sriov.active)
2742 		return -ENOTSUP;
2743 
2744 	ret = eth_i40e_dev_uninit(dev);
2745 	if (ret)
2746 		return ret;
2747 
2748 	ret = eth_i40e_dev_init(dev, NULL);
2749 
2750 	return ret;
2751 }
2752 
2753 static int
2754 i40e_dev_promiscuous_enable(struct rte_eth_dev *dev)
2755 {
2756 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2757 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2758 	struct i40e_vsi *vsi = pf->main_vsi;
2759 	int status;
2760 
2761 	status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
2762 						     true, NULL, true);
2763 	if (status != I40E_SUCCESS) {
2764 		PMD_DRV_LOG(ERR, "Failed to enable unicast promiscuous");
2765 		return -EAGAIN;
2766 	}
2767 
2768 	status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
2769 							TRUE, NULL);
2770 	if (status != I40E_SUCCESS) {
2771 		PMD_DRV_LOG(ERR, "Failed to enable multicast promiscuous");
2772 		/* Rollback unicast promiscuous mode */
2773 		i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
2774 						    false, NULL, true);
2775 		return -EAGAIN;
2776 	}
2777 
2778 	return 0;
2779 }
2780 
2781 static int
2782 i40e_dev_promiscuous_disable(struct rte_eth_dev *dev)
2783 {
2784 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2785 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2786 	struct i40e_vsi *vsi = pf->main_vsi;
2787 	int status;
2788 
2789 	status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
2790 						     false, NULL, true);
2791 	if (status != I40E_SUCCESS) {
2792 		PMD_DRV_LOG(ERR, "Failed to disable unicast promiscuous");
2793 		return -EAGAIN;
2794 	}
2795 
2796 	/* must remain in all_multicast mode */
2797 	if (dev->data->all_multicast == 1)
2798 		return 0;
2799 
2800 	status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
2801 							false, NULL);
2802 	if (status != I40E_SUCCESS) {
2803 		PMD_DRV_LOG(ERR, "Failed to disable multicast promiscuous");
2804 		/* Rollback unicast promiscuous mode */
2805 		i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
2806 						    true, NULL, true);
2807 		return -EAGAIN;
2808 	}
2809 
2810 	return 0;
2811 }
2812 
2813 static int
2814 i40e_dev_allmulticast_enable(struct rte_eth_dev *dev)
2815 {
2816 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2817 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2818 	struct i40e_vsi *vsi = pf->main_vsi;
2819 	int ret;
2820 
2821 	ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, TRUE, NULL);
2822 	if (ret != I40E_SUCCESS) {
2823 		PMD_DRV_LOG(ERR, "Failed to enable multicast promiscuous");
2824 		return -EAGAIN;
2825 	}
2826 
2827 	return 0;
2828 }
2829 
2830 static int
2831 i40e_dev_allmulticast_disable(struct rte_eth_dev *dev)
2832 {
2833 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2834 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2835 	struct i40e_vsi *vsi = pf->main_vsi;
2836 	int ret;
2837 
2838 	if (dev->data->promiscuous == 1)
2839 		return 0; /* must remain in all_multicast mode */
2840 
2841 	ret = i40e_aq_set_vsi_multicast_promiscuous(hw,
2842 				vsi->seid, FALSE, NULL);
2843 	if (ret != I40E_SUCCESS) {
2844 		PMD_DRV_LOG(ERR, "Failed to disable multicast promiscuous");
2845 		return -EAGAIN;
2846 	}
2847 
2848 	return 0;
2849 }
2850 
2851 /*
2852  * Set device link up.
2853  */
2854 static int
2855 i40e_dev_set_link_up(struct rte_eth_dev *dev)
2856 {
2857 	/* re-apply link speed setting */
2858 	return i40e_apply_link_speed(dev);
2859 }
2860 
2861 /*
2862  * Set device link down.
2863  */
2864 static int
2865 i40e_dev_set_link_down(struct rte_eth_dev *dev)
2866 {
2867 	uint8_t speed = I40E_LINK_SPEED_UNKNOWN;
2868 	uint8_t abilities = 0;
2869 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2870 
2871 	abilities = I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
2872 	return i40e_phy_conf_link(hw, abilities, speed, false);
2873 }
2874 
2875 static __rte_always_inline void
2876 update_link_reg(struct i40e_hw *hw, struct rte_eth_link *link)
2877 {
2878 /* Link status registers and values*/
2879 #define I40E_PRTMAC_LINKSTA		0x001E2420
2880 #define I40E_REG_LINK_UP		0x40000080
2881 #define I40E_PRTMAC_MACC		0x001E24E0
2882 #define I40E_REG_MACC_25GB		0x00020000
2883 #define I40E_REG_SPEED_MASK		0x38000000
2884 #define I40E_REG_SPEED_0		0x00000000
2885 #define I40E_REG_SPEED_1		0x08000000
2886 #define I40E_REG_SPEED_2		0x10000000
2887 #define I40E_REG_SPEED_3		0x18000000
2888 #define I40E_REG_SPEED_4		0x20000000
2889 	uint32_t link_speed;
2890 	uint32_t reg_val;
2891 
2892 	reg_val = I40E_READ_REG(hw, I40E_PRTMAC_LINKSTA);
2893 	link_speed = reg_val & I40E_REG_SPEED_MASK;
2894 	reg_val &= I40E_REG_LINK_UP;
2895 	link->link_status = (reg_val == I40E_REG_LINK_UP) ? 1 : 0;
2896 
2897 	if (unlikely(link->link_status == 0))
2898 		return;
2899 
2900 	/* Parse the link status */
2901 	switch (link_speed) {
2902 	case I40E_REG_SPEED_0:
2903 		link->link_speed = ETH_SPEED_NUM_100M;
2904 		break;
2905 	case I40E_REG_SPEED_1:
2906 		link->link_speed = ETH_SPEED_NUM_1G;
2907 		break;
2908 	case I40E_REG_SPEED_2:
2909 		if (hw->mac.type == I40E_MAC_X722)
2910 			link->link_speed = ETH_SPEED_NUM_2_5G;
2911 		else
2912 			link->link_speed = ETH_SPEED_NUM_10G;
2913 		break;
2914 	case I40E_REG_SPEED_3:
2915 		if (hw->mac.type == I40E_MAC_X722) {
2916 			link->link_speed = ETH_SPEED_NUM_5G;
2917 		} else {
2918 			reg_val = I40E_READ_REG(hw, I40E_PRTMAC_MACC);
2919 
2920 			if (reg_val & I40E_REG_MACC_25GB)
2921 				link->link_speed = ETH_SPEED_NUM_25G;
2922 			else
2923 				link->link_speed = ETH_SPEED_NUM_40G;
2924 		}
2925 		break;
2926 	case I40E_REG_SPEED_4:
2927 		if (hw->mac.type == I40E_MAC_X722)
2928 			link->link_speed = ETH_SPEED_NUM_10G;
2929 		else
2930 			link->link_speed = ETH_SPEED_NUM_20G;
2931 		break;
2932 	default:
2933 		PMD_DRV_LOG(ERR, "Unknown link speed info %u", link_speed);
2934 		break;
2935 	}
2936 }
2937 
2938 static __rte_always_inline void
2939 update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
2940 	bool enable_lse, int wait_to_complete)
2941 {
2942 #define CHECK_INTERVAL             100  /* 100ms */
2943 #define MAX_REPEAT_TIME            10  /* 1s (10 * 100ms) in total */
2944 	uint32_t rep_cnt = MAX_REPEAT_TIME;
2945 	struct i40e_link_status link_status;
2946 	int status;
2947 
2948 	memset(&link_status, 0, sizeof(link_status));
2949 
2950 	do {
2951 		memset(&link_status, 0, sizeof(link_status));
2952 
2953 		/* Get link status information from hardware */
2954 		status = i40e_aq_get_link_info(hw, enable_lse,
2955 						&link_status, NULL);
2956 		if (unlikely(status != I40E_SUCCESS)) {
2957 			link->link_speed = ETH_SPEED_NUM_NONE;
2958 			link->link_duplex = ETH_LINK_FULL_DUPLEX;
2959 			PMD_DRV_LOG(ERR, "Failed to get link info");
2960 			return;
2961 		}
2962 
2963 		link->link_status = link_status.link_info & I40E_AQ_LINK_UP;
2964 		if (!wait_to_complete || link->link_status)
2965 			break;
2966 
2967 		rte_delay_ms(CHECK_INTERVAL);
2968 	} while (--rep_cnt);
2969 
2970 	/* Parse the link status */
2971 	switch (link_status.link_speed) {
2972 	case I40E_LINK_SPEED_100MB:
2973 		link->link_speed = ETH_SPEED_NUM_100M;
2974 		break;
2975 	case I40E_LINK_SPEED_1GB:
2976 		link->link_speed = ETH_SPEED_NUM_1G;
2977 		break;
2978 	case I40E_LINK_SPEED_10GB:
2979 		link->link_speed = ETH_SPEED_NUM_10G;
2980 		break;
2981 	case I40E_LINK_SPEED_20GB:
2982 		link->link_speed = ETH_SPEED_NUM_20G;
2983 		break;
2984 	case I40E_LINK_SPEED_25GB:
2985 		link->link_speed = ETH_SPEED_NUM_25G;
2986 		break;
2987 	case I40E_LINK_SPEED_40GB:
2988 		link->link_speed = ETH_SPEED_NUM_40G;
2989 		break;
2990 	default:
2991 		if (link->link_status)
2992 			link->link_speed = ETH_SPEED_NUM_UNKNOWN;
2993 		else
2994 			link->link_speed = ETH_SPEED_NUM_NONE;
2995 		break;
2996 	}
2997 }
2998 
2999 int
3000 i40e_dev_link_update(struct rte_eth_dev *dev,
3001 		     int wait_to_complete)
3002 {
3003 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3004 	struct rte_eth_link link;
3005 	bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false;
3006 	int ret;
3007 
3008 	memset(&link, 0, sizeof(link));
3009 
3010 	/* i40e uses full duplex only */
3011 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
3012 	link.link_autoneg = !(dev->data->dev_conf.link_speeds &
3013 			ETH_LINK_SPEED_FIXED);
3014 
3015 	if (!wait_to_complete && !enable_lse)
3016 		update_link_reg(hw, &link);
3017 	else
3018 		update_link_aq(hw, &link, enable_lse, wait_to_complete);
3019 
3020 	if (hw->switch_dev)
3021 		rte_eth_linkstatus_get(hw->switch_dev, &link);
3022 
3023 	ret = rte_eth_linkstatus_set(dev, &link);
3024 	i40e_notify_all_vfs_link_status(dev);
3025 
3026 	return ret;
3027 }
3028 
3029 static void
3030 i40e_stat_update_48_in_64(struct i40e_hw *hw, uint32_t hireg,
3031 			  uint32_t loreg, bool offset_loaded, uint64_t *offset,
3032 			  uint64_t *stat, uint64_t *prev_stat)
3033 {
3034 	i40e_stat_update_48(hw, hireg, loreg, offset_loaded, offset, stat);
3035 	/* enlarge the limitation when statistics counters overflowed */
3036 	if (offset_loaded) {
3037 		if (I40E_RXTX_BYTES_L_48_BIT(*prev_stat) > *stat)
3038 			*stat += (uint64_t)1 << I40E_48_BIT_WIDTH;
3039 		*stat += I40E_RXTX_BYTES_H_16_BIT(*prev_stat);
3040 	}
3041 	*prev_stat = *stat;
3042 }
3043 
3044 /* Get all the statistics of a VSI */
3045 void
3046 i40e_update_vsi_stats(struct i40e_vsi *vsi)
3047 {
3048 	struct i40e_eth_stats *oes = &vsi->eth_stats_offset;
3049 	struct i40e_eth_stats *nes = &vsi->eth_stats;
3050 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
3051 	int idx = rte_le_to_cpu_16(vsi->info.stat_counter_idx);
3052 
3053 	i40e_stat_update_48_in_64(hw, I40E_GLV_GORCH(idx), I40E_GLV_GORCL(idx),
3054 				  vsi->offset_loaded, &oes->rx_bytes,
3055 				  &nes->rx_bytes, &vsi->prev_rx_bytes);
3056 	i40e_stat_update_48(hw, I40E_GLV_UPRCH(idx), I40E_GLV_UPRCL(idx),
3057 			    vsi->offset_loaded, &oes->rx_unicast,
3058 			    &nes->rx_unicast);
3059 	i40e_stat_update_48(hw, I40E_GLV_MPRCH(idx), I40E_GLV_MPRCL(idx),
3060 			    vsi->offset_loaded, &oes->rx_multicast,
3061 			    &nes->rx_multicast);
3062 	i40e_stat_update_48(hw, I40E_GLV_BPRCH(idx), I40E_GLV_BPRCL(idx),
3063 			    vsi->offset_loaded, &oes->rx_broadcast,
3064 			    &nes->rx_broadcast);
3065 	/* exclude CRC bytes */
3066 	nes->rx_bytes -= (nes->rx_unicast + nes->rx_multicast +
3067 		nes->rx_broadcast) * RTE_ETHER_CRC_LEN;
3068 
3069 	i40e_stat_update_32(hw, I40E_GLV_RDPC(idx), vsi->offset_loaded,
3070 			    &oes->rx_discards, &nes->rx_discards);
3071 	/* GLV_REPC not supported */
3072 	/* GLV_RMPC not supported */
3073 	i40e_stat_update_32(hw, I40E_GLV_RUPP(idx), vsi->offset_loaded,
3074 			    &oes->rx_unknown_protocol,
3075 			    &nes->rx_unknown_protocol);
3076 	i40e_stat_update_48_in_64(hw, I40E_GLV_GOTCH(idx), I40E_GLV_GOTCL(idx),
3077 				  vsi->offset_loaded, &oes->tx_bytes,
3078 				  &nes->tx_bytes, &vsi->prev_tx_bytes);
3079 	i40e_stat_update_48(hw, I40E_GLV_UPTCH(idx), I40E_GLV_UPTCL(idx),
3080 			    vsi->offset_loaded, &oes->tx_unicast,
3081 			    &nes->tx_unicast);
3082 	i40e_stat_update_48(hw, I40E_GLV_MPTCH(idx), I40E_GLV_MPTCL(idx),
3083 			    vsi->offset_loaded, &oes->tx_multicast,
3084 			    &nes->tx_multicast);
3085 	i40e_stat_update_48(hw, I40E_GLV_BPTCH(idx), I40E_GLV_BPTCL(idx),
3086 			    vsi->offset_loaded,  &oes->tx_broadcast,
3087 			    &nes->tx_broadcast);
3088 	/* GLV_TDPC not supported */
3089 	i40e_stat_update_32(hw, I40E_GLV_TEPC(idx), vsi->offset_loaded,
3090 			    &oes->tx_errors, &nes->tx_errors);
3091 	vsi->offset_loaded = true;
3092 
3093 	PMD_DRV_LOG(DEBUG, "***************** VSI[%u] stats start *******************",
3094 		    vsi->vsi_id);
3095 	PMD_DRV_LOG(DEBUG, "rx_bytes:            %"PRIu64"", nes->rx_bytes);
3096 	PMD_DRV_LOG(DEBUG, "rx_unicast:          %"PRIu64"", nes->rx_unicast);
3097 	PMD_DRV_LOG(DEBUG, "rx_multicast:        %"PRIu64"", nes->rx_multicast);
3098 	PMD_DRV_LOG(DEBUG, "rx_broadcast:        %"PRIu64"", nes->rx_broadcast);
3099 	PMD_DRV_LOG(DEBUG, "rx_discards:         %"PRIu64"", nes->rx_discards);
3100 	PMD_DRV_LOG(DEBUG, "rx_unknown_protocol: %"PRIu64"",
3101 		    nes->rx_unknown_protocol);
3102 	PMD_DRV_LOG(DEBUG, "tx_bytes:            %"PRIu64"", nes->tx_bytes);
3103 	PMD_DRV_LOG(DEBUG, "tx_unicast:          %"PRIu64"", nes->tx_unicast);
3104 	PMD_DRV_LOG(DEBUG, "tx_multicast:        %"PRIu64"", nes->tx_multicast);
3105 	PMD_DRV_LOG(DEBUG, "tx_broadcast:        %"PRIu64"", nes->tx_broadcast);
3106 	PMD_DRV_LOG(DEBUG, "tx_discards:         %"PRIu64"", nes->tx_discards);
3107 	PMD_DRV_LOG(DEBUG, "tx_errors:           %"PRIu64"", nes->tx_errors);
3108 	PMD_DRV_LOG(DEBUG, "***************** VSI[%u] stats end *******************",
3109 		    vsi->vsi_id);
3110 }
3111 
3112 static void
3113 i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
3114 {
3115 	unsigned int i;
3116 	struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
3117 	struct i40e_hw_port_stats *os = &pf->stats_offset; /* old stats */
3118 
3119 	/* Get rx/tx bytes of internal transfer packets */
3120 	i40e_stat_update_48_in_64(hw, I40E_GLV_GORCH(hw->port),
3121 				  I40E_GLV_GORCL(hw->port),
3122 				  pf->offset_loaded,
3123 				  &pf->internal_stats_offset.rx_bytes,
3124 				  &pf->internal_stats.rx_bytes,
3125 				  &pf->internal_prev_rx_bytes);
3126 	i40e_stat_update_48_in_64(hw, I40E_GLV_GOTCH(hw->port),
3127 				  I40E_GLV_GOTCL(hw->port),
3128 				  pf->offset_loaded,
3129 				  &pf->internal_stats_offset.tx_bytes,
3130 				  &pf->internal_stats.tx_bytes,
3131 				  &pf->internal_prev_tx_bytes);
3132 	/* Get total internal rx packet count */
3133 	i40e_stat_update_48(hw, I40E_GLV_UPRCH(hw->port),
3134 			    I40E_GLV_UPRCL(hw->port),
3135 			    pf->offset_loaded,
3136 			    &pf->internal_stats_offset.rx_unicast,
3137 			    &pf->internal_stats.rx_unicast);
3138 	i40e_stat_update_48(hw, I40E_GLV_MPRCH(hw->port),
3139 			    I40E_GLV_MPRCL(hw->port),
3140 			    pf->offset_loaded,
3141 			    &pf->internal_stats_offset.rx_multicast,
3142 			    &pf->internal_stats.rx_multicast);
3143 	i40e_stat_update_48(hw, I40E_GLV_BPRCH(hw->port),
3144 			    I40E_GLV_BPRCL(hw->port),
3145 			    pf->offset_loaded,
3146 			    &pf->internal_stats_offset.rx_broadcast,
3147 			    &pf->internal_stats.rx_broadcast);
3148 	/* Get total internal tx packet count */
3149 	i40e_stat_update_48(hw, I40E_GLV_UPTCH(hw->port),
3150 			    I40E_GLV_UPTCL(hw->port),
3151 			    pf->offset_loaded,
3152 			    &pf->internal_stats_offset.tx_unicast,
3153 			    &pf->internal_stats.tx_unicast);
3154 	i40e_stat_update_48(hw, I40E_GLV_MPTCH(hw->port),
3155 			    I40E_GLV_MPTCL(hw->port),
3156 			    pf->offset_loaded,
3157 			    &pf->internal_stats_offset.tx_multicast,
3158 			    &pf->internal_stats.tx_multicast);
3159 	i40e_stat_update_48(hw, I40E_GLV_BPTCH(hw->port),
3160 			    I40E_GLV_BPTCL(hw->port),
3161 			    pf->offset_loaded,
3162 			    &pf->internal_stats_offset.tx_broadcast,
3163 			    &pf->internal_stats.tx_broadcast);
3164 
3165 	/* exclude CRC size */
3166 	pf->internal_stats.rx_bytes -= (pf->internal_stats.rx_unicast +
3167 		pf->internal_stats.rx_multicast +
3168 		pf->internal_stats.rx_broadcast) * RTE_ETHER_CRC_LEN;
3169 
3170 	/* Get statistics of struct i40e_eth_stats */
3171 	i40e_stat_update_48_in_64(hw, I40E_GLPRT_GORCH(hw->port),
3172 				  I40E_GLPRT_GORCL(hw->port),
3173 				  pf->offset_loaded, &os->eth.rx_bytes,
3174 				  &ns->eth.rx_bytes, &pf->prev_rx_bytes);
3175 	i40e_stat_update_48(hw, I40E_GLPRT_UPRCH(hw->port),
3176 			    I40E_GLPRT_UPRCL(hw->port),
3177 			    pf->offset_loaded, &os->eth.rx_unicast,
3178 			    &ns->eth.rx_unicast);
3179 	i40e_stat_update_48(hw, I40E_GLPRT_MPRCH(hw->port),
3180 			    I40E_GLPRT_MPRCL(hw->port),
3181 			    pf->offset_loaded, &os->eth.rx_multicast,
3182 			    &ns->eth.rx_multicast);
3183 	i40e_stat_update_48(hw, I40E_GLPRT_BPRCH(hw->port),
3184 			    I40E_GLPRT_BPRCL(hw->port),
3185 			    pf->offset_loaded, &os->eth.rx_broadcast,
3186 			    &ns->eth.rx_broadcast);
3187 	/* Workaround: CRC size should not be included in byte statistics,
3188 	 * so subtract RTE_ETHER_CRC_LEN from the byte counter for each rx
3189 	 * packet.
3190 	 */
3191 	ns->eth.rx_bytes -= (ns->eth.rx_unicast + ns->eth.rx_multicast +
3192 		ns->eth.rx_broadcast) * RTE_ETHER_CRC_LEN;
3193 
3194 	/* exclude internal rx bytes
3195 	 * Workaround: it is possible I40E_GLV_GORCH[H/L] is updated before
3196 	 * I40E_GLPRT_GORCH[H/L], so there is a small window that cause negative
3197 	 * value.
3198 	 * same to I40E_GLV_UPRC[H/L], I40E_GLV_MPRC[H/L], I40E_GLV_BPRC[H/L].
3199 	 */
3200 	if (ns->eth.rx_bytes < pf->internal_stats.rx_bytes)
3201 		ns->eth.rx_bytes = 0;
3202 	else
3203 		ns->eth.rx_bytes -= pf->internal_stats.rx_bytes;
3204 
3205 	if (ns->eth.rx_unicast < pf->internal_stats.rx_unicast)
3206 		ns->eth.rx_unicast = 0;
3207 	else
3208 		ns->eth.rx_unicast -= pf->internal_stats.rx_unicast;
3209 
3210 	if (ns->eth.rx_multicast < pf->internal_stats.rx_multicast)
3211 		ns->eth.rx_multicast = 0;
3212 	else
3213 		ns->eth.rx_multicast -= pf->internal_stats.rx_multicast;
3214 
3215 	if (ns->eth.rx_broadcast < pf->internal_stats.rx_broadcast)
3216 		ns->eth.rx_broadcast = 0;
3217 	else
3218 		ns->eth.rx_broadcast -= pf->internal_stats.rx_broadcast;
3219 
3220 	i40e_stat_update_32(hw, I40E_GLPRT_RDPC(hw->port),
3221 			    pf->offset_loaded, &os->eth.rx_discards,
3222 			    &ns->eth.rx_discards);
3223 	/* GLPRT_REPC not supported */
3224 	/* GLPRT_RMPC not supported */
3225 	i40e_stat_update_32(hw, I40E_GLPRT_RUPP(hw->port),
3226 			    pf->offset_loaded,
3227 			    &os->eth.rx_unknown_protocol,
3228 			    &ns->eth.rx_unknown_protocol);
3229 	i40e_stat_update_48_in_64(hw, I40E_GLPRT_GOTCH(hw->port),
3230 				  I40E_GLPRT_GOTCL(hw->port),
3231 				  pf->offset_loaded, &os->eth.tx_bytes,
3232 				  &ns->eth.tx_bytes, &pf->prev_tx_bytes);
3233 	i40e_stat_update_48(hw, I40E_GLPRT_UPTCH(hw->port),
3234 			    I40E_GLPRT_UPTCL(hw->port),
3235 			    pf->offset_loaded, &os->eth.tx_unicast,
3236 			    &ns->eth.tx_unicast);
3237 	i40e_stat_update_48(hw, I40E_GLPRT_MPTCH(hw->port),
3238 			    I40E_GLPRT_MPTCL(hw->port),
3239 			    pf->offset_loaded, &os->eth.tx_multicast,
3240 			    &ns->eth.tx_multicast);
3241 	i40e_stat_update_48(hw, I40E_GLPRT_BPTCH(hw->port),
3242 			    I40E_GLPRT_BPTCL(hw->port),
3243 			    pf->offset_loaded, &os->eth.tx_broadcast,
3244 			    &ns->eth.tx_broadcast);
3245 	ns->eth.tx_bytes -= (ns->eth.tx_unicast + ns->eth.tx_multicast +
3246 		ns->eth.tx_broadcast) * RTE_ETHER_CRC_LEN;
3247 
3248 	/* exclude internal tx bytes
3249 	 * Workaround: it is possible I40E_GLV_GOTCH[H/L] is updated before
3250 	 * I40E_GLPRT_GOTCH[H/L], so there is a small window that cause negative
3251 	 * value.
3252 	 * same to I40E_GLV_UPTC[H/L], I40E_GLV_MPTC[H/L], I40E_GLV_BPTC[H/L].
3253 	 */
3254 	if (ns->eth.tx_bytes < pf->internal_stats.tx_bytes)
3255 		ns->eth.tx_bytes = 0;
3256 	else
3257 		ns->eth.tx_bytes -= pf->internal_stats.tx_bytes;
3258 
3259 	if (ns->eth.tx_unicast < pf->internal_stats.tx_unicast)
3260 		ns->eth.tx_unicast = 0;
3261 	else
3262 		ns->eth.tx_unicast -= pf->internal_stats.tx_unicast;
3263 
3264 	if (ns->eth.tx_multicast < pf->internal_stats.tx_multicast)
3265 		ns->eth.tx_multicast = 0;
3266 	else
3267 		ns->eth.tx_multicast -= pf->internal_stats.tx_multicast;
3268 
3269 	if (ns->eth.tx_broadcast < pf->internal_stats.tx_broadcast)
3270 		ns->eth.tx_broadcast = 0;
3271 	else
3272 		ns->eth.tx_broadcast -= pf->internal_stats.tx_broadcast;
3273 
3274 	/* GLPRT_TEPC not supported */
3275 
3276 	/* additional port specific stats */
3277 	i40e_stat_update_32(hw, I40E_GLPRT_TDOLD(hw->port),
3278 			    pf->offset_loaded, &os->tx_dropped_link_down,
3279 			    &ns->tx_dropped_link_down);
3280 	i40e_stat_update_32(hw, I40E_GLPRT_CRCERRS(hw->port),
3281 			    pf->offset_loaded, &os->crc_errors,
3282 			    &ns->crc_errors);
3283 	i40e_stat_update_32(hw, I40E_GLPRT_ILLERRC(hw->port),
3284 			    pf->offset_loaded, &os->illegal_bytes,
3285 			    &ns->illegal_bytes);
3286 	/* GLPRT_ERRBC not supported */
3287 	i40e_stat_update_32(hw, I40E_GLPRT_MLFC(hw->port),
3288 			    pf->offset_loaded, &os->mac_local_faults,
3289 			    &ns->mac_local_faults);
3290 	i40e_stat_update_32(hw, I40E_GLPRT_MRFC(hw->port),
3291 			    pf->offset_loaded, &os->mac_remote_faults,
3292 			    &ns->mac_remote_faults);
3293 	i40e_stat_update_32(hw, I40E_GLPRT_RLEC(hw->port),
3294 			    pf->offset_loaded, &os->rx_length_errors,
3295 			    &ns->rx_length_errors);
3296 	i40e_stat_update_32(hw, I40E_GLPRT_LXONRXC(hw->port),
3297 			    pf->offset_loaded, &os->link_xon_rx,
3298 			    &ns->link_xon_rx);
3299 	i40e_stat_update_32(hw, I40E_GLPRT_LXOFFRXC(hw->port),
3300 			    pf->offset_loaded, &os->link_xoff_rx,
3301 			    &ns->link_xoff_rx);
3302 	for (i = 0; i < 8; i++) {
3303 		i40e_stat_update_32(hw, I40E_GLPRT_PXONRXC(hw->port, i),
3304 				    pf->offset_loaded,
3305 				    &os->priority_xon_rx[i],
3306 				    &ns->priority_xon_rx[i]);
3307 		i40e_stat_update_32(hw, I40E_GLPRT_PXOFFRXC(hw->port, i),
3308 				    pf->offset_loaded,
3309 				    &os->priority_xoff_rx[i],
3310 				    &ns->priority_xoff_rx[i]);
3311 	}
3312 	i40e_stat_update_32(hw, I40E_GLPRT_LXONTXC(hw->port),
3313 			    pf->offset_loaded, &os->link_xon_tx,
3314 			    &ns->link_xon_tx);
3315 	i40e_stat_update_32(hw, I40E_GLPRT_LXOFFTXC(hw->port),
3316 			    pf->offset_loaded, &os->link_xoff_tx,
3317 			    &ns->link_xoff_tx);
3318 	for (i = 0; i < 8; i++) {
3319 		i40e_stat_update_32(hw, I40E_GLPRT_PXONTXC(hw->port, i),
3320 				    pf->offset_loaded,
3321 				    &os->priority_xon_tx[i],
3322 				    &ns->priority_xon_tx[i]);
3323 		i40e_stat_update_32(hw, I40E_GLPRT_PXOFFTXC(hw->port, i),
3324 				    pf->offset_loaded,
3325 				    &os->priority_xoff_tx[i],
3326 				    &ns->priority_xoff_tx[i]);
3327 		i40e_stat_update_32(hw, I40E_GLPRT_RXON2OFFCNT(hw->port, i),
3328 				    pf->offset_loaded,
3329 				    &os->priority_xon_2_xoff[i],
3330 				    &ns->priority_xon_2_xoff[i]);
3331 	}
3332 	i40e_stat_update_48(hw, I40E_GLPRT_PRC64H(hw->port),
3333 			    I40E_GLPRT_PRC64L(hw->port),
3334 			    pf->offset_loaded, &os->rx_size_64,
3335 			    &ns->rx_size_64);
3336 	i40e_stat_update_48(hw, I40E_GLPRT_PRC127H(hw->port),
3337 			    I40E_GLPRT_PRC127L(hw->port),
3338 			    pf->offset_loaded, &os->rx_size_127,
3339 			    &ns->rx_size_127);
3340 	i40e_stat_update_48(hw, I40E_GLPRT_PRC255H(hw->port),
3341 			    I40E_GLPRT_PRC255L(hw->port),
3342 			    pf->offset_loaded, &os->rx_size_255,
3343 			    &ns->rx_size_255);
3344 	i40e_stat_update_48(hw, I40E_GLPRT_PRC511H(hw->port),
3345 			    I40E_GLPRT_PRC511L(hw->port),
3346 			    pf->offset_loaded, &os->rx_size_511,
3347 			    &ns->rx_size_511);
3348 	i40e_stat_update_48(hw, I40E_GLPRT_PRC1023H(hw->port),
3349 			    I40E_GLPRT_PRC1023L(hw->port),
3350 			    pf->offset_loaded, &os->rx_size_1023,
3351 			    &ns->rx_size_1023);
3352 	i40e_stat_update_48(hw, I40E_GLPRT_PRC1522H(hw->port),
3353 			    I40E_GLPRT_PRC1522L(hw->port),
3354 			    pf->offset_loaded, &os->rx_size_1522,
3355 			    &ns->rx_size_1522);
3356 	i40e_stat_update_48(hw, I40E_GLPRT_PRC9522H(hw->port),
3357 			    I40E_GLPRT_PRC9522L(hw->port),
3358 			    pf->offset_loaded, &os->rx_size_big,
3359 			    &ns->rx_size_big);
3360 	i40e_stat_update_32(hw, I40E_GLPRT_RUC(hw->port),
3361 			    pf->offset_loaded, &os->rx_undersize,
3362 			    &ns->rx_undersize);
3363 	i40e_stat_update_32(hw, I40E_GLPRT_RFC(hw->port),
3364 			    pf->offset_loaded, &os->rx_fragments,
3365 			    &ns->rx_fragments);
3366 	i40e_stat_update_32(hw, I40E_GLPRT_ROC(hw->port),
3367 			    pf->offset_loaded, &os->rx_oversize,
3368 			    &ns->rx_oversize);
3369 	i40e_stat_update_32(hw, I40E_GLPRT_RJC(hw->port),
3370 			    pf->offset_loaded, &os->rx_jabber,
3371 			    &ns->rx_jabber);
3372 	i40e_stat_update_48(hw, I40E_GLPRT_PTC64H(hw->port),
3373 			    I40E_GLPRT_PTC64L(hw->port),
3374 			    pf->offset_loaded, &os->tx_size_64,
3375 			    &ns->tx_size_64);
3376 	i40e_stat_update_48(hw, I40E_GLPRT_PTC127H(hw->port),
3377 			    I40E_GLPRT_PTC127L(hw->port),
3378 			    pf->offset_loaded, &os->tx_size_127,
3379 			    &ns->tx_size_127);
3380 	i40e_stat_update_48(hw, I40E_GLPRT_PTC255H(hw->port),
3381 			    I40E_GLPRT_PTC255L(hw->port),
3382 			    pf->offset_loaded, &os->tx_size_255,
3383 			    &ns->tx_size_255);
3384 	i40e_stat_update_48(hw, I40E_GLPRT_PTC511H(hw->port),
3385 			    I40E_GLPRT_PTC511L(hw->port),
3386 			    pf->offset_loaded, &os->tx_size_511,
3387 			    &ns->tx_size_511);
3388 	i40e_stat_update_48(hw, I40E_GLPRT_PTC1023H(hw->port),
3389 			    I40E_GLPRT_PTC1023L(hw->port),
3390 			    pf->offset_loaded, &os->tx_size_1023,
3391 			    &ns->tx_size_1023);
3392 	i40e_stat_update_48(hw, I40E_GLPRT_PTC1522H(hw->port),
3393 			    I40E_GLPRT_PTC1522L(hw->port),
3394 			    pf->offset_loaded, &os->tx_size_1522,
3395 			    &ns->tx_size_1522);
3396 	i40e_stat_update_48(hw, I40E_GLPRT_PTC9522H(hw->port),
3397 			    I40E_GLPRT_PTC9522L(hw->port),
3398 			    pf->offset_loaded, &os->tx_size_big,
3399 			    &ns->tx_size_big);
3400 	i40e_stat_update_32(hw, I40E_GLQF_PCNT(pf->fdir.match_counter_index),
3401 			   pf->offset_loaded,
3402 			   &os->fd_sb_match, &ns->fd_sb_match);
3403 	/* GLPRT_MSPDC not supported */
3404 	/* GLPRT_XEC not supported */
3405 
3406 	pf->offset_loaded = true;
3407 
3408 	if (pf->main_vsi)
3409 		i40e_update_vsi_stats(pf->main_vsi);
3410 }
3411 
3412 /* Get all statistics of a port */
3413 static int
3414 i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
3415 {
3416 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
3417 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3418 	struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
3419 	struct i40e_vsi *vsi;
3420 	unsigned i;
3421 
3422 	/* call read registers - updates values, now write them to struct */
3423 	i40e_read_stats_registers(pf, hw);
3424 
3425 	stats->ipackets = pf->main_vsi->eth_stats.rx_unicast +
3426 			pf->main_vsi->eth_stats.rx_multicast +
3427 			pf->main_vsi->eth_stats.rx_broadcast -
3428 			pf->main_vsi->eth_stats.rx_discards;
3429 	stats->opackets = ns->eth.tx_unicast +
3430 			ns->eth.tx_multicast +
3431 			ns->eth.tx_broadcast;
3432 	stats->ibytes   = pf->main_vsi->eth_stats.rx_bytes;
3433 	stats->obytes   = ns->eth.tx_bytes;
3434 	stats->oerrors  = ns->eth.tx_errors +
3435 			pf->main_vsi->eth_stats.tx_errors;
3436 
3437 	/* Rx Errors */
3438 	stats->imissed  = ns->eth.rx_discards +
3439 			pf->main_vsi->eth_stats.rx_discards;
3440 	stats->ierrors  = ns->crc_errors +
3441 			ns->rx_length_errors + ns->rx_undersize +
3442 			ns->rx_oversize + ns->rx_fragments + ns->rx_jabber;
3443 
3444 	if (pf->vfs) {
3445 		for (i = 0; i < pf->vf_num; i++) {
3446 			vsi = pf->vfs[i].vsi;
3447 			i40e_update_vsi_stats(vsi);
3448 
3449 			stats->ipackets += (vsi->eth_stats.rx_unicast +
3450 					vsi->eth_stats.rx_multicast +
3451 					vsi->eth_stats.rx_broadcast -
3452 					vsi->eth_stats.rx_discards);
3453 			stats->ibytes   += vsi->eth_stats.rx_bytes;
3454 			stats->oerrors  += vsi->eth_stats.tx_errors;
3455 			stats->imissed  += vsi->eth_stats.rx_discards;
3456 		}
3457 	}
3458 
3459 	PMD_DRV_LOG(DEBUG, "***************** PF stats start *******************");
3460 	PMD_DRV_LOG(DEBUG, "rx_bytes:            %"PRIu64"", ns->eth.rx_bytes);
3461 	PMD_DRV_LOG(DEBUG, "rx_unicast:          %"PRIu64"", ns->eth.rx_unicast);
3462 	PMD_DRV_LOG(DEBUG, "rx_multicast:        %"PRIu64"", ns->eth.rx_multicast);
3463 	PMD_DRV_LOG(DEBUG, "rx_broadcast:        %"PRIu64"", ns->eth.rx_broadcast);
3464 	PMD_DRV_LOG(DEBUG, "rx_discards:         %"PRIu64"", ns->eth.rx_discards);
3465 	PMD_DRV_LOG(DEBUG, "rx_unknown_protocol: %"PRIu64"",
3466 		    ns->eth.rx_unknown_protocol);
3467 	PMD_DRV_LOG(DEBUG, "tx_bytes:            %"PRIu64"", ns->eth.tx_bytes);
3468 	PMD_DRV_LOG(DEBUG, "tx_unicast:          %"PRIu64"", ns->eth.tx_unicast);
3469 	PMD_DRV_LOG(DEBUG, "tx_multicast:        %"PRIu64"", ns->eth.tx_multicast);
3470 	PMD_DRV_LOG(DEBUG, "tx_broadcast:        %"PRIu64"", ns->eth.tx_broadcast);
3471 	PMD_DRV_LOG(DEBUG, "tx_discards:         %"PRIu64"", ns->eth.tx_discards);
3472 	PMD_DRV_LOG(DEBUG, "tx_errors:           %"PRIu64"", ns->eth.tx_errors);
3473 
3474 	PMD_DRV_LOG(DEBUG, "tx_dropped_link_down:     %"PRIu64"",
3475 		    ns->tx_dropped_link_down);
3476 	PMD_DRV_LOG(DEBUG, "crc_errors:               %"PRIu64"", ns->crc_errors);
3477 	PMD_DRV_LOG(DEBUG, "illegal_bytes:            %"PRIu64"",
3478 		    ns->illegal_bytes);
3479 	PMD_DRV_LOG(DEBUG, "error_bytes:              %"PRIu64"", ns->error_bytes);
3480 	PMD_DRV_LOG(DEBUG, "mac_local_faults:         %"PRIu64"",
3481 		    ns->mac_local_faults);
3482 	PMD_DRV_LOG(DEBUG, "mac_remote_faults:        %"PRIu64"",
3483 		    ns->mac_remote_faults);
3484 	PMD_DRV_LOG(DEBUG, "rx_length_errors:         %"PRIu64"",
3485 		    ns->rx_length_errors);
3486 	PMD_DRV_LOG(DEBUG, "link_xon_rx:              %"PRIu64"", ns->link_xon_rx);
3487 	PMD_DRV_LOG(DEBUG, "link_xoff_rx:             %"PRIu64"", ns->link_xoff_rx);
3488 	for (i = 0; i < 8; i++) {
3489 		PMD_DRV_LOG(DEBUG, "priority_xon_rx[%d]:      %"PRIu64"",
3490 				i, ns->priority_xon_rx[i]);
3491 		PMD_DRV_LOG(DEBUG, "priority_xoff_rx[%d]:     %"PRIu64"",
3492 				i, ns->priority_xoff_rx[i]);
3493 	}
3494 	PMD_DRV_LOG(DEBUG, "link_xon_tx:              %"PRIu64"", ns->link_xon_tx);
3495 	PMD_DRV_LOG(DEBUG, "link_xoff_tx:             %"PRIu64"", ns->link_xoff_tx);
3496 	for (i = 0; i < 8; i++) {
3497 		PMD_DRV_LOG(DEBUG, "priority_xon_tx[%d]:      %"PRIu64"",
3498 				i, ns->priority_xon_tx[i]);
3499 		PMD_DRV_LOG(DEBUG, "priority_xoff_tx[%d]:     %"PRIu64"",
3500 				i, ns->priority_xoff_tx[i]);
3501 		PMD_DRV_LOG(DEBUG, "priority_xon_2_xoff[%d]:  %"PRIu64"",
3502 				i, ns->priority_xon_2_xoff[i]);
3503 	}
3504 	PMD_DRV_LOG(DEBUG, "rx_size_64:               %"PRIu64"", ns->rx_size_64);
3505 	PMD_DRV_LOG(DEBUG, "rx_size_127:              %"PRIu64"", ns->rx_size_127);
3506 	PMD_DRV_LOG(DEBUG, "rx_size_255:              %"PRIu64"", ns->rx_size_255);
3507 	PMD_DRV_LOG(DEBUG, "rx_size_511:              %"PRIu64"", ns->rx_size_511);
3508 	PMD_DRV_LOG(DEBUG, "rx_size_1023:             %"PRIu64"", ns->rx_size_1023);
3509 	PMD_DRV_LOG(DEBUG, "rx_size_1522:             %"PRIu64"", ns->rx_size_1522);
3510 	PMD_DRV_LOG(DEBUG, "rx_size_big:              %"PRIu64"", ns->rx_size_big);
3511 	PMD_DRV_LOG(DEBUG, "rx_undersize:             %"PRIu64"", ns->rx_undersize);
3512 	PMD_DRV_LOG(DEBUG, "rx_fragments:             %"PRIu64"", ns->rx_fragments);
3513 	PMD_DRV_LOG(DEBUG, "rx_oversize:              %"PRIu64"", ns->rx_oversize);
3514 	PMD_DRV_LOG(DEBUG, "rx_jabber:                %"PRIu64"", ns->rx_jabber);
3515 	PMD_DRV_LOG(DEBUG, "tx_size_64:               %"PRIu64"", ns->tx_size_64);
3516 	PMD_DRV_LOG(DEBUG, "tx_size_127:              %"PRIu64"", ns->tx_size_127);
3517 	PMD_DRV_LOG(DEBUG, "tx_size_255:              %"PRIu64"", ns->tx_size_255);
3518 	PMD_DRV_LOG(DEBUG, "tx_size_511:              %"PRIu64"", ns->tx_size_511);
3519 	PMD_DRV_LOG(DEBUG, "tx_size_1023:             %"PRIu64"", ns->tx_size_1023);
3520 	PMD_DRV_LOG(DEBUG, "tx_size_1522:             %"PRIu64"", ns->tx_size_1522);
3521 	PMD_DRV_LOG(DEBUG, "tx_size_big:              %"PRIu64"", ns->tx_size_big);
3522 	PMD_DRV_LOG(DEBUG, "mac_short_packet_dropped: %"PRIu64"",
3523 			ns->mac_short_packet_dropped);
3524 	PMD_DRV_LOG(DEBUG, "checksum_error:           %"PRIu64"",
3525 		    ns->checksum_error);
3526 	PMD_DRV_LOG(DEBUG, "fdir_match:               %"PRIu64"", ns->fd_sb_match);
3527 	PMD_DRV_LOG(DEBUG, "***************** PF stats end ********************");
3528 	return 0;
3529 }
3530 
3531 /* Reset the statistics */
3532 static int
3533 i40e_dev_stats_reset(struct rte_eth_dev *dev)
3534 {
3535 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
3536 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3537 
3538 	/* Mark PF and VSI stats to update the offset, aka "reset" */
3539 	pf->offset_loaded = false;
3540 	if (pf->main_vsi)
3541 		pf->main_vsi->offset_loaded = false;
3542 
3543 	/* read the stats, reading current register values into offset */
3544 	i40e_read_stats_registers(pf, hw);
3545 
3546 	return 0;
3547 }
3548 
3549 static uint32_t
3550 i40e_xstats_calc_num(void)
3551 {
3552 	return I40E_NB_ETH_XSTATS + I40E_NB_HW_PORT_XSTATS +
3553 		(I40E_NB_RXQ_PRIO_XSTATS * 8) +
3554 		(I40E_NB_TXQ_PRIO_XSTATS * 8);
3555 }
3556 
3557 static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
3558 				     struct rte_eth_xstat_name *xstats_names,
3559 				     __rte_unused unsigned limit)
3560 {
3561 	unsigned count = 0;
3562 	unsigned i, prio;
3563 
3564 	if (xstats_names == NULL)
3565 		return i40e_xstats_calc_num();
3566 
3567 	/* Note: limit checked in rte_eth_xstats_names() */
3568 
3569 	/* Get stats from i40e_eth_stats struct */
3570 	for (i = 0; i < I40E_NB_ETH_XSTATS; i++) {
3571 		strlcpy(xstats_names[count].name,
3572 			rte_i40e_stats_strings[i].name,
3573 			sizeof(xstats_names[count].name));
3574 		count++;
3575 	}
3576 
3577 	/* Get individiual stats from i40e_hw_port struct */
3578 	for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
3579 		strlcpy(xstats_names[count].name,
3580 			rte_i40e_hw_port_strings[i].name,
3581 			sizeof(xstats_names[count].name));
3582 		count++;
3583 	}
3584 
3585 	for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) {
3586 		for (prio = 0; prio < 8; prio++) {
3587 			snprintf(xstats_names[count].name,
3588 				 sizeof(xstats_names[count].name),
3589 				 "rx_priority%u_%s", prio,
3590 				 rte_i40e_rxq_prio_strings[i].name);
3591 			count++;
3592 		}
3593 	}
3594 
3595 	for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) {
3596 		for (prio = 0; prio < 8; prio++) {
3597 			snprintf(xstats_names[count].name,
3598 				 sizeof(xstats_names[count].name),
3599 				 "tx_priority%u_%s", prio,
3600 				 rte_i40e_txq_prio_strings[i].name);
3601 			count++;
3602 		}
3603 	}
3604 	return count;
3605 }
3606 
3607 static int
3608 i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
3609 		    unsigned n)
3610 {
3611 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
3612 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3613 	unsigned i, count, prio;
3614 	struct i40e_hw_port_stats *hw_stats = &pf->stats;
3615 
3616 	count = i40e_xstats_calc_num();
3617 	if (n < count)
3618 		return count;
3619 
3620 	i40e_read_stats_registers(pf, hw);
3621 
3622 	if (xstats == NULL)
3623 		return 0;
3624 
3625 	count = 0;
3626 
3627 	/* Get stats from i40e_eth_stats struct */
3628 	for (i = 0; i < I40E_NB_ETH_XSTATS; i++) {
3629 		xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) +
3630 			rte_i40e_stats_strings[i].offset);
3631 		xstats[count].id = count;
3632 		count++;
3633 	}
3634 
3635 	/* Get individiual stats from i40e_hw_port struct */
3636 	for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
3637 		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
3638 			rte_i40e_hw_port_strings[i].offset);
3639 		xstats[count].id = count;
3640 		count++;
3641 	}
3642 
3643 	for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) {
3644 		for (prio = 0; prio < 8; prio++) {
3645 			xstats[count].value =
3646 				*(uint64_t *)(((char *)hw_stats) +
3647 				rte_i40e_rxq_prio_strings[i].offset +
3648 				(sizeof(uint64_t) * prio));
3649 			xstats[count].id = count;
3650 			count++;
3651 		}
3652 	}
3653 
3654 	for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) {
3655 		for (prio = 0; prio < 8; prio++) {
3656 			xstats[count].value =
3657 				*(uint64_t *)(((char *)hw_stats) +
3658 				rte_i40e_txq_prio_strings[i].offset +
3659 				(sizeof(uint64_t) * prio));
3660 			xstats[count].id = count;
3661 			count++;
3662 		}
3663 	}
3664 
3665 	return count;
3666 }
3667 
3668 static int
3669 i40e_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
3670 {
3671 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3672 	u32 full_ver;
3673 	u8 ver, patch;
3674 	u16 build;
3675 	int ret;
3676 
3677 	full_ver = hw->nvm.oem_ver;
3678 	ver = (u8)(full_ver >> 24);
3679 	build = (u16)((full_ver >> 8) & 0xffff);
3680 	patch = (u8)(full_ver & 0xff);
3681 
3682 	ret = snprintf(fw_version, fw_size,
3683 		 "%d.%d%d 0x%08x %d.%d.%d",
3684 		 ((hw->nvm.version >> 12) & 0xf),
3685 		 ((hw->nvm.version >> 4) & 0xff),
3686 		 (hw->nvm.version & 0xf), hw->nvm.eetrack,
3687 		 ver, build, patch);
3688 
3689 	ret += 1; /* add the size of '\0' */
3690 	if (fw_size < (u32)ret)
3691 		return ret;
3692 	else
3693 		return 0;
3694 }
3695 
3696 /*
3697  * When using NVM 6.01(for X710 XL710 XXV710)/3.33(for X722) or later,
3698  * the Rx data path does not hang if the FW LLDP is stopped.
3699  * return true if lldp need to stop
3700  * return false if we cannot disable the LLDP to avoid Rx data path blocking.
3701  */
3702 static bool
3703 i40e_need_stop_lldp(struct rte_eth_dev *dev)
3704 {
3705 	double nvm_ver;
3706 	char ver_str[64] = {0};
3707 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3708 
3709 	i40e_fw_version_get(dev, ver_str, 64);
3710 	nvm_ver = atof(ver_str);
3711 	if ((hw->mac.type == I40E_MAC_X722 ||
3712 	     hw->mac.type == I40E_MAC_X722_VF) &&
3713 	     ((uint32_t)(nvm_ver * 1000) >= (uint32_t)(3.33 * 1000)))
3714 		return true;
3715 	else if ((uint32_t)(nvm_ver * 1000) >= (uint32_t)(6.01 * 1000))
3716 		return true;
3717 
3718 	return false;
3719 }
3720 
3721 static int
3722 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
3723 {
3724 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
3725 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3726 	struct i40e_vsi *vsi = pf->main_vsi;
3727 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
3728 
3729 	dev_info->max_rx_queues = vsi->nb_qps;
3730 	dev_info->max_tx_queues = vsi->nb_qps;
3731 	dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
3732 	dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
3733 	dev_info->max_mac_addrs = vsi->max_macaddrs;
3734 	dev_info->max_vfs = pci_dev->max_vfs;
3735 	dev_info->max_mtu = dev_info->max_rx_pktlen - I40E_ETH_OVERHEAD;
3736 	dev_info->min_mtu = RTE_ETHER_MIN_MTU;
3737 	dev_info->rx_queue_offload_capa = 0;
3738 	dev_info->rx_offload_capa =
3739 		DEV_RX_OFFLOAD_VLAN_STRIP |
3740 		DEV_RX_OFFLOAD_QINQ_STRIP |
3741 		DEV_RX_OFFLOAD_IPV4_CKSUM |
3742 		DEV_RX_OFFLOAD_UDP_CKSUM |
3743 		DEV_RX_OFFLOAD_TCP_CKSUM |
3744 		DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
3745 		DEV_RX_OFFLOAD_KEEP_CRC |
3746 		DEV_RX_OFFLOAD_SCATTER |
3747 		DEV_RX_OFFLOAD_VLAN_EXTEND |
3748 		DEV_RX_OFFLOAD_VLAN_FILTER |
3749 		DEV_RX_OFFLOAD_JUMBO_FRAME |
3750 		DEV_RX_OFFLOAD_RSS_HASH;
3751 
3752 	dev_info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE;
3753 	dev_info->tx_offload_capa =
3754 		DEV_TX_OFFLOAD_VLAN_INSERT |
3755 		DEV_TX_OFFLOAD_QINQ_INSERT |
3756 		DEV_TX_OFFLOAD_IPV4_CKSUM |
3757 		DEV_TX_OFFLOAD_UDP_CKSUM |
3758 		DEV_TX_OFFLOAD_TCP_CKSUM |
3759 		DEV_TX_OFFLOAD_SCTP_CKSUM |
3760 		DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
3761 		DEV_TX_OFFLOAD_TCP_TSO |
3762 		DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
3763 		DEV_TX_OFFLOAD_GRE_TNL_TSO |
3764 		DEV_TX_OFFLOAD_IPIP_TNL_TSO |
3765 		DEV_TX_OFFLOAD_GENEVE_TNL_TSO |
3766 		DEV_TX_OFFLOAD_MULTI_SEGS |
3767 		dev_info->tx_queue_offload_capa;
3768 	dev_info->dev_capa =
3769 		RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
3770 		RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
3771 
3772 	dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
3773 						sizeof(uint32_t);
3774 	dev_info->reta_size = pf->hash_lut_size;
3775 	dev_info->flow_type_rss_offloads = pf->adapter->flow_types_mask;
3776 
3777 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
3778 		.rx_thresh = {
3779 			.pthresh = I40E_DEFAULT_RX_PTHRESH,
3780 			.hthresh = I40E_DEFAULT_RX_HTHRESH,
3781 			.wthresh = I40E_DEFAULT_RX_WTHRESH,
3782 		},
3783 		.rx_free_thresh = I40E_DEFAULT_RX_FREE_THRESH,
3784 		.rx_drop_en = 0,
3785 		.offloads = 0,
3786 	};
3787 
3788 	dev_info->default_txconf = (struct rte_eth_txconf) {
3789 		.tx_thresh = {
3790 			.pthresh = I40E_DEFAULT_TX_PTHRESH,
3791 			.hthresh = I40E_DEFAULT_TX_HTHRESH,
3792 			.wthresh = I40E_DEFAULT_TX_WTHRESH,
3793 		},
3794 		.tx_free_thresh = I40E_DEFAULT_TX_FREE_THRESH,
3795 		.tx_rs_thresh = I40E_DEFAULT_TX_RSBIT_THRESH,
3796 		.offloads = 0,
3797 	};
3798 
3799 	dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
3800 		.nb_max = I40E_MAX_RING_DESC,
3801 		.nb_min = I40E_MIN_RING_DESC,
3802 		.nb_align = I40E_ALIGN_RING_DESC,
3803 	};
3804 
3805 	dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
3806 		.nb_max = I40E_MAX_RING_DESC,
3807 		.nb_min = I40E_MIN_RING_DESC,
3808 		.nb_align = I40E_ALIGN_RING_DESC,
3809 		.nb_seg_max = I40E_TX_MAX_SEG,
3810 		.nb_mtu_seg_max = I40E_TX_MAX_MTU_SEG,
3811 	};
3812 
3813 	if (pf->flags & I40E_FLAG_VMDQ) {
3814 		dev_info->max_vmdq_pools = pf->max_nb_vmdq_vsi;
3815 		dev_info->vmdq_queue_base = dev_info->max_rx_queues;
3816 		dev_info->vmdq_queue_num = pf->vmdq_nb_qps *
3817 						pf->max_nb_vmdq_vsi;
3818 		dev_info->vmdq_pool_base = I40E_VMDQ_POOL_BASE;
3819 		dev_info->max_rx_queues += dev_info->vmdq_queue_num;
3820 		dev_info->max_tx_queues += dev_info->vmdq_queue_num;
3821 	}
3822 
3823 	if (I40E_PHY_TYPE_SUPPORT_40G(hw->phy.phy_types)) {
3824 		/* For XL710 */
3825 		dev_info->speed_capa = ETH_LINK_SPEED_40G;
3826 		dev_info->default_rxportconf.nb_queues = 2;
3827 		dev_info->default_txportconf.nb_queues = 2;
3828 		if (dev->data->nb_rx_queues == 1)
3829 			dev_info->default_rxportconf.ring_size = 2048;
3830 		else
3831 			dev_info->default_rxportconf.ring_size = 1024;
3832 		if (dev->data->nb_tx_queues == 1)
3833 			dev_info->default_txportconf.ring_size = 1024;
3834 		else
3835 			dev_info->default_txportconf.ring_size = 512;
3836 
3837 	} else if (I40E_PHY_TYPE_SUPPORT_25G(hw->phy.phy_types)) {
3838 		/* For XXV710 */
3839 		dev_info->speed_capa = ETH_LINK_SPEED_25G;
3840 		dev_info->default_rxportconf.nb_queues = 1;
3841 		dev_info->default_txportconf.nb_queues = 1;
3842 		dev_info->default_rxportconf.ring_size = 256;
3843 		dev_info->default_txportconf.ring_size = 256;
3844 	} else {
3845 		/* For X710 */
3846 		dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
3847 		dev_info->default_rxportconf.nb_queues = 1;
3848 		dev_info->default_txportconf.nb_queues = 1;
3849 		if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_10G) {
3850 			dev_info->default_rxportconf.ring_size = 512;
3851 			dev_info->default_txportconf.ring_size = 256;
3852 		} else {
3853 			dev_info->default_rxportconf.ring_size = 256;
3854 			dev_info->default_txportconf.ring_size = 256;
3855 		}
3856 	}
3857 	dev_info->default_rxportconf.burst_size = 32;
3858 	dev_info->default_txportconf.burst_size = 32;
3859 
3860 	return 0;
3861 }
3862 
3863 static int
3864 i40e_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
3865 {
3866 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
3867 	struct i40e_vsi *vsi = pf->main_vsi;
3868 	PMD_INIT_FUNC_TRACE();
3869 
3870 	if (on)
3871 		return i40e_vsi_add_vlan(vsi, vlan_id);
3872 	else
3873 		return i40e_vsi_delete_vlan(vsi, vlan_id);
3874 }
3875 
3876 static int
3877 i40e_vlan_tpid_set_by_registers(struct rte_eth_dev *dev,
3878 				enum rte_vlan_type vlan_type,
3879 				uint16_t tpid, int qinq)
3880 {
3881 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3882 	uint64_t reg_r = 0;
3883 	uint64_t reg_w = 0;
3884 	uint16_t reg_id = 3;
3885 	int ret;
3886 
3887 	if (qinq) {
3888 		if (vlan_type == ETH_VLAN_TYPE_OUTER)
3889 			reg_id = 2;
3890 	}
3891 
3892 	ret = i40e_aq_debug_read_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id),
3893 					  &reg_r, NULL);
3894 	if (ret != I40E_SUCCESS) {
3895 		PMD_DRV_LOG(ERR,
3896 			   "Fail to debug read from I40E_GL_SWT_L2TAGCTRL[%d]",
3897 			   reg_id);
3898 		return -EIO;
3899 	}
3900 	PMD_DRV_LOG(DEBUG,
3901 		    "Debug read from I40E_GL_SWT_L2TAGCTRL[%d]: 0x%08"PRIx64,
3902 		    reg_id, reg_r);
3903 
3904 	reg_w = reg_r & (~(I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK));
3905 	reg_w |= ((uint64_t)tpid << I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT);
3906 	if (reg_r == reg_w) {
3907 		PMD_DRV_LOG(DEBUG, "No need to write");
3908 		return 0;
3909 	}
3910 
3911 	ret = i40e_aq_debug_write_global_register(hw,
3912 					   I40E_GL_SWT_L2TAGCTRL(reg_id),
3913 					   reg_w, NULL);
3914 	if (ret != I40E_SUCCESS) {
3915 		PMD_DRV_LOG(ERR,
3916 			    "Fail to debug write to I40E_GL_SWT_L2TAGCTRL[%d]",
3917 			    reg_id);
3918 		return -EIO;
3919 	}
3920 	PMD_DRV_LOG(DEBUG,
3921 		    "Global register 0x%08x is changed with value 0x%08x",
3922 		    I40E_GL_SWT_L2TAGCTRL(reg_id), (uint32_t)reg_w);
3923 
3924 	return 0;
3925 }
3926 
3927 static int
3928 i40e_vlan_tpid_set(struct rte_eth_dev *dev,
3929 		   enum rte_vlan_type vlan_type,
3930 		   uint16_t tpid)
3931 {
3932 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3933 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
3934 	int qinq = dev->data->dev_conf.rxmode.offloads &
3935 		   DEV_RX_OFFLOAD_VLAN_EXTEND;
3936 	int ret = 0;
3937 
3938 	if ((vlan_type != ETH_VLAN_TYPE_INNER &&
3939 	     vlan_type != ETH_VLAN_TYPE_OUTER) ||
3940 	    (!qinq && vlan_type == ETH_VLAN_TYPE_INNER)) {
3941 		PMD_DRV_LOG(ERR,
3942 			    "Unsupported vlan type.");
3943 		return -EINVAL;
3944 	}
3945 
3946 	if (pf->support_multi_driver) {
3947 		PMD_DRV_LOG(ERR, "Setting TPID is not supported.");
3948 		return -ENOTSUP;
3949 	}
3950 
3951 	/* 802.1ad frames ability is added in NVM API 1.7*/
3952 	if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {
3953 		if (qinq) {
3954 			if (vlan_type == ETH_VLAN_TYPE_OUTER)
3955 				hw->first_tag = rte_cpu_to_le_16(tpid);
3956 			else if (vlan_type == ETH_VLAN_TYPE_INNER)
3957 				hw->second_tag = rte_cpu_to_le_16(tpid);
3958 		} else {
3959 			if (vlan_type == ETH_VLAN_TYPE_OUTER)
3960 				hw->second_tag = rte_cpu_to_le_16(tpid);
3961 		}
3962 		ret = i40e_aq_set_switch_config(hw, 0, 0, 0, NULL);
3963 		if (ret != I40E_SUCCESS) {
3964 			PMD_DRV_LOG(ERR,
3965 				    "Set switch config failed aq_err: %d",
3966 				    hw->aq.asq_last_status);
3967 			ret = -EIO;
3968 		}
3969 	} else
3970 		/* If NVM API < 1.7, keep the register setting */
3971 		ret = i40e_vlan_tpid_set_by_registers(dev, vlan_type,
3972 						      tpid, qinq);
3973 
3974 	return ret;
3975 }
3976 
3977 /* Configure outer vlan stripping on or off in QinQ mode */
3978 static int
3979 i40e_vsi_config_outer_vlan_stripping(struct i40e_vsi *vsi, bool on)
3980 {
3981 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
3982 	int ret = I40E_SUCCESS;
3983 	uint32_t reg;
3984 
3985 	if (vsi->vsi_id >= I40E_MAX_NUM_VSIS) {
3986 		PMD_DRV_LOG(ERR, "VSI ID exceeds the maximum");
3987 		return -EINVAL;
3988 	}
3989 
3990 	/* Configure for outer VLAN RX stripping */
3991 	reg = I40E_READ_REG(hw, I40E_VSI_TSR(vsi->vsi_id));
3992 
3993 	if (on)
3994 		reg |= I40E_VSI_TSR_QINQ_STRIP;
3995 	else
3996 		reg &= ~I40E_VSI_TSR_QINQ_STRIP;
3997 
3998 	ret = i40e_aq_debug_write_register(hw,
3999 						   I40E_VSI_TSR(vsi->vsi_id),
4000 						   reg, NULL);
4001 	if (ret < 0) {
4002 		PMD_DRV_LOG(ERR, "Failed to update VSI_TSR[%d]",
4003 				    vsi->vsi_id);
4004 		return I40E_ERR_CONFIG;
4005 	}
4006 
4007 	return ret;
4008 }
4009 
4010 static int
4011 i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)
4012 {
4013 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4014 	struct i40e_vsi *vsi = pf->main_vsi;
4015 	struct rte_eth_rxmode *rxmode;
4016 
4017 	rxmode = &dev->data->dev_conf.rxmode;
4018 	if (mask & ETH_VLAN_FILTER_MASK) {
4019 		if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
4020 			i40e_vsi_config_vlan_filter(vsi, TRUE);
4021 		else
4022 			i40e_vsi_config_vlan_filter(vsi, FALSE);
4023 	}
4024 
4025 	if (mask & ETH_VLAN_STRIP_MASK) {
4026 		/* Enable or disable VLAN stripping */
4027 		if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
4028 			i40e_vsi_config_vlan_stripping(vsi, TRUE);
4029 		else
4030 			i40e_vsi_config_vlan_stripping(vsi, FALSE);
4031 	}
4032 
4033 	if (mask & ETH_VLAN_EXTEND_MASK) {
4034 		if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) {
4035 			i40e_vsi_config_double_vlan(vsi, TRUE);
4036 			/* Set global registers with default ethertype. */
4037 			i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER,
4038 					   RTE_ETHER_TYPE_VLAN);
4039 			i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER,
4040 					   RTE_ETHER_TYPE_VLAN);
4041 		}
4042 		else
4043 			i40e_vsi_config_double_vlan(vsi, FALSE);
4044 	}
4045 
4046 	if (mask & ETH_QINQ_STRIP_MASK) {
4047 		/* Enable or disable outer VLAN stripping */
4048 		if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP)
4049 			i40e_vsi_config_outer_vlan_stripping(vsi, TRUE);
4050 		else
4051 			i40e_vsi_config_outer_vlan_stripping(vsi, FALSE);
4052 	}
4053 
4054 	return 0;
4055 }
4056 
4057 static void
4058 i40e_vlan_strip_queue_set(__rte_unused struct rte_eth_dev *dev,
4059 			  __rte_unused uint16_t queue,
4060 			  __rte_unused int on)
4061 {
4062 	PMD_INIT_FUNC_TRACE();
4063 }
4064 
4065 static int
4066 i40e_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on)
4067 {
4068 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4069 	struct i40e_vsi *vsi = pf->main_vsi;
4070 	struct rte_eth_dev_data *data = I40E_VSI_TO_DEV_DATA(vsi);
4071 	struct i40e_vsi_vlan_pvid_info info;
4072 
4073 	memset(&info, 0, sizeof(info));
4074 	info.on = on;
4075 	if (info.on)
4076 		info.config.pvid = pvid;
4077 	else {
4078 		info.config.reject.tagged =
4079 				data->dev_conf.txmode.hw_vlan_reject_tagged;
4080 		info.config.reject.untagged =
4081 				data->dev_conf.txmode.hw_vlan_reject_untagged;
4082 	}
4083 
4084 	return i40e_vsi_vlan_pvid_set(vsi, &info);
4085 }
4086 
4087 static int
4088 i40e_dev_led_on(struct rte_eth_dev *dev)
4089 {
4090 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
4091 	uint32_t mode = i40e_led_get(hw);
4092 
4093 	if (mode == 0)
4094 		i40e_led_set(hw, 0xf, true); /* 0xf means led always true */
4095 
4096 	return 0;
4097 }
4098 
4099 static int
4100 i40e_dev_led_off(struct rte_eth_dev *dev)
4101 {
4102 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
4103 	uint32_t mode = i40e_led_get(hw);
4104 
4105 	if (mode != 0)
4106 		i40e_led_set(hw, 0, false);
4107 
4108 	return 0;
4109 }
4110 
4111 static int
4112 i40e_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
4113 {
4114 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
4115 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4116 
4117 	fc_conf->pause_time = pf->fc_conf.pause_time;
4118 
4119 	/* read out from register, in case they are modified by other port */
4120 	pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] =
4121 		I40E_READ_REG(hw, I40E_GLRPB_GHW) >> I40E_KILOSHIFT;
4122 	pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] =
4123 		I40E_READ_REG(hw, I40E_GLRPB_GLW) >> I40E_KILOSHIFT;
4124 
4125 	fc_conf->high_water =  pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS];
4126 	fc_conf->low_water = pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS];
4127 
4128 	 /* Return current mode according to actual setting*/
4129 	switch (hw->fc.current_mode) {
4130 	case I40E_FC_FULL:
4131 		fc_conf->mode = RTE_FC_FULL;
4132 		break;
4133 	case I40E_FC_TX_PAUSE:
4134 		fc_conf->mode = RTE_FC_TX_PAUSE;
4135 		break;
4136 	case I40E_FC_RX_PAUSE:
4137 		fc_conf->mode = RTE_FC_RX_PAUSE;
4138 		break;
4139 	case I40E_FC_NONE:
4140 	default:
4141 		fc_conf->mode = RTE_FC_NONE;
4142 	};
4143 
4144 	return 0;
4145 }
4146 
4147 static int
4148 i40e_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
4149 {
4150 	uint32_t mflcn_reg, fctrl_reg, reg;
4151 	uint32_t max_high_water;
4152 	uint8_t i, aq_failure;
4153 	int err;
4154 	struct i40e_hw *hw;
4155 	struct i40e_pf *pf;
4156 	enum i40e_fc_mode rte_fcmode_2_i40e_fcmode[] = {
4157 		[RTE_FC_NONE] = I40E_FC_NONE,
4158 		[RTE_FC_RX_PAUSE] = I40E_FC_RX_PAUSE,
4159 		[RTE_FC_TX_PAUSE] = I40E_FC_TX_PAUSE,
4160 		[RTE_FC_FULL] = I40E_FC_FULL
4161 	};
4162 
4163 	/* high_water field in the rte_eth_fc_conf using the kilobytes unit */
4164 
4165 	max_high_water = I40E_RXPBSIZE >> I40E_KILOSHIFT;
4166 	if ((fc_conf->high_water > max_high_water) ||
4167 			(fc_conf->high_water < fc_conf->low_water)) {
4168 		PMD_INIT_LOG(ERR,
4169 			"Invalid high/low water setup value in KB, High_water must be <= %d.",
4170 			max_high_water);
4171 		return -EINVAL;
4172 	}
4173 
4174 	hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
4175 	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4176 	hw->fc.requested_mode = rte_fcmode_2_i40e_fcmode[fc_conf->mode];
4177 
4178 	pf->fc_conf.pause_time = fc_conf->pause_time;
4179 	pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] = fc_conf->high_water;
4180 	pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] = fc_conf->low_water;
4181 
4182 	PMD_INIT_FUNC_TRACE();
4183 
4184 	/* All the link flow control related enable/disable register
4185 	 * configuration is handle by the F/W
4186 	 */
4187 	err = i40e_set_fc(hw, &aq_failure, true);
4188 	if (err < 0)
4189 		return -ENOSYS;
4190 
4191 	if (I40E_PHY_TYPE_SUPPORT_40G(hw->phy.phy_types)) {
4192 		/* Configure flow control refresh threshold,
4193 		 * the value for stat_tx_pause_refresh_timer[8]
4194 		 * is used for global pause operation.
4195 		 */
4196 
4197 		I40E_WRITE_REG(hw,
4198 			       I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(8),
4199 			       pf->fc_conf.pause_time);
4200 
4201 		/* configure the timer value included in transmitted pause
4202 		 * frame,
4203 		 * the value for stat_tx_pause_quanta[8] is used for global
4204 		 * pause operation
4205 		 */
4206 		I40E_WRITE_REG(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(8),
4207 			       pf->fc_conf.pause_time);
4208 
4209 		fctrl_reg = I40E_READ_REG(hw,
4210 					  I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL);
4211 
4212 		if (fc_conf->mac_ctrl_frame_fwd != 0)
4213 			fctrl_reg |= I40E_PRTMAC_FWD_CTRL;
4214 		else
4215 			fctrl_reg &= ~I40E_PRTMAC_FWD_CTRL;
4216 
4217 		I40E_WRITE_REG(hw, I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL,
4218 			       fctrl_reg);
4219 	} else {
4220 		/* Configure pause time (2 TCs per register) */
4221 		reg = (uint32_t)pf->fc_conf.pause_time * (uint32_t)0x00010001;
4222 		for (i = 0; i < I40E_MAX_TRAFFIC_CLASS / 2; i++)
4223 			I40E_WRITE_REG(hw, I40E_PRTDCB_FCTTVN(i), reg);
4224 
4225 		/* Configure flow control refresh threshold value */
4226 		I40E_WRITE_REG(hw, I40E_PRTDCB_FCRTV,
4227 			       pf->fc_conf.pause_time / 2);
4228 
4229 		mflcn_reg = I40E_READ_REG(hw, I40E_PRTDCB_MFLCN);
4230 
4231 		/* set or clear MFLCN.PMCF & MFLCN.DPF bits
4232 		 *depending on configuration
4233 		 */
4234 		if (fc_conf->mac_ctrl_frame_fwd != 0) {
4235 			mflcn_reg |= I40E_PRTDCB_MFLCN_PMCF_MASK;
4236 			mflcn_reg &= ~I40E_PRTDCB_MFLCN_DPF_MASK;
4237 		} else {
4238 			mflcn_reg &= ~I40E_PRTDCB_MFLCN_PMCF_MASK;
4239 			mflcn_reg |= I40E_PRTDCB_MFLCN_DPF_MASK;
4240 		}
4241 
4242 		I40E_WRITE_REG(hw, I40E_PRTDCB_MFLCN, mflcn_reg);
4243 	}
4244 
4245 	if (!pf->support_multi_driver) {
4246 		/* config water marker both based on the packets and bytes */
4247 		I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PHW,
4248 				 (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
4249 				 << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
4250 		I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PLW,
4251 				  (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
4252 				 << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
4253 		I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GHW,
4254 				  pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
4255 				  << I40E_KILOSHIFT);
4256 		I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GLW,
4257 				   pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
4258 				   << I40E_KILOSHIFT);
4259 	} else {
4260 		PMD_DRV_LOG(ERR,
4261 			    "Water marker configuration is not supported.");
4262 	}
4263 
4264 	I40E_WRITE_FLUSH(hw);
4265 
4266 	return 0;
4267 }
4268 
4269 static int
4270 i40e_priority_flow_ctrl_set(__rte_unused struct rte_eth_dev *dev,
4271 			    __rte_unused struct rte_eth_pfc_conf *pfc_conf)
4272 {
4273 	PMD_INIT_FUNC_TRACE();
4274 
4275 	return -ENOSYS;
4276 }
4277 
4278 /* Add a MAC address, and update filters */
4279 static int
4280 i40e_macaddr_add(struct rte_eth_dev *dev,
4281 		 struct rte_ether_addr *mac_addr,
4282 		 __rte_unused uint32_t index,
4283 		 uint32_t pool)
4284 {
4285 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4286 	struct i40e_mac_filter_info mac_filter;
4287 	struct i40e_vsi *vsi;
4288 	struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
4289 	int ret;
4290 
4291 	/* If VMDQ not enabled or configured, return */
4292 	if (pool != 0 && (!(pf->flags & I40E_FLAG_VMDQ) ||
4293 			  !pf->nb_cfg_vmdq_vsi)) {
4294 		PMD_DRV_LOG(ERR, "VMDQ not %s, can't set mac to pool %u",
4295 			pf->flags & I40E_FLAG_VMDQ ? "configured" : "enabled",
4296 			pool);
4297 		return -ENOTSUP;
4298 	}
4299 
4300 	if (pool > pf->nb_cfg_vmdq_vsi) {
4301 		PMD_DRV_LOG(ERR, "Pool number %u invalid. Max pool is %u",
4302 				pool, pf->nb_cfg_vmdq_vsi);
4303 		return -EINVAL;
4304 	}
4305 
4306 	rte_memcpy(&mac_filter.mac_addr, mac_addr, RTE_ETHER_ADDR_LEN);
4307 	if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
4308 		mac_filter.filter_type = I40E_MACVLAN_PERFECT_MATCH;
4309 	else
4310 		mac_filter.filter_type = I40E_MAC_PERFECT_MATCH;
4311 
4312 	if (pool == 0)
4313 		vsi = pf->main_vsi;
4314 	else
4315 		vsi = pf->vmdq[pool - 1].vsi;
4316 
4317 	ret = i40e_vsi_add_mac(vsi, &mac_filter);
4318 	if (ret != I40E_SUCCESS) {
4319 		PMD_DRV_LOG(ERR, "Failed to add MACVLAN filter");
4320 		return -ENODEV;
4321 	}
4322 	return 0;
4323 }
4324 
4325 /* Remove a MAC address, and update filters */
4326 static void
4327 i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index)
4328 {
4329 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4330 	struct i40e_vsi *vsi;
4331 	struct rte_eth_dev_data *data = dev->data;
4332 	struct rte_ether_addr *macaddr;
4333 	int ret;
4334 	uint32_t i;
4335 	uint64_t pool_sel;
4336 
4337 	macaddr = &(data->mac_addrs[index]);
4338 
4339 	pool_sel = dev->data->mac_pool_sel[index];
4340 
4341 	for (i = 0; i < sizeof(pool_sel) * CHAR_BIT; i++) {
4342 		if (pool_sel & (1ULL << i)) {
4343 			if (i == 0)
4344 				vsi = pf->main_vsi;
4345 			else {
4346 				/* No VMDQ pool enabled or configured */
4347 				if (!(pf->flags & I40E_FLAG_VMDQ) ||
4348 					(i > pf->nb_cfg_vmdq_vsi)) {
4349 					PMD_DRV_LOG(ERR,
4350 						"No VMDQ pool enabled/configured");
4351 					return;
4352 				}
4353 				vsi = pf->vmdq[i - 1].vsi;
4354 			}
4355 			ret = i40e_vsi_delete_mac(vsi, macaddr);
4356 
4357 			if (ret) {
4358 				PMD_DRV_LOG(ERR, "Failed to remove MACVLAN filter");
4359 				return;
4360 			}
4361 		}
4362 	}
4363 }
4364 
4365 static int
4366 i40e_get_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size)
4367 {
4368 	struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
4369 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
4370 	uint32_t reg;
4371 	int ret;
4372 
4373 	if (!lut)
4374 		return -EINVAL;
4375 
4376 	if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) {
4377 		ret = i40e_aq_get_rss_lut(hw, vsi->vsi_id,
4378 					  vsi->type != I40E_VSI_SRIOV,
4379 					  lut, lut_size);
4380 		if (ret) {
4381 			PMD_DRV_LOG(ERR, "Failed to get RSS lookup table");
4382 			return ret;
4383 		}
4384 	} else {
4385 		uint32_t *lut_dw = (uint32_t *)lut;
4386 		uint16_t i, lut_size_dw = lut_size / 4;
4387 
4388 		if (vsi->type == I40E_VSI_SRIOV) {
4389 			for (i = 0; i <= lut_size_dw; i++) {
4390 				reg = I40E_VFQF_HLUT1(i, vsi->user_param);
4391 				lut_dw[i] = i40e_read_rx_ctl(hw, reg);
4392 			}
4393 		} else {
4394 			for (i = 0; i < lut_size_dw; i++)
4395 				lut_dw[i] = I40E_READ_REG(hw,
4396 							  I40E_PFQF_HLUT(i));
4397 		}
4398 	}
4399 
4400 	return 0;
4401 }
4402 
4403 int
4404 i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size)
4405 {
4406 	struct i40e_pf *pf;
4407 	struct i40e_hw *hw;
4408 
4409 	if (!vsi || !lut)
4410 		return -EINVAL;
4411 
4412 	pf = I40E_VSI_TO_PF(vsi);
4413 	hw = I40E_VSI_TO_HW(vsi);
4414 
4415 	if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) {
4416 		enum i40e_status_code status;
4417 
4418 		status = i40e_aq_set_rss_lut(hw, vsi->vsi_id,
4419 					     vsi->type != I40E_VSI_SRIOV,
4420 					     lut, lut_size);
4421 		if (status) {
4422 			PMD_DRV_LOG(ERR,
4423 				    "Failed to update RSS lookup table, error status: %d",
4424 				    status);
4425 			return -EIO;
4426 		}
4427 	} else {
4428 		uint32_t *lut_dw = (uint32_t *)lut;
4429 		uint16_t i, lut_size_dw = lut_size / 4;
4430 
4431 		if (vsi->type == I40E_VSI_SRIOV) {
4432 			for (i = 0; i < lut_size_dw; i++)
4433 				I40E_WRITE_REG(
4434 					hw,
4435 					I40E_VFQF_HLUT1(i, vsi->user_param),
4436 					lut_dw[i]);
4437 		} else {
4438 			for (i = 0; i < lut_size_dw; i++)
4439 				I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i),
4440 					       lut_dw[i]);
4441 		}
4442 		I40E_WRITE_FLUSH(hw);
4443 	}
4444 
4445 	return 0;
4446 }
4447 
4448 static int
4449 i40e_dev_rss_reta_update(struct rte_eth_dev *dev,
4450 			 struct rte_eth_rss_reta_entry64 *reta_conf,
4451 			 uint16_t reta_size)
4452 {
4453 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4454 	uint16_t i, lut_size = pf->hash_lut_size;
4455 	uint16_t idx, shift;
4456 	uint8_t *lut;
4457 	int ret;
4458 
4459 	if (reta_size != lut_size ||
4460 		reta_size > ETH_RSS_RETA_SIZE_512) {
4461 		PMD_DRV_LOG(ERR,
4462 			"The size of hash lookup table configured (%d) doesn't match the number hardware can supported (%d)",
4463 			reta_size, lut_size);
4464 		return -EINVAL;
4465 	}
4466 
4467 	lut = rte_zmalloc("i40e_rss_lut", reta_size, 0);
4468 	if (!lut) {
4469 		PMD_DRV_LOG(ERR, "No memory can be allocated");
4470 		return -ENOMEM;
4471 	}
4472 	ret = i40e_get_rss_lut(pf->main_vsi, lut, reta_size);
4473 	if (ret)
4474 		goto out;
4475 	for (i = 0; i < reta_size; i++) {
4476 		idx = i / RTE_RETA_GROUP_SIZE;
4477 		shift = i % RTE_RETA_GROUP_SIZE;
4478 		if (reta_conf[idx].mask & (1ULL << shift))
4479 			lut[i] = reta_conf[idx].reta[shift];
4480 	}
4481 	ret = i40e_set_rss_lut(pf->main_vsi, lut, reta_size);
4482 
4483 	pf->adapter->rss_reta_updated = 1;
4484 
4485 out:
4486 	rte_free(lut);
4487 
4488 	return ret;
4489 }
4490 
4491 static int
4492 i40e_dev_rss_reta_query(struct rte_eth_dev *dev,
4493 			struct rte_eth_rss_reta_entry64 *reta_conf,
4494 			uint16_t reta_size)
4495 {
4496 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4497 	uint16_t i, lut_size = pf->hash_lut_size;
4498 	uint16_t idx, shift;
4499 	uint8_t *lut;
4500 	int ret;
4501 
4502 	if (reta_size != lut_size ||
4503 		reta_size > ETH_RSS_RETA_SIZE_512) {
4504 		PMD_DRV_LOG(ERR,
4505 			"The size of hash lookup table configured (%d) doesn't match the number hardware can supported (%d)",
4506 			reta_size, lut_size);
4507 		return -EINVAL;
4508 	}
4509 
4510 	lut = rte_zmalloc("i40e_rss_lut", reta_size, 0);
4511 	if (!lut) {
4512 		PMD_DRV_LOG(ERR, "No memory can be allocated");
4513 		return -ENOMEM;
4514 	}
4515 
4516 	ret = i40e_get_rss_lut(pf->main_vsi, lut, reta_size);
4517 	if (ret)
4518 		goto out;
4519 	for (i = 0; i < reta_size; i++) {
4520 		idx = i / RTE_RETA_GROUP_SIZE;
4521 		shift = i % RTE_RETA_GROUP_SIZE;
4522 		if (reta_conf[idx].mask & (1ULL << shift))
4523 			reta_conf[idx].reta[shift] = lut[i];
4524 	}
4525 
4526 out:
4527 	rte_free(lut);
4528 
4529 	return ret;
4530 }
4531 
4532 /**
4533  * i40e_allocate_dma_mem_d - specific memory alloc for shared code (base driver)
4534  * @hw:   pointer to the HW structure
4535  * @mem:  pointer to mem struct to fill out
4536  * @size: size of memory requested
4537  * @alignment: what to align the allocation to
4538  **/
4539 enum i40e_status_code
4540 i40e_allocate_dma_mem_d(__rte_unused struct i40e_hw *hw,
4541 			struct i40e_dma_mem *mem,
4542 			u64 size,
4543 			u32 alignment)
4544 {
4545 	const struct rte_memzone *mz = NULL;
4546 	char z_name[RTE_MEMZONE_NAMESIZE];
4547 
4548 	if (!mem)
4549 		return I40E_ERR_PARAM;
4550 
4551 	snprintf(z_name, sizeof(z_name), "i40e_dma_%"PRIu64, rte_rand());
4552 	mz = rte_memzone_reserve_bounded(z_name, size, SOCKET_ID_ANY,
4553 			RTE_MEMZONE_IOVA_CONTIG, alignment, RTE_PGSIZE_2M);
4554 	if (!mz)
4555 		return I40E_ERR_NO_MEMORY;
4556 
4557 	mem->size = size;
4558 	mem->va = mz->addr;
4559 	mem->pa = mz->iova;
4560 	mem->zone = (const void *)mz;
4561 	PMD_DRV_LOG(DEBUG,
4562 		"memzone %s allocated with physical address: %"PRIu64,
4563 		mz->name, mem->pa);
4564 
4565 	return I40E_SUCCESS;
4566 }
4567 
4568 /**
4569  * i40e_free_dma_mem_d - specific memory free for shared code (base driver)
4570  * @hw:   pointer to the HW structure
4571  * @mem:  ptr to mem struct to free
4572  **/
4573 enum i40e_status_code
4574 i40e_free_dma_mem_d(__rte_unused struct i40e_hw *hw,
4575 		    struct i40e_dma_mem *mem)
4576 {
4577 	if (!mem)
4578 		return I40E_ERR_PARAM;
4579 
4580 	PMD_DRV_LOG(DEBUG,
4581 		"memzone %s to be freed with physical address: %"PRIu64,
4582 		((const struct rte_memzone *)mem->zone)->name, mem->pa);
4583 	rte_memzone_free((const struct rte_memzone *)mem->zone);
4584 	mem->zone = NULL;
4585 	mem->va = NULL;
4586 	mem->pa = (u64)0;
4587 
4588 	return I40E_SUCCESS;
4589 }
4590 
4591 /**
4592  * i40e_allocate_virt_mem_d - specific memory alloc for shared code (base driver)
4593  * @hw:   pointer to the HW structure
4594  * @mem:  pointer to mem struct to fill out
4595  * @size: size of memory requested
4596  **/
4597 enum i40e_status_code
4598 i40e_allocate_virt_mem_d(__rte_unused struct i40e_hw *hw,
4599 			 struct i40e_virt_mem *mem,
4600 			 u32 size)
4601 {
4602 	if (!mem)
4603 		return I40E_ERR_PARAM;
4604 
4605 	mem->size = size;
4606 	mem->va = rte_zmalloc("i40e", size, 0);
4607 
4608 	if (mem->va)
4609 		return I40E_SUCCESS;
4610 	else
4611 		return I40E_ERR_NO_MEMORY;
4612 }
4613 
4614 /**
4615  * i40e_free_virt_mem_d - specific memory free for shared code (base driver)
4616  * @hw:   pointer to the HW structure
4617  * @mem:  pointer to mem struct to free
4618  **/
4619 enum i40e_status_code
4620 i40e_free_virt_mem_d(__rte_unused struct i40e_hw *hw,
4621 		     struct i40e_virt_mem *mem)
4622 {
4623 	if (!mem)
4624 		return I40E_ERR_PARAM;
4625 
4626 	rte_free(mem->va);
4627 	mem->va = NULL;
4628 
4629 	return I40E_SUCCESS;
4630 }
4631 
4632 void
4633 i40e_init_spinlock_d(struct i40e_spinlock *sp)
4634 {
4635 	rte_spinlock_init(&sp->spinlock);
4636 }
4637 
4638 void
4639 i40e_acquire_spinlock_d(struct i40e_spinlock *sp)
4640 {
4641 	rte_spinlock_lock(&sp->spinlock);
4642 }
4643 
4644 void
4645 i40e_release_spinlock_d(struct i40e_spinlock *sp)
4646 {
4647 	rte_spinlock_unlock(&sp->spinlock);
4648 }
4649 
4650 void
4651 i40e_destroy_spinlock_d(__rte_unused struct i40e_spinlock *sp)
4652 {
4653 	return;
4654 }
4655 
4656 /**
4657  * Get the hardware capabilities, which will be parsed
4658  * and saved into struct i40e_hw.
4659  */
4660 static int
4661 i40e_get_cap(struct i40e_hw *hw)
4662 {
4663 	struct i40e_aqc_list_capabilities_element_resp *buf;
4664 	uint16_t len, size = 0;
4665 	int ret;
4666 
4667 	/* Calculate a huge enough buff for saving response data temporarily */
4668 	len = sizeof(struct i40e_aqc_list_capabilities_element_resp) *
4669 						I40E_MAX_CAP_ELE_NUM;
4670 	buf = rte_zmalloc("i40e", len, 0);
4671 	if (!buf) {
4672 		PMD_DRV_LOG(ERR, "Failed to allocate memory");
4673 		return I40E_ERR_NO_MEMORY;
4674 	}
4675 
4676 	/* Get, parse the capabilities and save it to hw */
4677 	ret = i40e_aq_discover_capabilities(hw, buf, len, &size,
4678 			i40e_aqc_opc_list_func_capabilities, NULL);
4679 	if (ret != I40E_SUCCESS)
4680 		PMD_DRV_LOG(ERR, "Failed to discover capabilities");
4681 
4682 	/* Free the temporary buffer after being used */
4683 	rte_free(buf);
4684 
4685 	return ret;
4686 }
4687 
4688 #define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF	4
4689 
4690 static int i40e_pf_parse_vf_queue_number_handler(const char *key,
4691 		const char *value,
4692 		void *opaque)
4693 {
4694 	struct i40e_pf *pf;
4695 	unsigned long num;
4696 	char *end;
4697 
4698 	pf = (struct i40e_pf *)opaque;
4699 	RTE_SET_USED(key);
4700 
4701 	errno = 0;
4702 	num = strtoul(value, &end, 0);
4703 	if (errno != 0 || end == value || *end != 0) {
4704 		PMD_DRV_LOG(WARNING, "Wrong VF queue number = %s, Now it is "
4705 			    "kept the value = %hu", value, pf->vf_nb_qp_max);
4706 		return -(EINVAL);
4707 	}
4708 
4709 	if (num <= I40E_MAX_QP_NUM_PER_VF && rte_is_power_of_2(num))
4710 		pf->vf_nb_qp_max = (uint16_t)num;
4711 	else
4712 		/* here return 0 to make next valid same argument work */
4713 		PMD_DRV_LOG(WARNING, "Wrong VF queue number = %lu, it must be "
4714 			    "power of 2 and equal or less than 16 !, Now it is "
4715 			    "kept the value = %hu", num, pf->vf_nb_qp_max);
4716 
4717 	return 0;
4718 }
4719 
4720 static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev)
4721 {
4722 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4723 	struct rte_kvargs *kvlist;
4724 	int kvargs_count;
4725 
4726 	/* set default queue number per VF as 4 */
4727 	pf->vf_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF;
4728 
4729 	if (dev->device->devargs == NULL)
4730 		return 0;
4731 
4732 	kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);
4733 	if (kvlist == NULL)
4734 		return -(EINVAL);
4735 
4736 	kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_QUEUE_NUM_PER_VF_ARG);
4737 	if (!kvargs_count) {
4738 		rte_kvargs_free(kvlist);
4739 		return 0;
4740 	}
4741 
4742 	if (kvargs_count > 1)
4743 		PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
4744 			    "the first invalid or last valid one is used !",
4745 			    ETH_I40E_QUEUE_NUM_PER_VF_ARG);
4746 
4747 	rte_kvargs_process(kvlist, ETH_I40E_QUEUE_NUM_PER_VF_ARG,
4748 			   i40e_pf_parse_vf_queue_number_handler, pf);
4749 
4750 	rte_kvargs_free(kvlist);
4751 
4752 	return 0;
4753 }
4754 
4755 static int
4756 i40e_pf_parameter_init(struct rte_eth_dev *dev)
4757 {
4758 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
4759 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
4760 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
4761 	uint16_t qp_count = 0, vsi_count = 0;
4762 
4763 	if (pci_dev->max_vfs && !hw->func_caps.sr_iov_1_1) {
4764 		PMD_INIT_LOG(ERR, "HW configuration doesn't support SRIOV");
4765 		return -EINVAL;
4766 	}
4767 
4768 	i40e_pf_config_vf_rxq_number(dev);
4769 
4770 	/* Add the parameter init for LFC */
4771 	pf->fc_conf.pause_time = I40E_DEFAULT_PAUSE_TIME;
4772 	pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] = I40E_DEFAULT_HIGH_WATER;
4773 	pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] = I40E_DEFAULT_LOW_WATER;
4774 
4775 	pf->flags = I40E_FLAG_HEADER_SPLIT_DISABLED;
4776 	pf->max_num_vsi = hw->func_caps.num_vsis;
4777 	pf->lan_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF;
4778 	pf->vmdq_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM;
4779 
4780 	/* FDir queue/VSI allocation */
4781 	pf->fdir_qp_offset = 0;
4782 	if (hw->func_caps.fd) {
4783 		pf->flags |= I40E_FLAG_FDIR;
4784 		pf->fdir_nb_qps = I40E_DEFAULT_QP_NUM_FDIR;
4785 	} else {
4786 		pf->fdir_nb_qps = 0;
4787 	}
4788 	qp_count += pf->fdir_nb_qps;
4789 	vsi_count += 1;
4790 
4791 	/* LAN queue/VSI allocation */
4792 	pf->lan_qp_offset = pf->fdir_qp_offset + pf->fdir_nb_qps;
4793 	if (!hw->func_caps.rss) {
4794 		pf->lan_nb_qps = 1;
4795 	} else {
4796 		pf->flags |= I40E_FLAG_RSS;
4797 		if (hw->mac.type == I40E_MAC_X722)
4798 			pf->flags |= I40E_FLAG_RSS_AQ_CAPABLE;
4799 		pf->lan_nb_qps = pf->lan_nb_qp_max;
4800 	}
4801 	qp_count += pf->lan_nb_qps;
4802 	vsi_count += 1;
4803 
4804 	/* VF queue/VSI allocation */
4805 	pf->vf_qp_offset = pf->lan_qp_offset + pf->lan_nb_qps;
4806 	if (hw->func_caps.sr_iov_1_1 && pci_dev->max_vfs) {
4807 		pf->flags |= I40E_FLAG_SRIOV;
4808 		pf->vf_nb_qps = pf->vf_nb_qp_max;
4809 		pf->vf_num = pci_dev->max_vfs;
4810 		PMD_DRV_LOG(DEBUG,
4811 			"%u VF VSIs, %u queues per VF VSI, in total %u queues",
4812 			pf->vf_num, pf->vf_nb_qps, pf->vf_nb_qps * pf->vf_num);
4813 	} else {
4814 		pf->vf_nb_qps = 0;
4815 		pf->vf_num = 0;
4816 	}
4817 	qp_count += pf->vf_nb_qps * pf->vf_num;
4818 	vsi_count += pf->vf_num;
4819 
4820 	/* VMDq queue/VSI allocation */
4821 	pf->vmdq_qp_offset = pf->vf_qp_offset + pf->vf_nb_qps * pf->vf_num;
4822 	pf->vmdq_nb_qps = 0;
4823 	pf->max_nb_vmdq_vsi = 0;
4824 	if (hw->func_caps.vmdq) {
4825 		if (qp_count < hw->func_caps.num_tx_qp &&
4826 			vsi_count < hw->func_caps.num_vsis) {
4827 			pf->max_nb_vmdq_vsi = (hw->func_caps.num_tx_qp -
4828 				qp_count) / pf->vmdq_nb_qp_max;
4829 
4830 			/* Limit the maximum number of VMDq vsi to the maximum
4831 			 * ethdev can support
4832 			 */
4833 			pf->max_nb_vmdq_vsi = RTE_MIN(pf->max_nb_vmdq_vsi,
4834 				hw->func_caps.num_vsis - vsi_count);
4835 			pf->max_nb_vmdq_vsi = RTE_MIN(pf->max_nb_vmdq_vsi,
4836 				ETH_64_POOLS);
4837 			if (pf->max_nb_vmdq_vsi) {
4838 				pf->flags |= I40E_FLAG_VMDQ;
4839 				pf->vmdq_nb_qps = pf->vmdq_nb_qp_max;
4840 				PMD_DRV_LOG(DEBUG,
4841 					"%u VMDQ VSIs, %u queues per VMDQ VSI, in total %u queues",
4842 					pf->max_nb_vmdq_vsi, pf->vmdq_nb_qps,
4843 					pf->vmdq_nb_qps * pf->max_nb_vmdq_vsi);
4844 			} else {
4845 				PMD_DRV_LOG(INFO,
4846 					"No enough queues left for VMDq");
4847 			}
4848 		} else {
4849 			PMD_DRV_LOG(INFO, "No queue or VSI left for VMDq");
4850 		}
4851 	}
4852 	qp_count += pf->vmdq_nb_qps * pf->max_nb_vmdq_vsi;
4853 	vsi_count += pf->max_nb_vmdq_vsi;
4854 
4855 	if (hw->func_caps.dcb)
4856 		pf->flags |= I40E_FLAG_DCB;
4857 
4858 	if (qp_count > hw->func_caps.num_tx_qp) {
4859 		PMD_DRV_LOG(ERR,
4860 			"Failed to allocate %u queues, which exceeds the hardware maximum %u",
4861 			qp_count, hw->func_caps.num_tx_qp);
4862 		return -EINVAL;
4863 	}
4864 	if (vsi_count > hw->func_caps.num_vsis) {
4865 		PMD_DRV_LOG(ERR,
4866 			"Failed to allocate %u VSIs, which exceeds the hardware maximum %u",
4867 			vsi_count, hw->func_caps.num_vsis);
4868 		return -EINVAL;
4869 	}
4870 
4871 	return 0;
4872 }
4873 
4874 static int
4875 i40e_pf_get_switch_config(struct i40e_pf *pf)
4876 {
4877 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
4878 	struct i40e_aqc_get_switch_config_resp *switch_config;
4879 	struct i40e_aqc_switch_config_element_resp *element;
4880 	uint16_t start_seid = 0, num_reported;
4881 	int ret;
4882 
4883 	switch_config = (struct i40e_aqc_get_switch_config_resp *)\
4884 			rte_zmalloc("i40e", I40E_AQ_LARGE_BUF, 0);
4885 	if (!switch_config) {
4886 		PMD_DRV_LOG(ERR, "Failed to allocated memory");
4887 		return -ENOMEM;
4888 	}
4889 
4890 	/* Get the switch configurations */
4891 	ret = i40e_aq_get_switch_config(hw, switch_config,
4892 		I40E_AQ_LARGE_BUF, &start_seid, NULL);
4893 	if (ret != I40E_SUCCESS) {
4894 		PMD_DRV_LOG(ERR, "Failed to get switch configurations");
4895 		goto fail;
4896 	}
4897 	num_reported = rte_le_to_cpu_16(switch_config->header.num_reported);
4898 	if (num_reported != 1) { /* The number should be 1 */
4899 		PMD_DRV_LOG(ERR, "Wrong number of switch config reported");
4900 		goto fail;
4901 	}
4902 
4903 	/* Parse the switch configuration elements */
4904 	element = &(switch_config->element[0]);
4905 	if (element->element_type == I40E_SWITCH_ELEMENT_TYPE_VSI) {
4906 		pf->mac_seid = rte_le_to_cpu_16(element->uplink_seid);
4907 		pf->main_vsi_seid = rte_le_to_cpu_16(element->seid);
4908 	} else
4909 		PMD_DRV_LOG(INFO, "Unknown element type");
4910 
4911 fail:
4912 	rte_free(switch_config);
4913 
4914 	return ret;
4915 }
4916 
4917 static int
4918 i40e_res_pool_init (struct i40e_res_pool_info *pool, uint32_t base,
4919 			uint32_t num)
4920 {
4921 	struct pool_entry *entry;
4922 
4923 	if (pool == NULL || num == 0)
4924 		return -EINVAL;
4925 
4926 	entry = rte_zmalloc("i40e", sizeof(*entry), 0);
4927 	if (entry == NULL) {
4928 		PMD_DRV_LOG(ERR, "Failed to allocate memory for resource pool");
4929 		return -ENOMEM;
4930 	}
4931 
4932 	/* queue heap initialize */
4933 	pool->num_free = num;
4934 	pool->num_alloc = 0;
4935 	pool->base = base;
4936 	LIST_INIT(&pool->alloc_list);
4937 	LIST_INIT(&pool->free_list);
4938 
4939 	/* Initialize element  */
4940 	entry->base = 0;
4941 	entry->len = num;
4942 
4943 	LIST_INSERT_HEAD(&pool->free_list, entry, next);
4944 	return 0;
4945 }
4946 
4947 static void
4948 i40e_res_pool_destroy(struct i40e_res_pool_info *pool)
4949 {
4950 	struct pool_entry *entry, *next_entry;
4951 
4952 	if (pool == NULL)
4953 		return;
4954 
4955 	for (entry = LIST_FIRST(&pool->alloc_list);
4956 			entry && (next_entry = LIST_NEXT(entry, next), 1);
4957 			entry = next_entry) {
4958 		LIST_REMOVE(entry, next);
4959 		rte_free(entry);
4960 	}
4961 
4962 	for (entry = LIST_FIRST(&pool->free_list);
4963 			entry && (next_entry = LIST_NEXT(entry, next), 1);
4964 			entry = next_entry) {
4965 		LIST_REMOVE(entry, next);
4966 		rte_free(entry);
4967 	}
4968 
4969 	pool->num_free = 0;
4970 	pool->num_alloc = 0;
4971 	pool->base = 0;
4972 	LIST_INIT(&pool->alloc_list);
4973 	LIST_INIT(&pool->free_list);
4974 }
4975 
4976 static int
4977 i40e_res_pool_free(struct i40e_res_pool_info *pool,
4978 		       uint32_t base)
4979 {
4980 	struct pool_entry *entry, *next, *prev, *valid_entry = NULL;
4981 	uint32_t pool_offset;
4982 	uint16_t len;
4983 	int insert;
4984 
4985 	if (pool == NULL) {
4986 		PMD_DRV_LOG(ERR, "Invalid parameter");
4987 		return -EINVAL;
4988 	}
4989 
4990 	pool_offset = base - pool->base;
4991 	/* Lookup in alloc list */
4992 	LIST_FOREACH(entry, &pool->alloc_list, next) {
4993 		if (entry->base == pool_offset) {
4994 			valid_entry = entry;
4995 			LIST_REMOVE(entry, next);
4996 			break;
4997 		}
4998 	}
4999 
5000 	/* Not find, return */
5001 	if (valid_entry == NULL) {
5002 		PMD_DRV_LOG(ERR, "Failed to find entry");
5003 		return -EINVAL;
5004 	}
5005 
5006 	/**
5007 	 * Found it, move it to free list  and try to merge.
5008 	 * In order to make merge easier, always sort it by qbase.
5009 	 * Find adjacent prev and last entries.
5010 	 */
5011 	prev = next = NULL;
5012 	LIST_FOREACH(entry, &pool->free_list, next) {
5013 		if (entry->base > valid_entry->base) {
5014 			next = entry;
5015 			break;
5016 		}
5017 		prev = entry;
5018 	}
5019 
5020 	insert = 0;
5021 	len = valid_entry->len;
5022 	/* Try to merge with next one*/
5023 	if (next != NULL) {
5024 		/* Merge with next one */
5025 		if (valid_entry->base + len == next->base) {
5026 			next->base = valid_entry->base;
5027 			next->len += len;
5028 			rte_free(valid_entry);
5029 			valid_entry = next;
5030 			insert = 1;
5031 		}
5032 	}
5033 
5034 	if (prev != NULL) {
5035 		/* Merge with previous one */
5036 		if (prev->base + prev->len == valid_entry->base) {
5037 			prev->len += len;
5038 			/* If it merge with next one, remove next node */
5039 			if (insert == 1) {
5040 				LIST_REMOVE(valid_entry, next);
5041 				rte_free(valid_entry);
5042 				valid_entry = NULL;
5043 			} else {
5044 				rte_free(valid_entry);
5045 				valid_entry = NULL;
5046 				insert = 1;
5047 			}
5048 		}
5049 	}
5050 
5051 	/* Not find any entry to merge, insert */
5052 	if (insert == 0) {
5053 		if (prev != NULL)
5054 			LIST_INSERT_AFTER(prev, valid_entry, next);
5055 		else if (next != NULL)
5056 			LIST_INSERT_BEFORE(next, valid_entry, next);
5057 		else /* It's empty list, insert to head */
5058 			LIST_INSERT_HEAD(&pool->free_list, valid_entry, next);
5059 	}
5060 
5061 	pool->num_free += len;
5062 	pool->num_alloc -= len;
5063 
5064 	return 0;
5065 }
5066 
5067 static int
5068 i40e_res_pool_alloc(struct i40e_res_pool_info *pool,
5069 		       uint16_t num)
5070 {
5071 	struct pool_entry *entry, *valid_entry;
5072 
5073 	if (pool == NULL || num == 0) {
5074 		PMD_DRV_LOG(ERR, "Invalid parameter");
5075 		return -EINVAL;
5076 	}
5077 
5078 	if (pool->num_free < num) {
5079 		PMD_DRV_LOG(ERR, "No resource. ask:%u, available:%u",
5080 			    num, pool->num_free);
5081 		return -ENOMEM;
5082 	}
5083 
5084 	valid_entry = NULL;
5085 	/* Lookup  in free list and find most fit one */
5086 	LIST_FOREACH(entry, &pool->free_list, next) {
5087 		if (entry->len >= num) {
5088 			/* Find best one */
5089 			if (entry->len == num) {
5090 				valid_entry = entry;
5091 				break;
5092 			}
5093 			if (valid_entry == NULL || valid_entry->len > entry->len)
5094 				valid_entry = entry;
5095 		}
5096 	}
5097 
5098 	/* Not find one to satisfy the request, return */
5099 	if (valid_entry == NULL) {
5100 		PMD_DRV_LOG(ERR, "No valid entry found");
5101 		return -ENOMEM;
5102 	}
5103 	/**
5104 	 * The entry have equal queue number as requested,
5105 	 * remove it from alloc_list.
5106 	 */
5107 	if (valid_entry->len == num) {
5108 		LIST_REMOVE(valid_entry, next);
5109 	} else {
5110 		/**
5111 		 * The entry have more numbers than requested,
5112 		 * create a new entry for alloc_list and minus its
5113 		 * queue base and number in free_list.
5114 		 */
5115 		entry = rte_zmalloc("res_pool", sizeof(*entry), 0);
5116 		if (entry == NULL) {
5117 			PMD_DRV_LOG(ERR,
5118 				"Failed to allocate memory for resource pool");
5119 			return -ENOMEM;
5120 		}
5121 		entry->base = valid_entry->base;
5122 		entry->len = num;
5123 		valid_entry->base += num;
5124 		valid_entry->len -= num;
5125 		valid_entry = entry;
5126 	}
5127 
5128 	/* Insert it into alloc list, not sorted */
5129 	LIST_INSERT_HEAD(&pool->alloc_list, valid_entry, next);
5130 
5131 	pool->num_free -= valid_entry->len;
5132 	pool->num_alloc += valid_entry->len;
5133 
5134 	return valid_entry->base + pool->base;
5135 }
5136 
5137 /**
5138  * bitmap_is_subset - Check whether src2 is subset of src1
5139  **/
5140 static inline int
5141 bitmap_is_subset(uint8_t src1, uint8_t src2)
5142 {
5143 	return !((src1 ^ src2) & src2);
5144 }
5145 
5146 static enum i40e_status_code
5147 validate_tcmap_parameter(struct i40e_vsi *vsi, uint8_t enabled_tcmap)
5148 {
5149 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
5150 
5151 	/* If DCB is not supported, only default TC is supported */
5152 	if (!hw->func_caps.dcb && enabled_tcmap != I40E_DEFAULT_TCMAP) {
5153 		PMD_DRV_LOG(ERR, "DCB is not enabled, only TC0 is supported");
5154 		return I40E_NOT_SUPPORTED;
5155 	}
5156 
5157 	if (!bitmap_is_subset(hw->func_caps.enabled_tcmap, enabled_tcmap)) {
5158 		PMD_DRV_LOG(ERR,
5159 			"Enabled TC map 0x%x not applicable to HW support 0x%x",
5160 			hw->func_caps.enabled_tcmap, enabled_tcmap);
5161 		return I40E_NOT_SUPPORTED;
5162 	}
5163 	return I40E_SUCCESS;
5164 }
5165 
5166 int
5167 i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi,
5168 				struct i40e_vsi_vlan_pvid_info *info)
5169 {
5170 	struct i40e_hw *hw;
5171 	struct i40e_vsi_context ctxt;
5172 	uint8_t vlan_flags = 0;
5173 	int ret;
5174 
5175 	if (vsi == NULL || info == NULL) {
5176 		PMD_DRV_LOG(ERR, "invalid parameters");
5177 		return I40E_ERR_PARAM;
5178 	}
5179 
5180 	if (info->on) {
5181 		vsi->info.pvid = info->config.pvid;
5182 		/**
5183 		 * If insert pvid is enabled, only tagged pkts are
5184 		 * allowed to be sent out.
5185 		 */
5186 		vlan_flags |= I40E_AQ_VSI_PVLAN_INSERT_PVID |
5187 				I40E_AQ_VSI_PVLAN_MODE_TAGGED;
5188 	} else {
5189 		vsi->info.pvid = 0;
5190 		if (info->config.reject.tagged == 0)
5191 			vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_TAGGED;
5192 
5193 		if (info->config.reject.untagged == 0)
5194 			vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_UNTAGGED;
5195 	}
5196 	vsi->info.port_vlan_flags &= ~(I40E_AQ_VSI_PVLAN_INSERT_PVID |
5197 					I40E_AQ_VSI_PVLAN_MODE_MASK);
5198 	vsi->info.port_vlan_flags |= vlan_flags;
5199 	vsi->info.valid_sections =
5200 		rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID);
5201 	memset(&ctxt, 0, sizeof(ctxt));
5202 	rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
5203 	ctxt.seid = vsi->seid;
5204 
5205 	hw = I40E_VSI_TO_HW(vsi);
5206 	ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
5207 	if (ret != I40E_SUCCESS)
5208 		PMD_DRV_LOG(ERR, "Failed to update VSI params");
5209 
5210 	return ret;
5211 }
5212 
5213 static int
5214 i40e_vsi_update_tc_bandwidth(struct i40e_vsi *vsi, uint8_t enabled_tcmap)
5215 {
5216 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
5217 	int i, ret;
5218 	struct i40e_aqc_configure_vsi_tc_bw_data tc_bw_data;
5219 
5220 	ret = validate_tcmap_parameter(vsi, enabled_tcmap);
5221 	if (ret != I40E_SUCCESS)
5222 		return ret;
5223 
5224 	if (!vsi->seid) {
5225 		PMD_DRV_LOG(ERR, "seid not valid");
5226 		return -EINVAL;
5227 	}
5228 
5229 	memset(&tc_bw_data, 0, sizeof(tc_bw_data));
5230 	tc_bw_data.tc_valid_bits = enabled_tcmap;
5231 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
5232 		tc_bw_data.tc_bw_credits[i] =
5233 			(enabled_tcmap & (1 << i)) ? 1 : 0;
5234 
5235 	ret = i40e_aq_config_vsi_tc_bw(hw, vsi->seid, &tc_bw_data, NULL);
5236 	if (ret != I40E_SUCCESS) {
5237 		PMD_DRV_LOG(ERR, "Failed to configure TC BW");
5238 		return ret;
5239 	}
5240 
5241 	rte_memcpy(vsi->info.qs_handle, tc_bw_data.qs_handles,
5242 					sizeof(vsi->info.qs_handle));
5243 	return I40E_SUCCESS;
5244 }
5245 
5246 static enum i40e_status_code
5247 i40e_vsi_config_tc_queue_mapping(struct i40e_vsi *vsi,
5248 				 struct i40e_aqc_vsi_properties_data *info,
5249 				 uint8_t enabled_tcmap)
5250 {
5251 	enum i40e_status_code ret;
5252 	int i, total_tc = 0;
5253 	uint16_t qpnum_per_tc, bsf, qp_idx;
5254 
5255 	ret = validate_tcmap_parameter(vsi, enabled_tcmap);
5256 	if (ret != I40E_SUCCESS)
5257 		return ret;
5258 
5259 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
5260 		if (enabled_tcmap & (1 << i))
5261 			total_tc++;
5262 	if (total_tc == 0)
5263 		total_tc = 1;
5264 	vsi->enabled_tc = enabled_tcmap;
5265 
5266 	/* Number of queues per enabled TC */
5267 	qpnum_per_tc = i40e_align_floor(vsi->nb_qps / total_tc);
5268 	qpnum_per_tc = RTE_MIN(qpnum_per_tc, I40E_MAX_Q_PER_TC);
5269 	bsf = rte_bsf32(qpnum_per_tc);
5270 
5271 	/* Adjust the queue number to actual queues that can be applied */
5272 	if (!(vsi->type == I40E_VSI_MAIN && total_tc == 1))
5273 		vsi->nb_qps = qpnum_per_tc * total_tc;
5274 
5275 	/**
5276 	 * Configure TC and queue mapping parameters, for enabled TC,
5277 	 * allocate qpnum_per_tc queues to this traffic. For disabled TC,
5278 	 * default queue will serve it.
5279 	 */
5280 	qp_idx = 0;
5281 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
5282 		if (vsi->enabled_tc & (1 << i)) {
5283 			info->tc_mapping[i] = rte_cpu_to_le_16((qp_idx <<
5284 					I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) |
5285 				(bsf << I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT));
5286 			qp_idx += qpnum_per_tc;
5287 		} else
5288 			info->tc_mapping[i] = 0;
5289 	}
5290 
5291 	/* Associate queue number with VSI */
5292 	if (vsi->type == I40E_VSI_SRIOV) {
5293 		info->mapping_flags |=
5294 			rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_NONCONTIG);
5295 		for (i = 0; i < vsi->nb_qps; i++)
5296 			info->queue_mapping[i] =
5297 				rte_cpu_to_le_16(vsi->base_queue + i);
5298 	} else {
5299 		info->mapping_flags |=
5300 			rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_CONTIG);
5301 		info->queue_mapping[0] = rte_cpu_to_le_16(vsi->base_queue);
5302 	}
5303 	info->valid_sections |=
5304 		rte_cpu_to_le_16(I40E_AQ_VSI_PROP_QUEUE_MAP_VALID);
5305 
5306 	return I40E_SUCCESS;
5307 }
5308 
5309 static int
5310 i40e_veb_release(struct i40e_veb *veb)
5311 {
5312 	struct i40e_vsi *vsi;
5313 	struct i40e_hw *hw;
5314 
5315 	if (veb == NULL)
5316 		return -EINVAL;
5317 
5318 	if (!TAILQ_EMPTY(&veb->head)) {
5319 		PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove");
5320 		return -EACCES;
5321 	}
5322 	/* associate_vsi field is NULL for floating VEB */
5323 	if (veb->associate_vsi != NULL) {
5324 		vsi = veb->associate_vsi;
5325 		hw = I40E_VSI_TO_HW(vsi);
5326 
5327 		vsi->uplink_seid = veb->uplink_seid;
5328 		vsi->veb = NULL;
5329 	} else {
5330 		veb->associate_pf->main_vsi->floating_veb = NULL;
5331 		hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi);
5332 	}
5333 
5334 	i40e_aq_delete_element(hw, veb->seid, NULL);
5335 	rte_free(veb);
5336 	return I40E_SUCCESS;
5337 }
5338 
5339 /* Setup a veb */
5340 static struct i40e_veb *
5341 i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi)
5342 {
5343 	struct i40e_veb *veb;
5344 	int ret;
5345 	struct i40e_hw *hw;
5346 
5347 	if (pf == NULL) {
5348 		PMD_DRV_LOG(ERR,
5349 			    "veb setup failed, associated PF shouldn't null");
5350 		return NULL;
5351 	}
5352 	hw = I40E_PF_TO_HW(pf);
5353 
5354 	veb = rte_zmalloc("i40e_veb", sizeof(struct i40e_veb), 0);
5355 	if (!veb) {
5356 		PMD_DRV_LOG(ERR, "Failed to allocate memory for veb");
5357 		goto fail;
5358 	}
5359 
5360 	veb->associate_vsi = vsi;
5361 	veb->associate_pf = pf;
5362 	TAILQ_INIT(&veb->head);
5363 	veb->uplink_seid = vsi ? vsi->uplink_seid : 0;
5364 
5365 	/* create floating veb if vsi is NULL */
5366 	if (vsi != NULL) {
5367 		ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid,
5368 				      I40E_DEFAULT_TCMAP, false,
5369 				      &veb->seid, false, NULL);
5370 	} else {
5371 		ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP,
5372 				      true, &veb->seid, false, NULL);
5373 	}
5374 
5375 	if (ret != I40E_SUCCESS) {
5376 		PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d",
5377 			    hw->aq.asq_last_status);
5378 		goto fail;
5379 	}
5380 	veb->enabled_tc = I40E_DEFAULT_TCMAP;
5381 
5382 	/* get statistics index */
5383 	ret = i40e_aq_get_veb_parameters(hw, veb->seid, NULL, NULL,
5384 				&veb->stats_idx, NULL, NULL, NULL);
5385 	if (ret != I40E_SUCCESS) {
5386 		PMD_DRV_LOG(ERR, "Get veb statistics index failed, aq_err: %d",
5387 			    hw->aq.asq_last_status);
5388 		goto fail;
5389 	}
5390 	/* Get VEB bandwidth, to be implemented */
5391 	/* Now associated vsi binding to the VEB, set uplink to this VEB */
5392 	if (vsi)
5393 		vsi->uplink_seid = veb->seid;
5394 
5395 	return veb;
5396 fail:
5397 	rte_free(veb);
5398 	return NULL;
5399 }
5400 
5401 int
5402 i40e_vsi_release(struct i40e_vsi *vsi)
5403 {
5404 	struct i40e_pf *pf;
5405 	struct i40e_hw *hw;
5406 	struct i40e_vsi_list *vsi_list;
5407 	void *temp;
5408 	int ret;
5409 	struct i40e_mac_filter *f;
5410 	uint16_t user_param;
5411 
5412 	if (!vsi)
5413 		return I40E_SUCCESS;
5414 
5415 	if (!vsi->adapter)
5416 		return -EFAULT;
5417 
5418 	user_param = vsi->user_param;
5419 
5420 	pf = I40E_VSI_TO_PF(vsi);
5421 	hw = I40E_VSI_TO_HW(vsi);
5422 
5423 	/* VSI has child to attach, release child first */
5424 	if (vsi->veb) {
5425 		TAILQ_FOREACH_SAFE(vsi_list, &vsi->veb->head, list, temp) {
5426 			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
5427 				return -1;
5428 		}
5429 		i40e_veb_release(vsi->veb);
5430 	}
5431 
5432 	if (vsi->floating_veb) {
5433 		TAILQ_FOREACH_SAFE(vsi_list, &vsi->floating_veb->head, list, temp) {
5434 			if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS)
5435 				return -1;
5436 		}
5437 	}
5438 
5439 	/* Remove all macvlan filters of the VSI */
5440 	i40e_vsi_remove_all_macvlan_filter(vsi);
5441 	TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp)
5442 		rte_free(f);
5443 
5444 	if (vsi->type != I40E_VSI_MAIN &&
5445 	    ((vsi->type != I40E_VSI_SRIOV) ||
5446 	    !pf->floating_veb_list[user_param])) {
5447 		/* Remove vsi from parent's sibling list */
5448 		if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) {
5449 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
5450 			return I40E_ERR_PARAM;
5451 		}
5452 		TAILQ_REMOVE(&vsi->parent_vsi->veb->head,
5453 				&vsi->sib_vsi_list, list);
5454 
5455 		/* Remove all switch element of the VSI */
5456 		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
5457 		if (ret != I40E_SUCCESS)
5458 			PMD_DRV_LOG(ERR, "Failed to delete element");
5459 	}
5460 
5461 	if ((vsi->type == I40E_VSI_SRIOV) &&
5462 	    pf->floating_veb_list[user_param]) {
5463 		/* Remove vsi from parent's sibling list */
5464 		if (vsi->parent_vsi == NULL ||
5465 		    vsi->parent_vsi->floating_veb == NULL) {
5466 			PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL");
5467 			return I40E_ERR_PARAM;
5468 		}
5469 		TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head,
5470 			     &vsi->sib_vsi_list, list);
5471 
5472 		/* Remove all switch element of the VSI */
5473 		ret = i40e_aq_delete_element(hw, vsi->seid, NULL);
5474 		if (ret != I40E_SUCCESS)
5475 			PMD_DRV_LOG(ERR, "Failed to delete element");
5476 	}
5477 
5478 	i40e_res_pool_free(&pf->qp_pool, vsi->base_queue);
5479 
5480 	if (vsi->type != I40E_VSI_SRIOV)
5481 		i40e_res_pool_free(&pf->msix_pool, vsi->msix_intr);
5482 	rte_free(vsi);
5483 
5484 	return I40E_SUCCESS;
5485 }
5486 
5487 static int
5488 i40e_update_default_filter_setting(struct i40e_vsi *vsi)
5489 {
5490 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
5491 	struct i40e_aqc_remove_macvlan_element_data def_filter;
5492 	struct i40e_mac_filter_info filter;
5493 	int ret;
5494 
5495 	if (vsi->type != I40E_VSI_MAIN)
5496 		return I40E_ERR_CONFIG;
5497 	memset(&def_filter, 0, sizeof(def_filter));
5498 	rte_memcpy(def_filter.mac_addr, hw->mac.perm_addr,
5499 					ETH_ADDR_LEN);
5500 	def_filter.vlan_tag = 0;
5501 	def_filter.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH |
5502 				I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
5503 	ret = i40e_aq_remove_macvlan(hw, vsi->seid, &def_filter, 1, NULL);
5504 	if (ret != I40E_SUCCESS) {
5505 		struct i40e_mac_filter *f;
5506 		struct rte_ether_addr *mac;
5507 
5508 		PMD_DRV_LOG(DEBUG,
5509 			    "Cannot remove the default macvlan filter");
5510 		/* It needs to add the permanent mac into mac list */
5511 		f = rte_zmalloc("macv_filter", sizeof(*f), 0);
5512 		if (f == NULL) {
5513 			PMD_DRV_LOG(ERR, "failed to allocate memory");
5514 			return I40E_ERR_NO_MEMORY;
5515 		}
5516 		mac = &f->mac_info.mac_addr;
5517 		rte_memcpy(&mac->addr_bytes, hw->mac.perm_addr,
5518 				ETH_ADDR_LEN);
5519 		f->mac_info.filter_type = I40E_MACVLAN_PERFECT_MATCH;
5520 		TAILQ_INSERT_TAIL(&vsi->mac_list, f, next);
5521 		vsi->mac_num++;
5522 
5523 		return ret;
5524 	}
5525 	rte_memcpy(&filter.mac_addr,
5526 		(struct rte_ether_addr *)(hw->mac.perm_addr), ETH_ADDR_LEN);
5527 	filter.filter_type = I40E_MACVLAN_PERFECT_MATCH;
5528 	return i40e_vsi_add_mac(vsi, &filter);
5529 }
5530 
5531 /*
5532  * i40e_vsi_get_bw_config - Query VSI BW Information
5533  * @vsi: the VSI to be queried
5534  *
5535  * Returns 0 on success, negative value on failure
5536  */
5537 static enum i40e_status_code
5538 i40e_vsi_get_bw_config(struct i40e_vsi *vsi)
5539 {
5540 	struct i40e_aqc_query_vsi_bw_config_resp bw_config;
5541 	struct i40e_aqc_query_vsi_ets_sla_config_resp ets_sla_config;
5542 	struct i40e_hw *hw = &vsi->adapter->hw;
5543 	i40e_status ret;
5544 	int i;
5545 	uint32_t bw_max;
5546 
5547 	memset(&bw_config, 0, sizeof(bw_config));
5548 	ret = i40e_aq_query_vsi_bw_config(hw, vsi->seid, &bw_config, NULL);
5549 	if (ret != I40E_SUCCESS) {
5550 		PMD_DRV_LOG(ERR, "VSI failed to get bandwidth configuration %u",
5551 			    hw->aq.asq_last_status);
5552 		return ret;
5553 	}
5554 
5555 	memset(&ets_sla_config, 0, sizeof(ets_sla_config));
5556 	ret = i40e_aq_query_vsi_ets_sla_config(hw, vsi->seid,
5557 					&ets_sla_config, NULL);
5558 	if (ret != I40E_SUCCESS) {
5559 		PMD_DRV_LOG(ERR,
5560 			"VSI failed to get TC bandwdith configuration %u",
5561 			hw->aq.asq_last_status);
5562 		return ret;
5563 	}
5564 
5565 	/* store and print out BW info */
5566 	vsi->bw_info.bw_limit = rte_le_to_cpu_16(bw_config.port_bw_limit);
5567 	vsi->bw_info.bw_max = bw_config.max_bw;
5568 	PMD_DRV_LOG(DEBUG, "VSI bw limit:%u", vsi->bw_info.bw_limit);
5569 	PMD_DRV_LOG(DEBUG, "VSI max_bw:%u", vsi->bw_info.bw_max);
5570 	bw_max = rte_le_to_cpu_16(ets_sla_config.tc_bw_max[0]) |
5571 		    (rte_le_to_cpu_16(ets_sla_config.tc_bw_max[1]) <<
5572 		     I40E_16_BIT_WIDTH);
5573 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
5574 		vsi->bw_info.bw_ets_share_credits[i] =
5575 				ets_sla_config.share_credits[i];
5576 		vsi->bw_info.bw_ets_credits[i] =
5577 				rte_le_to_cpu_16(ets_sla_config.credits[i]);
5578 		/* 4 bits per TC, 4th bit is reserved */
5579 		vsi->bw_info.bw_ets_max[i] =
5580 			(uint8_t)((bw_max >> (i * I40E_4_BIT_WIDTH)) &
5581 				  RTE_LEN2MASK(3, uint8_t));
5582 		PMD_DRV_LOG(DEBUG, "\tVSI TC%u:share credits %u", i,
5583 			    vsi->bw_info.bw_ets_share_credits[i]);
5584 		PMD_DRV_LOG(DEBUG, "\tVSI TC%u:credits %u", i,
5585 			    vsi->bw_info.bw_ets_credits[i]);
5586 		PMD_DRV_LOG(DEBUG, "\tVSI TC%u: max credits: %u", i,
5587 			    vsi->bw_info.bw_ets_max[i]);
5588 	}
5589 
5590 	return I40E_SUCCESS;
5591 }
5592 
5593 /* i40e_enable_pf_lb
5594  * @pf: pointer to the pf structure
5595  *
5596  * allow loopback on pf
5597  */
5598 static inline void
5599 i40e_enable_pf_lb(struct i40e_pf *pf)
5600 {
5601 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
5602 	struct i40e_vsi_context ctxt;
5603 	int ret;
5604 
5605 	/* Use the FW API if FW >= v5.0 */
5606 	if (hw->aq.fw_maj_ver < 5 && hw->mac.type != I40E_MAC_X722) {
5607 		PMD_INIT_LOG(ERR, "FW < v5.0, cannot enable loopback");
5608 		return;
5609 	}
5610 
5611 	memset(&ctxt, 0, sizeof(ctxt));
5612 	ctxt.seid = pf->main_vsi_seid;
5613 	ctxt.pf_num = hw->pf_id;
5614 	ret = i40e_aq_get_vsi_params(hw, &ctxt, NULL);
5615 	if (ret) {
5616 		PMD_DRV_LOG(ERR, "cannot get pf vsi config, err %d, aq_err %d",
5617 			    ret, hw->aq.asq_last_status);
5618 		return;
5619 	}
5620 	ctxt.flags = I40E_AQ_VSI_TYPE_PF;
5621 	ctxt.info.valid_sections =
5622 		rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID);
5623 	ctxt.info.switch_id |=
5624 		rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
5625 
5626 	ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
5627 	if (ret)
5628 		PMD_DRV_LOG(ERR, "update vsi switch failed, aq_err=%d",
5629 			    hw->aq.asq_last_status);
5630 }
5631 
5632 /* Setup a VSI */
5633 struct i40e_vsi *
5634 i40e_vsi_setup(struct i40e_pf *pf,
5635 	       enum i40e_vsi_type type,
5636 	       struct i40e_vsi *uplink_vsi,
5637 	       uint16_t user_param)
5638 {
5639 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
5640 	struct i40e_vsi *vsi;
5641 	struct i40e_mac_filter_info filter;
5642 	int ret;
5643 	struct i40e_vsi_context ctxt;
5644 	struct rte_ether_addr broadcast =
5645 		{.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
5646 
5647 	if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV &&
5648 	    uplink_vsi == NULL) {
5649 		PMD_DRV_LOG(ERR,
5650 			"VSI setup failed, VSI link shouldn't be NULL");
5651 		return NULL;
5652 	}
5653 
5654 	if (type == I40E_VSI_MAIN && uplink_vsi != NULL) {
5655 		PMD_DRV_LOG(ERR,
5656 			"VSI setup failed, MAIN VSI uplink VSI should be NULL");
5657 		return NULL;
5658 	}
5659 
5660 	/* two situations
5661 	 * 1.type is not MAIN and uplink vsi is not NULL
5662 	 * If uplink vsi didn't setup VEB, create one first under veb field
5663 	 * 2.type is SRIOV and the uplink is NULL
5664 	 * If floating VEB is NULL, create one veb under floating veb field
5665 	 */
5666 
5667 	if (type != I40E_VSI_MAIN && uplink_vsi != NULL &&
5668 	    uplink_vsi->veb == NULL) {
5669 		uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi);
5670 
5671 		if (uplink_vsi->veb == NULL) {
5672 			PMD_DRV_LOG(ERR, "VEB setup failed");
5673 			return NULL;
5674 		}
5675 		/* set ALLOWLOOPBACk on pf, when veb is created */
5676 		i40e_enable_pf_lb(pf);
5677 	}
5678 
5679 	if (type == I40E_VSI_SRIOV && uplink_vsi == NULL &&
5680 	    pf->main_vsi->floating_veb == NULL) {
5681 		pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi);
5682 
5683 		if (pf->main_vsi->floating_veb == NULL) {
5684 			PMD_DRV_LOG(ERR, "VEB setup failed");
5685 			return NULL;
5686 		}
5687 	}
5688 
5689 	vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);
5690 	if (!vsi) {
5691 		PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");
5692 		return NULL;
5693 	}
5694 	TAILQ_INIT(&vsi->mac_list);
5695 	vsi->type = type;
5696 	vsi->adapter = I40E_PF_TO_ADAPTER(pf);
5697 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
5698 	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
5699 	vsi->user_param = user_param;
5700 	vsi->vlan_anti_spoof_on = 0;
5701 	vsi->vlan_filter_on = 0;
5702 	/* Allocate queues */
5703 	switch (vsi->type) {
5704 	case I40E_VSI_MAIN  :
5705 		vsi->nb_qps = pf->lan_nb_qps;
5706 		break;
5707 	case I40E_VSI_SRIOV :
5708 		vsi->nb_qps = pf->vf_nb_qps;
5709 		break;
5710 	case I40E_VSI_VMDQ2:
5711 		vsi->nb_qps = pf->vmdq_nb_qps;
5712 		break;
5713 	case I40E_VSI_FDIR:
5714 		vsi->nb_qps = pf->fdir_nb_qps;
5715 		break;
5716 	default:
5717 		goto fail_mem;
5718 	}
5719 	/*
5720 	 * The filter status descriptor is reported in rx queue 0,
5721 	 * while the tx queue for fdir filter programming has no
5722 	 * such constraints, can be non-zero queues.
5723 	 * To simplify it, choose FDIR vsi use queue 0 pair.
5724 	 * To make sure it will use queue 0 pair, queue allocation
5725 	 * need be done before this function is called
5726 	 */
5727 	if (type != I40E_VSI_FDIR) {
5728 		ret = i40e_res_pool_alloc(&pf->qp_pool, vsi->nb_qps);
5729 			if (ret < 0) {
5730 				PMD_DRV_LOG(ERR, "VSI %d allocate queue failed %d",
5731 						vsi->seid, ret);
5732 				goto fail_mem;
5733 			}
5734 			vsi->base_queue = ret;
5735 	} else
5736 		vsi->base_queue = I40E_FDIR_QUEUE_ID;
5737 
5738 	/* VF has MSIX interrupt in VF range, don't allocate here */
5739 	if (type == I40E_VSI_MAIN) {
5740 		if (pf->support_multi_driver) {
5741 			/* If support multi-driver, need to use INT0 instead of
5742 			 * allocating from msix pool. The Msix pool is init from
5743 			 * INT1, so it's OK just set msix_intr to 0 and nb_msix
5744 			 * to 1 without calling i40e_res_pool_alloc.
5745 			 */
5746 			vsi->msix_intr = 0;
5747 			vsi->nb_msix = 1;
5748 		} else {
5749 			ret = i40e_res_pool_alloc(&pf->msix_pool,
5750 						  RTE_MIN(vsi->nb_qps,
5751 						     RTE_MAX_RXTX_INTR_VEC_ID));
5752 			if (ret < 0) {
5753 				PMD_DRV_LOG(ERR,
5754 					    "VSI MAIN %d get heap failed %d",
5755 					    vsi->seid, ret);
5756 				goto fail_queue_alloc;
5757 			}
5758 			vsi->msix_intr = ret;
5759 			vsi->nb_msix = RTE_MIN(vsi->nb_qps,
5760 					       RTE_MAX_RXTX_INTR_VEC_ID);
5761 		}
5762 	} else if (type != I40E_VSI_SRIOV) {
5763 		ret = i40e_res_pool_alloc(&pf->msix_pool, 1);
5764 		if (ret < 0) {
5765 			PMD_DRV_LOG(ERR, "VSI %d get heap failed %d", vsi->seid, ret);
5766 			if (type != I40E_VSI_FDIR)
5767 				goto fail_queue_alloc;
5768 			vsi->msix_intr = 0;
5769 			vsi->nb_msix = 0;
5770 		} else {
5771 			vsi->msix_intr = ret;
5772 			vsi->nb_msix = 1;
5773 		}
5774 	} else {
5775 		vsi->msix_intr = 0;
5776 		vsi->nb_msix = 0;
5777 	}
5778 
5779 	/* Add VSI */
5780 	if (type == I40E_VSI_MAIN) {
5781 		/* For main VSI, no need to add since it's default one */
5782 		vsi->uplink_seid = pf->mac_seid;
5783 		vsi->seid = pf->main_vsi_seid;
5784 		/* Bind queues with specific MSIX interrupt */
5785 		/**
5786 		 * Needs 2 interrupt at least, one for misc cause which will
5787 		 * enabled from OS side, Another for queues binding the
5788 		 * interrupt from device side only.
5789 		 */
5790 
5791 		/* Get default VSI parameters from hardware */
5792 		memset(&ctxt, 0, sizeof(ctxt));
5793 		ctxt.seid = vsi->seid;
5794 		ctxt.pf_num = hw->pf_id;
5795 		ctxt.uplink_seid = vsi->uplink_seid;
5796 		ctxt.vf_num = 0;
5797 		ret = i40e_aq_get_vsi_params(hw, &ctxt, NULL);
5798 		if (ret != I40E_SUCCESS) {
5799 			PMD_DRV_LOG(ERR, "Failed to get VSI params");
5800 			goto fail_msix_alloc;
5801 		}
5802 		rte_memcpy(&vsi->info, &ctxt.info,
5803 			sizeof(struct i40e_aqc_vsi_properties_data));
5804 		vsi->vsi_id = ctxt.vsi_number;
5805 		vsi->info.valid_sections = 0;
5806 
5807 		/* Configure tc, enabled TC0 only */
5808 		if (i40e_vsi_update_tc_bandwidth(vsi, I40E_DEFAULT_TCMAP) !=
5809 			I40E_SUCCESS) {
5810 			PMD_DRV_LOG(ERR, "Failed to update TC bandwidth");
5811 			goto fail_msix_alloc;
5812 		}
5813 
5814 		/* TC, queue mapping */
5815 		memset(&ctxt, 0, sizeof(ctxt));
5816 		vsi->info.valid_sections |=
5817 			rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID);
5818 		vsi->info.port_vlan_flags = I40E_AQ_VSI_PVLAN_MODE_ALL |
5819 					I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH;
5820 		rte_memcpy(&ctxt.info, &vsi->info,
5821 			sizeof(struct i40e_aqc_vsi_properties_data));
5822 		ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info,
5823 						I40E_DEFAULT_TCMAP);
5824 		if (ret != I40E_SUCCESS) {
5825 			PMD_DRV_LOG(ERR,
5826 				"Failed to configure TC queue mapping");
5827 			goto fail_msix_alloc;
5828 		}
5829 		ctxt.seid = vsi->seid;
5830 		ctxt.pf_num = hw->pf_id;
5831 		ctxt.uplink_seid = vsi->uplink_seid;
5832 		ctxt.vf_num = 0;
5833 
5834 		/* Update VSI parameters */
5835 		ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
5836 		if (ret != I40E_SUCCESS) {
5837 			PMD_DRV_LOG(ERR, "Failed to update VSI params");
5838 			goto fail_msix_alloc;
5839 		}
5840 
5841 		rte_memcpy(&vsi->info.tc_mapping, &ctxt.info.tc_mapping,
5842 						sizeof(vsi->info.tc_mapping));
5843 		rte_memcpy(&vsi->info.queue_mapping,
5844 				&ctxt.info.queue_mapping,
5845 			sizeof(vsi->info.queue_mapping));
5846 		vsi->info.mapping_flags = ctxt.info.mapping_flags;
5847 		vsi->info.valid_sections = 0;
5848 
5849 		rte_memcpy(pf->dev_addr.addr_bytes, hw->mac.perm_addr,
5850 				ETH_ADDR_LEN);
5851 
5852 		/**
5853 		 * Updating default filter settings are necessary to prevent
5854 		 * reception of tagged packets.
5855 		 * Some old firmware configurations load a default macvlan
5856 		 * filter which accepts both tagged and untagged packets.
5857 		 * The updating is to use a normal filter instead if needed.
5858 		 * For NVM 4.2.2 or after, the updating is not needed anymore.
5859 		 * The firmware with correct configurations load the default
5860 		 * macvlan filter which is expected and cannot be removed.
5861 		 */
5862 		i40e_update_default_filter_setting(vsi);
5863 		i40e_config_qinq(hw, vsi);
5864 	} else if (type == I40E_VSI_SRIOV) {
5865 		memset(&ctxt, 0, sizeof(ctxt));
5866 		/**
5867 		 * For other VSI, the uplink_seid equals to uplink VSI's
5868 		 * uplink_seid since they share same VEB
5869 		 */
5870 		if (uplink_vsi == NULL)
5871 			vsi->uplink_seid = pf->main_vsi->floating_veb->seid;
5872 		else
5873 			vsi->uplink_seid = uplink_vsi->uplink_seid;
5874 		ctxt.pf_num = hw->pf_id;
5875 		ctxt.vf_num = hw->func_caps.vf_base_id + user_param;
5876 		ctxt.uplink_seid = vsi->uplink_seid;
5877 		ctxt.connection_type = 0x1;
5878 		ctxt.flags = I40E_AQ_VSI_TYPE_VF;
5879 
5880 		/* Use the VEB configuration if FW >= v5.0 */
5881 		if (hw->aq.fw_maj_ver >= 5 || hw->mac.type == I40E_MAC_X722) {
5882 			/* Configure switch ID */
5883 			ctxt.info.valid_sections |=
5884 			rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID);
5885 			ctxt.info.switch_id =
5886 			rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
5887 		}
5888 
5889 		/* Configure port/vlan */
5890 		ctxt.info.valid_sections |=
5891 			rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID);
5892 		ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_ALL;
5893 		ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info,
5894 						hw->func_caps.enabled_tcmap);
5895 		if (ret != I40E_SUCCESS) {
5896 			PMD_DRV_LOG(ERR,
5897 				"Failed to configure TC queue mapping");
5898 			goto fail_msix_alloc;
5899 		}
5900 
5901 		ctxt.info.up_enable_bits = hw->func_caps.enabled_tcmap;
5902 		ctxt.info.valid_sections |=
5903 			rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SCHED_VALID);
5904 		/**
5905 		 * Since VSI is not created yet, only configure parameter,
5906 		 * will add vsi below.
5907 		 */
5908 
5909 		i40e_config_qinq(hw, vsi);
5910 	} else if (type == I40E_VSI_VMDQ2) {
5911 		memset(&ctxt, 0, sizeof(ctxt));
5912 		/*
5913 		 * For other VSI, the uplink_seid equals to uplink VSI's
5914 		 * uplink_seid since they share same VEB
5915 		 */
5916 		vsi->uplink_seid = uplink_vsi->uplink_seid;
5917 		ctxt.pf_num = hw->pf_id;
5918 		ctxt.vf_num = 0;
5919 		ctxt.uplink_seid = vsi->uplink_seid;
5920 		ctxt.connection_type = 0x1;
5921 		ctxt.flags = I40E_AQ_VSI_TYPE_VMDQ2;
5922 
5923 		ctxt.info.valid_sections |=
5924 				rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID);
5925 		/* user_param carries flag to enable loop back */
5926 		if (user_param) {
5927 			ctxt.info.switch_id =
5928 			rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB);
5929 			ctxt.info.switch_id |=
5930 			rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
5931 		}
5932 
5933 		/* Configure port/vlan */
5934 		ctxt.info.valid_sections |=
5935 			rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID);
5936 		ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_ALL;
5937 		ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info,
5938 						I40E_DEFAULT_TCMAP);
5939 		if (ret != I40E_SUCCESS) {
5940 			PMD_DRV_LOG(ERR,
5941 				"Failed to configure TC queue mapping");
5942 			goto fail_msix_alloc;
5943 		}
5944 		ctxt.info.up_enable_bits = I40E_DEFAULT_TCMAP;
5945 		ctxt.info.valid_sections |=
5946 			rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SCHED_VALID);
5947 	} else if (type == I40E_VSI_FDIR) {
5948 		memset(&ctxt, 0, sizeof(ctxt));
5949 		vsi->uplink_seid = uplink_vsi->uplink_seid;
5950 		ctxt.pf_num = hw->pf_id;
5951 		ctxt.vf_num = 0;
5952 		ctxt.uplink_seid = vsi->uplink_seid;
5953 		ctxt.connection_type = 0x1;     /* regular data port */
5954 		ctxt.flags = I40E_AQ_VSI_TYPE_PF;
5955 		ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info,
5956 						I40E_DEFAULT_TCMAP);
5957 		if (ret != I40E_SUCCESS) {
5958 			PMD_DRV_LOG(ERR,
5959 				"Failed to configure TC queue mapping.");
5960 			goto fail_msix_alloc;
5961 		}
5962 		ctxt.info.up_enable_bits = I40E_DEFAULT_TCMAP;
5963 		ctxt.info.valid_sections |=
5964 			rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SCHED_VALID);
5965 	} else {
5966 		PMD_DRV_LOG(ERR, "VSI: Not support other type VSI yet");
5967 		goto fail_msix_alloc;
5968 	}
5969 
5970 	if (vsi->type != I40E_VSI_MAIN) {
5971 		ret = i40e_aq_add_vsi(hw, &ctxt, NULL);
5972 		if (ret != I40E_SUCCESS) {
5973 			PMD_DRV_LOG(ERR, "add vsi failed, aq_err=%d",
5974 				    hw->aq.asq_last_status);
5975 			goto fail_msix_alloc;
5976 		}
5977 		memcpy(&vsi->info, &ctxt.info, sizeof(ctxt.info));
5978 		vsi->info.valid_sections = 0;
5979 		vsi->seid = ctxt.seid;
5980 		vsi->vsi_id = ctxt.vsi_number;
5981 		vsi->sib_vsi_list.vsi = vsi;
5982 		if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) {
5983 			TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head,
5984 					  &vsi->sib_vsi_list, list);
5985 		} else {
5986 			TAILQ_INSERT_TAIL(&uplink_vsi->veb->head,
5987 					  &vsi->sib_vsi_list, list);
5988 		}
5989 	}
5990 
5991 	/* MAC/VLAN configuration */
5992 	rte_memcpy(&filter.mac_addr, &broadcast, RTE_ETHER_ADDR_LEN);
5993 	filter.filter_type = I40E_MACVLAN_PERFECT_MATCH;
5994 
5995 	ret = i40e_vsi_add_mac(vsi, &filter);
5996 	if (ret != I40E_SUCCESS) {
5997 		PMD_DRV_LOG(ERR, "Failed to add MACVLAN filter");
5998 		goto fail_msix_alloc;
5999 	}
6000 
6001 	/* Get VSI BW information */
6002 	i40e_vsi_get_bw_config(vsi);
6003 	return vsi;
6004 fail_msix_alloc:
6005 	i40e_res_pool_free(&pf->msix_pool,vsi->msix_intr);
6006 fail_queue_alloc:
6007 	i40e_res_pool_free(&pf->qp_pool,vsi->base_queue);
6008 fail_mem:
6009 	rte_free(vsi);
6010 	return NULL;
6011 }
6012 
6013 /* Configure vlan filter on or off */
6014 int
6015 i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on)
6016 {
6017 	int i, num;
6018 	struct i40e_mac_filter *f;
6019 	void *temp;
6020 	struct i40e_mac_filter_info *mac_filter;
6021 	enum i40e_mac_filter_type desired_filter;
6022 	int ret = I40E_SUCCESS;
6023 
6024 	if (on) {
6025 		/* Filter to match MAC and VLAN */
6026 		desired_filter = I40E_MACVLAN_PERFECT_MATCH;
6027 	} else {
6028 		/* Filter to match only MAC */
6029 		desired_filter = I40E_MAC_PERFECT_MATCH;
6030 	}
6031 
6032 	num = vsi->mac_num;
6033 
6034 	mac_filter = rte_zmalloc("mac_filter_info_data",
6035 				 num * sizeof(*mac_filter), 0);
6036 	if (mac_filter == NULL) {
6037 		PMD_DRV_LOG(ERR, "failed to allocate memory");
6038 		return I40E_ERR_NO_MEMORY;
6039 	}
6040 
6041 	i = 0;
6042 
6043 	/* Remove all existing mac */
6044 	TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) {
6045 		mac_filter[i] = f->mac_info;
6046 		ret = i40e_vsi_delete_mac(vsi, &f->mac_info.mac_addr);
6047 		if (ret) {
6048 			PMD_DRV_LOG(ERR, "Update VSI failed to %s vlan filter",
6049 				    on ? "enable" : "disable");
6050 			goto DONE;
6051 		}
6052 		i++;
6053 	}
6054 
6055 	/* Override with new filter */
6056 	for (i = 0; i < num; i++) {
6057 		mac_filter[i].filter_type = desired_filter;
6058 		ret = i40e_vsi_add_mac(vsi, &mac_filter[i]);
6059 		if (ret) {
6060 			PMD_DRV_LOG(ERR, "Update VSI failed to %s vlan filter",
6061 				    on ? "enable" : "disable");
6062 			goto DONE;
6063 		}
6064 	}
6065 
6066 DONE:
6067 	rte_free(mac_filter);
6068 	return ret;
6069 }
6070 
6071 /* Configure vlan stripping on or off */
6072 int
6073 i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on)
6074 {
6075 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
6076 	struct i40e_vsi_context ctxt;
6077 	uint8_t vlan_flags;
6078 	int ret = I40E_SUCCESS;
6079 
6080 	/* Check if it has been already on or off */
6081 	if (vsi->info.valid_sections &
6082 		rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID)) {
6083 		if (on) {
6084 			if ((vsi->info.port_vlan_flags &
6085 				I40E_AQ_VSI_PVLAN_EMOD_MASK) == 0)
6086 				return 0; /* already on */
6087 		} else {
6088 			if ((vsi->info.port_vlan_flags &
6089 				I40E_AQ_VSI_PVLAN_EMOD_MASK) ==
6090 				I40E_AQ_VSI_PVLAN_EMOD_MASK)
6091 				return 0; /* already off */
6092 		}
6093 	}
6094 
6095 	if (on)
6096 		vlan_flags = I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH;
6097 	else
6098 		vlan_flags = I40E_AQ_VSI_PVLAN_EMOD_NOTHING;
6099 	vsi->info.valid_sections =
6100 		rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID);
6101 	vsi->info.port_vlan_flags &= ~(I40E_AQ_VSI_PVLAN_EMOD_MASK);
6102 	vsi->info.port_vlan_flags |= vlan_flags;
6103 	ctxt.seid = vsi->seid;
6104 	rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
6105 	ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
6106 	if (ret)
6107 		PMD_DRV_LOG(INFO, "Update VSI failed to %s vlan stripping",
6108 			    on ? "enable" : "disable");
6109 
6110 	return ret;
6111 }
6112 
6113 static int
6114 i40e_dev_init_vlan(struct rte_eth_dev *dev)
6115 {
6116 	struct rte_eth_dev_data *data = dev->data;
6117 	int ret;
6118 	int mask = 0;
6119 
6120 	/* Apply vlan offload setting */
6121 	mask = ETH_VLAN_STRIP_MASK |
6122 	       ETH_QINQ_STRIP_MASK |
6123 	       ETH_VLAN_FILTER_MASK |
6124 	       ETH_VLAN_EXTEND_MASK;
6125 	ret = i40e_vlan_offload_set(dev, mask);
6126 	if (ret) {
6127 		PMD_DRV_LOG(INFO, "Failed to update vlan offload");
6128 		return ret;
6129 	}
6130 
6131 	/* Apply pvid setting */
6132 	ret = i40e_vlan_pvid_set(dev, data->dev_conf.txmode.pvid,
6133 				data->dev_conf.txmode.hw_vlan_insert_pvid);
6134 	if (ret)
6135 		PMD_DRV_LOG(INFO, "Failed to update VSI params");
6136 
6137 	return ret;
6138 }
6139 
6140 static int
6141 i40e_vsi_config_double_vlan(struct i40e_vsi *vsi, int on)
6142 {
6143 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
6144 
6145 	return i40e_aq_set_port_parameters(hw, vsi->seid, 0, 1, on, NULL);
6146 }
6147 
6148 static int
6149 i40e_update_flow_control(struct i40e_hw *hw)
6150 {
6151 #define I40E_LINK_PAUSE_RXTX (I40E_AQ_LINK_PAUSE_RX | I40E_AQ_LINK_PAUSE_TX)
6152 	struct i40e_link_status link_status;
6153 	uint32_t rxfc = 0, txfc = 0, reg;
6154 	uint8_t an_info;
6155 	int ret;
6156 
6157 	memset(&link_status, 0, sizeof(link_status));
6158 	ret = i40e_aq_get_link_info(hw, FALSE, &link_status, NULL);
6159 	if (ret != I40E_SUCCESS) {
6160 		PMD_DRV_LOG(ERR, "Failed to get link status information");
6161 		goto write_reg; /* Disable flow control */
6162 	}
6163 
6164 	an_info = hw->phy.link_info.an_info;
6165 	if (!(an_info & I40E_AQ_AN_COMPLETED)) {
6166 		PMD_DRV_LOG(INFO, "Link auto negotiation not completed");
6167 		ret = I40E_ERR_NOT_READY;
6168 		goto write_reg; /* Disable flow control */
6169 	}
6170 	/**
6171 	 * If link auto negotiation is enabled, flow control needs to
6172 	 * be configured according to it
6173 	 */
6174 	switch (an_info & I40E_LINK_PAUSE_RXTX) {
6175 	case I40E_LINK_PAUSE_RXTX:
6176 		rxfc = 1;
6177 		txfc = 1;
6178 		hw->fc.current_mode = I40E_FC_FULL;
6179 		break;
6180 	case I40E_AQ_LINK_PAUSE_RX:
6181 		rxfc = 1;
6182 		hw->fc.current_mode = I40E_FC_RX_PAUSE;
6183 		break;
6184 	case I40E_AQ_LINK_PAUSE_TX:
6185 		txfc = 1;
6186 		hw->fc.current_mode = I40E_FC_TX_PAUSE;
6187 		break;
6188 	default:
6189 		hw->fc.current_mode = I40E_FC_NONE;
6190 		break;
6191 	}
6192 
6193 write_reg:
6194 	I40E_WRITE_REG(hw, I40E_PRTDCB_FCCFG,
6195 		txfc << I40E_PRTDCB_FCCFG_TFCE_SHIFT);
6196 	reg = I40E_READ_REG(hw, I40E_PRTDCB_MFLCN);
6197 	reg &= ~I40E_PRTDCB_MFLCN_RFCE_MASK;
6198 	reg |= rxfc << I40E_PRTDCB_MFLCN_RFCE_SHIFT;
6199 	I40E_WRITE_REG(hw, I40E_PRTDCB_MFLCN, reg);
6200 
6201 	return ret;
6202 }
6203 
6204 /* PF setup */
6205 static int
6206 i40e_pf_setup(struct i40e_pf *pf)
6207 {
6208 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
6209 	struct i40e_filter_control_settings settings;
6210 	struct i40e_vsi *vsi;
6211 	int ret;
6212 
6213 	/* Clear all stats counters */
6214 	pf->offset_loaded = FALSE;
6215 	memset(&pf->stats, 0, sizeof(struct i40e_hw_port_stats));
6216 	memset(&pf->stats_offset, 0, sizeof(struct i40e_hw_port_stats));
6217 	memset(&pf->internal_stats, 0, sizeof(struct i40e_eth_stats));
6218 	memset(&pf->internal_stats_offset, 0, sizeof(struct i40e_eth_stats));
6219 
6220 	ret = i40e_pf_get_switch_config(pf);
6221 	if (ret != I40E_SUCCESS) {
6222 		PMD_DRV_LOG(ERR, "Could not get switch config, err %d", ret);
6223 		return ret;
6224 	}
6225 
6226 	ret = rte_eth_switch_domain_alloc(&pf->switch_domain_id);
6227 	if (ret)
6228 		PMD_INIT_LOG(WARNING,
6229 			"failed to allocate switch domain for device %d", ret);
6230 
6231 	if (pf->flags & I40E_FLAG_FDIR) {
6232 		/* make queue allocated first, let FDIR use queue pair 0*/
6233 		ret = i40e_res_pool_alloc(&pf->qp_pool, I40E_DEFAULT_QP_NUM_FDIR);
6234 		if (ret != I40E_FDIR_QUEUE_ID) {
6235 			PMD_DRV_LOG(ERR,
6236 				"queue allocation fails for FDIR: ret =%d",
6237 				ret);
6238 			pf->flags &= ~I40E_FLAG_FDIR;
6239 		}
6240 	}
6241 	/*  main VSI setup */
6242 	vsi = i40e_vsi_setup(pf, I40E_VSI_MAIN, NULL, 0);
6243 	if (!vsi) {
6244 		PMD_DRV_LOG(ERR, "Setup of main vsi failed");
6245 		return I40E_ERR_NOT_READY;
6246 	}
6247 	pf->main_vsi = vsi;
6248 
6249 	/* Configure filter control */
6250 	memset(&settings, 0, sizeof(settings));
6251 	if (hw->func_caps.rss_table_size == ETH_RSS_RETA_SIZE_128)
6252 		settings.hash_lut_size = I40E_HASH_LUT_SIZE_128;
6253 	else if (hw->func_caps.rss_table_size == ETH_RSS_RETA_SIZE_512)
6254 		settings.hash_lut_size = I40E_HASH_LUT_SIZE_512;
6255 	else {
6256 		PMD_DRV_LOG(ERR, "Hash lookup table size (%u) not supported",
6257 			hw->func_caps.rss_table_size);
6258 		return I40E_ERR_PARAM;
6259 	}
6260 	PMD_DRV_LOG(INFO, "Hardware capability of hash lookup table size: %u",
6261 		hw->func_caps.rss_table_size);
6262 	pf->hash_lut_size = hw->func_caps.rss_table_size;
6263 
6264 	/* Enable ethtype and macvlan filters */
6265 	settings.enable_ethtype = TRUE;
6266 	settings.enable_macvlan = TRUE;
6267 	ret = i40e_set_filter_control(hw, &settings);
6268 	if (ret)
6269 		PMD_INIT_LOG(WARNING, "setup_pf_filter_control failed: %d",
6270 								ret);
6271 
6272 	/* Update flow control according to the auto negotiation */
6273 	i40e_update_flow_control(hw);
6274 
6275 	return I40E_SUCCESS;
6276 }
6277 
6278 int
6279 i40e_switch_tx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on)
6280 {
6281 	uint32_t reg;
6282 	uint16_t j;
6283 
6284 	/**
6285 	 * Set or clear TX Queue Disable flags,
6286 	 * which is required by hardware.
6287 	 */
6288 	i40e_pre_tx_queue_cfg(hw, q_idx, on);
6289 	rte_delay_us(I40E_PRE_TX_Q_CFG_WAIT_US);
6290 
6291 	/* Wait until the request is finished */
6292 	for (j = 0; j < I40E_CHK_Q_ENA_COUNT; j++) {
6293 		rte_delay_us(I40E_CHK_Q_ENA_INTERVAL_US);
6294 		reg = I40E_READ_REG(hw, I40E_QTX_ENA(q_idx));
6295 		if (!(((reg >> I40E_QTX_ENA_QENA_REQ_SHIFT) & 0x1) ^
6296 			((reg >> I40E_QTX_ENA_QENA_STAT_SHIFT)
6297 							& 0x1))) {
6298 			break;
6299 		}
6300 	}
6301 	if (on) {
6302 		if (reg & I40E_QTX_ENA_QENA_STAT_MASK)
6303 			return I40E_SUCCESS; /* already on, skip next steps */
6304 
6305 		I40E_WRITE_REG(hw, I40E_QTX_HEAD(q_idx), 0);
6306 		reg |= I40E_QTX_ENA_QENA_REQ_MASK;
6307 	} else {
6308 		if (!(reg & I40E_QTX_ENA_QENA_STAT_MASK))
6309 			return I40E_SUCCESS; /* already off, skip next steps */
6310 		reg &= ~I40E_QTX_ENA_QENA_REQ_MASK;
6311 	}
6312 	/* Write the register */
6313 	I40E_WRITE_REG(hw, I40E_QTX_ENA(q_idx), reg);
6314 	/* Check the result */
6315 	for (j = 0; j < I40E_CHK_Q_ENA_COUNT; j++) {
6316 		rte_delay_us(I40E_CHK_Q_ENA_INTERVAL_US);
6317 		reg = I40E_READ_REG(hw, I40E_QTX_ENA(q_idx));
6318 		if (on) {
6319 			if ((reg & I40E_QTX_ENA_QENA_REQ_MASK) &&
6320 				(reg & I40E_QTX_ENA_QENA_STAT_MASK))
6321 				break;
6322 		} else {
6323 			if (!(reg & I40E_QTX_ENA_QENA_REQ_MASK) &&
6324 				!(reg & I40E_QTX_ENA_QENA_STAT_MASK))
6325 				break;
6326 		}
6327 	}
6328 	/* Check if it is timeout */
6329 	if (j >= I40E_CHK_Q_ENA_COUNT) {
6330 		PMD_DRV_LOG(ERR, "Failed to %s tx queue[%u]",
6331 			    (on ? "enable" : "disable"), q_idx);
6332 		return I40E_ERR_TIMEOUT;
6333 	}
6334 
6335 	return I40E_SUCCESS;
6336 }
6337 
6338 int
6339 i40e_switch_rx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on)
6340 {
6341 	uint32_t reg;
6342 	uint16_t j;
6343 
6344 	/* Wait until the request is finished */
6345 	for (j = 0; j < I40E_CHK_Q_ENA_COUNT; j++) {
6346 		rte_delay_us(I40E_CHK_Q_ENA_INTERVAL_US);
6347 		reg = I40E_READ_REG(hw, I40E_QRX_ENA(q_idx));
6348 		if (!((reg >> I40E_QRX_ENA_QENA_REQ_SHIFT) & 0x1) ^
6349 			((reg >> I40E_QRX_ENA_QENA_STAT_SHIFT) & 0x1))
6350 			break;
6351 	}
6352 
6353 	if (on) {
6354 		if (reg & I40E_QRX_ENA_QENA_STAT_MASK)
6355 			return I40E_SUCCESS; /* Already on, skip next steps */
6356 		reg |= I40E_QRX_ENA_QENA_REQ_MASK;
6357 	} else {
6358 		if (!(reg & I40E_QRX_ENA_QENA_STAT_MASK))
6359 			return I40E_SUCCESS; /* Already off, skip next steps */
6360 		reg &= ~I40E_QRX_ENA_QENA_REQ_MASK;
6361 	}
6362 
6363 	/* Write the register */
6364 	I40E_WRITE_REG(hw, I40E_QRX_ENA(q_idx), reg);
6365 	/* Check the result */
6366 	for (j = 0; j < I40E_CHK_Q_ENA_COUNT; j++) {
6367 		rte_delay_us(I40E_CHK_Q_ENA_INTERVAL_US);
6368 		reg = I40E_READ_REG(hw, I40E_QRX_ENA(q_idx));
6369 		if (on) {
6370 			if ((reg & I40E_QRX_ENA_QENA_REQ_MASK) &&
6371 				(reg & I40E_QRX_ENA_QENA_STAT_MASK))
6372 				break;
6373 		} else {
6374 			if (!(reg & I40E_QRX_ENA_QENA_REQ_MASK) &&
6375 				!(reg & I40E_QRX_ENA_QENA_STAT_MASK))
6376 				break;
6377 		}
6378 	}
6379 
6380 	/* Check if it is timeout */
6381 	if (j >= I40E_CHK_Q_ENA_COUNT) {
6382 		PMD_DRV_LOG(ERR, "Failed to %s rx queue[%u]",
6383 			    (on ? "enable" : "disable"), q_idx);
6384 		return I40E_ERR_TIMEOUT;
6385 	}
6386 
6387 	return I40E_SUCCESS;
6388 }
6389 
6390 /* Initialize VSI for TX */
6391 static int
6392 i40e_dev_tx_init(struct i40e_pf *pf)
6393 {
6394 	struct rte_eth_dev_data *data = pf->dev_data;
6395 	uint16_t i;
6396 	uint32_t ret = I40E_SUCCESS;
6397 	struct i40e_tx_queue *txq;
6398 
6399 	for (i = 0; i < data->nb_tx_queues; i++) {
6400 		txq = data->tx_queues[i];
6401 		if (!txq || !txq->q_set)
6402 			continue;
6403 		ret = i40e_tx_queue_init(txq);
6404 		if (ret != I40E_SUCCESS)
6405 			break;
6406 	}
6407 	if (ret == I40E_SUCCESS)
6408 		i40e_set_tx_function(container_of(pf, struct i40e_adapter, pf)
6409 				     ->eth_dev);
6410 
6411 	return ret;
6412 }
6413 
6414 /* Initialize VSI for RX */
6415 static int
6416 i40e_dev_rx_init(struct i40e_pf *pf)
6417 {
6418 	struct rte_eth_dev_data *data = pf->dev_data;
6419 	int ret = I40E_SUCCESS;
6420 	uint16_t i;
6421 	struct i40e_rx_queue *rxq;
6422 
6423 	i40e_pf_config_rss(pf);
6424 	for (i = 0; i < data->nb_rx_queues; i++) {
6425 		rxq = data->rx_queues[i];
6426 		if (!rxq || !rxq->q_set)
6427 			continue;
6428 
6429 		ret = i40e_rx_queue_init(rxq);
6430 		if (ret != I40E_SUCCESS) {
6431 			PMD_DRV_LOG(ERR,
6432 				"Failed to do RX queue initialization");
6433 			break;
6434 		}
6435 	}
6436 	if (ret == I40E_SUCCESS)
6437 		i40e_set_rx_function(container_of(pf, struct i40e_adapter, pf)
6438 				     ->eth_dev);
6439 
6440 	return ret;
6441 }
6442 
6443 static int
6444 i40e_dev_rxtx_init(struct i40e_pf *pf)
6445 {
6446 	int err;
6447 
6448 	err = i40e_dev_tx_init(pf);
6449 	if (err) {
6450 		PMD_DRV_LOG(ERR, "Failed to do TX initialization");
6451 		return err;
6452 	}
6453 	err = i40e_dev_rx_init(pf);
6454 	if (err) {
6455 		PMD_DRV_LOG(ERR, "Failed to do RX initialization");
6456 		return err;
6457 	}
6458 
6459 	return err;
6460 }
6461 
6462 static int
6463 i40e_vmdq_setup(struct rte_eth_dev *dev)
6464 {
6465 	struct rte_eth_conf *conf = &dev->data->dev_conf;
6466 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
6467 	int i, err, conf_vsis, j, loop;
6468 	struct i40e_vsi *vsi;
6469 	struct i40e_vmdq_info *vmdq_info;
6470 	struct rte_eth_vmdq_rx_conf *vmdq_conf;
6471 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
6472 
6473 	/*
6474 	 * Disable interrupt to avoid message from VF. Furthermore, it will
6475 	 * avoid race condition in VSI creation/destroy.
6476 	 */
6477 	i40e_pf_disable_irq0(hw);
6478 
6479 	if ((pf->flags & I40E_FLAG_VMDQ) == 0) {
6480 		PMD_INIT_LOG(ERR, "FW doesn't support VMDQ");
6481 		return -ENOTSUP;
6482 	}
6483 
6484 	conf_vsis = conf->rx_adv_conf.vmdq_rx_conf.nb_queue_pools;
6485 	if (conf_vsis > pf->max_nb_vmdq_vsi) {
6486 		PMD_INIT_LOG(ERR, "VMDQ config: %u, max support:%u",
6487 			conf->rx_adv_conf.vmdq_rx_conf.nb_queue_pools,
6488 			pf->max_nb_vmdq_vsi);
6489 		return -ENOTSUP;
6490 	}
6491 
6492 	if (pf->vmdq != NULL) {
6493 		PMD_INIT_LOG(INFO, "VMDQ already configured");
6494 		return 0;
6495 	}
6496 
6497 	pf->vmdq = rte_zmalloc("vmdq_info_struct",
6498 				sizeof(*vmdq_info) * conf_vsis, 0);
6499 
6500 	if (pf->vmdq == NULL) {
6501 		PMD_INIT_LOG(ERR, "Failed to allocate memory");
6502 		return -ENOMEM;
6503 	}
6504 
6505 	vmdq_conf = &conf->rx_adv_conf.vmdq_rx_conf;
6506 
6507 	/* Create VMDQ VSI */
6508 	for (i = 0; i < conf_vsis; i++) {
6509 		vsi = i40e_vsi_setup(pf, I40E_VSI_VMDQ2, pf->main_vsi,
6510 				vmdq_conf->enable_loop_back);
6511 		if (vsi == NULL) {
6512 			PMD_INIT_LOG(ERR, "Failed to create VMDQ VSI");
6513 			err = -1;
6514 			goto err_vsi_setup;
6515 		}
6516 		vmdq_info = &pf->vmdq[i];
6517 		vmdq_info->pf = pf;
6518 		vmdq_info->vsi = vsi;
6519 	}
6520 	pf->nb_cfg_vmdq_vsi = conf_vsis;
6521 
6522 	/* Configure Vlan */
6523 	loop = sizeof(vmdq_conf->pool_map[0].pools) * CHAR_BIT;
6524 	for (i = 0; i < vmdq_conf->nb_pool_maps; i++) {
6525 		for (j = 0; j < loop && j < pf->nb_cfg_vmdq_vsi; j++) {
6526 			if (vmdq_conf->pool_map[i].pools & (1UL << j)) {
6527 				PMD_INIT_LOG(INFO, "Add vlan %u to vmdq pool %u",
6528 					vmdq_conf->pool_map[i].vlan_id, j);
6529 
6530 				err = i40e_vsi_add_vlan(pf->vmdq[j].vsi,
6531 						vmdq_conf->pool_map[i].vlan_id);
6532 				if (err) {
6533 					PMD_INIT_LOG(ERR, "Failed to add vlan");
6534 					err = -1;
6535 					goto err_vsi_setup;
6536 				}
6537 			}
6538 		}
6539 	}
6540 
6541 	i40e_pf_enable_irq0(hw);
6542 
6543 	return 0;
6544 
6545 err_vsi_setup:
6546 	for (i = 0; i < conf_vsis; i++)
6547 		if (pf->vmdq[i].vsi == NULL)
6548 			break;
6549 		else
6550 			i40e_vsi_release(pf->vmdq[i].vsi);
6551 
6552 	rte_free(pf->vmdq);
6553 	pf->vmdq = NULL;
6554 	i40e_pf_enable_irq0(hw);
6555 	return err;
6556 }
6557 
6558 static void
6559 i40e_stat_update_32(struct i40e_hw *hw,
6560 		   uint32_t reg,
6561 		   bool offset_loaded,
6562 		   uint64_t *offset,
6563 		   uint64_t *stat)
6564 {
6565 	uint64_t new_data;
6566 
6567 	new_data = (uint64_t)I40E_READ_REG(hw, reg);
6568 	if (!offset_loaded)
6569 		*offset = new_data;
6570 
6571 	if (new_data >= *offset)
6572 		*stat = (uint64_t)(new_data - *offset);
6573 	else
6574 		*stat = (uint64_t)((new_data +
6575 			((uint64_t)1 << I40E_32_BIT_WIDTH)) - *offset);
6576 }
6577 
6578 static void
6579 i40e_stat_update_48(struct i40e_hw *hw,
6580 		   uint32_t hireg,
6581 		   uint32_t loreg,
6582 		   bool offset_loaded,
6583 		   uint64_t *offset,
6584 		   uint64_t *stat)
6585 {
6586 	uint64_t new_data;
6587 
6588 	if (hw->device_id == I40E_DEV_ID_QEMU) {
6589 		new_data = (uint64_t)I40E_READ_REG(hw, loreg);
6590 		new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) &
6591 				I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH;
6592 	} else {
6593 		new_data = I40E_READ_REG64(hw, loreg);
6594 	}
6595 
6596 	if (!offset_loaded)
6597 		*offset = new_data;
6598 
6599 	if (new_data >= *offset)
6600 		*stat = new_data - *offset;
6601 	else
6602 		*stat = (uint64_t)((new_data +
6603 			((uint64_t)1 << I40E_48_BIT_WIDTH)) - *offset);
6604 
6605 	*stat &= I40E_48_BIT_MASK;
6606 }
6607 
6608 /* Disable IRQ0 */
6609 void
6610 i40e_pf_disable_irq0(struct i40e_hw *hw)
6611 {
6612 	/* Disable all interrupt types */
6613 	I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
6614 		       I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
6615 	I40E_WRITE_FLUSH(hw);
6616 }
6617 
6618 /* Enable IRQ0 */
6619 void
6620 i40e_pf_enable_irq0(struct i40e_hw *hw)
6621 {
6622 	I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
6623 		I40E_PFINT_DYN_CTL0_INTENA_MASK |
6624 		I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
6625 		I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
6626 	I40E_WRITE_FLUSH(hw);
6627 }
6628 
6629 static void
6630 i40e_pf_config_irq0(struct i40e_hw *hw, bool no_queue)
6631 {
6632 	/* read pending request and disable first */
6633 	i40e_pf_disable_irq0(hw);
6634 	I40E_WRITE_REG(hw, I40E_PFINT_ICR0_ENA, I40E_PFINT_ICR0_ENA_MASK);
6635 	I40E_WRITE_REG(hw, I40E_PFINT_STAT_CTL0,
6636 		I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_MASK);
6637 
6638 	if (no_queue)
6639 		/* Link no queues with irq0 */
6640 		I40E_WRITE_REG(hw, I40E_PFINT_LNKLST0,
6641 			       I40E_PFINT_LNKLST0_FIRSTQ_INDX_MASK);
6642 }
6643 
6644 static void
6645 i40e_dev_handle_vfr_event(struct rte_eth_dev *dev)
6646 {
6647 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
6648 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
6649 	int i;
6650 	uint16_t abs_vf_id;
6651 	uint32_t index, offset, val;
6652 
6653 	if (!pf->vfs)
6654 		return;
6655 	/**
6656 	 * Try to find which VF trigger a reset, use absolute VF id to access
6657 	 * since the reg is global register.
6658 	 */
6659 	for (i = 0; i < pf->vf_num; i++) {
6660 		abs_vf_id = hw->func_caps.vf_base_id + i;
6661 		index = abs_vf_id / I40E_UINT32_BIT_SIZE;
6662 		offset = abs_vf_id % I40E_UINT32_BIT_SIZE;
6663 		val = I40E_READ_REG(hw, I40E_GLGEN_VFLRSTAT(index));
6664 		/* VFR event occurred */
6665 		if (val & (0x1 << offset)) {
6666 			int ret;
6667 
6668 			/* Clear the event first */
6669 			I40E_WRITE_REG(hw, I40E_GLGEN_VFLRSTAT(index),
6670 							(0x1 << offset));
6671 			PMD_DRV_LOG(INFO, "VF %u reset occurred", abs_vf_id);
6672 			/**
6673 			 * Only notify a VF reset event occurred,
6674 			 * don't trigger another SW reset
6675 			 */
6676 			ret = i40e_pf_host_vf_reset(&pf->vfs[i], 0);
6677 			if (ret != I40E_SUCCESS)
6678 				PMD_DRV_LOG(ERR, "Failed to do VF reset");
6679 		}
6680 	}
6681 }
6682 
6683 static void
6684 i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev)
6685 {
6686 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
6687 	int i;
6688 
6689 	for (i = 0; i < pf->vf_num; i++)
6690 		i40e_notify_vf_link_status(dev, &pf->vfs[i]);
6691 }
6692 
6693 static void
6694 i40e_dev_handle_aq_msg(struct rte_eth_dev *dev)
6695 {
6696 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
6697 	struct i40e_arq_event_info info;
6698 	uint16_t pending, opcode;
6699 	int ret;
6700 
6701 	info.buf_len = I40E_AQ_BUF_SZ;
6702 	info.msg_buf = rte_zmalloc("msg_buffer", info.buf_len, 0);
6703 	if (!info.msg_buf) {
6704 		PMD_DRV_LOG(ERR, "Failed to allocate mem");
6705 		return;
6706 	}
6707 
6708 	pending = 1;
6709 	while (pending) {
6710 		ret = i40e_clean_arq_element(hw, &info, &pending);
6711 
6712 		if (ret != I40E_SUCCESS) {
6713 			PMD_DRV_LOG(INFO,
6714 				"Failed to read msg from AdminQ, aq_err: %u",
6715 				hw->aq.asq_last_status);
6716 			break;
6717 		}
6718 		opcode = rte_le_to_cpu_16(info.desc.opcode);
6719 
6720 		switch (opcode) {
6721 		case i40e_aqc_opc_send_msg_to_pf:
6722 			/* Refer to i40e_aq_send_msg_to_pf() for argument layout*/
6723 			i40e_pf_host_handle_vf_msg(dev,
6724 					rte_le_to_cpu_16(info.desc.retval),
6725 					rte_le_to_cpu_32(info.desc.cookie_high),
6726 					rte_le_to_cpu_32(info.desc.cookie_low),
6727 					info.msg_buf,
6728 					info.msg_len);
6729 			break;
6730 		case i40e_aqc_opc_get_link_status:
6731 			ret = i40e_dev_link_update(dev, 0);
6732 			if (!ret)
6733 				rte_eth_dev_callback_process(dev,
6734 					RTE_ETH_EVENT_INTR_LSC, NULL);
6735 			break;
6736 		default:
6737 			PMD_DRV_LOG(DEBUG, "Request %u is not supported yet",
6738 				    opcode);
6739 			break;
6740 		}
6741 	}
6742 	rte_free(info.msg_buf);
6743 }
6744 
6745 static void
6746 i40e_handle_mdd_event(struct rte_eth_dev *dev)
6747 {
6748 #define I40E_MDD_CLEAR32 0xFFFFFFFF
6749 #define I40E_MDD_CLEAR16 0xFFFF
6750 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
6751 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
6752 	bool mdd_detected = false;
6753 	struct i40e_pf_vf *vf;
6754 	uint32_t reg;
6755 	int i;
6756 
6757 	/* find what triggered the MDD event */
6758 	reg = I40E_READ_REG(hw, I40E_GL_MDET_TX);
6759 	if (reg & I40E_GL_MDET_TX_VALID_MASK) {
6760 		uint8_t pf_num = (reg & I40E_GL_MDET_TX_PF_NUM_MASK) >>
6761 				I40E_GL_MDET_TX_PF_NUM_SHIFT;
6762 		uint16_t vf_num = (reg & I40E_GL_MDET_TX_VF_NUM_MASK) >>
6763 				I40E_GL_MDET_TX_VF_NUM_SHIFT;
6764 		uint8_t event = (reg & I40E_GL_MDET_TX_EVENT_MASK) >>
6765 				I40E_GL_MDET_TX_EVENT_SHIFT;
6766 		uint16_t queue = ((reg & I40E_GL_MDET_TX_QUEUE_MASK) >>
6767 				I40E_GL_MDET_TX_QUEUE_SHIFT) -
6768 					hw->func_caps.base_queue;
6769 		PMD_DRV_LOG(WARNING, "Malicious Driver Detection event 0x%02x on TX "
6770 			"queue %d PF number 0x%02x VF number 0x%02x device %s\n",
6771 				event, queue, pf_num, vf_num, dev->data->name);
6772 		I40E_WRITE_REG(hw, I40E_GL_MDET_TX, I40E_MDD_CLEAR32);
6773 		mdd_detected = true;
6774 	}
6775 	reg = I40E_READ_REG(hw, I40E_GL_MDET_RX);
6776 	if (reg & I40E_GL_MDET_RX_VALID_MASK) {
6777 		uint8_t func = (reg & I40E_GL_MDET_RX_FUNCTION_MASK) >>
6778 				I40E_GL_MDET_RX_FUNCTION_SHIFT;
6779 		uint8_t event = (reg & I40E_GL_MDET_RX_EVENT_MASK) >>
6780 				I40E_GL_MDET_RX_EVENT_SHIFT;
6781 		uint16_t queue = ((reg & I40E_GL_MDET_RX_QUEUE_MASK) >>
6782 				I40E_GL_MDET_RX_QUEUE_SHIFT) -
6783 					hw->func_caps.base_queue;
6784 
6785 		PMD_DRV_LOG(WARNING, "Malicious Driver Detection event 0x%02x on RX "
6786 				"queue %d of function 0x%02x device %s\n",
6787 					event, queue, func, dev->data->name);
6788 		I40E_WRITE_REG(hw, I40E_GL_MDET_RX, I40E_MDD_CLEAR32);
6789 		mdd_detected = true;
6790 	}
6791 
6792 	if (mdd_detected) {
6793 		reg = I40E_READ_REG(hw, I40E_PF_MDET_TX);
6794 		if (reg & I40E_PF_MDET_TX_VALID_MASK) {
6795 			I40E_WRITE_REG(hw, I40E_PF_MDET_TX, I40E_MDD_CLEAR16);
6796 			PMD_DRV_LOG(WARNING, "TX driver issue detected on PF\n");
6797 		}
6798 		reg = I40E_READ_REG(hw, I40E_PF_MDET_RX);
6799 		if (reg & I40E_PF_MDET_RX_VALID_MASK) {
6800 			I40E_WRITE_REG(hw, I40E_PF_MDET_RX,
6801 					I40E_MDD_CLEAR16);
6802 			PMD_DRV_LOG(WARNING, "RX driver issue detected on PF\n");
6803 		}
6804 	}
6805 
6806 	/* see if one of the VFs needs its hand slapped */
6807 	for (i = 0; i < pf->vf_num && mdd_detected; i++) {
6808 		vf = &pf->vfs[i];
6809 		reg = I40E_READ_REG(hw, I40E_VP_MDET_TX(i));
6810 		if (reg & I40E_VP_MDET_TX_VALID_MASK) {
6811 			I40E_WRITE_REG(hw, I40E_VP_MDET_TX(i),
6812 					I40E_MDD_CLEAR16);
6813 			vf->num_mdd_events++;
6814 			PMD_DRV_LOG(WARNING, "TX driver issue detected on VF %d %-"
6815 					PRIu64 "times\n",
6816 					i, vf->num_mdd_events);
6817 		}
6818 
6819 		reg = I40E_READ_REG(hw, I40E_VP_MDET_RX(i));
6820 		if (reg & I40E_VP_MDET_RX_VALID_MASK) {
6821 			I40E_WRITE_REG(hw, I40E_VP_MDET_RX(i),
6822 					I40E_MDD_CLEAR16);
6823 			vf->num_mdd_events++;
6824 			PMD_DRV_LOG(WARNING, "RX driver issue detected on VF %d %-"
6825 					PRIu64 "times\n",
6826 					i, vf->num_mdd_events);
6827 		}
6828 	}
6829 }
6830 
6831 /**
6832  * Interrupt handler triggered by NIC  for handling
6833  * specific interrupt.
6834  *
6835  * @param handle
6836  *  Pointer to interrupt handle.
6837  * @param param
6838  *  The address of parameter (struct rte_eth_dev *) regsitered before.
6839  *
6840  * @return
6841  *  void
6842  */
6843 static void
6844 i40e_dev_interrupt_handler(void *param)
6845 {
6846 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
6847 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
6848 	uint32_t icr0;
6849 
6850 	/* Disable interrupt */
6851 	i40e_pf_disable_irq0(hw);
6852 
6853 	/* read out interrupt causes */
6854 	icr0 = I40E_READ_REG(hw, I40E_PFINT_ICR0);
6855 
6856 	/* No interrupt event indicated */
6857 	if (!(icr0 & I40E_PFINT_ICR0_INTEVENT_MASK)) {
6858 		PMD_DRV_LOG(INFO, "No interrupt event");
6859 		goto done;
6860 	}
6861 	if (icr0 & I40E_PFINT_ICR0_ECC_ERR_MASK)
6862 		PMD_DRV_LOG(ERR, "ICR0: unrecoverable ECC error");
6863 	if (icr0 & I40E_PFINT_ICR0_MAL_DETECT_MASK) {
6864 		PMD_DRV_LOG(ERR, "ICR0: malicious programming detected");
6865 		i40e_handle_mdd_event(dev);
6866 	}
6867 	if (icr0 & I40E_PFINT_ICR0_GRST_MASK)
6868 		PMD_DRV_LOG(INFO, "ICR0: global reset requested");
6869 	if (icr0 & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK)
6870 		PMD_DRV_LOG(INFO, "ICR0: PCI exception activated");
6871 	if (icr0 & I40E_PFINT_ICR0_STORM_DETECT_MASK)
6872 		PMD_DRV_LOG(INFO, "ICR0: a change in the storm control state");
6873 	if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK)
6874 		PMD_DRV_LOG(ERR, "ICR0: HMC error");
6875 	if (icr0 & I40E_PFINT_ICR0_PE_CRITERR_MASK)
6876 		PMD_DRV_LOG(ERR, "ICR0: protocol engine critical error");
6877 
6878 	if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) {
6879 		PMD_DRV_LOG(INFO, "ICR0: VF reset detected");
6880 		i40e_dev_handle_vfr_event(dev);
6881 	}
6882 	if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) {
6883 		PMD_DRV_LOG(INFO, "ICR0: adminq event");
6884 		i40e_dev_handle_aq_msg(dev);
6885 	}
6886 
6887 done:
6888 	/* Enable interrupt */
6889 	i40e_pf_enable_irq0(hw);
6890 }
6891 
6892 static void
6893 i40e_dev_alarm_handler(void *param)
6894 {
6895 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
6896 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
6897 	uint32_t icr0;
6898 
6899 	/* Disable interrupt */
6900 	i40e_pf_disable_irq0(hw);
6901 
6902 	/* read out interrupt causes */
6903 	icr0 = I40E_READ_REG(hw, I40E_PFINT_ICR0);
6904 
6905 	/* No interrupt event indicated */
6906 	if (!(icr0 & I40E_PFINT_ICR0_INTEVENT_MASK))
6907 		goto done;
6908 	if (icr0 & I40E_PFINT_ICR0_ECC_ERR_MASK)
6909 		PMD_DRV_LOG(ERR, "ICR0: unrecoverable ECC error");
6910 	if (icr0 & I40E_PFINT_ICR0_MAL_DETECT_MASK) {
6911 		PMD_DRV_LOG(ERR, "ICR0: malicious programming detected");
6912 		i40e_handle_mdd_event(dev);
6913 	}
6914 	if (icr0 & I40E_PFINT_ICR0_GRST_MASK)
6915 		PMD_DRV_LOG(INFO, "ICR0: global reset requested");
6916 	if (icr0 & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK)
6917 		PMD_DRV_LOG(INFO, "ICR0: PCI exception activated");
6918 	if (icr0 & I40E_PFINT_ICR0_STORM_DETECT_MASK)
6919 		PMD_DRV_LOG(INFO, "ICR0: a change in the storm control state");
6920 	if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK)
6921 		PMD_DRV_LOG(ERR, "ICR0: HMC error");
6922 	if (icr0 & I40E_PFINT_ICR0_PE_CRITERR_MASK)
6923 		PMD_DRV_LOG(ERR, "ICR0: protocol engine critical error");
6924 
6925 	if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) {
6926 		PMD_DRV_LOG(INFO, "ICR0: VF reset detected");
6927 		i40e_dev_handle_vfr_event(dev);
6928 	}
6929 	if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) {
6930 		PMD_DRV_LOG(INFO, "ICR0: adminq event");
6931 		i40e_dev_handle_aq_msg(dev);
6932 	}
6933 
6934 done:
6935 	/* Enable interrupt */
6936 	i40e_pf_enable_irq0(hw);
6937 	rte_eal_alarm_set(I40E_ALARM_INTERVAL,
6938 			  i40e_dev_alarm_handler, dev);
6939 }
6940 
6941 int
6942 i40e_add_macvlan_filters(struct i40e_vsi *vsi,
6943 			 struct i40e_macvlan_filter *filter,
6944 			 int total)
6945 {
6946 	int ele_num, ele_buff_size;
6947 	int num, actual_num, i;
6948 	uint16_t flags;
6949 	int ret = I40E_SUCCESS;
6950 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
6951 	struct i40e_aqc_add_macvlan_element_data *req_list;
6952 
6953 	if (filter == NULL  || total == 0)
6954 		return I40E_ERR_PARAM;
6955 	ele_num = hw->aq.asq_buf_size / sizeof(*req_list);
6956 	ele_buff_size = hw->aq.asq_buf_size;
6957 
6958 	req_list = rte_zmalloc("macvlan_add", ele_buff_size, 0);
6959 	if (req_list == NULL) {
6960 		PMD_DRV_LOG(ERR, "Fail to allocate memory");
6961 		return I40E_ERR_NO_MEMORY;
6962 	}
6963 
6964 	num = 0;
6965 	do {
6966 		actual_num = (num + ele_num > total) ? (total - num) : ele_num;
6967 		memset(req_list, 0, ele_buff_size);
6968 
6969 		for (i = 0; i < actual_num; i++) {
6970 			rte_memcpy(req_list[i].mac_addr,
6971 				&filter[num + i].macaddr, ETH_ADDR_LEN);
6972 			req_list[i].vlan_tag =
6973 				rte_cpu_to_le_16(filter[num + i].vlan_id);
6974 
6975 			switch (filter[num + i].filter_type) {
6976 			case I40E_MAC_PERFECT_MATCH:
6977 				flags = I40E_AQC_MACVLAN_ADD_PERFECT_MATCH |
6978 					I40E_AQC_MACVLAN_ADD_IGNORE_VLAN;
6979 				break;
6980 			case I40E_MACVLAN_PERFECT_MATCH:
6981 				flags = I40E_AQC_MACVLAN_ADD_PERFECT_MATCH;
6982 				break;
6983 			case I40E_MAC_HASH_MATCH:
6984 				flags = I40E_AQC_MACVLAN_ADD_HASH_MATCH |
6985 					I40E_AQC_MACVLAN_ADD_IGNORE_VLAN;
6986 				break;
6987 			case I40E_MACVLAN_HASH_MATCH:
6988 				flags = I40E_AQC_MACVLAN_ADD_HASH_MATCH;
6989 				break;
6990 			default:
6991 				PMD_DRV_LOG(ERR, "Invalid MAC match type");
6992 				ret = I40E_ERR_PARAM;
6993 				goto DONE;
6994 			}
6995 
6996 			req_list[i].queue_number = 0;
6997 
6998 			req_list[i].flags = rte_cpu_to_le_16(flags);
6999 		}
7000 
7001 		ret = i40e_aq_add_macvlan(hw, vsi->seid, req_list,
7002 						actual_num, NULL);
7003 		if (ret != I40E_SUCCESS) {
7004 			PMD_DRV_LOG(ERR, "Failed to add macvlan filter");
7005 			goto DONE;
7006 		}
7007 		num += actual_num;
7008 	} while (num < total);
7009 
7010 DONE:
7011 	rte_free(req_list);
7012 	return ret;
7013 }
7014 
7015 int
7016 i40e_remove_macvlan_filters(struct i40e_vsi *vsi,
7017 			    struct i40e_macvlan_filter *filter,
7018 			    int total)
7019 {
7020 	int ele_num, ele_buff_size;
7021 	int num, actual_num, i;
7022 	uint16_t flags;
7023 	int ret = I40E_SUCCESS;
7024 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
7025 	struct i40e_aqc_remove_macvlan_element_data *req_list;
7026 
7027 	if (filter == NULL  || total == 0)
7028 		return I40E_ERR_PARAM;
7029 
7030 	ele_num = hw->aq.asq_buf_size / sizeof(*req_list);
7031 	ele_buff_size = hw->aq.asq_buf_size;
7032 
7033 	req_list = rte_zmalloc("macvlan_remove", ele_buff_size, 0);
7034 	if (req_list == NULL) {
7035 		PMD_DRV_LOG(ERR, "Fail to allocate memory");
7036 		return I40E_ERR_NO_MEMORY;
7037 	}
7038 
7039 	num = 0;
7040 	do {
7041 		actual_num = (num + ele_num > total) ? (total - num) : ele_num;
7042 		memset(req_list, 0, ele_buff_size);
7043 
7044 		for (i = 0; i < actual_num; i++) {
7045 			rte_memcpy(req_list[i].mac_addr,
7046 				&filter[num + i].macaddr, ETH_ADDR_LEN);
7047 			req_list[i].vlan_tag =
7048 				rte_cpu_to_le_16(filter[num + i].vlan_id);
7049 
7050 			switch (filter[num + i].filter_type) {
7051 			case I40E_MAC_PERFECT_MATCH:
7052 				flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH |
7053 					I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
7054 				break;
7055 			case I40E_MACVLAN_PERFECT_MATCH:
7056 				flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH;
7057 				break;
7058 			case I40E_MAC_HASH_MATCH:
7059 				flags = I40E_AQC_MACVLAN_DEL_HASH_MATCH |
7060 					I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
7061 				break;
7062 			case I40E_MACVLAN_HASH_MATCH:
7063 				flags = I40E_AQC_MACVLAN_DEL_HASH_MATCH;
7064 				break;
7065 			default:
7066 				PMD_DRV_LOG(ERR, "Invalid MAC filter type");
7067 				ret = I40E_ERR_PARAM;
7068 				goto DONE;
7069 			}
7070 			req_list[i].flags = rte_cpu_to_le_16(flags);
7071 		}
7072 
7073 		ret = i40e_aq_remove_macvlan(hw, vsi->seid, req_list,
7074 						actual_num, NULL);
7075 		if (ret != I40E_SUCCESS) {
7076 			PMD_DRV_LOG(ERR, "Failed to remove macvlan filter");
7077 			goto DONE;
7078 		}
7079 		num += actual_num;
7080 	} while (num < total);
7081 
7082 DONE:
7083 	rte_free(req_list);
7084 	return ret;
7085 }
7086 
7087 /* Find out specific MAC filter */
7088 static struct i40e_mac_filter *
7089 i40e_find_mac_filter(struct i40e_vsi *vsi,
7090 			 struct rte_ether_addr *macaddr)
7091 {
7092 	struct i40e_mac_filter *f;
7093 
7094 	TAILQ_FOREACH(f, &vsi->mac_list, next) {
7095 		if (rte_is_same_ether_addr(macaddr, &f->mac_info.mac_addr))
7096 			return f;
7097 	}
7098 
7099 	return NULL;
7100 }
7101 
7102 static bool
7103 i40e_find_vlan_filter(struct i40e_vsi *vsi,
7104 			 uint16_t vlan_id)
7105 {
7106 	uint32_t vid_idx, vid_bit;
7107 
7108 	if (vlan_id > ETH_VLAN_ID_MAX)
7109 		return 0;
7110 
7111 	vid_idx = I40E_VFTA_IDX(vlan_id);
7112 	vid_bit = I40E_VFTA_BIT(vlan_id);
7113 
7114 	if (vsi->vfta[vid_idx] & vid_bit)
7115 		return 1;
7116 	else
7117 		return 0;
7118 }
7119 
7120 static void
7121 i40e_store_vlan_filter(struct i40e_vsi *vsi,
7122 		       uint16_t vlan_id, bool on)
7123 {
7124 	uint32_t vid_idx, vid_bit;
7125 
7126 	vid_idx = I40E_VFTA_IDX(vlan_id);
7127 	vid_bit = I40E_VFTA_BIT(vlan_id);
7128 
7129 	if (on)
7130 		vsi->vfta[vid_idx] |= vid_bit;
7131 	else
7132 		vsi->vfta[vid_idx] &= ~vid_bit;
7133 }
7134 
7135 void
7136 i40e_set_vlan_filter(struct i40e_vsi *vsi,
7137 		     uint16_t vlan_id, bool on)
7138 {
7139 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
7140 	struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0};
7141 	int ret;
7142 
7143 	if (vlan_id > ETH_VLAN_ID_MAX)
7144 		return;
7145 
7146 	i40e_store_vlan_filter(vsi, vlan_id, on);
7147 
7148 	if ((!vsi->vlan_anti_spoof_on && !vsi->vlan_filter_on) || !vlan_id)
7149 		return;
7150 
7151 	vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id);
7152 
7153 	if (on) {
7154 		ret = i40e_aq_add_vlan(hw, vsi->seid,
7155 				       &vlan_data, 1, NULL);
7156 		if (ret != I40E_SUCCESS)
7157 			PMD_DRV_LOG(ERR, "Failed to add vlan filter");
7158 	} else {
7159 		ret = i40e_aq_remove_vlan(hw, vsi->seid,
7160 					  &vlan_data, 1, NULL);
7161 		if (ret != I40E_SUCCESS)
7162 			PMD_DRV_LOG(ERR,
7163 				    "Failed to remove vlan filter");
7164 	}
7165 }
7166 
7167 /**
7168  * Find all vlan options for specific mac addr,
7169  * return with actual vlan found.
7170  */
7171 int
7172 i40e_find_all_vlan_for_mac(struct i40e_vsi *vsi,
7173 			   struct i40e_macvlan_filter *mv_f,
7174 			   int num, struct rte_ether_addr *addr)
7175 {
7176 	int i;
7177 	uint32_t j, k;
7178 
7179 	/**
7180 	 * Not to use i40e_find_vlan_filter to decrease the loop time,
7181 	 * although the code looks complex.
7182 	  */
7183 	if (num < vsi->vlan_num)
7184 		return I40E_ERR_PARAM;
7185 
7186 	i = 0;
7187 	for (j = 0; j < I40E_VFTA_SIZE; j++) {
7188 		if (vsi->vfta[j]) {
7189 			for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) {
7190 				if (vsi->vfta[j] & (1 << k)) {
7191 					if (i > num - 1) {
7192 						PMD_DRV_LOG(ERR,
7193 							"vlan number doesn't match");
7194 						return I40E_ERR_PARAM;
7195 					}
7196 					rte_memcpy(&mv_f[i].macaddr,
7197 							addr, ETH_ADDR_LEN);
7198 					mv_f[i].vlan_id =
7199 						j * I40E_UINT32_BIT_SIZE + k;
7200 					i++;
7201 				}
7202 			}
7203 		}
7204 	}
7205 	return I40E_SUCCESS;
7206 }
7207 
7208 static inline int
7209 i40e_find_all_mac_for_vlan(struct i40e_vsi *vsi,
7210 			   struct i40e_macvlan_filter *mv_f,
7211 			   int num,
7212 			   uint16_t vlan)
7213 {
7214 	int i = 0;
7215 	struct i40e_mac_filter *f;
7216 
7217 	if (num < vsi->mac_num)
7218 		return I40E_ERR_PARAM;
7219 
7220 	TAILQ_FOREACH(f, &vsi->mac_list, next) {
7221 		if (i > num - 1) {
7222 			PMD_DRV_LOG(ERR, "buffer number not match");
7223 			return I40E_ERR_PARAM;
7224 		}
7225 		rte_memcpy(&mv_f[i].macaddr, &f->mac_info.mac_addr,
7226 				ETH_ADDR_LEN);
7227 		mv_f[i].vlan_id = vlan;
7228 		mv_f[i].filter_type = f->mac_info.filter_type;
7229 		i++;
7230 	}
7231 
7232 	return I40E_SUCCESS;
7233 }
7234 
7235 static int
7236 i40e_vsi_remove_all_macvlan_filter(struct i40e_vsi *vsi)
7237 {
7238 	int i, j, num;
7239 	struct i40e_mac_filter *f;
7240 	struct i40e_macvlan_filter *mv_f;
7241 	int ret = I40E_SUCCESS;
7242 
7243 	if (vsi == NULL || vsi->mac_num == 0)
7244 		return I40E_ERR_PARAM;
7245 
7246 	/* Case that no vlan is set */
7247 	if (vsi->vlan_num == 0)
7248 		num = vsi->mac_num;
7249 	else
7250 		num = vsi->mac_num * vsi->vlan_num;
7251 
7252 	mv_f = rte_zmalloc("macvlan_data", num * sizeof(*mv_f), 0);
7253 	if (mv_f == NULL) {
7254 		PMD_DRV_LOG(ERR, "failed to allocate memory");
7255 		return I40E_ERR_NO_MEMORY;
7256 	}
7257 
7258 	i = 0;
7259 	if (vsi->vlan_num == 0) {
7260 		TAILQ_FOREACH(f, &vsi->mac_list, next) {
7261 			rte_memcpy(&mv_f[i].macaddr,
7262 				&f->mac_info.mac_addr, ETH_ADDR_LEN);
7263 			mv_f[i].filter_type = f->mac_info.filter_type;
7264 			mv_f[i].vlan_id = 0;
7265 			i++;
7266 		}
7267 	} else {
7268 		TAILQ_FOREACH(f, &vsi->mac_list, next) {
7269 			ret = i40e_find_all_vlan_for_mac(vsi,&mv_f[i],
7270 					vsi->vlan_num, &f->mac_info.mac_addr);
7271 			if (ret != I40E_SUCCESS)
7272 				goto DONE;
7273 			for (j = i; j < i + vsi->vlan_num; j++)
7274 				mv_f[j].filter_type = f->mac_info.filter_type;
7275 			i += vsi->vlan_num;
7276 		}
7277 	}
7278 
7279 	ret = i40e_remove_macvlan_filters(vsi, mv_f, num);
7280 DONE:
7281 	rte_free(mv_f);
7282 
7283 	return ret;
7284 }
7285 
7286 int
7287 i40e_vsi_add_vlan(struct i40e_vsi *vsi, uint16_t vlan)
7288 {
7289 	struct i40e_macvlan_filter *mv_f;
7290 	int mac_num;
7291 	int ret = I40E_SUCCESS;
7292 
7293 	if (!vsi || vlan > RTE_ETHER_MAX_VLAN_ID)
7294 		return I40E_ERR_PARAM;
7295 
7296 	/* If it's already set, just return */
7297 	if (i40e_find_vlan_filter(vsi,vlan))
7298 		return I40E_SUCCESS;
7299 
7300 	mac_num = vsi->mac_num;
7301 
7302 	if (mac_num == 0) {
7303 		PMD_DRV_LOG(ERR, "Error! VSI doesn't have a mac addr");
7304 		return I40E_ERR_PARAM;
7305 	}
7306 
7307 	mv_f = rte_zmalloc("macvlan_data", mac_num * sizeof(*mv_f), 0);
7308 
7309 	if (mv_f == NULL) {
7310 		PMD_DRV_LOG(ERR, "failed to allocate memory");
7311 		return I40E_ERR_NO_MEMORY;
7312 	}
7313 
7314 	ret = i40e_find_all_mac_for_vlan(vsi, mv_f, mac_num, vlan);
7315 
7316 	if (ret != I40E_SUCCESS)
7317 		goto DONE;
7318 
7319 	ret = i40e_add_macvlan_filters(vsi, mv_f, mac_num);
7320 
7321 	if (ret != I40E_SUCCESS)
7322 		goto DONE;
7323 
7324 	i40e_set_vlan_filter(vsi, vlan, 1);
7325 
7326 	vsi->vlan_num++;
7327 	ret = I40E_SUCCESS;
7328 DONE:
7329 	rte_free(mv_f);
7330 	return ret;
7331 }
7332 
7333 int
7334 i40e_vsi_delete_vlan(struct i40e_vsi *vsi, uint16_t vlan)
7335 {
7336 	struct i40e_macvlan_filter *mv_f;
7337 	int mac_num;
7338 	int ret = I40E_SUCCESS;
7339 
7340 	/**
7341 	 * Vlan 0 is the generic filter for untagged packets
7342 	 * and can't be removed.
7343 	 */
7344 	if (!vsi || vlan == 0 || vlan > RTE_ETHER_MAX_VLAN_ID)
7345 		return I40E_ERR_PARAM;
7346 
7347 	/* If can't find it, just return */
7348 	if (!i40e_find_vlan_filter(vsi, vlan))
7349 		return I40E_ERR_PARAM;
7350 
7351 	mac_num = vsi->mac_num;
7352 
7353 	if (mac_num == 0) {
7354 		PMD_DRV_LOG(ERR, "Error! VSI doesn't have a mac addr");
7355 		return I40E_ERR_PARAM;
7356 	}
7357 
7358 	mv_f = rte_zmalloc("macvlan_data", mac_num * sizeof(*mv_f), 0);
7359 
7360 	if (mv_f == NULL) {
7361 		PMD_DRV_LOG(ERR, "failed to allocate memory");
7362 		return I40E_ERR_NO_MEMORY;
7363 	}
7364 
7365 	ret = i40e_find_all_mac_for_vlan(vsi, mv_f, mac_num, vlan);
7366 
7367 	if (ret != I40E_SUCCESS)
7368 		goto DONE;
7369 
7370 	ret = i40e_remove_macvlan_filters(vsi, mv_f, mac_num);
7371 
7372 	if (ret != I40E_SUCCESS)
7373 		goto DONE;
7374 
7375 	/* This is last vlan to remove, replace all mac filter with vlan 0 */
7376 	if (vsi->vlan_num == 1) {
7377 		ret = i40e_find_all_mac_for_vlan(vsi, mv_f, mac_num, 0);
7378 		if (ret != I40E_SUCCESS)
7379 			goto DONE;
7380 
7381 		ret = i40e_add_macvlan_filters(vsi, mv_f, mac_num);
7382 		if (ret != I40E_SUCCESS)
7383 			goto DONE;
7384 	}
7385 
7386 	i40e_set_vlan_filter(vsi, vlan, 0);
7387 
7388 	vsi->vlan_num--;
7389 	ret = I40E_SUCCESS;
7390 DONE:
7391 	rte_free(mv_f);
7392 	return ret;
7393 }
7394 
7395 int
7396 i40e_vsi_add_mac(struct i40e_vsi *vsi, struct i40e_mac_filter_info *mac_filter)
7397 {
7398 	struct i40e_mac_filter *f;
7399 	struct i40e_macvlan_filter *mv_f;
7400 	int i, vlan_num = 0;
7401 	int ret = I40E_SUCCESS;
7402 
7403 	/* If it's add and we've config it, return */
7404 	f = i40e_find_mac_filter(vsi, &mac_filter->mac_addr);
7405 	if (f != NULL)
7406 		return I40E_SUCCESS;
7407 	if (mac_filter->filter_type == I40E_MACVLAN_PERFECT_MATCH ||
7408 		mac_filter->filter_type == I40E_MACVLAN_HASH_MATCH) {
7409 
7410 		/**
7411 		 * If vlan_num is 0, that's the first time to add mac,
7412 		 * set mask for vlan_id 0.
7413 		 */
7414 		if (vsi->vlan_num == 0) {
7415 			i40e_set_vlan_filter(vsi, 0, 1);
7416 			vsi->vlan_num = 1;
7417 		}
7418 		vlan_num = vsi->vlan_num;
7419 	} else if (mac_filter->filter_type == I40E_MAC_PERFECT_MATCH ||
7420 			mac_filter->filter_type == I40E_MAC_HASH_MATCH)
7421 		vlan_num = 1;
7422 
7423 	mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0);
7424 	if (mv_f == NULL) {
7425 		PMD_DRV_LOG(ERR, "failed to allocate memory");
7426 		return I40E_ERR_NO_MEMORY;
7427 	}
7428 
7429 	for (i = 0; i < vlan_num; i++) {
7430 		mv_f[i].filter_type = mac_filter->filter_type;
7431 		rte_memcpy(&mv_f[i].macaddr, &mac_filter->mac_addr,
7432 				ETH_ADDR_LEN);
7433 	}
7434 
7435 	if (mac_filter->filter_type == I40E_MACVLAN_PERFECT_MATCH ||
7436 		mac_filter->filter_type == I40E_MACVLAN_HASH_MATCH) {
7437 		ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num,
7438 					&mac_filter->mac_addr);
7439 		if (ret != I40E_SUCCESS)
7440 			goto DONE;
7441 	}
7442 
7443 	ret = i40e_add_macvlan_filters(vsi, mv_f, vlan_num);
7444 	if (ret != I40E_SUCCESS)
7445 		goto DONE;
7446 
7447 	/* Add the mac addr into mac list */
7448 	f = rte_zmalloc("macv_filter", sizeof(*f), 0);
7449 	if (f == NULL) {
7450 		PMD_DRV_LOG(ERR, "failed to allocate memory");
7451 		ret = I40E_ERR_NO_MEMORY;
7452 		goto DONE;
7453 	}
7454 	rte_memcpy(&f->mac_info.mac_addr, &mac_filter->mac_addr,
7455 			ETH_ADDR_LEN);
7456 	f->mac_info.filter_type = mac_filter->filter_type;
7457 	TAILQ_INSERT_TAIL(&vsi->mac_list, f, next);
7458 	vsi->mac_num++;
7459 
7460 	ret = I40E_SUCCESS;
7461 DONE:
7462 	rte_free(mv_f);
7463 
7464 	return ret;
7465 }
7466 
7467 int
7468 i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct rte_ether_addr *addr)
7469 {
7470 	struct i40e_mac_filter *f;
7471 	struct i40e_macvlan_filter *mv_f;
7472 	int i, vlan_num;
7473 	enum i40e_mac_filter_type filter_type;
7474 	int ret = I40E_SUCCESS;
7475 
7476 	/* Can't find it, return an error */
7477 	f = i40e_find_mac_filter(vsi, addr);
7478 	if (f == NULL)
7479 		return I40E_ERR_PARAM;
7480 
7481 	vlan_num = vsi->vlan_num;
7482 	filter_type = f->mac_info.filter_type;
7483 	if (filter_type == I40E_MACVLAN_PERFECT_MATCH ||
7484 		filter_type == I40E_MACVLAN_HASH_MATCH) {
7485 		if (vlan_num == 0) {
7486 			PMD_DRV_LOG(ERR, "VLAN number shouldn't be 0");
7487 			return I40E_ERR_PARAM;
7488 		}
7489 	} else if (filter_type == I40E_MAC_PERFECT_MATCH ||
7490 			filter_type == I40E_MAC_HASH_MATCH)
7491 		vlan_num = 1;
7492 
7493 	mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0);
7494 	if (mv_f == NULL) {
7495 		PMD_DRV_LOG(ERR, "failed to allocate memory");
7496 		return I40E_ERR_NO_MEMORY;
7497 	}
7498 
7499 	for (i = 0; i < vlan_num; i++) {
7500 		mv_f[i].filter_type = filter_type;
7501 		rte_memcpy(&mv_f[i].macaddr, &f->mac_info.mac_addr,
7502 				ETH_ADDR_LEN);
7503 	}
7504 	if (filter_type == I40E_MACVLAN_PERFECT_MATCH ||
7505 			filter_type == I40E_MACVLAN_HASH_MATCH) {
7506 		ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num, addr);
7507 		if (ret != I40E_SUCCESS)
7508 			goto DONE;
7509 	}
7510 
7511 	ret = i40e_remove_macvlan_filters(vsi, mv_f, vlan_num);
7512 	if (ret != I40E_SUCCESS)
7513 		goto DONE;
7514 
7515 	/* Remove the mac addr into mac list */
7516 	TAILQ_REMOVE(&vsi->mac_list, f, next);
7517 	rte_free(f);
7518 	vsi->mac_num--;
7519 
7520 	ret = I40E_SUCCESS;
7521 DONE:
7522 	rte_free(mv_f);
7523 	return ret;
7524 }
7525 
7526 /* Configure hash enable flags for RSS */
7527 uint64_t
7528 i40e_config_hena(const struct i40e_adapter *adapter, uint64_t flags)
7529 {
7530 	uint64_t hena = 0;
7531 	int i;
7532 
7533 	if (!flags)
7534 		return hena;
7535 
7536 	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < I40E_FLOW_TYPE_MAX; i++) {
7537 		if (flags & (1ULL << i))
7538 			hena |= adapter->pctypes_tbl[i];
7539 	}
7540 
7541 	return hena;
7542 }
7543 
7544 /* Parse the hash enable flags */
7545 uint64_t
7546 i40e_parse_hena(const struct i40e_adapter *adapter, uint64_t flags)
7547 {
7548 	uint64_t rss_hf = 0;
7549 
7550 	if (!flags)
7551 		return rss_hf;
7552 	int i;
7553 
7554 	for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < I40E_FLOW_TYPE_MAX; i++) {
7555 		if (flags & adapter->pctypes_tbl[i])
7556 			rss_hf |= (1ULL << i);
7557 	}
7558 	return rss_hf;
7559 }
7560 
7561 /* Disable RSS */
7562 void
7563 i40e_pf_disable_rss(struct i40e_pf *pf)
7564 {
7565 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
7566 
7567 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
7568 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
7569 	I40E_WRITE_FLUSH(hw);
7570 }
7571 
7572 int
7573 i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len)
7574 {
7575 	struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
7576 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
7577 	uint16_t key_idx = (vsi->type == I40E_VSI_SRIOV) ?
7578 			   I40E_VFQF_HKEY_MAX_INDEX :
7579 			   I40E_PFQF_HKEY_MAX_INDEX;
7580 
7581 	if (!key || key_len == 0) {
7582 		PMD_DRV_LOG(DEBUG, "No key to be configured");
7583 		return 0;
7584 	} else if (key_len != (key_idx + 1) *
7585 		sizeof(uint32_t)) {
7586 		PMD_DRV_LOG(ERR, "Invalid key length %u", key_len);
7587 		return -EINVAL;
7588 	}
7589 
7590 	if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) {
7591 		struct i40e_aqc_get_set_rss_key_data *key_dw =
7592 				(struct i40e_aqc_get_set_rss_key_data *)key;
7593 		enum i40e_status_code status =
7594 				i40e_aq_set_rss_key(hw, vsi->vsi_id, key_dw);
7595 
7596 		if (status) {
7597 			PMD_DRV_LOG(ERR,
7598 				    "Failed to configure RSS key via AQ, error status: %d",
7599 				    status);
7600 			return -EIO;
7601 		}
7602 	} else {
7603 		uint32_t *hash_key = (uint32_t *)key;
7604 		uint16_t i;
7605 
7606 		if (vsi->type == I40E_VSI_SRIOV) {
7607 			for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++)
7608 				I40E_WRITE_REG(
7609 					hw,
7610 					I40E_VFQF_HKEY1(i, vsi->user_param),
7611 					hash_key[i]);
7612 
7613 		} else {
7614 			for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++)
7615 				I40E_WRITE_REG(hw, I40E_PFQF_HKEY(i),
7616 					       hash_key[i]);
7617 		}
7618 		I40E_WRITE_FLUSH(hw);
7619 	}
7620 
7621 	return 0;
7622 }
7623 
7624 static int
7625 i40e_get_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t *key_len)
7626 {
7627 	struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
7628 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
7629 	uint32_t reg;
7630 	int ret;
7631 
7632 	if (!key || !key_len)
7633 		return 0;
7634 
7635 	if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) {
7636 		ret = i40e_aq_get_rss_key(hw, vsi->vsi_id,
7637 			(struct i40e_aqc_get_set_rss_key_data *)key);
7638 		if (ret) {
7639 			PMD_INIT_LOG(ERR, "Failed to get RSS key via AQ");
7640 			return ret;
7641 		}
7642 	} else {
7643 		uint32_t *key_dw = (uint32_t *)key;
7644 		uint16_t i;
7645 
7646 		if (vsi->type == I40E_VSI_SRIOV) {
7647 			for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) {
7648 				reg = I40E_VFQF_HKEY1(i, vsi->user_param);
7649 				key_dw[i] = i40e_read_rx_ctl(hw, reg);
7650 			}
7651 			*key_len = (I40E_VFQF_HKEY_MAX_INDEX + 1) *
7652 				   sizeof(uint32_t);
7653 		} else {
7654 			for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) {
7655 				reg = I40E_PFQF_HKEY(i);
7656 				key_dw[i] = i40e_read_rx_ctl(hw, reg);
7657 			}
7658 			*key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
7659 				   sizeof(uint32_t);
7660 		}
7661 	}
7662 	return 0;
7663 }
7664 
7665 static int
7666 i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf)
7667 {
7668 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
7669 	uint64_t hena;
7670 	int ret;
7671 
7672 	ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key,
7673 			       rss_conf->rss_key_len);
7674 	if (ret)
7675 		return ret;
7676 
7677 	hena = i40e_config_hena(pf->adapter, rss_conf->rss_hf);
7678 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
7679 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
7680 	I40E_WRITE_FLUSH(hw);
7681 
7682 	return 0;
7683 }
7684 
7685 static int
7686 i40e_dev_rss_hash_update(struct rte_eth_dev *dev,
7687 			 struct rte_eth_rss_conf *rss_conf)
7688 {
7689 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
7690 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
7691 	uint64_t rss_hf = rss_conf->rss_hf & pf->adapter->flow_types_mask;
7692 	uint64_t hena;
7693 
7694 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
7695 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
7696 
7697 	if (!(hena & pf->adapter->pctypes_mask)) { /* RSS disabled */
7698 		if (rss_hf != 0) /* Enable RSS */
7699 			return -EINVAL;
7700 		return 0; /* Nothing to do */
7701 	}
7702 	/* RSS enabled */
7703 	if (rss_hf == 0) /* Disable RSS */
7704 		return -EINVAL;
7705 
7706 	return i40e_hw_rss_hash_set(pf, rss_conf);
7707 }
7708 
7709 static int
7710 i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
7711 			   struct rte_eth_rss_conf *rss_conf)
7712 {
7713 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
7714 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
7715 	uint64_t hena;
7716 	int ret;
7717 
7718 	if (!rss_conf)
7719 		return -EINVAL;
7720 
7721 	ret = i40e_get_rss_key(pf->main_vsi, rss_conf->rss_key,
7722 			 &rss_conf->rss_key_len);
7723 	if (ret)
7724 		return ret;
7725 
7726 	hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
7727 	hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
7728 	rss_conf->rss_hf = i40e_parse_hena(pf->adapter, hena);
7729 
7730 	return 0;
7731 }
7732 
7733 static int
7734 i40e_dev_get_filter_type(uint16_t filter_type, uint16_t *flag)
7735 {
7736 	switch (filter_type) {
7737 	case RTE_TUNNEL_FILTER_IMAC_IVLAN:
7738 		*flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN;
7739 		break;
7740 	case RTE_TUNNEL_FILTER_IMAC_IVLAN_TENID:
7741 		*flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID;
7742 		break;
7743 	case RTE_TUNNEL_FILTER_IMAC_TENID:
7744 		*flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID;
7745 		break;
7746 	case RTE_TUNNEL_FILTER_OMAC_TENID_IMAC:
7747 		*flag = I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC;
7748 		break;
7749 	case ETH_TUNNEL_FILTER_IMAC:
7750 		*flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC;
7751 		break;
7752 	case ETH_TUNNEL_FILTER_OIP:
7753 		*flag = I40E_AQC_ADD_CLOUD_FILTER_OIP;
7754 		break;
7755 	case ETH_TUNNEL_FILTER_IIP:
7756 		*flag = I40E_AQC_ADD_CLOUD_FILTER_IIP;
7757 		break;
7758 	default:
7759 		PMD_DRV_LOG(ERR, "invalid tunnel filter type");
7760 		return -EINVAL;
7761 	}
7762 
7763 	return 0;
7764 }
7765 
7766 /* Convert tunnel filter structure */
7767 static int
7768 i40e_tunnel_filter_convert(
7769 	struct i40e_aqc_cloud_filters_element_bb *cld_filter,
7770 	struct i40e_tunnel_filter *tunnel_filter)
7771 {
7772 	rte_ether_addr_copy((struct rte_ether_addr *)
7773 			&cld_filter->element.outer_mac,
7774 		(struct rte_ether_addr *)&tunnel_filter->input.outer_mac);
7775 	rte_ether_addr_copy((struct rte_ether_addr *)
7776 			&cld_filter->element.inner_mac,
7777 		(struct rte_ether_addr *)&tunnel_filter->input.inner_mac);
7778 	tunnel_filter->input.inner_vlan = cld_filter->element.inner_vlan;
7779 	if ((rte_le_to_cpu_16(cld_filter->element.flags) &
7780 	     I40E_AQC_ADD_CLOUD_FLAGS_IPV6) ==
7781 	    I40E_AQC_ADD_CLOUD_FLAGS_IPV6)
7782 		tunnel_filter->input.ip_type = I40E_TUNNEL_IPTYPE_IPV6;
7783 	else
7784 		tunnel_filter->input.ip_type = I40E_TUNNEL_IPTYPE_IPV4;
7785 	tunnel_filter->input.flags = cld_filter->element.flags;
7786 	tunnel_filter->input.tenant_id = cld_filter->element.tenant_id;
7787 	tunnel_filter->queue = cld_filter->element.queue_number;
7788 	rte_memcpy(tunnel_filter->input.general_fields,
7789 		   cld_filter->general_fields,
7790 		   sizeof(cld_filter->general_fields));
7791 
7792 	return 0;
7793 }
7794 
7795 /* Check if there exists the tunnel filter */
7796 struct i40e_tunnel_filter *
7797 i40e_sw_tunnel_filter_lookup(struct i40e_tunnel_rule *tunnel_rule,
7798 			     const struct i40e_tunnel_filter_input *input)
7799 {
7800 	int ret;
7801 
7802 	ret = rte_hash_lookup(tunnel_rule->hash_table, (const void *)input);
7803 	if (ret < 0)
7804 		return NULL;
7805 
7806 	return tunnel_rule->hash_map[ret];
7807 }
7808 
7809 /* Add a tunnel filter into the SW list */
7810 static int
7811 i40e_sw_tunnel_filter_insert(struct i40e_pf *pf,
7812 			     struct i40e_tunnel_filter *tunnel_filter)
7813 {
7814 	struct i40e_tunnel_rule *rule = &pf->tunnel;
7815 	int ret;
7816 
7817 	ret = rte_hash_add_key(rule->hash_table, &tunnel_filter->input);
7818 	if (ret < 0) {
7819 		PMD_DRV_LOG(ERR,
7820 			    "Failed to insert tunnel filter to hash table %d!",
7821 			    ret);
7822 		return ret;
7823 	}
7824 	rule->hash_map[ret] = tunnel_filter;
7825 
7826 	TAILQ_INSERT_TAIL(&rule->tunnel_list, tunnel_filter, rules);
7827 
7828 	return 0;
7829 }
7830 
7831 /* Delete a tunnel filter from the SW list */
7832 int
7833 i40e_sw_tunnel_filter_del(struct i40e_pf *pf,
7834 			  struct i40e_tunnel_filter_input *input)
7835 {
7836 	struct i40e_tunnel_rule *rule = &pf->tunnel;
7837 	struct i40e_tunnel_filter *tunnel_filter;
7838 	int ret;
7839 
7840 	ret = rte_hash_del_key(rule->hash_table, input);
7841 	if (ret < 0) {
7842 		PMD_DRV_LOG(ERR,
7843 			    "Failed to delete tunnel filter to hash table %d!",
7844 			    ret);
7845 		return ret;
7846 	}
7847 	tunnel_filter = rule->hash_map[ret];
7848 	rule->hash_map[ret] = NULL;
7849 
7850 	TAILQ_REMOVE(&rule->tunnel_list, tunnel_filter, rules);
7851 	rte_free(tunnel_filter);
7852 
7853 	return 0;
7854 }
7855 
7856 #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_TR_WORD0 0x48
7857 #define I40E_TR_VXLAN_GRE_KEY_MASK		0x4
7858 #define I40E_TR_GENEVE_KEY_MASK			0x8
7859 #define I40E_TR_GENERIC_UDP_TUNNEL_MASK		0x40
7860 #define I40E_TR_GRE_KEY_MASK			0x400
7861 #define I40E_TR_GRE_KEY_WITH_XSUM_MASK		0x800
7862 #define I40E_TR_GRE_NO_KEY_MASK			0x8000
7863 #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_PORT_TR_WORD0 0x49
7864 #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_DIRECTION_WORD0 0x41
7865 #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_INGRESS_WORD0 0x80
7866 #define I40E_DIRECTION_INGRESS_KEY		0x8000
7867 #define I40E_TR_L4_TYPE_TCP			0x2
7868 #define I40E_TR_L4_TYPE_UDP			0x4
7869 #define I40E_TR_L4_TYPE_SCTP			0x8
7870 
7871 static enum
7872 i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf)
7873 {
7874 	struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
7875 	struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
7876 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
7877 	struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
7878 	enum i40e_status_code status = I40E_SUCCESS;
7879 
7880 	if (pf->support_multi_driver) {
7881 		PMD_DRV_LOG(ERR, "Replace l1 filter is not supported.");
7882 		return I40E_NOT_SUPPORTED;
7883 	}
7884 
7885 	memset(&filter_replace, 0,
7886 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
7887 	memset(&filter_replace_buf, 0,
7888 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
7889 
7890 	/* create L1 filter */
7891 	filter_replace.old_filter_type =
7892 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC;
7893 	filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X11;
7894 	filter_replace.tr_bit = 0;
7895 
7896 	/* Prepare the buffer, 3 entries */
7897 	filter_replace_buf.data[0] =
7898 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0;
7899 	filter_replace_buf.data[0] |=
7900 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
7901 	filter_replace_buf.data[2] = 0xFF;
7902 	filter_replace_buf.data[3] = 0xFF;
7903 	filter_replace_buf.data[4] =
7904 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1;
7905 	filter_replace_buf.data[4] |=
7906 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
7907 	filter_replace_buf.data[7] = 0xF0;
7908 	filter_replace_buf.data[8]
7909 		= I40E_AQC_REPLACE_CLOUD_CMD_INPUT_TR_WORD0;
7910 	filter_replace_buf.data[8] |=
7911 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
7912 	filter_replace_buf.data[10] = I40E_TR_VXLAN_GRE_KEY_MASK |
7913 		I40E_TR_GENEVE_KEY_MASK |
7914 		I40E_TR_GENERIC_UDP_TUNNEL_MASK;
7915 	filter_replace_buf.data[11] = (I40E_TR_GRE_KEY_MASK |
7916 		I40E_TR_GRE_KEY_WITH_XSUM_MASK |
7917 		I40E_TR_GRE_NO_KEY_MASK) >> 8;
7918 
7919 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
7920 					       &filter_replace_buf);
7921 	if (!status && (filter_replace.old_filter_type !=
7922 			filter_replace.new_filter_type))
7923 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type."
7924 			    " original: 0x%x, new: 0x%x",
7925 			    dev->device->name,
7926 			    filter_replace.old_filter_type,
7927 			    filter_replace.new_filter_type);
7928 
7929 	return status;
7930 }
7931 
7932 static enum
7933 i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf)
7934 {
7935 	struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
7936 	struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
7937 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
7938 	struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
7939 	enum i40e_status_code status = I40E_SUCCESS;
7940 
7941 	if (pf->support_multi_driver) {
7942 		PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
7943 		return I40E_NOT_SUPPORTED;
7944 	}
7945 
7946 	/* For MPLSoUDP */
7947 	memset(&filter_replace, 0,
7948 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
7949 	memset(&filter_replace_buf, 0,
7950 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
7951 	filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER |
7952 		I40E_AQC_MIRROR_CLOUD_FILTER;
7953 	filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IIP;
7954 	filter_replace.new_filter_type =
7955 		I40E_AQC_ADD_CLOUD_FILTER_0X11;
7956 	/* Prepare the buffer, 2 entries */
7957 	filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
7958 	filter_replace_buf.data[0] |=
7959 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
7960 	filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_0X11;
7961 	filter_replace_buf.data[4] |=
7962 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
7963 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
7964 					       &filter_replace_buf);
7965 	if (status < 0)
7966 		return status;
7967 	if (filter_replace.old_filter_type !=
7968 	    filter_replace.new_filter_type)
7969 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
7970 			    " original: 0x%x, new: 0x%x",
7971 			    dev->device->name,
7972 			    filter_replace.old_filter_type,
7973 			    filter_replace.new_filter_type);
7974 
7975 	/* For MPLSoGRE */
7976 	memset(&filter_replace, 0,
7977 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
7978 	memset(&filter_replace_buf, 0,
7979 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
7980 
7981 	filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER |
7982 		I40E_AQC_MIRROR_CLOUD_FILTER;
7983 	filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IMAC;
7984 	filter_replace.new_filter_type =
7985 		I40E_AQC_ADD_CLOUD_FILTER_0X12;
7986 	/* Prepare the buffer, 2 entries */
7987 	filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
7988 	filter_replace_buf.data[0] |=
7989 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
7990 	filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_0X11;
7991 	filter_replace_buf.data[4] |=
7992 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
7993 
7994 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
7995 					       &filter_replace_buf);
7996 	if (!status && (filter_replace.old_filter_type !=
7997 			filter_replace.new_filter_type))
7998 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
7999 			    " original: 0x%x, new: 0x%x",
8000 			    dev->device->name,
8001 			    filter_replace.old_filter_type,
8002 			    filter_replace.new_filter_type);
8003 
8004 	return status;
8005 }
8006 
8007 static enum i40e_status_code
8008 i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
8009 {
8010 	struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
8011 	struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
8012 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
8013 	struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
8014 	enum i40e_status_code status = I40E_SUCCESS;
8015 
8016 	if (pf->support_multi_driver) {
8017 		PMD_DRV_LOG(ERR, "Replace l1 filter is not supported.");
8018 		return I40E_NOT_SUPPORTED;
8019 	}
8020 
8021 	/* For GTP-C */
8022 	memset(&filter_replace, 0,
8023 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
8024 	memset(&filter_replace_buf, 0,
8025 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
8026 	/* create L1 filter */
8027 	filter_replace.old_filter_type =
8028 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC;
8029 	filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X12;
8030 	filter_replace.tr_bit = I40E_AQC_NEW_TR_22 |
8031 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8032 	/* Prepare the buffer, 2 entries */
8033 	filter_replace_buf.data[0] =
8034 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0;
8035 	filter_replace_buf.data[0] |=
8036 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8037 	filter_replace_buf.data[2] = 0xFF;
8038 	filter_replace_buf.data[3] = 0xFF;
8039 	filter_replace_buf.data[4] =
8040 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1;
8041 	filter_replace_buf.data[4] |=
8042 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8043 	filter_replace_buf.data[6] = 0xFF;
8044 	filter_replace_buf.data[7] = 0xFF;
8045 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
8046 					       &filter_replace_buf);
8047 	if (status < 0)
8048 		return status;
8049 	if (filter_replace.old_filter_type !=
8050 	    filter_replace.new_filter_type)
8051 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type."
8052 			    " original: 0x%x, new: 0x%x",
8053 			    dev->device->name,
8054 			    filter_replace.old_filter_type,
8055 			    filter_replace.new_filter_type);
8056 
8057 	/* for GTP-U */
8058 	memset(&filter_replace, 0,
8059 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
8060 	memset(&filter_replace_buf, 0,
8061 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
8062 	/* create L1 filter */
8063 	filter_replace.old_filter_type =
8064 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TUNNLE_KEY;
8065 	filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X13;
8066 	filter_replace.tr_bit = I40E_AQC_NEW_TR_21 |
8067 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8068 	/* Prepare the buffer, 2 entries */
8069 	filter_replace_buf.data[0] =
8070 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0;
8071 	filter_replace_buf.data[0] |=
8072 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8073 	filter_replace_buf.data[2] = 0xFF;
8074 	filter_replace_buf.data[3] = 0xFF;
8075 	filter_replace_buf.data[4] =
8076 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1;
8077 	filter_replace_buf.data[4] |=
8078 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8079 	filter_replace_buf.data[6] = 0xFF;
8080 	filter_replace_buf.data[7] = 0xFF;
8081 
8082 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
8083 					       &filter_replace_buf);
8084 	if (!status && (filter_replace.old_filter_type !=
8085 			filter_replace.new_filter_type))
8086 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type."
8087 			    " original: 0x%x, new: 0x%x",
8088 			    dev->device->name,
8089 			    filter_replace.old_filter_type,
8090 			    filter_replace.new_filter_type);
8091 
8092 	return status;
8093 }
8094 
8095 static enum
8096 i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
8097 {
8098 	struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
8099 	struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
8100 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
8101 	struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
8102 	enum i40e_status_code status = I40E_SUCCESS;
8103 
8104 	if (pf->support_multi_driver) {
8105 		PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
8106 		return I40E_NOT_SUPPORTED;
8107 	}
8108 
8109 	/* for GTP-C */
8110 	memset(&filter_replace, 0,
8111 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
8112 	memset(&filter_replace_buf, 0,
8113 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
8114 	filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER;
8115 	filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN;
8116 	filter_replace.new_filter_type =
8117 		I40E_AQC_ADD_CLOUD_FILTER_0X11;
8118 	/* Prepare the buffer, 2 entries */
8119 	filter_replace_buf.data[0] = I40E_AQC_ADD_L1_FILTER_0X12;
8120 	filter_replace_buf.data[0] |=
8121 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8122 	filter_replace_buf.data[4] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
8123 	filter_replace_buf.data[4] |=
8124 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8125 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
8126 					       &filter_replace_buf);
8127 	if (status < 0)
8128 		return status;
8129 	if (filter_replace.old_filter_type !=
8130 	    filter_replace.new_filter_type)
8131 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
8132 			    " original: 0x%x, new: 0x%x",
8133 			    dev->device->name,
8134 			    filter_replace.old_filter_type,
8135 			    filter_replace.new_filter_type);
8136 
8137 	/* for GTP-U */
8138 	memset(&filter_replace, 0,
8139 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
8140 	memset(&filter_replace_buf, 0,
8141 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
8142 	filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER;
8143 	filter_replace.old_filter_type =
8144 		I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID;
8145 	filter_replace.new_filter_type =
8146 		I40E_AQC_ADD_CLOUD_FILTER_0X12;
8147 	/* Prepare the buffer, 2 entries */
8148 	filter_replace_buf.data[0] = I40E_AQC_ADD_L1_FILTER_0X13;
8149 	filter_replace_buf.data[0] |=
8150 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8151 	filter_replace_buf.data[4] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
8152 	filter_replace_buf.data[4] |=
8153 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8154 
8155 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
8156 					       &filter_replace_buf);
8157 	if (!status && (filter_replace.old_filter_type !=
8158 			filter_replace.new_filter_type))
8159 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
8160 			    " original: 0x%x, new: 0x%x",
8161 			    dev->device->name,
8162 			    filter_replace.old_filter_type,
8163 			    filter_replace.new_filter_type);
8164 
8165 	return status;
8166 }
8167 
8168 static enum i40e_status_code
8169 i40e_replace_port_l1_filter(struct i40e_pf *pf,
8170 			    enum i40e_l4_port_type l4_port_type)
8171 {
8172 	struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
8173 	struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
8174 	enum i40e_status_code status = I40E_SUCCESS;
8175 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
8176 	struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
8177 
8178 	if (pf->support_multi_driver) {
8179 		PMD_DRV_LOG(ERR, "Replace l1 filter is not supported.");
8180 		return I40E_NOT_SUPPORTED;
8181 	}
8182 
8183 	memset(&filter_replace, 0,
8184 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
8185 	memset(&filter_replace_buf, 0,
8186 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
8187 
8188 	/* create L1 filter */
8189 	if (l4_port_type == I40E_L4_PORT_TYPE_SRC) {
8190 		filter_replace.old_filter_type =
8191 			I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TUNNLE_KEY;
8192 		filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X11;
8193 		filter_replace_buf.data[8] =
8194 			I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_SRC_PORT;
8195 	} else {
8196 		filter_replace.old_filter_type =
8197 			I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_IVLAN;
8198 		filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X10;
8199 		filter_replace_buf.data[8] =
8200 			I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_DST_PORT;
8201 	}
8202 
8203 	filter_replace.tr_bit = 0;
8204 	/* Prepare the buffer, 3 entries */
8205 	filter_replace_buf.data[0] =
8206 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_DIRECTION_WORD0;
8207 	filter_replace_buf.data[0] |=
8208 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8209 	filter_replace_buf.data[2] = 0x00;
8210 	filter_replace_buf.data[3] =
8211 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_INGRESS_WORD0;
8212 	filter_replace_buf.data[4] =
8213 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_PORT_TR_WORD0;
8214 	filter_replace_buf.data[4] |=
8215 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8216 	filter_replace_buf.data[5] = 0x00;
8217 	filter_replace_buf.data[6] = I40E_TR_L4_TYPE_UDP |
8218 		I40E_TR_L4_TYPE_TCP |
8219 		I40E_TR_L4_TYPE_SCTP;
8220 	filter_replace_buf.data[7] = 0x00;
8221 	filter_replace_buf.data[8] |=
8222 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8223 	filter_replace_buf.data[9] = 0x00;
8224 	filter_replace_buf.data[10] = 0xFF;
8225 	filter_replace_buf.data[11] = 0xFF;
8226 
8227 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
8228 					       &filter_replace_buf);
8229 	if (!status && filter_replace.old_filter_type !=
8230 	    filter_replace.new_filter_type)
8231 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type."
8232 			    " original: 0x%x, new: 0x%x",
8233 			    dev->device->name,
8234 			    filter_replace.old_filter_type,
8235 			    filter_replace.new_filter_type);
8236 
8237 	return status;
8238 }
8239 
8240 static enum i40e_status_code
8241 i40e_replace_port_cloud_filter(struct i40e_pf *pf,
8242 			       enum i40e_l4_port_type l4_port_type)
8243 {
8244 	struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
8245 	struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
8246 	enum i40e_status_code status = I40E_SUCCESS;
8247 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
8248 	struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
8249 
8250 	if (pf->support_multi_driver) {
8251 		PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
8252 		return I40E_NOT_SUPPORTED;
8253 	}
8254 
8255 	memset(&filter_replace, 0,
8256 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
8257 	memset(&filter_replace_buf, 0,
8258 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
8259 
8260 	if (l4_port_type == I40E_L4_PORT_TYPE_SRC) {
8261 		filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IIP;
8262 		filter_replace.new_filter_type =
8263 			I40E_AQC_ADD_CLOUD_FILTER_0X11;
8264 		filter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_0X11;
8265 	} else {
8266 		filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_OIP;
8267 		filter_replace.new_filter_type =
8268 			I40E_AQC_ADD_CLOUD_FILTER_0X10;
8269 		filter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_0X10;
8270 	}
8271 
8272 	filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER;
8273 	filter_replace.tr_bit = 0;
8274 	/* Prepare the buffer, 2 entries */
8275 	filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
8276 	filter_replace_buf.data[0] |=
8277 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8278 	filter_replace_buf.data[4] |=
8279 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
8280 	status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
8281 					       &filter_replace_buf);
8282 
8283 	if (!status && filter_replace.old_filter_type !=
8284 	    filter_replace.new_filter_type)
8285 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
8286 			    " original: 0x%x, new: 0x%x",
8287 			    dev->device->name,
8288 			    filter_replace.old_filter_type,
8289 			    filter_replace.new_filter_type);
8290 
8291 	return status;
8292 }
8293 
8294 int
8295 i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
8296 		      struct i40e_tunnel_filter_conf *tunnel_filter,
8297 		      uint8_t add)
8298 {
8299 	uint16_t ip_type;
8300 	uint32_t ipv4_addr, ipv4_addr_le;
8301 	uint8_t i, tun_type = 0;
8302 	/* internal variable to convert ipv6 byte order */
8303 	uint32_t convert_ipv6[4];
8304 	int val, ret = 0;
8305 	struct i40e_pf_vf *vf = NULL;
8306 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
8307 	struct i40e_vsi *vsi;
8308 	struct i40e_aqc_cloud_filters_element_bb *cld_filter;
8309 	struct i40e_aqc_cloud_filters_element_bb *pfilter;
8310 	struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
8311 	struct i40e_tunnel_filter *tunnel, *node;
8312 	struct i40e_tunnel_filter check_filter; /* Check if filter exists */
8313 	uint32_t teid_le;
8314 	bool big_buffer = 0;
8315 
8316 	cld_filter = rte_zmalloc("tunnel_filter",
8317 			 sizeof(struct i40e_aqc_add_rm_cloud_filt_elem_ext),
8318 			 0);
8319 
8320 	if (cld_filter == NULL) {
8321 		PMD_DRV_LOG(ERR, "Failed to alloc memory.");
8322 		return -ENOMEM;
8323 	}
8324 	pfilter = cld_filter;
8325 
8326 	rte_ether_addr_copy(&tunnel_filter->outer_mac,
8327 			(struct rte_ether_addr *)&pfilter->element.outer_mac);
8328 	rte_ether_addr_copy(&tunnel_filter->inner_mac,
8329 			(struct rte_ether_addr *)&pfilter->element.inner_mac);
8330 
8331 	pfilter->element.inner_vlan =
8332 		rte_cpu_to_le_16(tunnel_filter->inner_vlan);
8333 	if (tunnel_filter->ip_type == I40E_TUNNEL_IPTYPE_IPV4) {
8334 		ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV4;
8335 		ipv4_addr = rte_be_to_cpu_32(tunnel_filter->ip_addr.ipv4_addr);
8336 		ipv4_addr_le = rte_cpu_to_le_32(ipv4_addr);
8337 		rte_memcpy(&pfilter->element.ipaddr.v4.data,
8338 				&ipv4_addr_le,
8339 				sizeof(pfilter->element.ipaddr.v4.data));
8340 	} else {
8341 		ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV6;
8342 		for (i = 0; i < 4; i++) {
8343 			convert_ipv6[i] =
8344 			rte_cpu_to_le_32(rte_be_to_cpu_32(
8345 					 tunnel_filter->ip_addr.ipv6_addr[i]));
8346 		}
8347 		rte_memcpy(&pfilter->element.ipaddr.v6.data,
8348 			   &convert_ipv6,
8349 			   sizeof(pfilter->element.ipaddr.v6.data));
8350 	}
8351 
8352 	/* check tunneled type */
8353 	switch (tunnel_filter->tunnel_type) {
8354 	case I40E_TUNNEL_TYPE_VXLAN:
8355 		tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN;
8356 		break;
8357 	case I40E_TUNNEL_TYPE_NVGRE:
8358 		tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC;
8359 		break;
8360 	case I40E_TUNNEL_TYPE_IP_IN_GRE:
8361 		tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_IP;
8362 		break;
8363 	case I40E_TUNNEL_TYPE_MPLSoUDP:
8364 		if (!pf->mpls_replace_flag) {
8365 			i40e_replace_mpls_l1_filter(pf);
8366 			i40e_replace_mpls_cloud_filter(pf);
8367 			pf->mpls_replace_flag = 1;
8368 		}
8369 		teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);
8370 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0] =
8371 			teid_le >> 4;
8372 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] =
8373 			(teid_le & 0xF) << 12;
8374 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] =
8375 			0x40;
8376 		big_buffer = 1;
8377 		tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSOUDP;
8378 		break;
8379 	case I40E_TUNNEL_TYPE_MPLSoGRE:
8380 		if (!pf->mpls_replace_flag) {
8381 			i40e_replace_mpls_l1_filter(pf);
8382 			i40e_replace_mpls_cloud_filter(pf);
8383 			pf->mpls_replace_flag = 1;
8384 		}
8385 		teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);
8386 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0] =
8387 			teid_le >> 4;
8388 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] =
8389 			(teid_le & 0xF) << 12;
8390 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] =
8391 			0x0;
8392 		big_buffer = 1;
8393 		tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSOGRE;
8394 		break;
8395 	case I40E_TUNNEL_TYPE_GTPC:
8396 		if (!pf->gtp_replace_flag) {
8397 			i40e_replace_gtp_l1_filter(pf);
8398 			i40e_replace_gtp_cloud_filter(pf);
8399 			pf->gtp_replace_flag = 1;
8400 		}
8401 		teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);
8402 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD0] =
8403 			(teid_le >> 16) & 0xFFFF;
8404 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD1] =
8405 			teid_le & 0xFFFF;
8406 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD2] =
8407 			0x0;
8408 		big_buffer = 1;
8409 		break;
8410 	case I40E_TUNNEL_TYPE_GTPU:
8411 		if (!pf->gtp_replace_flag) {
8412 			i40e_replace_gtp_l1_filter(pf);
8413 			i40e_replace_gtp_cloud_filter(pf);
8414 			pf->gtp_replace_flag = 1;
8415 		}
8416 		teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);
8417 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD0] =
8418 			(teid_le >> 16) & 0xFFFF;
8419 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD1] =
8420 			teid_le & 0xFFFF;
8421 		pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD2] =
8422 			0x0;
8423 		big_buffer = 1;
8424 		break;
8425 	case I40E_TUNNEL_TYPE_QINQ:
8426 		if (!pf->qinq_replace_flag) {
8427 			ret = i40e_cloud_filter_qinq_create(pf);
8428 			if (ret < 0)
8429 				PMD_DRV_LOG(DEBUG,
8430 					    "QinQ tunnel filter already created.");
8431 			pf->qinq_replace_flag = 1;
8432 		}
8433 		/*	Add in the General fields the values of
8434 		 *	the Outer and Inner VLAN
8435 		 *	Big Buffer should be set, see changes in
8436 		 *	i40e_aq_add_cloud_filters
8437 		 */
8438 		pfilter->general_fields[0] = tunnel_filter->inner_vlan;
8439 		pfilter->general_fields[1] = tunnel_filter->outer_vlan;
8440 		big_buffer = 1;
8441 		break;
8442 	case I40E_CLOUD_TYPE_UDP:
8443 	case I40E_CLOUD_TYPE_TCP:
8444 	case I40E_CLOUD_TYPE_SCTP:
8445 		if (tunnel_filter->l4_port_type == I40E_L4_PORT_TYPE_SRC) {
8446 			if (!pf->sport_replace_flag) {
8447 				i40e_replace_port_l1_filter(pf,
8448 						tunnel_filter->l4_port_type);
8449 				i40e_replace_port_cloud_filter(pf,
8450 						tunnel_filter->l4_port_type);
8451 				pf->sport_replace_flag = 1;
8452 			}
8453 			teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);
8454 			pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0] =
8455 				I40E_DIRECTION_INGRESS_KEY;
8456 
8457 			if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_UDP)
8458 				pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] =
8459 					I40E_TR_L4_TYPE_UDP;
8460 			else if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_TCP)
8461 				pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] =
8462 					I40E_TR_L4_TYPE_TCP;
8463 			else
8464 				pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] =
8465 					I40E_TR_L4_TYPE_SCTP;
8466 
8467 			pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] =
8468 				(teid_le >> 16) & 0xFFFF;
8469 			big_buffer = 1;
8470 		} else {
8471 			if (!pf->dport_replace_flag) {
8472 				i40e_replace_port_l1_filter(pf,
8473 						tunnel_filter->l4_port_type);
8474 				i40e_replace_port_cloud_filter(pf,
8475 						tunnel_filter->l4_port_type);
8476 				pf->dport_replace_flag = 1;
8477 			}
8478 			teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);
8479 			pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD0] =
8480 				I40E_DIRECTION_INGRESS_KEY;
8481 
8482 			if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_UDP)
8483 				pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1] =
8484 					I40E_TR_L4_TYPE_UDP;
8485 			else if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_TCP)
8486 				pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1] =
8487 					I40E_TR_L4_TYPE_TCP;
8488 			else
8489 				pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1] =
8490 					I40E_TR_L4_TYPE_SCTP;
8491 
8492 			pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD2] =
8493 				(teid_le >> 16) & 0xFFFF;
8494 			big_buffer = 1;
8495 		}
8496 
8497 		break;
8498 	default:
8499 		/* Other tunnel types is not supported. */
8500 		PMD_DRV_LOG(ERR, "tunnel type is not supported.");
8501 		rte_free(cld_filter);
8502 		return -EINVAL;
8503 	}
8504 
8505 	if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_MPLSoUDP)
8506 		pfilter->element.flags =
8507 			I40E_AQC_ADD_CLOUD_FILTER_0X11;
8508 	else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_MPLSoGRE)
8509 		pfilter->element.flags =
8510 			I40E_AQC_ADD_CLOUD_FILTER_0X12;
8511 	else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_GTPC)
8512 		pfilter->element.flags =
8513 			I40E_AQC_ADD_CLOUD_FILTER_0X11;
8514 	else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_GTPU)
8515 		pfilter->element.flags =
8516 			I40E_AQC_ADD_CLOUD_FILTER_0X12;
8517 	else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_QINQ)
8518 		pfilter->element.flags |=
8519 			I40E_AQC_ADD_CLOUD_FILTER_0X10;
8520 	else if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_UDP ||
8521 		 tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_TCP ||
8522 		 tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_SCTP) {
8523 		if (tunnel_filter->l4_port_type == I40E_L4_PORT_TYPE_SRC)
8524 			pfilter->element.flags |=
8525 				I40E_AQC_ADD_CLOUD_FILTER_0X11;
8526 		else
8527 			pfilter->element.flags |=
8528 				I40E_AQC_ADD_CLOUD_FILTER_0X10;
8529 	} else {
8530 		val = i40e_dev_get_filter_type(tunnel_filter->filter_type,
8531 						&pfilter->element.flags);
8532 		if (val < 0) {
8533 			rte_free(cld_filter);
8534 			return -EINVAL;
8535 		}
8536 	}
8537 
8538 	pfilter->element.flags |= rte_cpu_to_le_16(
8539 		I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE |
8540 		ip_type | (tun_type << I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT));
8541 	pfilter->element.tenant_id = rte_cpu_to_le_32(tunnel_filter->tenant_id);
8542 	pfilter->element.queue_number =
8543 		rte_cpu_to_le_16(tunnel_filter->queue_id);
8544 
8545 	if (!tunnel_filter->is_to_vf)
8546 		vsi = pf->main_vsi;
8547 	else {
8548 		if (tunnel_filter->vf_id >= pf->vf_num) {
8549 			PMD_DRV_LOG(ERR, "Invalid argument.");
8550 			rte_free(cld_filter);
8551 			return -EINVAL;
8552 		}
8553 		vf = &pf->vfs[tunnel_filter->vf_id];
8554 		vsi = vf->vsi;
8555 	}
8556 
8557 	/* Check if there is the filter in SW list */
8558 	memset(&check_filter, 0, sizeof(check_filter));
8559 	i40e_tunnel_filter_convert(cld_filter, &check_filter);
8560 	check_filter.is_to_vf = tunnel_filter->is_to_vf;
8561 	check_filter.vf_id = tunnel_filter->vf_id;
8562 	node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &check_filter.input);
8563 	if (add && node) {
8564 		PMD_DRV_LOG(ERR, "Conflict with existing tunnel rules!");
8565 		rte_free(cld_filter);
8566 		return -EINVAL;
8567 	}
8568 
8569 	if (!add && !node) {
8570 		PMD_DRV_LOG(ERR, "There's no corresponding tunnel filter!");
8571 		rte_free(cld_filter);
8572 		return -EINVAL;
8573 	}
8574 
8575 	if (add) {
8576 		if (big_buffer)
8577 			ret = i40e_aq_add_cloud_filters_bb(hw,
8578 						   vsi->seid, cld_filter, 1);
8579 		else
8580 			ret = i40e_aq_add_cloud_filters(hw,
8581 					vsi->seid, &cld_filter->element, 1);
8582 		if (ret < 0) {
8583 			PMD_DRV_LOG(ERR, "Failed to add a tunnel filter.");
8584 			rte_free(cld_filter);
8585 			return -ENOTSUP;
8586 		}
8587 		tunnel = rte_zmalloc("tunnel_filter", sizeof(*tunnel), 0);
8588 		if (tunnel == NULL) {
8589 			PMD_DRV_LOG(ERR, "Failed to alloc memory.");
8590 			rte_free(cld_filter);
8591 			return -ENOMEM;
8592 		}
8593 
8594 		rte_memcpy(tunnel, &check_filter, sizeof(check_filter));
8595 		ret = i40e_sw_tunnel_filter_insert(pf, tunnel);
8596 		if (ret < 0)
8597 			rte_free(tunnel);
8598 	} else {
8599 		if (big_buffer)
8600 			ret = i40e_aq_rem_cloud_filters_bb(
8601 				hw, vsi->seid, cld_filter, 1);
8602 		else
8603 			ret = i40e_aq_rem_cloud_filters(hw, vsi->seid,
8604 						&cld_filter->element, 1);
8605 		if (ret < 0) {
8606 			PMD_DRV_LOG(ERR, "Failed to delete a tunnel filter.");
8607 			rte_free(cld_filter);
8608 			return -ENOTSUP;
8609 		}
8610 		ret = i40e_sw_tunnel_filter_del(pf, &node->input);
8611 	}
8612 
8613 	rte_free(cld_filter);
8614 	return ret;
8615 }
8616 
8617 static int
8618 i40e_get_vxlan_port_idx(struct i40e_pf *pf, uint16_t port)
8619 {
8620 	uint8_t i;
8621 
8622 	for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) {
8623 		if (pf->vxlan_ports[i] == port)
8624 			return i;
8625 	}
8626 
8627 	return -1;
8628 }
8629 
8630 static int
8631 i40e_add_vxlan_port(struct i40e_pf *pf, uint16_t port, int udp_type)
8632 {
8633 	int  idx, ret;
8634 	uint8_t filter_idx = 0;
8635 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
8636 
8637 	idx = i40e_get_vxlan_port_idx(pf, port);
8638 
8639 	/* Check if port already exists */
8640 	if (idx >= 0) {
8641 		PMD_DRV_LOG(ERR, "Port %d already offloaded", port);
8642 		return -EINVAL;
8643 	}
8644 
8645 	/* Now check if there is space to add the new port */
8646 	idx = i40e_get_vxlan_port_idx(pf, 0);
8647 	if (idx < 0) {
8648 		PMD_DRV_LOG(ERR,
8649 			"Maximum number of UDP ports reached, not adding port %d",
8650 			port);
8651 		return -ENOSPC;
8652 	}
8653 
8654 	ret =  i40e_aq_add_udp_tunnel(hw, port, udp_type,
8655 					&filter_idx, NULL);
8656 	if (ret < 0) {
8657 		PMD_DRV_LOG(ERR, "Failed to add VXLAN UDP port %d", port);
8658 		return -1;
8659 	}
8660 
8661 	PMD_DRV_LOG(INFO, "Added port %d with AQ command with index %d",
8662 			 port,  filter_idx);
8663 
8664 	/* New port: add it and mark its index in the bitmap */
8665 	pf->vxlan_ports[idx] = port;
8666 	pf->vxlan_bitmap |= (1 << idx);
8667 
8668 	if (!(pf->flags & I40E_FLAG_VXLAN))
8669 		pf->flags |= I40E_FLAG_VXLAN;
8670 
8671 	return 0;
8672 }
8673 
8674 static int
8675 i40e_del_vxlan_port(struct i40e_pf *pf, uint16_t port)
8676 {
8677 	int idx;
8678 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
8679 
8680 	if (!(pf->flags & I40E_FLAG_VXLAN)) {
8681 		PMD_DRV_LOG(ERR, "VXLAN UDP port was not configured.");
8682 		return -EINVAL;
8683 	}
8684 
8685 	idx = i40e_get_vxlan_port_idx(pf, port);
8686 
8687 	if (idx < 0) {
8688 		PMD_DRV_LOG(ERR, "Port %d doesn't exist", port);
8689 		return -EINVAL;
8690 	}
8691 
8692 	if (i40e_aq_del_udp_tunnel(hw, idx, NULL) < 0) {
8693 		PMD_DRV_LOG(ERR, "Failed to delete VXLAN UDP port %d", port);
8694 		return -1;
8695 	}
8696 
8697 	PMD_DRV_LOG(INFO, "Deleted port %d with AQ command with index %d",
8698 			port, idx);
8699 
8700 	pf->vxlan_ports[idx] = 0;
8701 	pf->vxlan_bitmap &= ~(1 << idx);
8702 
8703 	if (!pf->vxlan_bitmap)
8704 		pf->flags &= ~I40E_FLAG_VXLAN;
8705 
8706 	return 0;
8707 }
8708 
8709 /* Add UDP tunneling port */
8710 static int
8711 i40e_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
8712 			     struct rte_eth_udp_tunnel *udp_tunnel)
8713 {
8714 	int ret = 0;
8715 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
8716 
8717 	if (udp_tunnel == NULL)
8718 		return -EINVAL;
8719 
8720 	switch (udp_tunnel->prot_type) {
8721 	case RTE_TUNNEL_TYPE_VXLAN:
8722 		ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port,
8723 					  I40E_AQC_TUNNEL_TYPE_VXLAN);
8724 		break;
8725 	case RTE_TUNNEL_TYPE_VXLAN_GPE:
8726 		ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port,
8727 					  I40E_AQC_TUNNEL_TYPE_VXLAN_GPE);
8728 		break;
8729 	case RTE_TUNNEL_TYPE_GENEVE:
8730 	case RTE_TUNNEL_TYPE_TEREDO:
8731 		PMD_DRV_LOG(ERR, "Tunnel type is not supported now.");
8732 		ret = -1;
8733 		break;
8734 
8735 	default:
8736 		PMD_DRV_LOG(ERR, "Invalid tunnel type");
8737 		ret = -1;
8738 		break;
8739 	}
8740 
8741 	return ret;
8742 }
8743 
8744 /* Remove UDP tunneling port */
8745 static int
8746 i40e_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
8747 			     struct rte_eth_udp_tunnel *udp_tunnel)
8748 {
8749 	int ret = 0;
8750 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
8751 
8752 	if (udp_tunnel == NULL)
8753 		return -EINVAL;
8754 
8755 	switch (udp_tunnel->prot_type) {
8756 	case RTE_TUNNEL_TYPE_VXLAN:
8757 	case RTE_TUNNEL_TYPE_VXLAN_GPE:
8758 		ret = i40e_del_vxlan_port(pf, udp_tunnel->udp_port);
8759 		break;
8760 	case RTE_TUNNEL_TYPE_GENEVE:
8761 	case RTE_TUNNEL_TYPE_TEREDO:
8762 		PMD_DRV_LOG(ERR, "Tunnel type is not supported now.");
8763 		ret = -1;
8764 		break;
8765 	default:
8766 		PMD_DRV_LOG(ERR, "Invalid tunnel type");
8767 		ret = -1;
8768 		break;
8769 	}
8770 
8771 	return ret;
8772 }
8773 
8774 /* Calculate the maximum number of contiguous PF queues that are configured */
8775 int
8776 i40e_pf_calc_configured_queues_num(struct i40e_pf *pf)
8777 {
8778 	struct rte_eth_dev_data *data = pf->dev_data;
8779 	int i, num;
8780 	struct i40e_rx_queue *rxq;
8781 
8782 	num = 0;
8783 	for (i = 0; i < pf->lan_nb_qps; i++) {
8784 		rxq = data->rx_queues[i];
8785 		if (rxq && rxq->q_set)
8786 			num++;
8787 		else
8788 			break;
8789 	}
8790 
8791 	return num;
8792 }
8793 
8794 /* Reset the global configure of hash function and input sets */
8795 static void
8796 i40e_pf_global_rss_reset(struct i40e_pf *pf)
8797 {
8798 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
8799 	uint32_t reg, reg_val;
8800 	int i;
8801 
8802 	/* Reset global RSS function sets */
8803 	reg_val = i40e_read_rx_ctl(hw, I40E_GLQF_CTL);
8804 	if (!(reg_val & I40E_GLQF_CTL_HTOEP_MASK)) {
8805 		reg_val |= I40E_GLQF_CTL_HTOEP_MASK;
8806 		i40e_write_global_rx_ctl(hw, I40E_GLQF_CTL, reg_val);
8807 	}
8808 
8809 	for (i = 0; i <= I40E_FILTER_PCTYPE_L2_PAYLOAD; i++) {
8810 		uint64_t inset;
8811 		int j, pctype;
8812 
8813 		if (hw->mac.type == I40E_MAC_X722)
8814 			pctype = i40e_read_rx_ctl(hw, I40E_GLQF_FD_PCTYPES(i));
8815 		else
8816 			pctype = i;
8817 
8818 		/* Reset pctype insets */
8819 		inset = i40e_get_default_input_set(i);
8820 		if (inset) {
8821 			pf->hash_input_set[pctype] = inset;
8822 			inset = i40e_translate_input_set_reg(hw->mac.type,
8823 							     inset);
8824 
8825 			reg = I40E_GLQF_HASH_INSET(0, pctype);
8826 			i40e_check_write_global_reg(hw, reg, (uint32_t)inset);
8827 			reg = I40E_GLQF_HASH_INSET(1, pctype);
8828 			i40e_check_write_global_reg(hw, reg,
8829 						    (uint32_t)(inset >> 32));
8830 
8831 			/* Clear unused mask registers of the pctype */
8832 			for (j = 0; j < I40E_INSET_MASK_NUM_REG; j++) {
8833 				reg = I40E_GLQF_HASH_MSK(j, pctype);
8834 				i40e_check_write_global_reg(hw, reg, 0);
8835 			}
8836 		}
8837 
8838 		/* Reset pctype symmetric sets */
8839 		reg = I40E_GLQF_HSYM(pctype);
8840 		reg_val = i40e_read_rx_ctl(hw, reg);
8841 		if (reg_val & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
8842 			reg_val &= ~I40E_GLQF_HSYM_SYMH_ENA_MASK;
8843 			i40e_write_global_rx_ctl(hw, reg, reg_val);
8844 		}
8845 	}
8846 	I40E_WRITE_FLUSH(hw);
8847 }
8848 
8849 int
8850 i40e_pf_reset_rss_reta(struct i40e_pf *pf)
8851 {
8852 	struct i40e_hw *hw = &pf->adapter->hw;
8853 	uint8_t lut[ETH_RSS_RETA_SIZE_512];
8854 	uint32_t i;
8855 	int num;
8856 
8857 	/* If both VMDQ and RSS enabled, not all of PF queues are
8858 	 * configured. It's necessary to calculate the actual PF
8859 	 * queues that are configured.
8860 	 */
8861 	if (pf->dev_data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_VMDQ_FLAG)
8862 		num = i40e_pf_calc_configured_queues_num(pf);
8863 	else
8864 		num = pf->dev_data->nb_rx_queues;
8865 
8866 	num = RTE_MIN(num, I40E_MAX_Q_PER_TC);
8867 	if (num <= 0)
8868 		return 0;
8869 
8870 	for (i = 0; i < hw->func_caps.rss_table_size; i++)
8871 		lut[i] = (uint8_t)(i % (uint32_t)num);
8872 
8873 	return i40e_set_rss_lut(pf->main_vsi, lut, (uint16_t)i);
8874 }
8875 
8876 int
8877 i40e_pf_reset_rss_key(struct i40e_pf *pf)
8878 {
8879 	const uint8_t key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) *
8880 			sizeof(uint32_t);
8881 	uint8_t *rss_key;
8882 
8883 	/* Reset key */
8884 	rss_key = pf->dev_data->dev_conf.rx_adv_conf.rss_conf.rss_key;
8885 	if (!rss_key ||
8886 	    pf->dev_data->dev_conf.rx_adv_conf.rss_conf.rss_key_len < key_len) {
8887 		static uint32_t rss_key_default[] = {0x6b793944,
8888 			0x23504cb5, 0x5bea75b6, 0x309f4f12, 0x3dc0a2b8,
8889 			0x024ddcdf, 0x339b8ca0, 0x4c4af64a, 0x34fac605,
8890 			0x55d85839, 0x3a58997d, 0x2ec938e1, 0x66031581};
8891 
8892 		rss_key = (uint8_t *)rss_key_default;
8893 	}
8894 
8895 	return i40e_set_rss_key(pf->main_vsi, rss_key, key_len);
8896 }
8897 
8898 static int
8899 i40e_pf_rss_reset(struct i40e_pf *pf)
8900 {
8901 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
8902 
8903 	int ret;
8904 
8905 	pf->hash_filter_enabled = 0;
8906 	i40e_pf_disable_rss(pf);
8907 	i40e_set_symmetric_hash_enable_per_port(hw, 0);
8908 
8909 	if (!pf->support_multi_driver)
8910 		i40e_pf_global_rss_reset(pf);
8911 
8912 	/* Reset RETA table */
8913 	if (pf->adapter->rss_reta_updated == 0) {
8914 		ret = i40e_pf_reset_rss_reta(pf);
8915 		if (ret)
8916 			return ret;
8917 	}
8918 
8919 	return i40e_pf_reset_rss_key(pf);
8920 }
8921 
8922 /* Configure RSS */
8923 int
8924 i40e_pf_config_rss(struct i40e_pf *pf)
8925 {
8926 	struct i40e_hw *hw;
8927 	enum rte_eth_rx_mq_mode mq_mode;
8928 	uint64_t rss_hf, hena;
8929 	int ret;
8930 
8931 	ret = i40e_pf_rss_reset(pf);
8932 	if (ret) {
8933 		PMD_DRV_LOG(ERR, "Reset RSS failed, RSS has been disabled");
8934 		return ret;
8935 	}
8936 
8937 	rss_hf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
8938 	mq_mode = pf->dev_data->dev_conf.rxmode.mq_mode;
8939 	if (!(rss_hf & pf->adapter->flow_types_mask) ||
8940 	    !(mq_mode & ETH_MQ_RX_RSS_FLAG))
8941 		return 0;
8942 
8943 	hw = I40E_PF_TO_HW(pf);
8944 	hena = i40e_config_hena(pf->adapter, rss_hf);
8945 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena);
8946 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32));
8947 	I40E_WRITE_FLUSH(hw);
8948 
8949 	return 0;
8950 }
8951 
8952 #define I40E_GL_PRS_FVBM_MSK_ENA 0x80000000
8953 #define I40E_GL_PRS_FVBM(_i)     (0x00269760 + ((_i) * 4))
8954 int
8955 i40e_dev_set_gre_key_len(struct i40e_hw *hw, uint8_t len)
8956 {
8957 	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
8958 	uint32_t val, reg;
8959 	int ret = -EINVAL;
8960 
8961 	if (pf->support_multi_driver) {
8962 		PMD_DRV_LOG(ERR, "GRE key length configuration is unsupported");
8963 		return -ENOTSUP;
8964 	}
8965 
8966 	val = I40E_READ_REG(hw, I40E_GL_PRS_FVBM(2));
8967 	PMD_DRV_LOG(DEBUG, "Read original GL_PRS_FVBM with 0x%08x", val);
8968 
8969 	if (len == 3) {
8970 		reg = val | I40E_GL_PRS_FVBM_MSK_ENA;
8971 	} else if (len == 4) {
8972 		reg = val & ~I40E_GL_PRS_FVBM_MSK_ENA;
8973 	} else {
8974 		PMD_DRV_LOG(ERR, "Unsupported GRE key length of %u", len);
8975 		return ret;
8976 	}
8977 
8978 	if (reg != val) {
8979 		ret = i40e_aq_debug_write_global_register(hw,
8980 						   I40E_GL_PRS_FVBM(2),
8981 						   reg, NULL);
8982 		if (ret != 0)
8983 			return ret;
8984 		PMD_DRV_LOG(DEBUG, "Global register 0x%08x is changed "
8985 			    "with value 0x%08x",
8986 			    I40E_GL_PRS_FVBM(2), reg);
8987 	} else {
8988 		ret = 0;
8989 	}
8990 	PMD_DRV_LOG(DEBUG, "Read modified GL_PRS_FVBM with 0x%08x",
8991 		    I40E_READ_REG(hw, I40E_GL_PRS_FVBM(2)));
8992 
8993 	return ret;
8994 }
8995 
8996 /* Set the symmetric hash enable configurations per port */
8997 void
8998 i40e_set_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t enable)
8999 {
9000 	uint32_t reg = i40e_read_rx_ctl(hw, I40E_PRTQF_CTL_0);
9001 
9002 	if (enable > 0) {
9003 		if (reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK)
9004 			return;
9005 
9006 		reg |= I40E_PRTQF_CTL_0_HSYM_ENA_MASK;
9007 	} else {
9008 		if (!(reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK))
9009 			return;
9010 
9011 		reg &= ~I40E_PRTQF_CTL_0_HSYM_ENA_MASK;
9012 	}
9013 	i40e_write_rx_ctl(hw, I40E_PRTQF_CTL_0, reg);
9014 	I40E_WRITE_FLUSH(hw);
9015 }
9016 
9017 /**
9018  * Valid input sets for hash and flow director filters per PCTYPE
9019  */
9020 static uint64_t
9021 i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
9022 		enum rte_filter_type filter)
9023 {
9024 	uint64_t valid;
9025 
9026 	static const uint64_t valid_hash_inset_table[] = {
9027 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
9028 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9029 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9030 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_SRC |
9031 			I40E_INSET_IPV4_DST | I40E_INSET_IPV4_TOS |
9032 			I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL |
9033 			I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID |
9034 			I40E_INSET_FLEX_PAYLOAD,
9035 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
9036 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9037 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9038 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS |
9039 			I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL |
9040 			I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID |
9041 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9042 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
9043 			I40E_INSET_FLEX_PAYLOAD,
9044 		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
9045 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9046 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9047 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS |
9048 			I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL |
9049 			I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID |
9050 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9051 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
9052 			I40E_INSET_FLEX_PAYLOAD,
9053 		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
9054 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9055 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9056 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS |
9057 			I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL |
9058 			I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID |
9059 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9060 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
9061 			I40E_INSET_FLEX_PAYLOAD,
9062 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
9063 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9064 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9065 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS |
9066 			I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL |
9067 			I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID |
9068 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9069 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
9070 			I40E_INSET_TCP_FLAGS | I40E_INSET_FLEX_PAYLOAD,
9071 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
9072 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9073 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9074 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS |
9075 			I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL |
9076 			I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID |
9077 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9078 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
9079 			I40E_INSET_TCP_FLAGS | I40E_INSET_FLEX_PAYLOAD,
9080 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
9081 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9082 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9083 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS |
9084 			I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL |
9085 			I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID |
9086 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9087 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
9088 			I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD,
9089 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
9090 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9091 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9092 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS |
9093 			I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL |
9094 			I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID |
9095 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9096 			I40E_INSET_FLEX_PAYLOAD,
9097 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
9098 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9099 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9100 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC |
9101 			I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR |
9102 			I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_TUNNEL_DMAC |
9103 			I40E_INSET_TUNNEL_ID | I40E_INSET_IPV6_SRC |
9104 			I40E_INSET_IPV6_DST | I40E_INSET_FLEX_PAYLOAD,
9105 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
9106 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9107 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9108 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC |
9109 			I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR |
9110 			I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC |
9111 			I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT |
9112 			I40E_INSET_DST_PORT | I40E_INSET_FLEX_PAYLOAD,
9113 		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
9114 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9115 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9116 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC |
9117 			I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR |
9118 			I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC |
9119 			I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT |
9120 			I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS |
9121 			I40E_INSET_FLEX_PAYLOAD,
9122 		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
9123 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9124 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9125 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC |
9126 			I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR |
9127 			I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC |
9128 			I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT |
9129 			I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS |
9130 			I40E_INSET_FLEX_PAYLOAD,
9131 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
9132 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9133 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9134 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC |
9135 			I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR |
9136 			I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC |
9137 			I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT |
9138 			I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS |
9139 			I40E_INSET_FLEX_PAYLOAD,
9140 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
9141 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9142 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9143 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC |
9144 			I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR |
9145 			I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC |
9146 			I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT |
9147 			I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS |
9148 			I40E_INSET_FLEX_PAYLOAD,
9149 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
9150 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9151 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9152 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC |
9153 			I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR |
9154 			I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC |
9155 			I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT |
9156 			I40E_INSET_DST_PORT | I40E_INSET_SCTP_VT |
9157 			I40E_INSET_FLEX_PAYLOAD,
9158 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
9159 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9160 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9161 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC |
9162 			I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR |
9163 			I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC |
9164 			I40E_INSET_IPV6_DST | I40E_INSET_TUNNEL_ID |
9165 			I40E_INSET_FLEX_PAYLOAD,
9166 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
9167 			I40E_INSET_DMAC | I40E_INSET_SMAC |
9168 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9169 			I40E_INSET_VLAN_TUNNEL | I40E_INSET_LAST_ETHER_TYPE |
9170 			I40E_INSET_FLEX_PAYLOAD,
9171 	};
9172 
9173 	/**
9174 	 * Flow director supports only fields defined in
9175 	 * union rte_eth_fdir_flow.
9176 	 */
9177 	static const uint64_t valid_fdir_inset_table[] = {
9178 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
9179 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9180 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9181 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
9182 		I40E_INSET_IPV4_TTL,
9183 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
9184 		I40E_INSET_DMAC | I40E_INSET_SMAC |
9185 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9186 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9187 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
9188 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9189 		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
9190 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9191 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9192 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
9193 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9194 		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
9195 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9196 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9197 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
9198 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9199 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
9200 		I40E_INSET_DMAC | I40E_INSET_SMAC |
9201 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9202 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9203 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
9204 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9205 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
9206 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9207 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9208 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
9209 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9210 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
9211 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9212 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9213 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
9214 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
9215 		I40E_INSET_SCTP_VT,
9216 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
9217 		I40E_INSET_DMAC | I40E_INSET_SMAC |
9218 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9219 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9220 		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
9221 		I40E_INSET_IPV4_TTL,
9222 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
9223 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9224 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9225 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
9226 		I40E_INSET_IPV6_HOP_LIMIT,
9227 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
9228 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9229 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9230 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
9231 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9232 		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
9233 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9234 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9235 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
9236 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9237 		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
9238 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9239 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9240 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
9241 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9242 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
9243 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9244 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9245 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
9246 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9247 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
9248 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9249 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9250 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
9251 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9252 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
9253 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9254 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9255 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
9256 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
9257 		I40E_INSET_SCTP_VT,
9258 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
9259 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9260 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9261 		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
9262 		I40E_INSET_IPV6_HOP_LIMIT,
9263 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
9264 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
9265 		I40E_INSET_LAST_ETHER_TYPE,
9266 	};
9267 
9268 	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD)
9269 		return 0;
9270 	if (filter == RTE_ETH_FILTER_HASH)
9271 		valid = valid_hash_inset_table[pctype];
9272 	else
9273 		valid = valid_fdir_inset_table[pctype];
9274 
9275 	return valid;
9276 }
9277 
9278 /**
9279  * Validate if the input set is allowed for a specific PCTYPE
9280  */
9281 int
9282 i40e_validate_input_set(enum i40e_filter_pctype pctype,
9283 		enum rte_filter_type filter, uint64_t inset)
9284 {
9285 	uint64_t valid;
9286 
9287 	valid = i40e_get_valid_input_set(pctype, filter);
9288 	if (inset & (~valid))
9289 		return -EINVAL;
9290 
9291 	return 0;
9292 }
9293 
9294 /* default input set fields combination per pctype */
9295 uint64_t
9296 i40e_get_default_input_set(uint16_t pctype)
9297 {
9298 	static const uint64_t default_inset_table[] = {
9299 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
9300 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
9301 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
9302 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9303 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9304 		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] =
9305 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9306 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9307 		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] =
9308 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9309 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9310 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
9311 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9312 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9313 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] =
9314 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9315 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9316 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
9317 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
9318 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
9319 			I40E_INSET_SCTP_VT,
9320 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
9321 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
9322 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
9323 			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
9324 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
9325 			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9326 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9327 		[I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] =
9328 			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9329 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9330 		[I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] =
9331 			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9332 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9333 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
9334 			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9335 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9336 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] =
9337 			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9338 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
9339 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
9340 			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
9341 			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
9342 			I40E_INSET_SCTP_VT,
9343 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
9344 			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
9345 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
9346 			I40E_INSET_LAST_ETHER_TYPE,
9347 	};
9348 
9349 	if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD)
9350 		return 0;
9351 
9352 	return default_inset_table[pctype];
9353 }
9354 
9355 /**
9356  * Translate the input set from bit masks to register aware bit masks
9357  * and vice versa
9358  */
9359 uint64_t
9360 i40e_translate_input_set_reg(enum i40e_mac_type type, uint64_t input)
9361 {
9362 	uint64_t val = 0;
9363 	uint16_t i;
9364 
9365 	struct inset_map {
9366 		uint64_t inset;
9367 		uint64_t inset_reg;
9368 	};
9369 
9370 	static const struct inset_map inset_map_common[] = {
9371 		{I40E_INSET_DMAC, I40E_REG_INSET_L2_DMAC},
9372 		{I40E_INSET_SMAC, I40E_REG_INSET_L2_SMAC},
9373 		{I40E_INSET_VLAN_OUTER, I40E_REG_INSET_L2_OUTER_VLAN},
9374 		{I40E_INSET_VLAN_INNER, I40E_REG_INSET_L2_INNER_VLAN},
9375 		{I40E_INSET_LAST_ETHER_TYPE, I40E_REG_INSET_LAST_ETHER_TYPE},
9376 		{I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS},
9377 		{I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6},
9378 		{I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6},
9379 		{I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC},
9380 		{I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR},
9381 		{I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT},
9382 		{I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT},
9383 		{I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT},
9384 		{I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG},
9385 		{I40E_INSET_TUNNEL_ID, I40E_REG_INSET_TUNNEL_ID},
9386 		{I40E_INSET_TUNNEL_DMAC,
9387 			I40E_REG_INSET_TUNNEL_L2_INNER_DST_MAC},
9388 		{I40E_INSET_TUNNEL_IPV4_DST, I40E_REG_INSET_TUNNEL_L3_DST_IP4},
9389 		{I40E_INSET_TUNNEL_IPV6_DST, I40E_REG_INSET_TUNNEL_L3_DST_IP6},
9390 		{I40E_INSET_TUNNEL_SRC_PORT,
9391 			I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT},
9392 		{I40E_INSET_TUNNEL_DST_PORT,
9393 			I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT},
9394 		{I40E_INSET_VLAN_TUNNEL, I40E_REG_INSET_TUNNEL_VLAN},
9395 		{I40E_INSET_FLEX_PAYLOAD_W1, I40E_REG_INSET_FLEX_PAYLOAD_WORD1},
9396 		{I40E_INSET_FLEX_PAYLOAD_W2, I40E_REG_INSET_FLEX_PAYLOAD_WORD2},
9397 		{I40E_INSET_FLEX_PAYLOAD_W3, I40E_REG_INSET_FLEX_PAYLOAD_WORD3},
9398 		{I40E_INSET_FLEX_PAYLOAD_W4, I40E_REG_INSET_FLEX_PAYLOAD_WORD4},
9399 		{I40E_INSET_FLEX_PAYLOAD_W5, I40E_REG_INSET_FLEX_PAYLOAD_WORD5},
9400 		{I40E_INSET_FLEX_PAYLOAD_W6, I40E_REG_INSET_FLEX_PAYLOAD_WORD6},
9401 		{I40E_INSET_FLEX_PAYLOAD_W7, I40E_REG_INSET_FLEX_PAYLOAD_WORD7},
9402 		{I40E_INSET_FLEX_PAYLOAD_W8, I40E_REG_INSET_FLEX_PAYLOAD_WORD8},
9403 	};
9404 
9405     /* some different registers map in x722*/
9406 	static const struct inset_map inset_map_diff_x722[] = {
9407 		{I40E_INSET_IPV4_SRC, I40E_X722_REG_INSET_L3_SRC_IP4},
9408 		{I40E_INSET_IPV4_DST, I40E_X722_REG_INSET_L3_DST_IP4},
9409 		{I40E_INSET_IPV4_PROTO, I40E_X722_REG_INSET_L3_IP4_PROTO},
9410 		{I40E_INSET_IPV4_TTL, I40E_X722_REG_INSET_L3_IP4_TTL},
9411 	};
9412 
9413 	static const struct inset_map inset_map_diff_not_x722[] = {
9414 		{I40E_INSET_IPV4_SRC, I40E_REG_INSET_L3_SRC_IP4},
9415 		{I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
9416 		{I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
9417 		{I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
9418 	};
9419 
9420 	if (input == 0)
9421 		return val;
9422 
9423 	/* Translate input set to register aware inset */
9424 	if (type == I40E_MAC_X722) {
9425 		for (i = 0; i < RTE_DIM(inset_map_diff_x722); i++) {
9426 			if (input & inset_map_diff_x722[i].inset)
9427 				val |= inset_map_diff_x722[i].inset_reg;
9428 		}
9429 	} else {
9430 		for (i = 0; i < RTE_DIM(inset_map_diff_not_x722); i++) {
9431 			if (input & inset_map_diff_not_x722[i].inset)
9432 				val |= inset_map_diff_not_x722[i].inset_reg;
9433 		}
9434 	}
9435 
9436 	for (i = 0; i < RTE_DIM(inset_map_common); i++) {
9437 		if (input & inset_map_common[i].inset)
9438 			val |= inset_map_common[i].inset_reg;
9439 	}
9440 
9441 	return val;
9442 }
9443 
9444 static int
9445 i40e_get_inset_field_offset(struct i40e_hw *hw, uint32_t pit_reg_start,
9446 			    uint32_t pit_reg_count, uint32_t hdr_off)
9447 {
9448 	const uint32_t pit_reg_end = pit_reg_start + pit_reg_count;
9449 	uint32_t field_off = I40E_FDIR_FIELD_OFFSET(hdr_off);
9450 	uint32_t i, reg_val, src_off, count;
9451 
9452 	for (i = pit_reg_start; i < pit_reg_end; i++) {
9453 		reg_val = i40e_read_rx_ctl(hw, I40E_GLQF_PIT(i));
9454 
9455 		src_off = I40E_GLQF_PIT_SOURCE_OFF_GET(reg_val);
9456 		count = I40E_GLQF_PIT_FSIZE_GET(reg_val);
9457 
9458 		if (src_off <= field_off && (src_off + count) > field_off)
9459 			break;
9460 	}
9461 
9462 	if (i >= pit_reg_end) {
9463 		PMD_DRV_LOG(ERR,
9464 			    "Hardware GLQF_PIT configuration does not support this field mask");
9465 		return -1;
9466 	}
9467 
9468 	return I40E_GLQF_PIT_DEST_OFF_GET(reg_val) + field_off - src_off;
9469 }
9470 
9471 int
9472 i40e_generate_inset_mask_reg(struct i40e_hw *hw, uint64_t inset,
9473 			     uint32_t *mask, uint8_t nb_elem)
9474 {
9475 	static const uint64_t mask_inset[] = {
9476 		I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL,
9477 		I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT };
9478 
9479 	static const struct {
9480 		uint64_t inset;
9481 		uint32_t mask;
9482 		uint32_t offset;
9483 	} inset_mask_offset_map[] = {
9484 		{ I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK,
9485 		  offsetof(struct rte_ipv4_hdr, type_of_service) },
9486 
9487 		{ I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK,
9488 		  offsetof(struct rte_ipv4_hdr, next_proto_id) },
9489 
9490 		{ I40E_INSET_IPV4_TTL, I40E_INSET_IPV4_TTL_MASK,
9491 		  offsetof(struct rte_ipv4_hdr, time_to_live) },
9492 
9493 		{ I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK,
9494 		  offsetof(struct rte_ipv6_hdr, vtc_flow) },
9495 
9496 		{ I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK,
9497 		  offsetof(struct rte_ipv6_hdr, proto) },
9498 
9499 		{ I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK,
9500 		  offsetof(struct rte_ipv6_hdr, hop_limits) },
9501 	};
9502 
9503 	uint32_t i;
9504 	int idx = 0;
9505 
9506 	assert(mask);
9507 	if (!inset)
9508 		return 0;
9509 
9510 	for (i = 0; i < RTE_DIM(mask_inset); i++) {
9511 		/* Clear the inset bit, if no MASK is required,
9512 		 * for example proto + ttl
9513 		 */
9514 		if ((mask_inset[i] & inset) == mask_inset[i]) {
9515 			inset &= ~mask_inset[i];
9516 			if (!inset)
9517 				return 0;
9518 		}
9519 	}
9520 
9521 	for (i = 0; i < RTE_DIM(inset_mask_offset_map); i++) {
9522 		uint32_t pit_start, pit_count;
9523 		int offset;
9524 
9525 		if (!(inset_mask_offset_map[i].inset & inset))
9526 			continue;
9527 
9528 		if (inset_mask_offset_map[i].inset &
9529 		    (I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
9530 		     I40E_INSET_IPV4_TTL)) {
9531 			pit_start = I40E_GLQF_PIT_IPV4_START;
9532 			pit_count = I40E_GLQF_PIT_IPV4_COUNT;
9533 		} else {
9534 			pit_start = I40E_GLQF_PIT_IPV6_START;
9535 			pit_count = I40E_GLQF_PIT_IPV6_COUNT;
9536 		}
9537 
9538 		offset = i40e_get_inset_field_offset(hw, pit_start, pit_count,
9539 				inset_mask_offset_map[i].offset);
9540 
9541 		if (offset < 0)
9542 			return -EINVAL;
9543 
9544 		if (idx >= nb_elem) {
9545 			PMD_DRV_LOG(ERR,
9546 				    "Configuration of inset mask out of range %u",
9547 				    nb_elem);
9548 			return -ERANGE;
9549 		}
9550 
9551 		mask[idx] = I40E_GLQF_PIT_BUILD((uint32_t)offset,
9552 						inset_mask_offset_map[i].mask);
9553 		idx++;
9554 	}
9555 
9556 	return idx;
9557 }
9558 
9559 void
9560 i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
9561 {
9562 	uint32_t reg = i40e_read_rx_ctl(hw, addr);
9563 
9564 	PMD_DRV_LOG(DEBUG, "[0x%08x] original: 0x%08x", addr, reg);
9565 	if (reg != val)
9566 		i40e_write_rx_ctl(hw, addr, val);
9567 	PMD_DRV_LOG(DEBUG, "[0x%08x] after: 0x%08x", addr,
9568 		    (uint32_t)i40e_read_rx_ctl(hw, addr));
9569 }
9570 
9571 void
9572 i40e_check_write_global_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val)
9573 {
9574 	uint32_t reg = i40e_read_rx_ctl(hw, addr);
9575 	struct rte_eth_dev *dev;
9576 
9577 	dev = ((struct i40e_adapter *)hw->back)->eth_dev;
9578 	if (reg != val) {
9579 		i40e_write_rx_ctl(hw, addr, val);
9580 		PMD_DRV_LOG(WARNING,
9581 			    "i40e device %s changed global register [0x%08x]."
9582 			    " original: 0x%08x, new: 0x%08x",
9583 			    dev->device->name, addr, reg,
9584 			    (uint32_t)i40e_read_rx_ctl(hw, addr));
9585 	}
9586 }
9587 
9588 static void
9589 i40e_filter_input_set_init(struct i40e_pf *pf)
9590 {
9591 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
9592 	enum i40e_filter_pctype pctype;
9593 	uint64_t input_set, inset_reg;
9594 	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
9595 	int num, i;
9596 	uint16_t flow_type;
9597 
9598 	for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
9599 	     pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) {
9600 		flow_type = i40e_pctype_to_flowtype(pf->adapter, pctype);
9601 
9602 		if (flow_type == RTE_ETH_FLOW_UNKNOWN)
9603 			continue;
9604 
9605 		input_set = i40e_get_default_input_set(pctype);
9606 
9607 		num = i40e_generate_inset_mask_reg(hw, input_set, mask_reg,
9608 						   I40E_INSET_MASK_NUM_REG);
9609 		if (num < 0)
9610 			return;
9611 		if (pf->support_multi_driver && num > 0) {
9612 			PMD_DRV_LOG(ERR, "Input set setting is not supported.");
9613 			return;
9614 		}
9615 		inset_reg = i40e_translate_input_set_reg(hw->mac.type,
9616 					input_set);
9617 
9618 		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
9619 				      (uint32_t)(inset_reg & UINT32_MAX));
9620 		i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
9621 				     (uint32_t)((inset_reg >>
9622 				     I40E_32_BIT_WIDTH) & UINT32_MAX));
9623 		if (!pf->support_multi_driver) {
9624 			i40e_check_write_global_reg(hw,
9625 					    I40E_GLQF_HASH_INSET(0, pctype),
9626 					    (uint32_t)(inset_reg & UINT32_MAX));
9627 			i40e_check_write_global_reg(hw,
9628 					     I40E_GLQF_HASH_INSET(1, pctype),
9629 					     (uint32_t)((inset_reg >>
9630 					      I40E_32_BIT_WIDTH) & UINT32_MAX));
9631 
9632 			for (i = 0; i < num; i++) {
9633 				i40e_check_write_global_reg(hw,
9634 						    I40E_GLQF_FD_MSK(i, pctype),
9635 						    mask_reg[i]);
9636 				i40e_check_write_global_reg(hw,
9637 						  I40E_GLQF_HASH_MSK(i, pctype),
9638 						  mask_reg[i]);
9639 			}
9640 			/*clear unused mask registers of the pctype */
9641 			for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
9642 				i40e_check_write_global_reg(hw,
9643 						    I40E_GLQF_FD_MSK(i, pctype),
9644 						    0);
9645 				i40e_check_write_global_reg(hw,
9646 						  I40E_GLQF_HASH_MSK(i, pctype),
9647 						  0);
9648 			}
9649 		} else {
9650 			PMD_DRV_LOG(ERR, "Input set setting is not supported.");
9651 		}
9652 		I40E_WRITE_FLUSH(hw);
9653 
9654 		/* store the default input set */
9655 		if (!pf->support_multi_driver)
9656 			pf->hash_input_set[pctype] = input_set;
9657 		pf->fdir.input_set[pctype] = input_set;
9658 	}
9659 }
9660 
9661 int
9662 i40e_set_hash_inset(struct i40e_hw *hw, uint64_t input_set,
9663 		    uint32_t pctype, bool add)
9664 {
9665 	struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
9666 	uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0};
9667 	uint64_t inset_reg = 0;
9668 	int num, i;
9669 
9670 	if (pf->support_multi_driver) {
9671 		PMD_DRV_LOG(ERR,
9672 			    "Modify input set is not permitted when multi-driver enabled.");
9673 		return -EPERM;
9674 	}
9675 
9676 	/* For X722, get translated pctype in fd pctype register */
9677 	if (hw->mac.type == I40E_MAC_X722)
9678 		pctype = i40e_read_rx_ctl(hw, I40E_GLQF_FD_PCTYPES(pctype));
9679 
9680 	if (add) {
9681 		/* get inset value in register */
9682 		inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
9683 		inset_reg <<= I40E_32_BIT_WIDTH;
9684 		inset_reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
9685 		input_set |= pf->hash_input_set[pctype];
9686 	}
9687 	num = i40e_generate_inset_mask_reg(hw, input_set, mask_reg,
9688 					   I40E_INSET_MASK_NUM_REG);
9689 	if (num < 0)
9690 		return -EINVAL;
9691 
9692 	inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set);
9693 
9694 	i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
9695 				    (uint32_t)(inset_reg & UINT32_MAX));
9696 	i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
9697 				    (uint32_t)((inset_reg >>
9698 				    I40E_32_BIT_WIDTH) & UINT32_MAX));
9699 
9700 	for (i = 0; i < num; i++)
9701 		i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
9702 					    mask_reg[i]);
9703 	/*clear unused mask registers of the pctype */
9704 	for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
9705 		i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype),
9706 					    0);
9707 	I40E_WRITE_FLUSH(hw);
9708 
9709 	pf->hash_input_set[pctype] = input_set;
9710 	return 0;
9711 }
9712 
9713 /* Convert ethertype filter structure */
9714 static int
9715 i40e_ethertype_filter_convert(const struct rte_eth_ethertype_filter *input,
9716 			      struct i40e_ethertype_filter *filter)
9717 {
9718 	rte_memcpy(&filter->input.mac_addr, &input->mac_addr,
9719 		RTE_ETHER_ADDR_LEN);
9720 	filter->input.ether_type = input->ether_type;
9721 	filter->flags = input->flags;
9722 	filter->queue = input->queue;
9723 
9724 	return 0;
9725 }
9726 
9727 /* Check if there exists the ehtertype filter */
9728 struct i40e_ethertype_filter *
9729 i40e_sw_ethertype_filter_lookup(struct i40e_ethertype_rule *ethertype_rule,
9730 				const struct i40e_ethertype_filter_input *input)
9731 {
9732 	int ret;
9733 
9734 	ret = rte_hash_lookup(ethertype_rule->hash_table, (const void *)input);
9735 	if (ret < 0)
9736 		return NULL;
9737 
9738 	return ethertype_rule->hash_map[ret];
9739 }
9740 
9741 /* Add ethertype filter in SW list */
9742 static int
9743 i40e_sw_ethertype_filter_insert(struct i40e_pf *pf,
9744 				struct i40e_ethertype_filter *filter)
9745 {
9746 	struct i40e_ethertype_rule *rule = &pf->ethertype;
9747 	int ret;
9748 
9749 	ret = rte_hash_add_key(rule->hash_table, &filter->input);
9750 	if (ret < 0) {
9751 		PMD_DRV_LOG(ERR,
9752 			    "Failed to insert ethertype filter"
9753 			    " to hash table %d!",
9754 			    ret);
9755 		return ret;
9756 	}
9757 	rule->hash_map[ret] = filter;
9758 
9759 	TAILQ_INSERT_TAIL(&rule->ethertype_list, filter, rules);
9760 
9761 	return 0;
9762 }
9763 
9764 /* Delete ethertype filter in SW list */
9765 int
9766 i40e_sw_ethertype_filter_del(struct i40e_pf *pf,
9767 			     struct i40e_ethertype_filter_input *input)
9768 {
9769 	struct i40e_ethertype_rule *rule = &pf->ethertype;
9770 	struct i40e_ethertype_filter *filter;
9771 	int ret;
9772 
9773 	ret = rte_hash_del_key(rule->hash_table, input);
9774 	if (ret < 0) {
9775 		PMD_DRV_LOG(ERR,
9776 			    "Failed to delete ethertype filter"
9777 			    " to hash table %d!",
9778 			    ret);
9779 		return ret;
9780 	}
9781 	filter = rule->hash_map[ret];
9782 	rule->hash_map[ret] = NULL;
9783 
9784 	TAILQ_REMOVE(&rule->ethertype_list, filter, rules);
9785 	rte_free(filter);
9786 
9787 	return 0;
9788 }
9789 
9790 /*
9791  * Configure ethertype filter, which can director packet by filtering
9792  * with mac address and ether_type or only ether_type
9793  */
9794 int
9795 i40e_ethertype_filter_set(struct i40e_pf *pf,
9796 			struct rte_eth_ethertype_filter *filter,
9797 			bool add)
9798 {
9799 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
9800 	struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype;
9801 	struct i40e_ethertype_filter *ethertype_filter, *node;
9802 	struct i40e_ethertype_filter check_filter;
9803 	struct i40e_control_filter_stats stats;
9804 	uint16_t flags = 0;
9805 	int ret;
9806 
9807 	if (filter->queue >= pf->dev_data->nb_rx_queues) {
9808 		PMD_DRV_LOG(ERR, "Invalid queue ID");
9809 		return -EINVAL;
9810 	}
9811 	if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
9812 		filter->ether_type == RTE_ETHER_TYPE_IPV6) {
9813 		PMD_DRV_LOG(ERR,
9814 			"unsupported ether_type(0x%04x) in control packet filter.",
9815 			filter->ether_type);
9816 		return -EINVAL;
9817 	}
9818 	if (filter->ether_type == RTE_ETHER_TYPE_VLAN)
9819 		PMD_DRV_LOG(WARNING,
9820 			"filter vlan ether_type in first tag is not supported.");
9821 
9822 	/* Check if there is the filter in SW list */
9823 	memset(&check_filter, 0, sizeof(check_filter));
9824 	i40e_ethertype_filter_convert(filter, &check_filter);
9825 	node = i40e_sw_ethertype_filter_lookup(ethertype_rule,
9826 					       &check_filter.input);
9827 	if (add && node) {
9828 		PMD_DRV_LOG(ERR, "Conflict with existing ethertype rules!");
9829 		return -EINVAL;
9830 	}
9831 
9832 	if (!add && !node) {
9833 		PMD_DRV_LOG(ERR, "There's no corresponding ethertype filter!");
9834 		return -EINVAL;
9835 	}
9836 
9837 	if (!(filter->flags & RTE_ETHTYPE_FLAGS_MAC))
9838 		flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC;
9839 	if (filter->flags & RTE_ETHTYPE_FLAGS_DROP)
9840 		flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP;
9841 	flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE;
9842 
9843 	memset(&stats, 0, sizeof(stats));
9844 	ret = i40e_aq_add_rem_control_packet_filter(hw,
9845 			filter->mac_addr.addr_bytes,
9846 			filter->ether_type, flags,
9847 			pf->main_vsi->seid,
9848 			filter->queue, add, &stats, NULL);
9849 
9850 	PMD_DRV_LOG(INFO,
9851 		"add/rem control packet filter, return %d, mac_etype_used = %u, etype_used = %u, mac_etype_free = %u, etype_free = %u",
9852 		ret, stats.mac_etype_used, stats.etype_used,
9853 		stats.mac_etype_free, stats.etype_free);
9854 	if (ret < 0)
9855 		return -ENOSYS;
9856 
9857 	/* Add or delete a filter in SW list */
9858 	if (add) {
9859 		ethertype_filter = rte_zmalloc("ethertype_filter",
9860 				       sizeof(*ethertype_filter), 0);
9861 		if (ethertype_filter == NULL) {
9862 			PMD_DRV_LOG(ERR, "Failed to alloc memory.");
9863 			return -ENOMEM;
9864 		}
9865 
9866 		rte_memcpy(ethertype_filter, &check_filter,
9867 			   sizeof(check_filter));
9868 		ret = i40e_sw_ethertype_filter_insert(pf, ethertype_filter);
9869 		if (ret < 0)
9870 			rte_free(ethertype_filter);
9871 	} else {
9872 		ret = i40e_sw_ethertype_filter_del(pf, &node->input);
9873 	}
9874 
9875 	return ret;
9876 }
9877 
9878 static int
9879 i40e_dev_flow_ops_get(struct rte_eth_dev *dev,
9880 		      const struct rte_flow_ops **ops)
9881 {
9882 	if (dev == NULL)
9883 		return -EINVAL;
9884 
9885 	*ops = &i40e_flow_ops;
9886 	return 0;
9887 }
9888 
9889 /*
9890  * Check and enable Extended Tag.
9891  * Enabling Extended Tag is important for 40G performance.
9892  */
9893 static void
9894 i40e_enable_extended_tag(struct rte_eth_dev *dev)
9895 {
9896 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
9897 	uint32_t buf = 0;
9898 	int ret;
9899 
9900 	ret = rte_pci_read_config(pci_dev, &buf, sizeof(buf),
9901 				      PCI_DEV_CAP_REG);
9902 	if (ret < 0) {
9903 		PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x",
9904 			    PCI_DEV_CAP_REG);
9905 		return;
9906 	}
9907 	if (!(buf & PCI_DEV_CAP_EXT_TAG_MASK)) {
9908 		PMD_DRV_LOG(ERR, "Does not support Extended Tag");
9909 		return;
9910 	}
9911 
9912 	buf = 0;
9913 	ret = rte_pci_read_config(pci_dev, &buf, sizeof(buf),
9914 				      PCI_DEV_CTRL_REG);
9915 	if (ret < 0) {
9916 		PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x",
9917 			    PCI_DEV_CTRL_REG);
9918 		return;
9919 	}
9920 	if (buf & PCI_DEV_CTRL_EXT_TAG_MASK) {
9921 		PMD_DRV_LOG(DEBUG, "Extended Tag has already been enabled");
9922 		return;
9923 	}
9924 	buf |= PCI_DEV_CTRL_EXT_TAG_MASK;
9925 	ret = rte_pci_write_config(pci_dev, &buf, sizeof(buf),
9926 				       PCI_DEV_CTRL_REG);
9927 	if (ret < 0) {
9928 		PMD_DRV_LOG(ERR, "Failed to write PCI offset 0x%x",
9929 			    PCI_DEV_CTRL_REG);
9930 		return;
9931 	}
9932 }
9933 
9934 /*
9935  * As some registers wouldn't be reset unless a global hardware reset,
9936  * hardware initialization is needed to put those registers into an
9937  * expected initial state.
9938  */
9939 static void
9940 i40e_hw_init(struct rte_eth_dev *dev)
9941 {
9942 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
9943 
9944 	i40e_enable_extended_tag(dev);
9945 
9946 	/* clear the PF Queue Filter control register */
9947 	i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, 0);
9948 
9949 	/* Disable symmetric hash per port */
9950 	i40e_set_symmetric_hash_enable_per_port(hw, 0);
9951 }
9952 
9953 /*
9954  * For X722 it is possible to have multiple pctypes mapped to the same flowtype
9955  * however this function will return only one highest pctype index,
9956  * which is not quite correct. This is known problem of i40e driver
9957  * and needs to be fixed later.
9958  */
9959 enum i40e_filter_pctype
9960 i40e_flowtype_to_pctype(const struct i40e_adapter *adapter, uint16_t flow_type)
9961 {
9962 	int i;
9963 	uint64_t pctype_mask;
9964 
9965 	if (flow_type < I40E_FLOW_TYPE_MAX) {
9966 		pctype_mask = adapter->pctypes_tbl[flow_type];
9967 		for (i = I40E_FILTER_PCTYPE_MAX - 1; i > 0; i--) {
9968 			if (pctype_mask & (1ULL << i))
9969 				return (enum i40e_filter_pctype)i;
9970 		}
9971 	}
9972 	return I40E_FILTER_PCTYPE_INVALID;
9973 }
9974 
9975 uint16_t
9976 i40e_pctype_to_flowtype(const struct i40e_adapter *adapter,
9977 			enum i40e_filter_pctype pctype)
9978 {
9979 	uint16_t flowtype;
9980 	uint64_t pctype_mask = 1ULL << pctype;
9981 
9982 	for (flowtype = RTE_ETH_FLOW_UNKNOWN + 1; flowtype < I40E_FLOW_TYPE_MAX;
9983 	     flowtype++) {
9984 		if (adapter->pctypes_tbl[flowtype] & pctype_mask)
9985 			return flowtype;
9986 	}
9987 
9988 	return RTE_ETH_FLOW_UNKNOWN;
9989 }
9990 
9991 /*
9992  * On X710, performance number is far from the expectation on recent firmware
9993  * versions; on XL710, performance number is also far from the expectation on
9994  * recent firmware versions, if promiscuous mode is disabled, or promiscuous
9995  * mode is enabled and port MAC address is equal to the packet destination MAC
9996  * address. The fix for this issue may not be integrated in the following
9997  * firmware version. So the workaround in software driver is needed. It needs
9998  * to modify the initial values of 3 internal only registers for both X710 and
9999  * XL710. Note that the values for X710 or XL710 could be different, and the
10000  * workaround can be removed when it is fixed in firmware in the future.
10001  */
10002 
10003 /* For both X710 and XL710 */
10004 #define I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_1	0x10000200
10005 #define I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_2	0x203F0200
10006 #define I40E_GL_SWR_PRI_JOIN_MAP_0		0x26CE00
10007 
10008 #define I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE 0x011f0200
10009 #define I40E_GL_SWR_PRI_JOIN_MAP_2       0x26CE08
10010 
10011 /* For X722 */
10012 #define I40E_X722_GL_SWR_PRI_JOIN_MAP_0_VALUE 0x20000200
10013 #define I40E_X722_GL_SWR_PRI_JOIN_MAP_2_VALUE 0x013F0200
10014 
10015 /* For X710 */
10016 #define I40E_GL_SWR_PM_UP_THR_EF_VALUE   0x03030303
10017 /* For XL710 */
10018 #define I40E_GL_SWR_PM_UP_THR_SF_VALUE   0x06060606
10019 #define I40E_GL_SWR_PM_UP_THR            0x269FBC
10020 
10021 /*
10022  * GL_SWR_PM_UP_THR:
10023  * The value is not impacted from the link speed, its value is set according
10024  * to the total number of ports for a better pipe-monitor configuration.
10025  */
10026 static bool
10027 i40e_get_swr_pm_cfg(struct i40e_hw *hw, uint32_t *value)
10028 {
10029 #define I40E_GL_SWR_PM_EF_DEVICE(dev) \
10030 		.device_id = (dev),   \
10031 		.val = I40E_GL_SWR_PM_UP_THR_EF_VALUE
10032 
10033 #define I40E_GL_SWR_PM_SF_DEVICE(dev) \
10034 		.device_id = (dev),   \
10035 		.val = I40E_GL_SWR_PM_UP_THR_SF_VALUE
10036 
10037 	static const struct {
10038 		uint16_t device_id;
10039 		uint32_t val;
10040 	} swr_pm_table[] = {
10041 		{ I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_SFP_XL710) },
10042 		{ I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_KX_C) },
10043 		{ I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T) },
10044 		{ I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T4) },
10045 		{ I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_SFP_X722) },
10046 
10047 		{ I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_KX_B) },
10048 		{ I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_A) },
10049 		{ I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_B) },
10050 		{ I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_20G_KR2) },
10051 		{ I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_20G_KR2_A) },
10052 		{ I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_25G_B) },
10053 		{ I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_25G_SFP28) },
10054 	};
10055 	uint32_t i;
10056 
10057 	if (value == NULL) {
10058 		PMD_DRV_LOG(ERR, "value is NULL");
10059 		return false;
10060 	}
10061 
10062 	for (i = 0; i < RTE_DIM(swr_pm_table); i++) {
10063 		if (hw->device_id == swr_pm_table[i].device_id) {
10064 			*value = swr_pm_table[i].val;
10065 
10066 			PMD_DRV_LOG(DEBUG, "Device 0x%x with GL_SWR_PM_UP_THR "
10067 				    "value - 0x%08x",
10068 				    hw->device_id, *value);
10069 			return true;
10070 		}
10071 	}
10072 
10073 	return false;
10074 }
10075 
10076 static int
10077 i40e_dev_sync_phy_type(struct i40e_hw *hw)
10078 {
10079 	enum i40e_status_code status;
10080 	struct i40e_aq_get_phy_abilities_resp phy_ab;
10081 	int ret = -ENOTSUP;
10082 	int retries = 0;
10083 
10084 	status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_ab,
10085 					      NULL);
10086 
10087 	while (status) {
10088 		PMD_INIT_LOG(WARNING, "Failed to sync phy type: status=%d",
10089 			status);
10090 		retries++;
10091 		rte_delay_us(100000);
10092 		if  (retries < 5)
10093 			status = i40e_aq_get_phy_capabilities(hw, false,
10094 					true, &phy_ab, NULL);
10095 		else
10096 			return ret;
10097 	}
10098 	return 0;
10099 }
10100 
10101 static void
10102 i40e_configure_registers(struct i40e_hw *hw)
10103 {
10104 	static struct {
10105 		uint32_t addr;
10106 		uint64_t val;
10107 	} reg_table[] = {
10108 		{I40E_GL_SWR_PRI_JOIN_MAP_0, 0},
10109 		{I40E_GL_SWR_PRI_JOIN_MAP_2, 0},
10110 		{I40E_GL_SWR_PM_UP_THR, 0}, /* Compute value dynamically */
10111 	};
10112 	uint64_t reg;
10113 	uint32_t i;
10114 	int ret;
10115 
10116 	for (i = 0; i < RTE_DIM(reg_table); i++) {
10117 		if (reg_table[i].addr == I40E_GL_SWR_PRI_JOIN_MAP_0) {
10118 			if (hw->mac.type == I40E_MAC_X722) /* For X722 */
10119 				reg_table[i].val =
10120 					I40E_X722_GL_SWR_PRI_JOIN_MAP_0_VALUE;
10121 			else /* For X710/XL710/XXV710 */
10122 				if (hw->aq.fw_maj_ver < 6)
10123 					reg_table[i].val =
10124 					     I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_1;
10125 				else
10126 					reg_table[i].val =
10127 					     I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_2;
10128 		}
10129 
10130 		if (reg_table[i].addr == I40E_GL_SWR_PRI_JOIN_MAP_2) {
10131 			if (hw->mac.type == I40E_MAC_X722) /* For X722 */
10132 				reg_table[i].val =
10133 					I40E_X722_GL_SWR_PRI_JOIN_MAP_2_VALUE;
10134 			else /* For X710/XL710/XXV710 */
10135 				reg_table[i].val =
10136 					I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE;
10137 		}
10138 
10139 		if (reg_table[i].addr == I40E_GL_SWR_PM_UP_THR) {
10140 			uint32_t cfg_val;
10141 
10142 			if (!i40e_get_swr_pm_cfg(hw, &cfg_val)) {
10143 				PMD_DRV_LOG(DEBUG, "Device 0x%x skips "
10144 					    "GL_SWR_PM_UP_THR value fixup",
10145 					    hw->device_id);
10146 				continue;
10147 			}
10148 
10149 			reg_table[i].val = cfg_val;
10150 		}
10151 
10152 		ret = i40e_aq_debug_read_register(hw, reg_table[i].addr,
10153 							&reg, NULL);
10154 		if (ret < 0) {
10155 			PMD_DRV_LOG(ERR, "Failed to read from 0x%"PRIx32,
10156 							reg_table[i].addr);
10157 			break;
10158 		}
10159 		PMD_DRV_LOG(DEBUG, "Read from 0x%"PRIx32": 0x%"PRIx64,
10160 						reg_table[i].addr, reg);
10161 		if (reg == reg_table[i].val)
10162 			continue;
10163 
10164 		ret = i40e_aq_debug_write_register(hw, reg_table[i].addr,
10165 						reg_table[i].val, NULL);
10166 		if (ret < 0) {
10167 			PMD_DRV_LOG(ERR,
10168 				"Failed to write 0x%"PRIx64" to the address of 0x%"PRIx32,
10169 				reg_table[i].val, reg_table[i].addr);
10170 			break;
10171 		}
10172 		PMD_DRV_LOG(DEBUG, "Write 0x%"PRIx64" to the address of "
10173 			"0x%"PRIx32, reg_table[i].val, reg_table[i].addr);
10174 	}
10175 }
10176 
10177 #define I40E_VSI_TSR_QINQ_CONFIG    0xc030
10178 #define I40E_VSI_L2TAGSTXVALID(_i)  (0x00042800 + ((_i) * 4))
10179 #define I40E_VSI_L2TAGSTXVALID_QINQ 0xab
10180 static int
10181 i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi)
10182 {
10183 	uint32_t reg;
10184 	int ret;
10185 
10186 	if (vsi->vsi_id >= I40E_MAX_NUM_VSIS) {
10187 		PMD_DRV_LOG(ERR, "VSI ID exceeds the maximum");
10188 		return -EINVAL;
10189 	}
10190 
10191 	/* Configure for double VLAN RX stripping */
10192 	reg = I40E_READ_REG(hw, I40E_VSI_TSR(vsi->vsi_id));
10193 	if ((reg & I40E_VSI_TSR_QINQ_CONFIG) != I40E_VSI_TSR_QINQ_CONFIG) {
10194 		reg |= I40E_VSI_TSR_QINQ_CONFIG;
10195 		ret = i40e_aq_debug_write_register(hw,
10196 						   I40E_VSI_TSR(vsi->vsi_id),
10197 						   reg, NULL);
10198 		if (ret < 0) {
10199 			PMD_DRV_LOG(ERR, "Failed to update VSI_TSR[%d]",
10200 				    vsi->vsi_id);
10201 			return I40E_ERR_CONFIG;
10202 		}
10203 	}
10204 
10205 	/* Configure for double VLAN TX insertion */
10206 	reg = I40E_READ_REG(hw, I40E_VSI_L2TAGSTXVALID(vsi->vsi_id));
10207 	if ((reg & 0xff) != I40E_VSI_L2TAGSTXVALID_QINQ) {
10208 		reg = I40E_VSI_L2TAGSTXVALID_QINQ;
10209 		ret = i40e_aq_debug_write_register(hw,
10210 						   I40E_VSI_L2TAGSTXVALID(
10211 						   vsi->vsi_id), reg, NULL);
10212 		if (ret < 0) {
10213 			PMD_DRV_LOG(ERR,
10214 				"Failed to update VSI_L2TAGSTXVALID[%d]",
10215 				vsi->vsi_id);
10216 			return I40E_ERR_CONFIG;
10217 		}
10218 	}
10219 
10220 	return 0;
10221 }
10222 
10223 /**
10224  * i40e_aq_add_mirror_rule
10225  * @hw: pointer to the hardware structure
10226  * @seid: VEB seid to add mirror rule to
10227  * @dst_id: destination vsi seid
10228  * @entries: Buffer which contains the entities to be mirrored
10229  * @count: number of entities contained in the buffer
10230  * @rule_id:the rule_id of the rule to be added
10231  *
10232  * Add a mirror rule for a given veb.
10233  *
10234  **/
10235 static enum i40e_status_code
10236 i40e_aq_add_mirror_rule(struct i40e_hw *hw,
10237 			uint16_t seid, uint16_t dst_id,
10238 			uint16_t rule_type, uint16_t *entries,
10239 			uint16_t count, uint16_t *rule_id)
10240 {
10241 	struct i40e_aq_desc desc;
10242 	struct i40e_aqc_add_delete_mirror_rule cmd;
10243 	struct i40e_aqc_add_delete_mirror_rule_completion *resp =
10244 		(struct i40e_aqc_add_delete_mirror_rule_completion *)
10245 		&desc.params.raw;
10246 	uint16_t buff_len;
10247 	enum i40e_status_code status;
10248 
10249 	i40e_fill_default_direct_cmd_desc(&desc,
10250 					  i40e_aqc_opc_add_mirror_rule);
10251 	memset(&cmd, 0, sizeof(cmd));
10252 
10253 	buff_len = sizeof(uint16_t) * count;
10254 	desc.datalen = rte_cpu_to_le_16(buff_len);
10255 	if (buff_len > 0)
10256 		desc.flags |= rte_cpu_to_le_16(
10257 			(uint16_t)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
10258 	cmd.rule_type = rte_cpu_to_le_16(rule_type <<
10259 				I40E_AQC_MIRROR_RULE_TYPE_SHIFT);
10260 	cmd.num_entries = rte_cpu_to_le_16(count);
10261 	cmd.seid = rte_cpu_to_le_16(seid);
10262 	cmd.destination = rte_cpu_to_le_16(dst_id);
10263 
10264 	rte_memcpy(&desc.params.raw, &cmd, sizeof(cmd));
10265 	status = i40e_asq_send_command(hw, &desc, entries, buff_len, NULL);
10266 	PMD_DRV_LOG(INFO,
10267 		"i40e_aq_add_mirror_rule, aq_status %d, rule_id = %u mirror_rules_used = %u, mirror_rules_free = %u,",
10268 		hw->aq.asq_last_status, resp->rule_id,
10269 		resp->mirror_rules_used, resp->mirror_rules_free);
10270 	*rule_id = rte_le_to_cpu_16(resp->rule_id);
10271 
10272 	return status;
10273 }
10274 
10275 /**
10276  * i40e_aq_del_mirror_rule
10277  * @hw: pointer to the hardware structure
10278  * @seid: VEB seid to add mirror rule to
10279  * @entries: Buffer which contains the entities to be mirrored
10280  * @count: number of entities contained in the buffer
10281  * @rule_id:the rule_id of the rule to be delete
10282  *
10283  * Delete a mirror rule for a given veb.
10284  *
10285  **/
10286 static enum i40e_status_code
10287 i40e_aq_del_mirror_rule(struct i40e_hw *hw,
10288 		uint16_t seid, uint16_t rule_type, uint16_t *entries,
10289 		uint16_t count, uint16_t rule_id)
10290 {
10291 	struct i40e_aq_desc desc;
10292 	struct i40e_aqc_add_delete_mirror_rule cmd;
10293 	uint16_t buff_len = 0;
10294 	enum i40e_status_code status;
10295 	void *buff = NULL;
10296 
10297 	i40e_fill_default_direct_cmd_desc(&desc,
10298 					  i40e_aqc_opc_delete_mirror_rule);
10299 	memset(&cmd, 0, sizeof(cmd));
10300 	if (rule_type == I40E_AQC_MIRROR_RULE_TYPE_VLAN) {
10301 		desc.flags |= rte_cpu_to_le_16((uint16_t)(I40E_AQ_FLAG_BUF |
10302 							  I40E_AQ_FLAG_RD));
10303 		cmd.num_entries = count;
10304 		buff_len = sizeof(uint16_t) * count;
10305 		desc.datalen = rte_cpu_to_le_16(buff_len);
10306 		buff = (void *)entries;
10307 	} else
10308 		/* rule id is filled in destination field for deleting mirror rule */
10309 		cmd.destination = rte_cpu_to_le_16(rule_id);
10310 
10311 	cmd.rule_type = rte_cpu_to_le_16(rule_type <<
10312 				I40E_AQC_MIRROR_RULE_TYPE_SHIFT);
10313 	cmd.seid = rte_cpu_to_le_16(seid);
10314 
10315 	rte_memcpy(&desc.params.raw, &cmd, sizeof(cmd));
10316 	status = i40e_asq_send_command(hw, &desc, buff, buff_len, NULL);
10317 
10318 	return status;
10319 }
10320 
10321 /**
10322  * i40e_mirror_rule_set
10323  * @dev: pointer to the hardware structure
10324  * @mirror_conf: mirror rule info
10325  * @sw_id: mirror rule's sw_id
10326  * @on: enable/disable
10327  *
10328  * set a mirror rule.
10329  *
10330  **/
10331 static int
10332 i40e_mirror_rule_set(struct rte_eth_dev *dev,
10333 			struct rte_eth_mirror_conf *mirror_conf,
10334 			uint8_t sw_id, uint8_t on)
10335 {
10336 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
10337 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
10338 	struct i40e_mirror_rule *it, *mirr_rule = NULL;
10339 	struct i40e_mirror_rule *parent = NULL;
10340 	uint16_t seid, dst_seid, rule_id;
10341 	uint16_t i, j = 0;
10342 	int ret;
10343 
10344 	PMD_DRV_LOG(DEBUG, "i40e_mirror_rule_set: sw_id = %d.", sw_id);
10345 
10346 	if (pf->main_vsi->veb == NULL || pf->vfs == NULL) {
10347 		PMD_DRV_LOG(ERR,
10348 			"mirror rule can not be configured without veb or vfs.");
10349 		return -ENOSYS;
10350 	}
10351 	if (pf->nb_mirror_rule > I40E_MAX_MIRROR_RULES) {
10352 		PMD_DRV_LOG(ERR, "mirror table is full.");
10353 		return -ENOSPC;
10354 	}
10355 	if (mirror_conf->dst_pool > pf->vf_num) {
10356 		PMD_DRV_LOG(ERR, "invalid destination pool %u.",
10357 				 mirror_conf->dst_pool);
10358 		return -EINVAL;
10359 	}
10360 
10361 	seid = pf->main_vsi->veb->seid;
10362 
10363 	TAILQ_FOREACH(it, &pf->mirror_list, rules) {
10364 		if (sw_id <= it->index) {
10365 			mirr_rule = it;
10366 			break;
10367 		}
10368 		parent = it;
10369 	}
10370 	if (mirr_rule && sw_id == mirr_rule->index) {
10371 		if (on) {
10372 			PMD_DRV_LOG(ERR, "mirror rule exists.");
10373 			return -EEXIST;
10374 		} else {
10375 			ret = i40e_aq_del_mirror_rule(hw, seid,
10376 					mirr_rule->rule_type,
10377 					mirr_rule->entries,
10378 					mirr_rule->num_entries, mirr_rule->id);
10379 			if (ret < 0) {
10380 				PMD_DRV_LOG(ERR,
10381 					"failed to remove mirror rule: ret = %d, aq_err = %d.",
10382 					ret, hw->aq.asq_last_status);
10383 				return -ENOSYS;
10384 			}
10385 			TAILQ_REMOVE(&pf->mirror_list, mirr_rule, rules);
10386 			rte_free(mirr_rule);
10387 			pf->nb_mirror_rule--;
10388 			return 0;
10389 		}
10390 	} else if (!on) {
10391 		PMD_DRV_LOG(ERR, "mirror rule doesn't exist.");
10392 		return -ENOENT;
10393 	}
10394 
10395 	mirr_rule = rte_zmalloc("i40e_mirror_rule",
10396 				sizeof(struct i40e_mirror_rule) , 0);
10397 	if (!mirr_rule) {
10398 		PMD_DRV_LOG(ERR, "failed to allocate memory");
10399 		return I40E_ERR_NO_MEMORY;
10400 	}
10401 	switch (mirror_conf->rule_type) {
10402 	case ETH_MIRROR_VLAN:
10403 		for (i = 0, j = 0; i < ETH_MIRROR_MAX_VLANS; i++) {
10404 			if (mirror_conf->vlan.vlan_mask & (1ULL << i)) {
10405 				mirr_rule->entries[j] =
10406 					mirror_conf->vlan.vlan_id[i];
10407 				j++;
10408 			}
10409 		}
10410 		if (j == 0) {
10411 			PMD_DRV_LOG(ERR, "vlan is not specified.");
10412 			rte_free(mirr_rule);
10413 			return -EINVAL;
10414 		}
10415 		mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_VLAN;
10416 		break;
10417 	case ETH_MIRROR_VIRTUAL_POOL_UP:
10418 	case ETH_MIRROR_VIRTUAL_POOL_DOWN:
10419 		/* check if the specified pool bit is out of range */
10420 		if (mirror_conf->pool_mask > (uint64_t)(1ULL << (pf->vf_num + 1))) {
10421 			PMD_DRV_LOG(ERR, "pool mask is out of range.");
10422 			rte_free(mirr_rule);
10423 			return -EINVAL;
10424 		}
10425 		for (i = 0, j = 0; i < pf->vf_num; i++) {
10426 			if (mirror_conf->pool_mask & (1ULL << i)) {
10427 				mirr_rule->entries[j] = pf->vfs[i].vsi->seid;
10428 				j++;
10429 			}
10430 		}
10431 		if (mirror_conf->pool_mask & (1ULL << pf->vf_num)) {
10432 			/* add pf vsi to entries */
10433 			mirr_rule->entries[j] = pf->main_vsi_seid;
10434 			j++;
10435 		}
10436 		if (j == 0) {
10437 			PMD_DRV_LOG(ERR, "pool is not specified.");
10438 			rte_free(mirr_rule);
10439 			return -EINVAL;
10440 		}
10441 		/* egress and ingress in aq commands means from switch but not port */
10442 		mirr_rule->rule_type =
10443 			(mirror_conf->rule_type == ETH_MIRROR_VIRTUAL_POOL_UP) ?
10444 			I40E_AQC_MIRROR_RULE_TYPE_VPORT_EGRESS :
10445 			I40E_AQC_MIRROR_RULE_TYPE_VPORT_INGRESS;
10446 		break;
10447 	case ETH_MIRROR_UPLINK_PORT:
10448 		/* egress and ingress in aq commands means from switch but not port*/
10449 		mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS;
10450 		break;
10451 	case ETH_MIRROR_DOWNLINK_PORT:
10452 		mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS;
10453 		break;
10454 	default:
10455 		PMD_DRV_LOG(ERR, "unsupported mirror type %d.",
10456 			mirror_conf->rule_type);
10457 		rte_free(mirr_rule);
10458 		return -EINVAL;
10459 	}
10460 
10461 	/* If the dst_pool is equal to vf_num, consider it as PF */
10462 	if (mirror_conf->dst_pool == pf->vf_num)
10463 		dst_seid = pf->main_vsi_seid;
10464 	else
10465 		dst_seid = pf->vfs[mirror_conf->dst_pool].vsi->seid;
10466 
10467 	ret = i40e_aq_add_mirror_rule(hw, seid, dst_seid,
10468 				      mirr_rule->rule_type, mirr_rule->entries,
10469 				      j, &rule_id);
10470 	if (ret < 0) {
10471 		PMD_DRV_LOG(ERR,
10472 			"failed to add mirror rule: ret = %d, aq_err = %d.",
10473 			ret, hw->aq.asq_last_status);
10474 		rte_free(mirr_rule);
10475 		return -ENOSYS;
10476 	}
10477 
10478 	mirr_rule->index = sw_id;
10479 	mirr_rule->num_entries = j;
10480 	mirr_rule->id = rule_id;
10481 	mirr_rule->dst_vsi_seid = dst_seid;
10482 
10483 	if (parent)
10484 		TAILQ_INSERT_AFTER(&pf->mirror_list, parent, mirr_rule, rules);
10485 	else
10486 		TAILQ_INSERT_HEAD(&pf->mirror_list, mirr_rule, rules);
10487 
10488 	pf->nb_mirror_rule++;
10489 	return 0;
10490 }
10491 
10492 /**
10493  * i40e_mirror_rule_reset
10494  * @dev: pointer to the device
10495  * @sw_id: mirror rule's sw_id
10496  *
10497  * reset a mirror rule.
10498  *
10499  **/
10500 static int
10501 i40e_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t sw_id)
10502 {
10503 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
10504 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
10505 	struct i40e_mirror_rule *it, *mirr_rule = NULL;
10506 	uint16_t seid;
10507 	int ret;
10508 
10509 	PMD_DRV_LOG(DEBUG, "i40e_mirror_rule_reset: sw_id = %d.", sw_id);
10510 
10511 	seid = pf->main_vsi->veb->seid;
10512 
10513 	TAILQ_FOREACH(it, &pf->mirror_list, rules) {
10514 		if (sw_id == it->index) {
10515 			mirr_rule = it;
10516 			break;
10517 		}
10518 	}
10519 	if (mirr_rule) {
10520 		ret = i40e_aq_del_mirror_rule(hw, seid,
10521 				mirr_rule->rule_type,
10522 				mirr_rule->entries,
10523 				mirr_rule->num_entries, mirr_rule->id);
10524 		if (ret < 0) {
10525 			PMD_DRV_LOG(ERR,
10526 				"failed to remove mirror rule: status = %d, aq_err = %d.",
10527 				ret, hw->aq.asq_last_status);
10528 			return -ENOSYS;
10529 		}
10530 		TAILQ_REMOVE(&pf->mirror_list, mirr_rule, rules);
10531 		rte_free(mirr_rule);
10532 		pf->nb_mirror_rule--;
10533 	} else {
10534 		PMD_DRV_LOG(ERR, "mirror rule doesn't exist.");
10535 		return -ENOENT;
10536 	}
10537 	return 0;
10538 }
10539 
10540 static uint64_t
10541 i40e_read_systime_cyclecounter(struct rte_eth_dev *dev)
10542 {
10543 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
10544 	uint64_t systim_cycles;
10545 
10546 	systim_cycles = (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TIME_L);
10547 	systim_cycles |= (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TIME_H)
10548 			<< 32;
10549 
10550 	return systim_cycles;
10551 }
10552 
10553 static uint64_t
10554 i40e_read_rx_tstamp_cyclecounter(struct rte_eth_dev *dev, uint8_t index)
10555 {
10556 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
10557 	uint64_t rx_tstamp;
10558 
10559 	rx_tstamp = (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_L(index));
10560 	rx_tstamp |= (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(index))
10561 			<< 32;
10562 
10563 	return rx_tstamp;
10564 }
10565 
10566 static uint64_t
10567 i40e_read_tx_tstamp_cyclecounter(struct rte_eth_dev *dev)
10568 {
10569 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
10570 	uint64_t tx_tstamp;
10571 
10572 	tx_tstamp = (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TXTIME_L);
10573 	tx_tstamp |= (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TXTIME_H)
10574 			<< 32;
10575 
10576 	return tx_tstamp;
10577 }
10578 
10579 static void
10580 i40e_start_timecounters(struct rte_eth_dev *dev)
10581 {
10582 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
10583 	struct i40e_adapter *adapter = dev->data->dev_private;
10584 	struct rte_eth_link link;
10585 	uint32_t tsync_inc_l;
10586 	uint32_t tsync_inc_h;
10587 
10588 	/* Get current link speed. */
10589 	i40e_dev_link_update(dev, 1);
10590 	rte_eth_linkstatus_get(dev, &link);
10591 
10592 	switch (link.link_speed) {
10593 	case ETH_SPEED_NUM_40G:
10594 	case ETH_SPEED_NUM_25G:
10595 		tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
10596 		tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
10597 		break;
10598 	case ETH_SPEED_NUM_10G:
10599 		tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
10600 		tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
10601 		break;
10602 	case ETH_SPEED_NUM_1G:
10603 		tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
10604 		tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
10605 		break;
10606 	default:
10607 		tsync_inc_l = 0x0;
10608 		tsync_inc_h = 0x0;
10609 	}
10610 
10611 	/* Set the timesync increment value. */
10612 	I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_L, tsync_inc_l);
10613 	I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_H, tsync_inc_h);
10614 
10615 	memset(&adapter->systime_tc, 0, sizeof(struct rte_timecounter));
10616 	memset(&adapter->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
10617 	memset(&adapter->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
10618 
10619 	adapter->systime_tc.cc_mask = I40E_CYCLECOUNTER_MASK;
10620 	adapter->systime_tc.cc_shift = 0;
10621 	adapter->systime_tc.nsec_mask = 0;
10622 
10623 	adapter->rx_tstamp_tc.cc_mask = I40E_CYCLECOUNTER_MASK;
10624 	adapter->rx_tstamp_tc.cc_shift = 0;
10625 	adapter->rx_tstamp_tc.nsec_mask = 0;
10626 
10627 	adapter->tx_tstamp_tc.cc_mask = I40E_CYCLECOUNTER_MASK;
10628 	adapter->tx_tstamp_tc.cc_shift = 0;
10629 	adapter->tx_tstamp_tc.nsec_mask = 0;
10630 }
10631 
10632 static int
10633 i40e_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
10634 {
10635 	struct i40e_adapter *adapter = dev->data->dev_private;
10636 
10637 	adapter->systime_tc.nsec += delta;
10638 	adapter->rx_tstamp_tc.nsec += delta;
10639 	adapter->tx_tstamp_tc.nsec += delta;
10640 
10641 	return 0;
10642 }
10643 
10644 static int
10645 i40e_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
10646 {
10647 	uint64_t ns;
10648 	struct i40e_adapter *adapter = dev->data->dev_private;
10649 
10650 	ns = rte_timespec_to_ns(ts);
10651 
10652 	/* Set the timecounters to a new value. */
10653 	adapter->systime_tc.nsec = ns;
10654 	adapter->rx_tstamp_tc.nsec = ns;
10655 	adapter->tx_tstamp_tc.nsec = ns;
10656 
10657 	return 0;
10658 }
10659 
10660 static int
10661 i40e_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
10662 {
10663 	uint64_t ns, systime_cycles;
10664 	struct i40e_adapter *adapter = dev->data->dev_private;
10665 
10666 	systime_cycles = i40e_read_systime_cyclecounter(dev);
10667 	ns = rte_timecounter_update(&adapter->systime_tc, systime_cycles);
10668 	*ts = rte_ns_to_timespec(ns);
10669 
10670 	return 0;
10671 }
10672 
10673 static int
10674 i40e_timesync_enable(struct rte_eth_dev *dev)
10675 {
10676 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
10677 	uint32_t tsync_ctl_l;
10678 	uint32_t tsync_ctl_h;
10679 
10680 	/* Stop the timesync system time. */
10681 	I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_L, 0x0);
10682 	I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_H, 0x0);
10683 	/* Reset the timesync system time value. */
10684 	I40E_WRITE_REG(hw, I40E_PRTTSYN_TIME_L, 0x0);
10685 	I40E_WRITE_REG(hw, I40E_PRTTSYN_TIME_H, 0x0);
10686 
10687 	i40e_start_timecounters(dev);
10688 
10689 	/* Clear timesync registers. */
10690 	I40E_READ_REG(hw, I40E_PRTTSYN_STAT_0);
10691 	I40E_READ_REG(hw, I40E_PRTTSYN_TXTIME_H);
10692 	I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(0));
10693 	I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(1));
10694 	I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(2));
10695 	I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(3));
10696 
10697 	/* Enable timestamping of PTP packets. */
10698 	tsync_ctl_l = I40E_READ_REG(hw, I40E_PRTTSYN_CTL0);
10699 	tsync_ctl_l |= I40E_PRTTSYN_TSYNENA;
10700 
10701 	tsync_ctl_h = I40E_READ_REG(hw, I40E_PRTTSYN_CTL1);
10702 	tsync_ctl_h |= I40E_PRTTSYN_TSYNENA;
10703 	tsync_ctl_h |= I40E_PRTTSYN_TSYNTYPE;
10704 
10705 	I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL0, tsync_ctl_l);
10706 	I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL1, tsync_ctl_h);
10707 
10708 	return 0;
10709 }
10710 
10711 static int
10712 i40e_timesync_disable(struct rte_eth_dev *dev)
10713 {
10714 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
10715 	uint32_t tsync_ctl_l;
10716 	uint32_t tsync_ctl_h;
10717 
10718 	/* Disable timestamping of transmitted PTP packets. */
10719 	tsync_ctl_l = I40E_READ_REG(hw, I40E_PRTTSYN_CTL0);
10720 	tsync_ctl_l &= ~I40E_PRTTSYN_TSYNENA;
10721 
10722 	tsync_ctl_h = I40E_READ_REG(hw, I40E_PRTTSYN_CTL1);
10723 	tsync_ctl_h &= ~I40E_PRTTSYN_TSYNENA;
10724 
10725 	I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL0, tsync_ctl_l);
10726 	I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL1, tsync_ctl_h);
10727 
10728 	/* Reset the timesync increment value. */
10729 	I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_L, 0x0);
10730 	I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_H, 0x0);
10731 
10732 	return 0;
10733 }
10734 
10735 static int
10736 i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
10737 				struct timespec *timestamp, uint32_t flags)
10738 {
10739 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
10740 	struct i40e_adapter *adapter = dev->data->dev_private;
10741 	uint32_t sync_status;
10742 	uint32_t index = flags & 0x03;
10743 	uint64_t rx_tstamp_cycles;
10744 	uint64_t ns;
10745 
10746 	sync_status = I40E_READ_REG(hw, I40E_PRTTSYN_STAT_1);
10747 	if ((sync_status & (1 << index)) == 0)
10748 		return -EINVAL;
10749 
10750 	rx_tstamp_cycles = i40e_read_rx_tstamp_cyclecounter(dev, index);
10751 	ns = rte_timecounter_update(&adapter->rx_tstamp_tc, rx_tstamp_cycles);
10752 	*timestamp = rte_ns_to_timespec(ns);
10753 
10754 	return 0;
10755 }
10756 
10757 static int
10758 i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
10759 				struct timespec *timestamp)
10760 {
10761 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
10762 	struct i40e_adapter *adapter = dev->data->dev_private;
10763 	uint32_t sync_status;
10764 	uint64_t tx_tstamp_cycles;
10765 	uint64_t ns;
10766 
10767 	sync_status = I40E_READ_REG(hw, I40E_PRTTSYN_STAT_0);
10768 	if ((sync_status & I40E_PRTTSYN_STAT_0_TXTIME_MASK) == 0)
10769 		return -EINVAL;
10770 
10771 	tx_tstamp_cycles = i40e_read_tx_tstamp_cyclecounter(dev);
10772 	ns = rte_timecounter_update(&adapter->tx_tstamp_tc, tx_tstamp_cycles);
10773 	*timestamp = rte_ns_to_timespec(ns);
10774 
10775 	return 0;
10776 }
10777 
10778 /*
10779  * i40e_parse_dcb_configure - parse dcb configure from user
10780  * @dev: the device being configured
10781  * @dcb_cfg: pointer of the result of parse
10782  * @*tc_map: bit map of enabled traffic classes
10783  *
10784  * Returns 0 on success, negative value on failure
10785  */
10786 static int
10787 i40e_parse_dcb_configure(struct rte_eth_dev *dev,
10788 			 struct i40e_dcbx_config *dcb_cfg,
10789 			 uint8_t *tc_map)
10790 {
10791 	struct rte_eth_dcb_rx_conf *dcb_rx_conf;
10792 	uint8_t i, tc_bw, bw_lf;
10793 
10794 	memset(dcb_cfg, 0, sizeof(struct i40e_dcbx_config));
10795 
10796 	dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf;
10797 	if (dcb_rx_conf->nb_tcs > I40E_MAX_TRAFFIC_CLASS) {
10798 		PMD_INIT_LOG(ERR, "number of tc exceeds max.");
10799 		return -EINVAL;
10800 	}
10801 
10802 	/* assume each tc has the same bw */
10803 	tc_bw = I40E_MAX_PERCENT / dcb_rx_conf->nb_tcs;
10804 	for (i = 0; i < dcb_rx_conf->nb_tcs; i++)
10805 		dcb_cfg->etscfg.tcbwtable[i] = tc_bw;
10806 	/* to ensure the sum of tcbw is equal to 100 */
10807 	bw_lf = I40E_MAX_PERCENT % dcb_rx_conf->nb_tcs;
10808 	for (i = 0; i < bw_lf; i++)
10809 		dcb_cfg->etscfg.tcbwtable[i]++;
10810 
10811 	/* assume each tc has the same Transmission Selection Algorithm */
10812 	for (i = 0; i < dcb_rx_conf->nb_tcs; i++)
10813 		dcb_cfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
10814 
10815 	for (i = 0; i < I40E_MAX_USER_PRIORITY; i++)
10816 		dcb_cfg->etscfg.prioritytable[i] =
10817 				dcb_rx_conf->dcb_tc[i];
10818 
10819 	/* FW needs one App to configure HW */
10820 	dcb_cfg->numapps = I40E_DEFAULT_DCB_APP_NUM;
10821 	dcb_cfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
10822 	dcb_cfg->app[0].priority = I40E_DEFAULT_DCB_APP_PRIO;
10823 	dcb_cfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
10824 
10825 	if (dcb_rx_conf->nb_tcs == 0)
10826 		*tc_map = 1; /* tc0 only */
10827 	else
10828 		*tc_map = RTE_LEN2MASK(dcb_rx_conf->nb_tcs, uint8_t);
10829 
10830 	if (dev->data->dev_conf.dcb_capability_en & ETH_DCB_PFC_SUPPORT) {
10831 		dcb_cfg->pfc.willing = 0;
10832 		dcb_cfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
10833 		dcb_cfg->pfc.pfcenable = *tc_map;
10834 	}
10835 	return 0;
10836 }
10837 
10838 
10839 static enum i40e_status_code
10840 i40e_vsi_update_queue_mapping(struct i40e_vsi *vsi,
10841 			      struct i40e_aqc_vsi_properties_data *info,
10842 			      uint8_t enabled_tcmap)
10843 {
10844 	enum i40e_status_code ret;
10845 	int i, total_tc = 0;
10846 	uint16_t qpnum_per_tc, bsf, qp_idx;
10847 	struct rte_eth_dev_data *dev_data = I40E_VSI_TO_DEV_DATA(vsi);
10848 	struct i40e_pf *pf = I40E_VSI_TO_PF(vsi);
10849 	uint16_t used_queues;
10850 
10851 	ret = validate_tcmap_parameter(vsi, enabled_tcmap);
10852 	if (ret != I40E_SUCCESS)
10853 		return ret;
10854 
10855 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
10856 		if (enabled_tcmap & (1 << i))
10857 			total_tc++;
10858 	}
10859 	if (total_tc == 0)
10860 		total_tc = 1;
10861 	vsi->enabled_tc = enabled_tcmap;
10862 
10863 	/* different VSI has different queues assigned */
10864 	if (vsi->type == I40E_VSI_MAIN)
10865 		used_queues = dev_data->nb_rx_queues -
10866 			pf->nb_cfg_vmdq_vsi * RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM;
10867 	else if (vsi->type == I40E_VSI_VMDQ2)
10868 		used_queues = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM;
10869 	else {
10870 		PMD_INIT_LOG(ERR, "unsupported VSI type.");
10871 		return I40E_ERR_NO_AVAILABLE_VSI;
10872 	}
10873 
10874 	qpnum_per_tc = used_queues / total_tc;
10875 	/* Number of queues per enabled TC */
10876 	if (qpnum_per_tc == 0) {
10877 		PMD_INIT_LOG(ERR, " number of queues is less that tcs.");
10878 		return I40E_ERR_INVALID_QP_ID;
10879 	}
10880 	qpnum_per_tc = RTE_MIN(i40e_align_floor(qpnum_per_tc),
10881 				I40E_MAX_Q_PER_TC);
10882 	bsf = rte_bsf32(qpnum_per_tc);
10883 
10884 	/**
10885 	 * Configure TC and queue mapping parameters, for enabled TC,
10886 	 * allocate qpnum_per_tc queues to this traffic. For disabled TC,
10887 	 * default queue will serve it.
10888 	 */
10889 	qp_idx = 0;
10890 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
10891 		if (vsi->enabled_tc & (1 << i)) {
10892 			info->tc_mapping[i] = rte_cpu_to_le_16((qp_idx <<
10893 					I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) |
10894 				(bsf << I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT));
10895 			qp_idx += qpnum_per_tc;
10896 		} else
10897 			info->tc_mapping[i] = 0;
10898 	}
10899 
10900 	/* Associate queue number with VSI, Keep vsi->nb_qps unchanged */
10901 	if (vsi->type == I40E_VSI_SRIOV) {
10902 		info->mapping_flags |=
10903 			rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_NONCONTIG);
10904 		for (i = 0; i < vsi->nb_qps; i++)
10905 			info->queue_mapping[i] =
10906 				rte_cpu_to_le_16(vsi->base_queue + i);
10907 	} else {
10908 		info->mapping_flags |=
10909 			rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_CONTIG);
10910 		info->queue_mapping[0] = rte_cpu_to_le_16(vsi->base_queue);
10911 	}
10912 	info->valid_sections |=
10913 		rte_cpu_to_le_16(I40E_AQ_VSI_PROP_QUEUE_MAP_VALID);
10914 
10915 	return I40E_SUCCESS;
10916 }
10917 
10918 /*
10919  * i40e_config_switch_comp_tc - Configure VEB tc setting for given TC map
10920  * @veb: VEB to be configured
10921  * @tc_map: enabled TC bitmap
10922  *
10923  * Returns 0 on success, negative value on failure
10924  */
10925 static enum i40e_status_code
10926 i40e_config_switch_comp_tc(struct i40e_veb *veb, uint8_t tc_map)
10927 {
10928 	struct i40e_aqc_configure_switching_comp_bw_config_data veb_bw;
10929 	struct i40e_aqc_query_switching_comp_bw_config_resp bw_query;
10930 	struct i40e_aqc_query_switching_comp_ets_config_resp ets_query;
10931 	struct i40e_hw *hw = I40E_VSI_TO_HW(veb->associate_vsi);
10932 	enum i40e_status_code ret = I40E_SUCCESS;
10933 	int i;
10934 	uint32_t bw_max;
10935 
10936 	/* Check if enabled_tc is same as existing or new TCs */
10937 	if (veb->enabled_tc == tc_map)
10938 		return ret;
10939 
10940 	/* configure tc bandwidth */
10941 	memset(&veb_bw, 0, sizeof(veb_bw));
10942 	veb_bw.tc_valid_bits = tc_map;
10943 	/* Enable ETS TCs with equal BW Share for now across all VSIs */
10944 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
10945 		if (tc_map & BIT_ULL(i))
10946 			veb_bw.tc_bw_share_credits[i] = 1;
10947 	}
10948 	ret = i40e_aq_config_switch_comp_bw_config(hw, veb->seid,
10949 						   &veb_bw, NULL);
10950 	if (ret) {
10951 		PMD_INIT_LOG(ERR,
10952 			"AQ command Config switch_comp BW allocation per TC failed = %d",
10953 			hw->aq.asq_last_status);
10954 		return ret;
10955 	}
10956 
10957 	memset(&ets_query, 0, sizeof(ets_query));
10958 	ret = i40e_aq_query_switch_comp_ets_config(hw, veb->seid,
10959 						   &ets_query, NULL);
10960 	if (ret != I40E_SUCCESS) {
10961 		PMD_DRV_LOG(ERR,
10962 			"Failed to get switch_comp ETS configuration %u",
10963 			hw->aq.asq_last_status);
10964 		return ret;
10965 	}
10966 	memset(&bw_query, 0, sizeof(bw_query));
10967 	ret = i40e_aq_query_switch_comp_bw_config(hw, veb->seid,
10968 						  &bw_query, NULL);
10969 	if (ret != I40E_SUCCESS) {
10970 		PMD_DRV_LOG(ERR,
10971 			"Failed to get switch_comp bandwidth configuration %u",
10972 			hw->aq.asq_last_status);
10973 		return ret;
10974 	}
10975 
10976 	/* store and print out BW info */
10977 	veb->bw_info.bw_limit = rte_le_to_cpu_16(ets_query.port_bw_limit);
10978 	veb->bw_info.bw_max = ets_query.tc_bw_max;
10979 	PMD_DRV_LOG(DEBUG, "switch_comp bw limit:%u", veb->bw_info.bw_limit);
10980 	PMD_DRV_LOG(DEBUG, "switch_comp max_bw:%u", veb->bw_info.bw_max);
10981 	bw_max = rte_le_to_cpu_16(bw_query.tc_bw_max[0]) |
10982 		    (rte_le_to_cpu_16(bw_query.tc_bw_max[1]) <<
10983 		     I40E_16_BIT_WIDTH);
10984 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
10985 		veb->bw_info.bw_ets_share_credits[i] =
10986 				bw_query.tc_bw_share_credits[i];
10987 		veb->bw_info.bw_ets_credits[i] =
10988 				rte_le_to_cpu_16(bw_query.tc_bw_limits[i]);
10989 		/* 4 bits per TC, 4th bit is reserved */
10990 		veb->bw_info.bw_ets_max[i] =
10991 			(uint8_t)((bw_max >> (i * I40E_4_BIT_WIDTH)) &
10992 				  RTE_LEN2MASK(3, uint8_t));
10993 		PMD_DRV_LOG(DEBUG, "\tVEB TC%u:share credits %u", i,
10994 			    veb->bw_info.bw_ets_share_credits[i]);
10995 		PMD_DRV_LOG(DEBUG, "\tVEB TC%u:credits %u", i,
10996 			    veb->bw_info.bw_ets_credits[i]);
10997 		PMD_DRV_LOG(DEBUG, "\tVEB TC%u: max credits: %u", i,
10998 			    veb->bw_info.bw_ets_max[i]);
10999 	}
11000 
11001 	veb->enabled_tc = tc_map;
11002 
11003 	return ret;
11004 }
11005 
11006 
11007 /*
11008  * i40e_vsi_config_tc - Configure VSI tc setting for given TC map
11009  * @vsi: VSI to be configured
11010  * @tc_map: enabled TC bitmap
11011  *
11012  * Returns 0 on success, negative value on failure
11013  */
11014 static enum i40e_status_code
11015 i40e_vsi_config_tc(struct i40e_vsi *vsi, uint8_t tc_map)
11016 {
11017 	struct i40e_aqc_configure_vsi_tc_bw_data bw_data;
11018 	struct i40e_vsi_context ctxt;
11019 	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
11020 	enum i40e_status_code ret = I40E_SUCCESS;
11021 	int i;
11022 
11023 	/* Check if enabled_tc is same as existing or new TCs */
11024 	if (vsi->enabled_tc == tc_map)
11025 		return ret;
11026 
11027 	/* configure tc bandwidth */
11028 	memset(&bw_data, 0, sizeof(bw_data));
11029 	bw_data.tc_valid_bits = tc_map;
11030 	/* Enable ETS TCs with equal BW Share for now across all VSIs */
11031 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
11032 		if (tc_map & BIT_ULL(i))
11033 			bw_data.tc_bw_credits[i] = 1;
11034 	}
11035 	ret = i40e_aq_config_vsi_tc_bw(hw, vsi->seid, &bw_data, NULL);
11036 	if (ret) {
11037 		PMD_INIT_LOG(ERR,
11038 			"AQ command Config VSI BW allocation per TC failed = %d",
11039 			hw->aq.asq_last_status);
11040 		goto out;
11041 	}
11042 	for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
11043 		vsi->info.qs_handle[i] = bw_data.qs_handles[i];
11044 
11045 	/* Update Queue Pairs Mapping for currently enabled UPs */
11046 	ctxt.seid = vsi->seid;
11047 	ctxt.pf_num = hw->pf_id;
11048 	ctxt.vf_num = 0;
11049 	ctxt.uplink_seid = vsi->uplink_seid;
11050 	ctxt.info = vsi->info;
11051 	i40e_get_cap(hw);
11052 	ret = i40e_vsi_update_queue_mapping(vsi, &ctxt.info, tc_map);
11053 	if (ret)
11054 		goto out;
11055 
11056 	/* Update the VSI after updating the VSI queue-mapping information */
11057 	ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
11058 	if (ret) {
11059 		PMD_INIT_LOG(ERR, "Failed to configure TC queue mapping = %d",
11060 			hw->aq.asq_last_status);
11061 		goto out;
11062 	}
11063 	/* update the local VSI info with updated queue map */
11064 	rte_memcpy(&vsi->info.tc_mapping, &ctxt.info.tc_mapping,
11065 					sizeof(vsi->info.tc_mapping));
11066 	rte_memcpy(&vsi->info.queue_mapping,
11067 			&ctxt.info.queue_mapping,
11068 		sizeof(vsi->info.queue_mapping));
11069 	vsi->info.mapping_flags = ctxt.info.mapping_flags;
11070 	vsi->info.valid_sections = 0;
11071 
11072 	/* query and update current VSI BW information */
11073 	ret = i40e_vsi_get_bw_config(vsi);
11074 	if (ret) {
11075 		PMD_INIT_LOG(ERR,
11076 			 "Failed updating vsi bw info, err %s aq_err %s",
11077 			 i40e_stat_str(hw, ret),
11078 			 i40e_aq_str(hw, hw->aq.asq_last_status));
11079 		goto out;
11080 	}
11081 
11082 	vsi->enabled_tc = tc_map;
11083 
11084 out:
11085 	return ret;
11086 }
11087 
11088 /*
11089  * i40e_dcb_hw_configure - program the dcb setting to hw
11090  * @pf: pf the configuration is taken on
11091  * @new_cfg: new configuration
11092  * @tc_map: enabled TC bitmap
11093  *
11094  * Returns 0 on success, negative value on failure
11095  */
11096 static enum i40e_status_code
11097 i40e_dcb_hw_configure(struct i40e_pf *pf,
11098 		      struct i40e_dcbx_config *new_cfg,
11099 		      uint8_t tc_map)
11100 {
11101 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
11102 	struct i40e_dcbx_config *old_cfg = &hw->local_dcbx_config;
11103 	struct i40e_vsi *main_vsi = pf->main_vsi;
11104 	struct i40e_vsi_list *vsi_list;
11105 	enum i40e_status_code ret;
11106 	int i;
11107 	uint32_t val;
11108 
11109 	/* Use the FW API if FW > v4.4*/
11110 	if (!(((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver >= 4)) ||
11111 	      (hw->aq.fw_maj_ver >= 5))) {
11112 		PMD_INIT_LOG(ERR,
11113 			"FW < v4.4, can not use FW LLDP API to configure DCB");
11114 		return I40E_ERR_FIRMWARE_API_VERSION;
11115 	}
11116 
11117 	/* Check if need reconfiguration */
11118 	if (!memcmp(new_cfg, old_cfg, sizeof(struct i40e_dcbx_config))) {
11119 		PMD_INIT_LOG(ERR, "No Change in DCB Config required.");
11120 		return I40E_SUCCESS;
11121 	}
11122 
11123 	/* Copy the new config to the current config */
11124 	*old_cfg = *new_cfg;
11125 	old_cfg->etsrec = old_cfg->etscfg;
11126 	ret = i40e_set_dcb_config(hw);
11127 	if (ret) {
11128 		PMD_INIT_LOG(ERR, "Set DCB Config failed, err %s aq_err %s",
11129 			 i40e_stat_str(hw, ret),
11130 			 i40e_aq_str(hw, hw->aq.asq_last_status));
11131 		return ret;
11132 	}
11133 	/* set receive Arbiter to RR mode and ETS scheme by default */
11134 	for (i = 0; i <= I40E_PRTDCB_RETSTCC_MAX_INDEX; i++) {
11135 		val = I40E_READ_REG(hw, I40E_PRTDCB_RETSTCC(i));
11136 		val &= ~(I40E_PRTDCB_RETSTCC_BWSHARE_MASK     |
11137 			 I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK |
11138 			 I40E_PRTDCB_RETSTCC_ETSTC_SHIFT);
11139 		val |= ((uint32_t)old_cfg->etscfg.tcbwtable[i] <<
11140 			I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT) &
11141 			 I40E_PRTDCB_RETSTCC_BWSHARE_MASK;
11142 		val |= ((uint32_t)1 << I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT) &
11143 			 I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK;
11144 		val |= ((uint32_t)1 << I40E_PRTDCB_RETSTCC_ETSTC_SHIFT) &
11145 			 I40E_PRTDCB_RETSTCC_ETSTC_MASK;
11146 		I40E_WRITE_REG(hw, I40E_PRTDCB_RETSTCC(i), val);
11147 	}
11148 	/* get local mib to check whether it is configured correctly */
11149 	/* IEEE mode */
11150 	hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
11151 	/* Get Local DCB Config */
11152 	i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
11153 				     &hw->local_dcbx_config);
11154 
11155 	/* if Veb is created, need to update TC of it at first */
11156 	if (main_vsi->veb) {
11157 		ret = i40e_config_switch_comp_tc(main_vsi->veb, tc_map);
11158 		if (ret)
11159 			PMD_INIT_LOG(WARNING,
11160 				 "Failed configuring TC for VEB seid=%d",
11161 				 main_vsi->veb->seid);
11162 	}
11163 	/* Update each VSI */
11164 	i40e_vsi_config_tc(main_vsi, tc_map);
11165 	if (main_vsi->veb) {
11166 		TAILQ_FOREACH(vsi_list, &main_vsi->veb->head, list) {
11167 			/* Beside main VSI and VMDQ VSIs, only enable default
11168 			 * TC for other VSIs
11169 			 */
11170 			if (vsi_list->vsi->type == I40E_VSI_VMDQ2)
11171 				ret = i40e_vsi_config_tc(vsi_list->vsi,
11172 							 tc_map);
11173 			else
11174 				ret = i40e_vsi_config_tc(vsi_list->vsi,
11175 							 I40E_DEFAULT_TCMAP);
11176 			if (ret)
11177 				PMD_INIT_LOG(WARNING,
11178 					"Failed configuring TC for VSI seid=%d",
11179 					vsi_list->vsi->seid);
11180 			/* continue */
11181 		}
11182 	}
11183 	return I40E_SUCCESS;
11184 }
11185 
11186 /*
11187  * i40e_dcb_init_configure - initial dcb config
11188  * @dev: device being configured
11189  * @sw_dcb: indicate whether dcb is sw configured or hw offload
11190  *
11191  * Returns 0 on success, negative value on failure
11192  */
11193 int
11194 i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb)
11195 {
11196 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
11197 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11198 	int i, ret = 0;
11199 
11200 	if ((pf->flags & I40E_FLAG_DCB) == 0) {
11201 		PMD_INIT_LOG(ERR, "HW doesn't support DCB");
11202 		return -ENOTSUP;
11203 	}
11204 
11205 	/* DCB initialization:
11206 	 * Update DCB configuration from the Firmware and configure
11207 	 * LLDP MIB change event.
11208 	 */
11209 	if (sw_dcb == TRUE) {
11210 		/* Stopping lldp is necessary for DPDK, but it will cause
11211 		 * DCB init failed. For i40e_init_dcb(), the prerequisite
11212 		 * for successful initialization of DCB is that LLDP is
11213 		 * enabled. So it is needed to start lldp before DCB init
11214 		 * and stop it after initialization.
11215 		 */
11216 		ret = i40e_aq_start_lldp(hw, true, NULL);
11217 		if (ret != I40E_SUCCESS)
11218 			PMD_INIT_LOG(DEBUG, "Failed to start lldp");
11219 
11220 		ret = i40e_init_dcb(hw, true);
11221 		/* If lldp agent is stopped, the return value from
11222 		 * i40e_init_dcb we expect is failure with I40E_AQ_RC_EPERM
11223 		 * adminq status. Otherwise, it should return success.
11224 		 */
11225 		if ((ret == I40E_SUCCESS) || (ret != I40E_SUCCESS &&
11226 		    hw->aq.asq_last_status == I40E_AQ_RC_EPERM)) {
11227 			memset(&hw->local_dcbx_config, 0,
11228 				sizeof(struct i40e_dcbx_config));
11229 			/* set dcb default configuration */
11230 			hw->local_dcbx_config.etscfg.willing = 0;
11231 			hw->local_dcbx_config.etscfg.maxtcs = 0;
11232 			hw->local_dcbx_config.etscfg.tcbwtable[0] = 100;
11233 			hw->local_dcbx_config.etscfg.tsatable[0] =
11234 						I40E_IEEE_TSA_ETS;
11235 			/* all UPs mapping to TC0 */
11236 			for (i = 0; i < I40E_MAX_USER_PRIORITY; i++)
11237 				hw->local_dcbx_config.etscfg.prioritytable[i] = 0;
11238 			hw->local_dcbx_config.etsrec =
11239 				hw->local_dcbx_config.etscfg;
11240 			hw->local_dcbx_config.pfc.willing = 0;
11241 			hw->local_dcbx_config.pfc.pfccap =
11242 						I40E_MAX_TRAFFIC_CLASS;
11243 			/* FW needs one App to configure HW */
11244 			hw->local_dcbx_config.numapps = 1;
11245 			hw->local_dcbx_config.app[0].selector =
11246 						I40E_APP_SEL_ETHTYPE;
11247 			hw->local_dcbx_config.app[0].priority = 3;
11248 			hw->local_dcbx_config.app[0].protocolid =
11249 						I40E_APP_PROTOID_FCOE;
11250 			ret = i40e_set_dcb_config(hw);
11251 			if (ret) {
11252 				PMD_INIT_LOG(ERR,
11253 					"default dcb config fails. err = %d, aq_err = %d.",
11254 					ret, hw->aq.asq_last_status);
11255 				return -ENOSYS;
11256 			}
11257 		} else {
11258 			PMD_INIT_LOG(ERR,
11259 				"DCB initialization in FW fails, err = %d, aq_err = %d.",
11260 				ret, hw->aq.asq_last_status);
11261 			return -ENOTSUP;
11262 		}
11263 
11264 		if (i40e_need_stop_lldp(dev)) {
11265 			ret = i40e_aq_stop_lldp(hw, true, true, NULL);
11266 			if (ret != I40E_SUCCESS)
11267 				PMD_INIT_LOG(DEBUG, "Failed to stop lldp");
11268 		}
11269 	} else {
11270 		ret = i40e_aq_start_lldp(hw, true, NULL);
11271 		if (ret != I40E_SUCCESS)
11272 			PMD_INIT_LOG(DEBUG, "Failed to start lldp");
11273 
11274 		ret = i40e_init_dcb(hw, true);
11275 		if (!ret) {
11276 			if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) {
11277 				PMD_INIT_LOG(ERR,
11278 					"HW doesn't support DCBX offload.");
11279 				return -ENOTSUP;
11280 			}
11281 		} else {
11282 			PMD_INIT_LOG(ERR,
11283 				"DCBX configuration failed, err = %d, aq_err = %d.",
11284 				ret, hw->aq.asq_last_status);
11285 			return -ENOTSUP;
11286 		}
11287 	}
11288 	return 0;
11289 }
11290 
11291 /*
11292  * i40e_dcb_setup - setup dcb related config
11293  * @dev: device being configured
11294  *
11295  * Returns 0 on success, negative value on failure
11296  */
11297 static int
11298 i40e_dcb_setup(struct rte_eth_dev *dev)
11299 {
11300 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
11301 	struct i40e_dcbx_config dcb_cfg;
11302 	uint8_t tc_map = 0;
11303 	int ret = 0;
11304 
11305 	if ((pf->flags & I40E_FLAG_DCB) == 0) {
11306 		PMD_INIT_LOG(ERR, "HW doesn't support DCB");
11307 		return -ENOTSUP;
11308 	}
11309 
11310 	if (pf->vf_num != 0)
11311 		PMD_INIT_LOG(DEBUG, " DCB only works on pf and vmdq vsis.");
11312 
11313 	ret = i40e_parse_dcb_configure(dev, &dcb_cfg, &tc_map);
11314 	if (ret) {
11315 		PMD_INIT_LOG(ERR, "invalid dcb config");
11316 		return -EINVAL;
11317 	}
11318 	ret = i40e_dcb_hw_configure(pf, &dcb_cfg, tc_map);
11319 	if (ret) {
11320 		PMD_INIT_LOG(ERR, "dcb sw configure fails");
11321 		return -ENOSYS;
11322 	}
11323 
11324 	return 0;
11325 }
11326 
11327 static int
11328 i40e_dev_get_dcb_info(struct rte_eth_dev *dev,
11329 		      struct rte_eth_dcb_info *dcb_info)
11330 {
11331 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
11332 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11333 	struct i40e_vsi *vsi = pf->main_vsi;
11334 	struct i40e_dcbx_config *dcb_cfg = &hw->local_dcbx_config;
11335 	uint16_t bsf, tc_mapping;
11336 	int i, j = 0;
11337 
11338 	if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_DCB_FLAG)
11339 		dcb_info->nb_tcs = rte_bsf32(vsi->enabled_tc + 1);
11340 	else
11341 		dcb_info->nb_tcs = 1;
11342 	for (i = 0; i < I40E_MAX_USER_PRIORITY; i++)
11343 		dcb_info->prio_tc[i] = dcb_cfg->etscfg.prioritytable[i];
11344 	for (i = 0; i < dcb_info->nb_tcs; i++)
11345 		dcb_info->tc_bws[i] = dcb_cfg->etscfg.tcbwtable[i];
11346 
11347 	/* get queue mapping if vmdq is disabled */
11348 	if (!pf->nb_cfg_vmdq_vsi) {
11349 		for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
11350 			if (!(vsi->enabled_tc & (1 << i)))
11351 				continue;
11352 			tc_mapping = rte_le_to_cpu_16(vsi->info.tc_mapping[i]);
11353 			dcb_info->tc_queue.tc_rxq[j][i].base =
11354 				(tc_mapping & I40E_AQ_VSI_TC_QUE_OFFSET_MASK) >>
11355 				I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT;
11356 			dcb_info->tc_queue.tc_txq[j][i].base =
11357 				dcb_info->tc_queue.tc_rxq[j][i].base;
11358 			bsf = (tc_mapping & I40E_AQ_VSI_TC_QUE_NUMBER_MASK) >>
11359 				I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT;
11360 			dcb_info->tc_queue.tc_rxq[j][i].nb_queue = 1 << bsf;
11361 			dcb_info->tc_queue.tc_txq[j][i].nb_queue =
11362 				dcb_info->tc_queue.tc_rxq[j][i].nb_queue;
11363 		}
11364 		return 0;
11365 	}
11366 
11367 	/* get queue mapping if vmdq is enabled */
11368 	do {
11369 		vsi = pf->vmdq[j].vsi;
11370 		for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
11371 			if (!(vsi->enabled_tc & (1 << i)))
11372 				continue;
11373 			tc_mapping = rte_le_to_cpu_16(vsi->info.tc_mapping[i]);
11374 			dcb_info->tc_queue.tc_rxq[j][i].base =
11375 				(tc_mapping & I40E_AQ_VSI_TC_QUE_OFFSET_MASK) >>
11376 				I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT;
11377 			dcb_info->tc_queue.tc_txq[j][i].base =
11378 				dcb_info->tc_queue.tc_rxq[j][i].base;
11379 			bsf = (tc_mapping & I40E_AQ_VSI_TC_QUE_NUMBER_MASK) >>
11380 				I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT;
11381 			dcb_info->tc_queue.tc_rxq[j][i].nb_queue = 1 << bsf;
11382 			dcb_info->tc_queue.tc_txq[j][i].nb_queue =
11383 				dcb_info->tc_queue.tc_rxq[j][i].nb_queue;
11384 		}
11385 		j++;
11386 	} while (j < RTE_MIN(pf->nb_cfg_vmdq_vsi, ETH_MAX_VMDQ_POOL));
11387 	return 0;
11388 }
11389 
11390 static int
11391 i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
11392 {
11393 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
11394 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
11395 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11396 	uint16_t msix_intr;
11397 
11398 	msix_intr = intr_handle->intr_vec[queue_id];
11399 	if (msix_intr == I40E_MISC_VEC_ID)
11400 		I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
11401 			       I40E_PFINT_DYN_CTL0_INTENA_MASK |
11402 			       I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
11403 			       I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
11404 	else
11405 		I40E_WRITE_REG(hw,
11406 			       I40E_PFINT_DYN_CTLN(msix_intr -
11407 						   I40E_RX_VEC_START),
11408 			       I40E_PFINT_DYN_CTLN_INTENA_MASK |
11409 			       I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
11410 			       I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
11411 
11412 	I40E_WRITE_FLUSH(hw);
11413 	rte_intr_ack(&pci_dev->intr_handle);
11414 
11415 	return 0;
11416 }
11417 
11418 static int
11419 i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
11420 {
11421 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
11422 	struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
11423 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11424 	uint16_t msix_intr;
11425 
11426 	msix_intr = intr_handle->intr_vec[queue_id];
11427 	if (msix_intr == I40E_MISC_VEC_ID)
11428 		I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0,
11429 			       I40E_PFINT_DYN_CTL0_ITR_INDX_MASK);
11430 	else
11431 		I40E_WRITE_REG(hw,
11432 			       I40E_PFINT_DYN_CTLN(msix_intr -
11433 						   I40E_RX_VEC_START),
11434 			       I40E_PFINT_DYN_CTLN_ITR_INDX_MASK);
11435 	I40E_WRITE_FLUSH(hw);
11436 
11437 	return 0;
11438 }
11439 
11440 /**
11441  * This function is used to check if the register is valid.
11442  * Below is the valid registers list for X722 only:
11443  * 0x2b800--0x2bb00
11444  * 0x38700--0x38a00
11445  * 0x3d800--0x3db00
11446  * 0x208e00--0x209000
11447  * 0x20be00--0x20c000
11448  * 0x263c00--0x264000
11449  * 0x265c00--0x266000
11450  */
11451 static inline int i40e_valid_regs(enum i40e_mac_type type, uint32_t reg_offset)
11452 {
11453 	if ((type != I40E_MAC_X722) &&
11454 	    ((reg_offset >= 0x2b800 && reg_offset <= 0x2bb00) ||
11455 	     (reg_offset >= 0x38700 && reg_offset <= 0x38a00) ||
11456 	     (reg_offset >= 0x3d800 && reg_offset <= 0x3db00) ||
11457 	     (reg_offset >= 0x208e00 && reg_offset <= 0x209000) ||
11458 	     (reg_offset >= 0x20be00 && reg_offset <= 0x20c000) ||
11459 	     (reg_offset >= 0x263c00 && reg_offset <= 0x264000) ||
11460 	     (reg_offset >= 0x265c00 && reg_offset <= 0x266000)))
11461 		return 0;
11462 	else
11463 		return 1;
11464 }
11465 
11466 static int i40e_get_regs(struct rte_eth_dev *dev,
11467 			 struct rte_dev_reg_info *regs)
11468 {
11469 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11470 	uint32_t *ptr_data = regs->data;
11471 	uint32_t reg_idx, arr_idx, arr_idx2, reg_offset;
11472 	const struct i40e_reg_info *reg_info;
11473 
11474 	if (ptr_data == NULL) {
11475 		regs->length = I40E_GLGEN_STAT_CLEAR + 4;
11476 		regs->width = sizeof(uint32_t);
11477 		return 0;
11478 	}
11479 
11480 	/* The first few registers have to be read using AQ operations */
11481 	reg_idx = 0;
11482 	while (i40e_regs_adminq[reg_idx].name) {
11483 		reg_info = &i40e_regs_adminq[reg_idx++];
11484 		for (arr_idx = 0; arr_idx <= reg_info->count1; arr_idx++)
11485 			for (arr_idx2 = 0;
11486 					arr_idx2 <= reg_info->count2;
11487 					arr_idx2++) {
11488 				reg_offset = arr_idx * reg_info->stride1 +
11489 					arr_idx2 * reg_info->stride2;
11490 				reg_offset += reg_info->base_addr;
11491 				ptr_data[reg_offset >> 2] =
11492 					i40e_read_rx_ctl(hw, reg_offset);
11493 			}
11494 	}
11495 
11496 	/* The remaining registers can be read using primitives */
11497 	reg_idx = 0;
11498 	while (i40e_regs_others[reg_idx].name) {
11499 		reg_info = &i40e_regs_others[reg_idx++];
11500 		for (arr_idx = 0; arr_idx <= reg_info->count1; arr_idx++)
11501 			for (arr_idx2 = 0;
11502 					arr_idx2 <= reg_info->count2;
11503 					arr_idx2++) {
11504 				reg_offset = arr_idx * reg_info->stride1 +
11505 					arr_idx2 * reg_info->stride2;
11506 				reg_offset += reg_info->base_addr;
11507 				if (!i40e_valid_regs(hw->mac.type, reg_offset))
11508 					ptr_data[reg_offset >> 2] = 0;
11509 				else
11510 					ptr_data[reg_offset >> 2] =
11511 						I40E_READ_REG(hw, reg_offset);
11512 			}
11513 	}
11514 
11515 	return 0;
11516 }
11517 
11518 static int i40e_get_eeprom_length(struct rte_eth_dev *dev)
11519 {
11520 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11521 
11522 	/* Convert word count to byte count */
11523 	return hw->nvm.sr_size << 1;
11524 }
11525 
11526 static int i40e_get_eeprom(struct rte_eth_dev *dev,
11527 			   struct rte_dev_eeprom_info *eeprom)
11528 {
11529 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11530 	uint16_t *data = eeprom->data;
11531 	uint16_t offset, length, cnt_words;
11532 	int ret_code;
11533 
11534 	offset = eeprom->offset >> 1;
11535 	length = eeprom->length >> 1;
11536 	cnt_words = length;
11537 
11538 	if (offset > hw->nvm.sr_size ||
11539 		offset + length > hw->nvm.sr_size) {
11540 		PMD_DRV_LOG(ERR, "Requested EEPROM bytes out of range.");
11541 		return -EINVAL;
11542 	}
11543 
11544 	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
11545 
11546 	ret_code = i40e_read_nvm_buffer(hw, offset, &cnt_words, data);
11547 	if (ret_code != I40E_SUCCESS || cnt_words != length) {
11548 		PMD_DRV_LOG(ERR, "EEPROM read failed.");
11549 		return -EIO;
11550 	}
11551 
11552 	return 0;
11553 }
11554 
11555 static int i40e_get_module_info(struct rte_eth_dev *dev,
11556 				struct rte_eth_dev_module_info *modinfo)
11557 {
11558 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11559 	uint32_t sff8472_comp = 0;
11560 	uint32_t sff8472_swap = 0;
11561 	uint32_t sff8636_rev = 0;
11562 	i40e_status status;
11563 	uint32_t type = 0;
11564 
11565 	/* Check if firmware supports reading module EEPROM. */
11566 	if (!(hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE)) {
11567 		PMD_DRV_LOG(ERR,
11568 			    "Module EEPROM memory read not supported. "
11569 			    "Please update the NVM image.\n");
11570 		return -EINVAL;
11571 	}
11572 
11573 	status = i40e_update_link_info(hw);
11574 	if (status)
11575 		return -EIO;
11576 
11577 	if (hw->phy.link_info.phy_type == I40E_PHY_TYPE_EMPTY) {
11578 		PMD_DRV_LOG(ERR,
11579 			    "Cannot read module EEPROM memory. "
11580 			    "No module connected.\n");
11581 		return -EINVAL;
11582 	}
11583 
11584 	type = hw->phy.link_info.module_type[0];
11585 
11586 	switch (type) {
11587 	case I40E_MODULE_TYPE_SFP:
11588 		status = i40e_aq_get_phy_register(hw,
11589 				I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
11590 				I40E_I2C_EEPROM_DEV_ADDR, 1,
11591 				I40E_MODULE_SFF_8472_COMP,
11592 				&sff8472_comp, NULL);
11593 		if (status)
11594 			return -EIO;
11595 
11596 		status = i40e_aq_get_phy_register(hw,
11597 				I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
11598 				I40E_I2C_EEPROM_DEV_ADDR, 1,
11599 				I40E_MODULE_SFF_8472_SWAP,
11600 				&sff8472_swap, NULL);
11601 		if (status)
11602 			return -EIO;
11603 
11604 		/* Check if the module requires address swap to access
11605 		 * the other EEPROM memory page.
11606 		 */
11607 		if (sff8472_swap & I40E_MODULE_SFF_ADDR_MODE) {
11608 			PMD_DRV_LOG(WARNING,
11609 				    "Module address swap to access "
11610 				    "page 0xA2 is not supported.\n");
11611 			modinfo->type = RTE_ETH_MODULE_SFF_8079;
11612 			modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN;
11613 		} else if (sff8472_comp == 0x00) {
11614 			/* Module is not SFF-8472 compliant */
11615 			modinfo->type = RTE_ETH_MODULE_SFF_8079;
11616 			modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN;
11617 		} else {
11618 			modinfo->type = RTE_ETH_MODULE_SFF_8472;
11619 			modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
11620 		}
11621 		break;
11622 	case I40E_MODULE_TYPE_QSFP_PLUS:
11623 		/* Read from memory page 0. */
11624 		status = i40e_aq_get_phy_register(hw,
11625 				I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
11626 				0, 1,
11627 				I40E_MODULE_REVISION_ADDR,
11628 				&sff8636_rev, NULL);
11629 		if (status)
11630 			return -EIO;
11631 		/* Determine revision compliance byte */
11632 		if (sff8636_rev > 0x02) {
11633 			/* Module is SFF-8636 compliant */
11634 			modinfo->type = RTE_ETH_MODULE_SFF_8636;
11635 			modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN;
11636 		} else {
11637 			modinfo->type = RTE_ETH_MODULE_SFF_8436;
11638 			modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN;
11639 		}
11640 		break;
11641 	case I40E_MODULE_TYPE_QSFP28:
11642 		modinfo->type = RTE_ETH_MODULE_SFF_8636;
11643 		modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN;
11644 		break;
11645 	default:
11646 		PMD_DRV_LOG(ERR, "Module type unrecognized\n");
11647 		return -EINVAL;
11648 	}
11649 	return 0;
11650 }
11651 
11652 static int i40e_get_module_eeprom(struct rte_eth_dev *dev,
11653 				  struct rte_dev_eeprom_info *info)
11654 {
11655 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11656 	bool is_sfp = false;
11657 	i40e_status status;
11658 	uint8_t *data;
11659 	uint32_t value = 0;
11660 	uint32_t i;
11661 
11662 	if (hw->phy.link_info.module_type[0] == I40E_MODULE_TYPE_SFP)
11663 		is_sfp = true;
11664 
11665 	data = info->data;
11666 	for (i = 0; i < info->length; i++) {
11667 		u32 offset = i + info->offset;
11668 		u32 addr = is_sfp ? I40E_I2C_EEPROM_DEV_ADDR : 0;
11669 
11670 		/* Check if we need to access the other memory page */
11671 		if (is_sfp) {
11672 			if (offset >= RTE_ETH_MODULE_SFF_8079_LEN) {
11673 				offset -= RTE_ETH_MODULE_SFF_8079_LEN;
11674 				addr = I40E_I2C_EEPROM_DEV_ADDR2;
11675 			}
11676 		} else {
11677 			while (offset >= RTE_ETH_MODULE_SFF_8436_LEN) {
11678 				/* Compute memory page number and offset. */
11679 				offset -= RTE_ETH_MODULE_SFF_8436_LEN / 2;
11680 				addr++;
11681 			}
11682 		}
11683 		status = i40e_aq_get_phy_register(hw,
11684 				I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
11685 				addr, 1, offset, &value, NULL);
11686 		if (status)
11687 			return -EIO;
11688 		data[i] = (uint8_t)value;
11689 	}
11690 	return 0;
11691 }
11692 
11693 static int i40e_set_default_mac_addr(struct rte_eth_dev *dev,
11694 				     struct rte_ether_addr *mac_addr)
11695 {
11696 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11697 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
11698 	struct i40e_vsi *vsi = pf->main_vsi;
11699 	struct i40e_mac_filter_info mac_filter;
11700 	struct i40e_mac_filter *f;
11701 	int ret;
11702 
11703 	if (!rte_is_valid_assigned_ether_addr(mac_addr)) {
11704 		PMD_DRV_LOG(ERR, "Tried to set invalid MAC address.");
11705 		return -EINVAL;
11706 	}
11707 
11708 	TAILQ_FOREACH(f, &vsi->mac_list, next) {
11709 		if (rte_is_same_ether_addr(&pf->dev_addr,
11710 						&f->mac_info.mac_addr))
11711 			break;
11712 	}
11713 
11714 	if (f == NULL) {
11715 		PMD_DRV_LOG(ERR, "Failed to find filter for default mac");
11716 		return -EIO;
11717 	}
11718 
11719 	mac_filter = f->mac_info;
11720 	ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr);
11721 	if (ret != I40E_SUCCESS) {
11722 		PMD_DRV_LOG(ERR, "Failed to delete mac filter");
11723 		return -EIO;
11724 	}
11725 	memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN);
11726 	ret = i40e_vsi_add_mac(vsi, &mac_filter);
11727 	if (ret != I40E_SUCCESS) {
11728 		PMD_DRV_LOG(ERR, "Failed to add mac filter");
11729 		return -EIO;
11730 	}
11731 	memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN);
11732 
11733 	ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL,
11734 					mac_addr->addr_bytes, NULL);
11735 	if (ret != I40E_SUCCESS) {
11736 		PMD_DRV_LOG(ERR, "Failed to change mac");
11737 		return -EIO;
11738 	}
11739 
11740 	return 0;
11741 }
11742 
11743 static int
11744 i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
11745 {
11746 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
11747 	struct rte_eth_dev_data *dev_data = pf->dev_data;
11748 	uint32_t frame_size = mtu + I40E_ETH_OVERHEAD;
11749 	int ret = 0;
11750 
11751 	/* check if mtu is within the allowed range */
11752 	if (mtu < RTE_ETHER_MIN_MTU || frame_size > I40E_FRAME_SIZE_MAX)
11753 		return -EINVAL;
11754 
11755 	/* mtu setting is forbidden if port is start */
11756 	if (dev_data->dev_started) {
11757 		PMD_DRV_LOG(ERR, "port %d must be stopped before configuration",
11758 			    dev_data->port_id);
11759 		return -EBUSY;
11760 	}
11761 
11762 	if (frame_size > I40E_ETH_MAX_LEN)
11763 		dev_data->dev_conf.rxmode.offloads |=
11764 			DEV_RX_OFFLOAD_JUMBO_FRAME;
11765 	else
11766 		dev_data->dev_conf.rxmode.offloads &=
11767 			~DEV_RX_OFFLOAD_JUMBO_FRAME;
11768 
11769 	dev_data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
11770 
11771 	return ret;
11772 }
11773 
11774 /* Restore ethertype filter */
11775 static void
11776 i40e_ethertype_filter_restore(struct i40e_pf *pf)
11777 {
11778 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
11779 	struct i40e_ethertype_filter_list
11780 		*ethertype_list = &pf->ethertype.ethertype_list;
11781 	struct i40e_ethertype_filter *f;
11782 	struct i40e_control_filter_stats stats;
11783 	uint16_t flags;
11784 
11785 	TAILQ_FOREACH(f, ethertype_list, rules) {
11786 		flags = 0;
11787 		if (!(f->flags & RTE_ETHTYPE_FLAGS_MAC))
11788 			flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC;
11789 		if (f->flags & RTE_ETHTYPE_FLAGS_DROP)
11790 			flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP;
11791 		flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE;
11792 
11793 		memset(&stats, 0, sizeof(stats));
11794 		i40e_aq_add_rem_control_packet_filter(hw,
11795 					    f->input.mac_addr.addr_bytes,
11796 					    f->input.ether_type,
11797 					    flags, pf->main_vsi->seid,
11798 					    f->queue, 1, &stats, NULL);
11799 	}
11800 	PMD_DRV_LOG(INFO, "Ethertype filter:"
11801 		    " mac_etype_used = %u, etype_used = %u,"
11802 		    " mac_etype_free = %u, etype_free = %u",
11803 		    stats.mac_etype_used, stats.etype_used,
11804 		    stats.mac_etype_free, stats.etype_free);
11805 }
11806 
11807 /* Restore tunnel filter */
11808 static void
11809 i40e_tunnel_filter_restore(struct i40e_pf *pf)
11810 {
11811 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
11812 	struct i40e_vsi *vsi;
11813 	struct i40e_pf_vf *vf;
11814 	struct i40e_tunnel_filter_list
11815 		*tunnel_list = &pf->tunnel.tunnel_list;
11816 	struct i40e_tunnel_filter *f;
11817 	struct i40e_aqc_cloud_filters_element_bb cld_filter;
11818 	bool big_buffer = 0;
11819 
11820 	TAILQ_FOREACH(f, tunnel_list, rules) {
11821 		if (!f->is_to_vf)
11822 			vsi = pf->main_vsi;
11823 		else {
11824 			vf = &pf->vfs[f->vf_id];
11825 			vsi = vf->vsi;
11826 		}
11827 		memset(&cld_filter, 0, sizeof(cld_filter));
11828 		rte_ether_addr_copy((struct rte_ether_addr *)
11829 				&f->input.outer_mac,
11830 			(struct rte_ether_addr *)&cld_filter.element.outer_mac);
11831 		rte_ether_addr_copy((struct rte_ether_addr *)
11832 				&f->input.inner_mac,
11833 			(struct rte_ether_addr *)&cld_filter.element.inner_mac);
11834 		cld_filter.element.inner_vlan = f->input.inner_vlan;
11835 		cld_filter.element.flags = f->input.flags;
11836 		cld_filter.element.tenant_id = f->input.tenant_id;
11837 		cld_filter.element.queue_number = f->queue;
11838 		rte_memcpy(cld_filter.general_fields,
11839 			   f->input.general_fields,
11840 			   sizeof(f->input.general_fields));
11841 
11842 		if (((f->input.flags &
11843 		     I40E_AQC_ADD_CLOUD_FILTER_0X11) ==
11844 		     I40E_AQC_ADD_CLOUD_FILTER_0X11) ||
11845 		    ((f->input.flags &
11846 		     I40E_AQC_ADD_CLOUD_FILTER_0X12) ==
11847 		     I40E_AQC_ADD_CLOUD_FILTER_0X12) ||
11848 		    ((f->input.flags &
11849 		     I40E_AQC_ADD_CLOUD_FILTER_0X10) ==
11850 		     I40E_AQC_ADD_CLOUD_FILTER_0X10))
11851 			big_buffer = 1;
11852 
11853 		if (big_buffer)
11854 			i40e_aq_add_cloud_filters_bb(hw,
11855 					vsi->seid, &cld_filter, 1);
11856 		else
11857 			i40e_aq_add_cloud_filters(hw, vsi->seid,
11858 						  &cld_filter.element, 1);
11859 	}
11860 }
11861 
11862 static void
11863 i40e_filter_restore(struct i40e_pf *pf)
11864 {
11865 	i40e_ethertype_filter_restore(pf);
11866 	i40e_tunnel_filter_restore(pf);
11867 	i40e_fdir_filter_restore(pf);
11868 	(void)i40e_hash_filter_restore(pf);
11869 }
11870 
11871 bool
11872 is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv)
11873 {
11874 	if (strcmp(dev->device->driver->name, drv->driver.name))
11875 		return false;
11876 
11877 	return true;
11878 }
11879 
11880 bool
11881 is_i40e_supported(struct rte_eth_dev *dev)
11882 {
11883 	return is_device_supported(dev, &rte_i40e_pmd);
11884 }
11885 
11886 struct i40e_customized_pctype*
11887 i40e_find_customized_pctype(struct i40e_pf *pf, uint8_t index)
11888 {
11889 	int i;
11890 
11891 	for (i = 0; i < I40E_CUSTOMIZED_MAX; i++) {
11892 		if (pf->customized_pctype[i].index == index)
11893 			return &pf->customized_pctype[i];
11894 	}
11895 	return NULL;
11896 }
11897 
11898 static int
11899 i40e_update_customized_pctype(struct rte_eth_dev *dev, uint8_t *pkg,
11900 			      uint32_t pkg_size, uint32_t proto_num,
11901 			      struct rte_pmd_i40e_proto_info *proto,
11902 			      enum rte_pmd_i40e_package_op op)
11903 {
11904 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
11905 	uint32_t pctype_num;
11906 	struct rte_pmd_i40e_ptype_info *pctype;
11907 	uint32_t buff_size;
11908 	struct i40e_customized_pctype *new_pctype = NULL;
11909 	uint8_t proto_id;
11910 	uint8_t pctype_value;
11911 	char name[64];
11912 	uint32_t i, j, n;
11913 	int ret;
11914 
11915 	if (op != RTE_PMD_I40E_PKG_OP_WR_ADD &&
11916 	    op != RTE_PMD_I40E_PKG_OP_WR_DEL) {
11917 		PMD_DRV_LOG(ERR, "Unsupported operation.");
11918 		return -1;
11919 	}
11920 
11921 	ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size,
11922 				(uint8_t *)&pctype_num, sizeof(pctype_num),
11923 				RTE_PMD_I40E_PKG_INFO_PCTYPE_NUM);
11924 	if (ret) {
11925 		PMD_DRV_LOG(ERR, "Failed to get pctype number");
11926 		return -1;
11927 	}
11928 	if (!pctype_num) {
11929 		PMD_DRV_LOG(INFO, "No new pctype added");
11930 		return -1;
11931 	}
11932 
11933 	buff_size = pctype_num * sizeof(struct rte_pmd_i40e_proto_info);
11934 	pctype = rte_zmalloc("new_pctype", buff_size, 0);
11935 	if (!pctype) {
11936 		PMD_DRV_LOG(ERR, "Failed to allocate memory");
11937 		return -1;
11938 	}
11939 	/* get information about new pctype list */
11940 	ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size,
11941 					(uint8_t *)pctype, buff_size,
11942 					RTE_PMD_I40E_PKG_INFO_PCTYPE_LIST);
11943 	if (ret) {
11944 		PMD_DRV_LOG(ERR, "Failed to get pctype list");
11945 		rte_free(pctype);
11946 		return -1;
11947 	}
11948 
11949 	/* Update customized pctype. */
11950 	for (i = 0; i < pctype_num; i++) {
11951 		pctype_value = pctype[i].ptype_id;
11952 		memset(name, 0, sizeof(name));
11953 		for (j = 0; j < RTE_PMD_I40E_PROTO_NUM; j++) {
11954 			proto_id = pctype[i].protocols[j];
11955 			if (proto_id == RTE_PMD_I40E_PROTO_UNUSED)
11956 				continue;
11957 			for (n = 0; n < proto_num; n++) {
11958 				if (proto[n].proto_id != proto_id)
11959 					continue;
11960 				strlcat(name, proto[n].name, sizeof(name));
11961 				strlcat(name, "_", sizeof(name));
11962 				break;
11963 			}
11964 		}
11965 		name[strlen(name) - 1] = '\0';
11966 		PMD_DRV_LOG(INFO, "name = %s\n", name);
11967 		if (!strcmp(name, "GTPC"))
11968 			new_pctype =
11969 				i40e_find_customized_pctype(pf,
11970 						      I40E_CUSTOMIZED_GTPC);
11971 		else if (!strcmp(name, "GTPU_IPV4"))
11972 			new_pctype =
11973 				i40e_find_customized_pctype(pf,
11974 						   I40E_CUSTOMIZED_GTPU_IPV4);
11975 		else if (!strcmp(name, "GTPU_IPV6"))
11976 			new_pctype =
11977 				i40e_find_customized_pctype(pf,
11978 						   I40E_CUSTOMIZED_GTPU_IPV6);
11979 		else if (!strcmp(name, "GTPU"))
11980 			new_pctype =
11981 				i40e_find_customized_pctype(pf,
11982 						      I40E_CUSTOMIZED_GTPU);
11983 		else if (!strcmp(name, "IPV4_L2TPV3"))
11984 			new_pctype =
11985 				i40e_find_customized_pctype(pf,
11986 						I40E_CUSTOMIZED_IPV4_L2TPV3);
11987 		else if (!strcmp(name, "IPV6_L2TPV3"))
11988 			new_pctype =
11989 				i40e_find_customized_pctype(pf,
11990 						I40E_CUSTOMIZED_IPV6_L2TPV3);
11991 		else if (!strcmp(name, "IPV4_ESP"))
11992 			new_pctype =
11993 				i40e_find_customized_pctype(pf,
11994 						I40E_CUSTOMIZED_ESP_IPV4);
11995 		else if (!strcmp(name, "IPV6_ESP"))
11996 			new_pctype =
11997 				i40e_find_customized_pctype(pf,
11998 						I40E_CUSTOMIZED_ESP_IPV6);
11999 		else if (!strcmp(name, "IPV4_UDP_ESP"))
12000 			new_pctype =
12001 				i40e_find_customized_pctype(pf,
12002 						I40E_CUSTOMIZED_ESP_IPV4_UDP);
12003 		else if (!strcmp(name, "IPV6_UDP_ESP"))
12004 			new_pctype =
12005 				i40e_find_customized_pctype(pf,
12006 						I40E_CUSTOMIZED_ESP_IPV6_UDP);
12007 		else if (!strcmp(name, "IPV4_AH"))
12008 			new_pctype =
12009 				i40e_find_customized_pctype(pf,
12010 						I40E_CUSTOMIZED_AH_IPV4);
12011 		else if (!strcmp(name, "IPV6_AH"))
12012 			new_pctype =
12013 				i40e_find_customized_pctype(pf,
12014 						I40E_CUSTOMIZED_AH_IPV6);
12015 		if (new_pctype) {
12016 			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) {
12017 				new_pctype->pctype = pctype_value;
12018 				new_pctype->valid = true;
12019 			} else {
12020 				new_pctype->pctype = I40E_FILTER_PCTYPE_INVALID;
12021 				new_pctype->valid = false;
12022 			}
12023 		}
12024 	}
12025 
12026 	rte_free(pctype);
12027 	return 0;
12028 }
12029 
12030 static int
12031 i40e_update_customized_ptype(struct rte_eth_dev *dev, uint8_t *pkg,
12032 			     uint32_t pkg_size, uint32_t proto_num,
12033 			     struct rte_pmd_i40e_proto_info *proto,
12034 			     enum rte_pmd_i40e_package_op op)
12035 {
12036 	struct rte_pmd_i40e_ptype_mapping *ptype_mapping;
12037 	uint16_t port_id = dev->data->port_id;
12038 	uint32_t ptype_num;
12039 	struct rte_pmd_i40e_ptype_info *ptype;
12040 	uint32_t buff_size;
12041 	uint8_t proto_id;
12042 	char name[RTE_PMD_I40E_DDP_NAME_SIZE];
12043 	uint32_t i, j, n;
12044 	bool in_tunnel;
12045 	int ret;
12046 
12047 	if (op != RTE_PMD_I40E_PKG_OP_WR_ADD &&
12048 	    op != RTE_PMD_I40E_PKG_OP_WR_DEL) {
12049 		PMD_DRV_LOG(ERR, "Unsupported operation.");
12050 		return -1;
12051 	}
12052 
12053 	if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
12054 		rte_pmd_i40e_ptype_mapping_reset(port_id);
12055 		return 0;
12056 	}
12057 
12058 	/* get information about new ptype num */
12059 	ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size,
12060 				(uint8_t *)&ptype_num, sizeof(ptype_num),
12061 				RTE_PMD_I40E_PKG_INFO_PTYPE_NUM);
12062 	if (ret) {
12063 		PMD_DRV_LOG(ERR, "Failed to get ptype number");
12064 		return ret;
12065 	}
12066 	if (!ptype_num) {
12067 		PMD_DRV_LOG(INFO, "No new ptype added");
12068 		return -1;
12069 	}
12070 
12071 	buff_size = ptype_num * sizeof(struct rte_pmd_i40e_ptype_info);
12072 	ptype = rte_zmalloc("new_ptype", buff_size, 0);
12073 	if (!ptype) {
12074 		PMD_DRV_LOG(ERR, "Failed to allocate memory");
12075 		return -1;
12076 	}
12077 
12078 	/* get information about new ptype list */
12079 	ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size,
12080 					(uint8_t *)ptype, buff_size,
12081 					RTE_PMD_I40E_PKG_INFO_PTYPE_LIST);
12082 	if (ret) {
12083 		PMD_DRV_LOG(ERR, "Failed to get ptype list");
12084 		rte_free(ptype);
12085 		return ret;
12086 	}
12087 
12088 	buff_size = ptype_num * sizeof(struct rte_pmd_i40e_ptype_mapping);
12089 	ptype_mapping = rte_zmalloc("ptype_mapping", buff_size, 0);
12090 	if (!ptype_mapping) {
12091 		PMD_DRV_LOG(ERR, "Failed to allocate memory");
12092 		rte_free(ptype);
12093 		return -1;
12094 	}
12095 
12096 	/* Update ptype mapping table. */
12097 	for (i = 0; i < ptype_num; i++) {
12098 		ptype_mapping[i].hw_ptype = ptype[i].ptype_id;
12099 		ptype_mapping[i].sw_ptype = 0;
12100 		in_tunnel = false;
12101 		for (j = 0; j < RTE_PMD_I40E_PROTO_NUM; j++) {
12102 			proto_id = ptype[i].protocols[j];
12103 			if (proto_id == RTE_PMD_I40E_PROTO_UNUSED)
12104 				continue;
12105 			for (n = 0; n < proto_num; n++) {
12106 				if (proto[n].proto_id != proto_id)
12107 					continue;
12108 				memset(name, 0, sizeof(name));
12109 				strcpy(name, proto[n].name);
12110 				PMD_DRV_LOG(INFO, "name = %s\n", name);
12111 				if (!strncasecmp(name, "PPPOE", 5))
12112 					ptype_mapping[i].sw_ptype |=
12113 						RTE_PTYPE_L2_ETHER_PPPOE;
12114 				else if (!strncasecmp(name, "IPV4FRAG", 8) &&
12115 					 !in_tunnel) {
12116 					ptype_mapping[i].sw_ptype |=
12117 						RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
12118 					ptype_mapping[i].sw_ptype |=
12119 						RTE_PTYPE_L4_FRAG;
12120 				} else if (!strncasecmp(name, "IPV4FRAG", 8) &&
12121 					   in_tunnel) {
12122 					ptype_mapping[i].sw_ptype |=
12123 					    RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN;
12124 					ptype_mapping[i].sw_ptype |=
12125 						RTE_PTYPE_INNER_L4_FRAG;
12126 				} else if (!strncasecmp(name, "OIPV4", 5)) {
12127 					ptype_mapping[i].sw_ptype |=
12128 						RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
12129 					in_tunnel = true;
12130 				} else if (!strncasecmp(name, "IPV4", 4) &&
12131 					   !in_tunnel)
12132 					ptype_mapping[i].sw_ptype |=
12133 						RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
12134 				else if (!strncasecmp(name, "IPV4", 4) &&
12135 					 in_tunnel)
12136 					ptype_mapping[i].sw_ptype |=
12137 					    RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN;
12138 				else if (!strncasecmp(name, "IPV6FRAG", 8) &&
12139 					 !in_tunnel) {
12140 					ptype_mapping[i].sw_ptype |=
12141 						RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
12142 					ptype_mapping[i].sw_ptype |=
12143 						RTE_PTYPE_L4_FRAG;
12144 				} else if (!strncasecmp(name, "IPV6FRAG", 8) &&
12145 					   in_tunnel) {
12146 					ptype_mapping[i].sw_ptype |=
12147 					    RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN;
12148 					ptype_mapping[i].sw_ptype |=
12149 						RTE_PTYPE_INNER_L4_FRAG;
12150 				} else if (!strncasecmp(name, "OIPV6", 5)) {
12151 					ptype_mapping[i].sw_ptype |=
12152 						RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
12153 					in_tunnel = true;
12154 				} else if (!strncasecmp(name, "IPV6", 4) &&
12155 					   !in_tunnel)
12156 					ptype_mapping[i].sw_ptype |=
12157 						RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
12158 				else if (!strncasecmp(name, "IPV6", 4) &&
12159 					 in_tunnel)
12160 					ptype_mapping[i].sw_ptype |=
12161 					    RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN;
12162 				else if (!strncasecmp(name, "UDP", 3) &&
12163 					 !in_tunnel)
12164 					ptype_mapping[i].sw_ptype |=
12165 						RTE_PTYPE_L4_UDP;
12166 				else if (!strncasecmp(name, "UDP", 3) &&
12167 					 in_tunnel)
12168 					ptype_mapping[i].sw_ptype |=
12169 						RTE_PTYPE_INNER_L4_UDP;
12170 				else if (!strncasecmp(name, "TCP", 3) &&
12171 					 !in_tunnel)
12172 					ptype_mapping[i].sw_ptype |=
12173 						RTE_PTYPE_L4_TCP;
12174 				else if (!strncasecmp(name, "TCP", 3) &&
12175 					 in_tunnel)
12176 					ptype_mapping[i].sw_ptype |=
12177 						RTE_PTYPE_INNER_L4_TCP;
12178 				else if (!strncasecmp(name, "SCTP", 4) &&
12179 					 !in_tunnel)
12180 					ptype_mapping[i].sw_ptype |=
12181 						RTE_PTYPE_L4_SCTP;
12182 				else if (!strncasecmp(name, "SCTP", 4) &&
12183 					 in_tunnel)
12184 					ptype_mapping[i].sw_ptype |=
12185 						RTE_PTYPE_INNER_L4_SCTP;
12186 				else if ((!strncasecmp(name, "ICMP", 4) ||
12187 					  !strncasecmp(name, "ICMPV6", 6)) &&
12188 					 !in_tunnel)
12189 					ptype_mapping[i].sw_ptype |=
12190 						RTE_PTYPE_L4_ICMP;
12191 				else if ((!strncasecmp(name, "ICMP", 4) ||
12192 					  !strncasecmp(name, "ICMPV6", 6)) &&
12193 					 in_tunnel)
12194 					ptype_mapping[i].sw_ptype |=
12195 						RTE_PTYPE_INNER_L4_ICMP;
12196 				else if (!strncasecmp(name, "GTPC", 4)) {
12197 					ptype_mapping[i].sw_ptype |=
12198 						RTE_PTYPE_TUNNEL_GTPC;
12199 					in_tunnel = true;
12200 				} else if (!strncasecmp(name, "GTPU", 4)) {
12201 					ptype_mapping[i].sw_ptype |=
12202 						RTE_PTYPE_TUNNEL_GTPU;
12203 					in_tunnel = true;
12204 				} else if (!strncasecmp(name, "ESP", 3)) {
12205 					ptype_mapping[i].sw_ptype |=
12206 						RTE_PTYPE_TUNNEL_ESP;
12207 					in_tunnel = true;
12208 				} else if (!strncasecmp(name, "GRENAT", 6)) {
12209 					ptype_mapping[i].sw_ptype |=
12210 						RTE_PTYPE_TUNNEL_GRENAT;
12211 					in_tunnel = true;
12212 				} else if (!strncasecmp(name, "L2TPV2CTL", 9) ||
12213 					   !strncasecmp(name, "L2TPV2", 6) ||
12214 					   !strncasecmp(name, "L2TPV3", 6)) {
12215 					ptype_mapping[i].sw_ptype |=
12216 						RTE_PTYPE_TUNNEL_L2TP;
12217 					in_tunnel = true;
12218 				}
12219 
12220 				break;
12221 			}
12222 		}
12223 	}
12224 
12225 	ret = rte_pmd_i40e_ptype_mapping_update(port_id, ptype_mapping,
12226 						ptype_num, 0);
12227 	if (ret)
12228 		PMD_DRV_LOG(ERR, "Failed to update ptype mapping table.");
12229 
12230 	rte_free(ptype_mapping);
12231 	rte_free(ptype);
12232 	return ret;
12233 }
12234 
12235 void
12236 i40e_update_customized_info(struct rte_eth_dev *dev, uint8_t *pkg,
12237 			    uint32_t pkg_size, enum rte_pmd_i40e_package_op op)
12238 {
12239 	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
12240 	uint32_t proto_num;
12241 	struct rte_pmd_i40e_proto_info *proto;
12242 	uint32_t buff_size;
12243 	uint32_t i;
12244 	int ret;
12245 
12246 	if (op != RTE_PMD_I40E_PKG_OP_WR_ADD &&
12247 	    op != RTE_PMD_I40E_PKG_OP_WR_DEL) {
12248 		PMD_DRV_LOG(ERR, "Unsupported operation.");
12249 		return;
12250 	}
12251 
12252 	/* get information about protocol number */
12253 	ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size,
12254 				       (uint8_t *)&proto_num, sizeof(proto_num),
12255 				       RTE_PMD_I40E_PKG_INFO_PROTOCOL_NUM);
12256 	if (ret) {
12257 		PMD_DRV_LOG(ERR, "Failed to get protocol number");
12258 		return;
12259 	}
12260 	if (!proto_num) {
12261 		PMD_DRV_LOG(INFO, "No new protocol added");
12262 		return;
12263 	}
12264 
12265 	buff_size = proto_num * sizeof(struct rte_pmd_i40e_proto_info);
12266 	proto = rte_zmalloc("new_proto", buff_size, 0);
12267 	if (!proto) {
12268 		PMD_DRV_LOG(ERR, "Failed to allocate memory");
12269 		return;
12270 	}
12271 
12272 	/* get information about protocol list */
12273 	ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size,
12274 					(uint8_t *)proto, buff_size,
12275 					RTE_PMD_I40E_PKG_INFO_PROTOCOL_LIST);
12276 	if (ret) {
12277 		PMD_DRV_LOG(ERR, "Failed to get protocol list");
12278 		rte_free(proto);
12279 		return;
12280 	}
12281 
12282 	/* Check if GTP is supported. */
12283 	for (i = 0; i < proto_num; i++) {
12284 		if (!strncmp(proto[i].name, "GTP", 3)) {
12285 			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
12286 				pf->gtp_support = true;
12287 			else
12288 				pf->gtp_support = false;
12289 			break;
12290 		}
12291 	}
12292 
12293 	/* Check if ESP is supported. */
12294 	for (i = 0; i < proto_num; i++) {
12295 		if (!strncmp(proto[i].name, "ESP", 3)) {
12296 			if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
12297 				pf->esp_support = true;
12298 			else
12299 				pf->esp_support = false;
12300 			break;
12301 		}
12302 	}
12303 
12304 	/* Update customized pctype info */
12305 	ret = i40e_update_customized_pctype(dev, pkg, pkg_size,
12306 					    proto_num, proto, op);
12307 	if (ret)
12308 		PMD_DRV_LOG(INFO, "No pctype is updated.");
12309 
12310 	/* Update customized ptype info */
12311 	ret = i40e_update_customized_ptype(dev, pkg, pkg_size,
12312 					   proto_num, proto, op);
12313 	if (ret)
12314 		PMD_DRV_LOG(INFO, "No ptype is updated.");
12315 
12316 	rte_free(proto);
12317 }
12318 
12319 /* Create a QinQ cloud filter
12320  *
12321  * The Fortville NIC has limited resources for tunnel filters,
12322  * so we can only reuse existing filters.
12323  *
12324  * In step 1 we define which Field Vector fields can be used for
12325  * filter types.
12326  * As we do not have the inner tag defined as a field,
12327  * we have to define it first, by reusing one of L1 entries.
12328  *
12329  * In step 2 we are replacing one of existing filter types with
12330  * a new one for QinQ.
12331  * As we reusing L1 and replacing L2, some of the default filter
12332  * types will disappear,which depends on L1 and L2 entries we reuse.
12333  *
12334  * Step 1: Create L1 filter of outer vlan (12b) + inner vlan (12b)
12335  *
12336  * 1.	Create L1 filter of outer vlan (12b) which will be in use
12337  *		later when we define the cloud filter.
12338  *	a.	Valid_flags.replace_cloud = 0
12339  *	b.	Old_filter = 10 (Stag_Inner_Vlan)
12340  *	c.	New_filter = 0x10
12341  *	d.	TR bit = 0xff (optional, not used here)
12342  *	e.	Buffer – 2 entries:
12343  *		i.	Byte 0 = 8 (outer vlan FV index).
12344  *			Byte 1 = 0 (rsv)
12345  *			Byte 2-3 = 0x0fff
12346  *		ii.	Byte 0 = 37 (inner vlan FV index).
12347  *			Byte 1 =0 (rsv)
12348  *			Byte 2-3 = 0x0fff
12349  *
12350  * Step 2:
12351  * 2.	Create cloud filter using two L1 filters entries: stag and
12352  *		new filter(outer vlan+ inner vlan)
12353  *	a.	Valid_flags.replace_cloud = 1
12354  *	b.	Old_filter = 1 (instead of outer IP)
12355  *	c.	New_filter = 0x10
12356  *	d.	Buffer – 2 entries:
12357  *		i.	Byte 0 = 0x80 | 7 (valid | Stag).
12358  *			Byte 1-3 = 0 (rsv)
12359  *		ii.	Byte 8 = 0x80 | 0x10 (valid | new l1 filter step1)
12360  *			Byte 9-11 = 0 (rsv)
12361  */
12362 static int
12363 i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
12364 {
12365 	int ret = -ENOTSUP;
12366 	struct i40e_aqc_replace_cloud_filters_cmd  filter_replace;
12367 	struct i40e_aqc_replace_cloud_filters_cmd_buf  filter_replace_buf;
12368 	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
12369 	struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev;
12370 
12371 	if (pf->support_multi_driver) {
12372 		PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
12373 		return ret;
12374 	}
12375 
12376 	/* Init */
12377 	memset(&filter_replace, 0,
12378 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
12379 	memset(&filter_replace_buf, 0,
12380 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
12381 
12382 	/* create L1 filter */
12383 	filter_replace.old_filter_type =
12384 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_IVLAN;
12385 	filter_replace.new_filter_type = I40E_AQC_ADD_CLOUD_FILTER_0X10;
12386 	filter_replace.tr_bit = 0;
12387 
12388 	/* Prepare the buffer, 2 entries */
12389 	filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_VLAN;
12390 	filter_replace_buf.data[0] |=
12391 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
12392 	/* Field Vector 12b mask */
12393 	filter_replace_buf.data[2] = 0xff;
12394 	filter_replace_buf.data[3] = 0x0f;
12395 	filter_replace_buf.data[4] =
12396 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_INNER_VLAN;
12397 	filter_replace_buf.data[4] |=
12398 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
12399 	/* Field Vector 12b mask */
12400 	filter_replace_buf.data[6] = 0xff;
12401 	filter_replace_buf.data[7] = 0x0f;
12402 	ret = i40e_aq_replace_cloud_filters(hw, &filter_replace,
12403 			&filter_replace_buf);
12404 	if (ret != I40E_SUCCESS)
12405 		return ret;
12406 
12407 	if (filter_replace.old_filter_type !=
12408 	    filter_replace.new_filter_type)
12409 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type."
12410 			    " original: 0x%x, new: 0x%x",
12411 			    dev->device->name,
12412 			    filter_replace.old_filter_type,
12413 			    filter_replace.new_filter_type);
12414 
12415 	/* Apply the second L2 cloud filter */
12416 	memset(&filter_replace, 0,
12417 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
12418 	memset(&filter_replace_buf, 0,
12419 	       sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
12420 
12421 	/* create L2 filter, input for L2 filter will be L1 filter  */
12422 	filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER;
12423 	filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_OIP;
12424 	filter_replace.new_filter_type = I40E_AQC_ADD_CLOUD_FILTER_0X10;
12425 
12426 	/* Prepare the buffer, 2 entries */
12427 	filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
12428 	filter_replace_buf.data[0] |=
12429 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
12430 	filter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_0X10;
12431 	filter_replace_buf.data[4] |=
12432 		I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
12433 	ret = i40e_aq_replace_cloud_filters(hw, &filter_replace,
12434 			&filter_replace_buf);
12435 	if (!ret && (filter_replace.old_filter_type !=
12436 		     filter_replace.new_filter_type))
12437 		PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type."
12438 			    " original: 0x%x, new: 0x%x",
12439 			    dev->device->name,
12440 			    filter_replace.old_filter_type,
12441 			    filter_replace.new_filter_type);
12442 
12443 	return ret;
12444 }
12445 
12446 RTE_LOG_REGISTER(i40e_logtype_init, pmd.net.i40e.init, NOTICE);
12447 RTE_LOG_REGISTER(i40e_logtype_driver, pmd.net.i40e.driver, NOTICE);
12448 #ifdef RTE_ETHDEV_DEBUG_RX
12449 RTE_LOG_REGISTER(i40e_logtype_rx, pmd.net.i40e.rx, DEBUG);
12450 #endif
12451 #ifdef RTE_ETHDEV_DEBUG_TX
12452 RTE_LOG_REGISTER(i40e_logtype_tx, pmd.net.i40e.tx, DEBUG);
12453 #endif
12454 
12455 RTE_PMD_REGISTER_PARAM_STRING(net_i40e,
12456 			      ETH_I40E_FLOATING_VEB_ARG "=1"
12457 			      ETH_I40E_FLOATING_VEB_LIST_ARG "=<string>"
12458 			      ETH_I40E_QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16"
12459 			      ETH_I40E_SUPPORT_MULTI_DRIVER "=1");
12460