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