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