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