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