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