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