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