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 vsi = pf->main_vsi; 1497 1498 /* Disable double vlan by default */ 1499 i40e_vsi_config_double_vlan(vsi, FALSE); 1500 1501 /* Disable S-TAG identification when floating_veb is disabled */ 1502 if (!pf->floating_veb) { 1503 ret = I40E_READ_REG(hw, I40E_PRT_L2TAGSEN); 1504 if (ret & I40E_L2_TAGS_S_TAG_MASK) { 1505 ret &= ~I40E_L2_TAGS_S_TAG_MASK; 1506 I40E_WRITE_REG(hw, I40E_PRT_L2TAGSEN, ret); 1507 } 1508 } 1509 1510 if (!vsi->max_macaddrs) 1511 len = ETHER_ADDR_LEN; 1512 else 1513 len = ETHER_ADDR_LEN * vsi->max_macaddrs; 1514 1515 /* Should be after VSI initialized */ 1516 dev->data->mac_addrs = rte_zmalloc("i40e", len, 0); 1517 if (!dev->data->mac_addrs) { 1518 PMD_INIT_LOG(ERR, 1519 "Failed to allocated memory for storing mac address"); 1520 goto err_mac_alloc; 1521 } 1522 ether_addr_copy((struct ether_addr *)hw->mac.perm_addr, 1523 &dev->data->mac_addrs[0]); 1524 1525 /* Init dcb to sw mode by default */ 1526 ret = i40e_dcb_init_configure(dev, TRUE); 1527 if (ret != I40E_SUCCESS) { 1528 PMD_INIT_LOG(INFO, "Failed to init dcb."); 1529 pf->flags &= ~I40E_FLAG_DCB; 1530 } 1531 /* Update HW struct after DCB configuration */ 1532 i40e_get_cap(hw); 1533 1534 /* initialize pf host driver to setup SRIOV resource if applicable */ 1535 i40e_pf_host_init(dev); 1536 1537 /* register callback func to eal lib */ 1538 rte_intr_callback_register(intr_handle, 1539 i40e_dev_interrupt_handler, dev); 1540 1541 /* configure and enable device interrupt */ 1542 i40e_pf_config_irq0(hw, TRUE); 1543 i40e_pf_enable_irq0(hw); 1544 1545 /* enable uio intr after callback register */ 1546 rte_intr_enable(intr_handle); 1547 1548 /* By default disable flexible payload in global configuration */ 1549 if (!pf->support_multi_driver) 1550 i40e_flex_payload_reg_set_default(hw); 1551 1552 /* 1553 * Add an ethertype filter to drop all flow control frames transmitted 1554 * from VSIs. By doing so, we stop VF from sending out PAUSE or PFC 1555 * frames to wire. 1556 */ 1557 i40e_add_tx_flow_control_drop_filter(pf); 1558 1559 /* Set the max frame size to 0x2600 by default, 1560 * in case other drivers changed the default value. 1561 */ 1562 i40e_aq_set_mac_config(hw, I40E_FRAME_SIZE_MAX, TRUE, 0, NULL); 1563 1564 /* initialize mirror rule list */ 1565 TAILQ_INIT(&pf->mirror_list); 1566 1567 /* initialize Traffic Manager configuration */ 1568 i40e_tm_conf_init(dev); 1569 1570 /* Initialize customized information */ 1571 i40e_init_customized_info(pf); 1572 1573 ret = i40e_init_ethtype_filter_list(dev); 1574 if (ret < 0) 1575 goto err_init_ethtype_filter_list; 1576 ret = i40e_init_tunnel_filter_list(dev); 1577 if (ret < 0) 1578 goto err_init_tunnel_filter_list; 1579 ret = i40e_init_fdir_filter_list(dev); 1580 if (ret < 0) 1581 goto err_init_fdir_filter_list; 1582 1583 /* initialize queue region configuration */ 1584 i40e_init_queue_region_conf(dev); 1585 1586 /* initialize rss configuration from rte_flow */ 1587 memset(&pf->rss_info, 0, 1588 sizeof(struct i40e_rte_flow_rss_conf)); 1589 1590 /* reset all stats of the device, including pf and main vsi */ 1591 i40e_dev_stats_reset(dev); 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 struct i40e_vsi *vsi; 3178 unsigned i; 3179 3180 /* call read registers - updates values, now write them to struct */ 3181 i40e_read_stats_registers(pf, hw); 3182 3183 stats->ipackets = pf->main_vsi->eth_stats.rx_unicast + 3184 pf->main_vsi->eth_stats.rx_multicast + 3185 pf->main_vsi->eth_stats.rx_broadcast - 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 = pf->main_vsi->eth_stats.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 if (pf->vfs) { 3203 for (i = 0; i < pf->vf_num; i++) { 3204 vsi = pf->vfs[i].vsi; 3205 i40e_update_vsi_stats(vsi); 3206 3207 stats->ipackets += (vsi->eth_stats.rx_unicast + 3208 vsi->eth_stats.rx_multicast + 3209 vsi->eth_stats.rx_broadcast - 3210 vsi->eth_stats.rx_discards); 3211 stats->ibytes += vsi->eth_stats.rx_bytes; 3212 stats->oerrors += vsi->eth_stats.tx_errors; 3213 stats->imissed += vsi->eth_stats.rx_discards; 3214 } 3215 } 3216 3217 PMD_DRV_LOG(DEBUG, "***************** PF stats start *******************"); 3218 PMD_DRV_LOG(DEBUG, "rx_bytes: %"PRIu64"", ns->eth.rx_bytes); 3219 PMD_DRV_LOG(DEBUG, "rx_unicast: %"PRIu64"", ns->eth.rx_unicast); 3220 PMD_DRV_LOG(DEBUG, "rx_multicast: %"PRIu64"", ns->eth.rx_multicast); 3221 PMD_DRV_LOG(DEBUG, "rx_broadcast: %"PRIu64"", ns->eth.rx_broadcast); 3222 PMD_DRV_LOG(DEBUG, "rx_discards: %"PRIu64"", ns->eth.rx_discards); 3223 PMD_DRV_LOG(DEBUG, "rx_unknown_protocol: %"PRIu64"", 3224 ns->eth.rx_unknown_protocol); 3225 PMD_DRV_LOG(DEBUG, "tx_bytes: %"PRIu64"", ns->eth.tx_bytes); 3226 PMD_DRV_LOG(DEBUG, "tx_unicast: %"PRIu64"", ns->eth.tx_unicast); 3227 PMD_DRV_LOG(DEBUG, "tx_multicast: %"PRIu64"", ns->eth.tx_multicast); 3228 PMD_DRV_LOG(DEBUG, "tx_broadcast: %"PRIu64"", ns->eth.tx_broadcast); 3229 PMD_DRV_LOG(DEBUG, "tx_discards: %"PRIu64"", ns->eth.tx_discards); 3230 PMD_DRV_LOG(DEBUG, "tx_errors: %"PRIu64"", ns->eth.tx_errors); 3231 3232 PMD_DRV_LOG(DEBUG, "tx_dropped_link_down: %"PRIu64"", 3233 ns->tx_dropped_link_down); 3234 PMD_DRV_LOG(DEBUG, "crc_errors: %"PRIu64"", ns->crc_errors); 3235 PMD_DRV_LOG(DEBUG, "illegal_bytes: %"PRIu64"", 3236 ns->illegal_bytes); 3237 PMD_DRV_LOG(DEBUG, "error_bytes: %"PRIu64"", ns->error_bytes); 3238 PMD_DRV_LOG(DEBUG, "mac_local_faults: %"PRIu64"", 3239 ns->mac_local_faults); 3240 PMD_DRV_LOG(DEBUG, "mac_remote_faults: %"PRIu64"", 3241 ns->mac_remote_faults); 3242 PMD_DRV_LOG(DEBUG, "rx_length_errors: %"PRIu64"", 3243 ns->rx_length_errors); 3244 PMD_DRV_LOG(DEBUG, "link_xon_rx: %"PRIu64"", ns->link_xon_rx); 3245 PMD_DRV_LOG(DEBUG, "link_xoff_rx: %"PRIu64"", ns->link_xoff_rx); 3246 for (i = 0; i < 8; i++) { 3247 PMD_DRV_LOG(DEBUG, "priority_xon_rx[%d]: %"PRIu64"", 3248 i, ns->priority_xon_rx[i]); 3249 PMD_DRV_LOG(DEBUG, "priority_xoff_rx[%d]: %"PRIu64"", 3250 i, ns->priority_xoff_rx[i]); 3251 } 3252 PMD_DRV_LOG(DEBUG, "link_xon_tx: %"PRIu64"", ns->link_xon_tx); 3253 PMD_DRV_LOG(DEBUG, "link_xoff_tx: %"PRIu64"", ns->link_xoff_tx); 3254 for (i = 0; i < 8; i++) { 3255 PMD_DRV_LOG(DEBUG, "priority_xon_tx[%d]: %"PRIu64"", 3256 i, ns->priority_xon_tx[i]); 3257 PMD_DRV_LOG(DEBUG, "priority_xoff_tx[%d]: %"PRIu64"", 3258 i, ns->priority_xoff_tx[i]); 3259 PMD_DRV_LOG(DEBUG, "priority_xon_2_xoff[%d]: %"PRIu64"", 3260 i, ns->priority_xon_2_xoff[i]); 3261 } 3262 PMD_DRV_LOG(DEBUG, "rx_size_64: %"PRIu64"", ns->rx_size_64); 3263 PMD_DRV_LOG(DEBUG, "rx_size_127: %"PRIu64"", ns->rx_size_127); 3264 PMD_DRV_LOG(DEBUG, "rx_size_255: %"PRIu64"", ns->rx_size_255); 3265 PMD_DRV_LOG(DEBUG, "rx_size_511: %"PRIu64"", ns->rx_size_511); 3266 PMD_DRV_LOG(DEBUG, "rx_size_1023: %"PRIu64"", ns->rx_size_1023); 3267 PMD_DRV_LOG(DEBUG, "rx_size_1522: %"PRIu64"", ns->rx_size_1522); 3268 PMD_DRV_LOG(DEBUG, "rx_size_big: %"PRIu64"", ns->rx_size_big); 3269 PMD_DRV_LOG(DEBUG, "rx_undersize: %"PRIu64"", ns->rx_undersize); 3270 PMD_DRV_LOG(DEBUG, "rx_fragments: %"PRIu64"", ns->rx_fragments); 3271 PMD_DRV_LOG(DEBUG, "rx_oversize: %"PRIu64"", ns->rx_oversize); 3272 PMD_DRV_LOG(DEBUG, "rx_jabber: %"PRIu64"", ns->rx_jabber); 3273 PMD_DRV_LOG(DEBUG, "tx_size_64: %"PRIu64"", ns->tx_size_64); 3274 PMD_DRV_LOG(DEBUG, "tx_size_127: %"PRIu64"", ns->tx_size_127); 3275 PMD_DRV_LOG(DEBUG, "tx_size_255: %"PRIu64"", ns->tx_size_255); 3276 PMD_DRV_LOG(DEBUG, "tx_size_511: %"PRIu64"", ns->tx_size_511); 3277 PMD_DRV_LOG(DEBUG, "tx_size_1023: %"PRIu64"", ns->tx_size_1023); 3278 PMD_DRV_LOG(DEBUG, "tx_size_1522: %"PRIu64"", ns->tx_size_1522); 3279 PMD_DRV_LOG(DEBUG, "tx_size_big: %"PRIu64"", ns->tx_size_big); 3280 PMD_DRV_LOG(DEBUG, "mac_short_packet_dropped: %"PRIu64"", 3281 ns->mac_short_packet_dropped); 3282 PMD_DRV_LOG(DEBUG, "checksum_error: %"PRIu64"", 3283 ns->checksum_error); 3284 PMD_DRV_LOG(DEBUG, "fdir_match: %"PRIu64"", ns->fd_sb_match); 3285 PMD_DRV_LOG(DEBUG, "***************** PF stats end ********************"); 3286 return 0; 3287 } 3288 3289 /* Reset the statistics */ 3290 static void 3291 i40e_dev_stats_reset(struct rte_eth_dev *dev) 3292 { 3293 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3294 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3295 3296 /* Mark PF and VSI stats to update the offset, aka "reset" */ 3297 pf->offset_loaded = false; 3298 if (pf->main_vsi) 3299 pf->main_vsi->offset_loaded = false; 3300 3301 /* read the stats, reading current register values into offset */ 3302 i40e_read_stats_registers(pf, hw); 3303 } 3304 3305 static uint32_t 3306 i40e_xstats_calc_num(void) 3307 { 3308 return I40E_NB_ETH_XSTATS + I40E_NB_HW_PORT_XSTATS + 3309 (I40E_NB_RXQ_PRIO_XSTATS * 8) + 3310 (I40E_NB_TXQ_PRIO_XSTATS * 8); 3311 } 3312 3313 static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, 3314 struct rte_eth_xstat_name *xstats_names, 3315 __rte_unused unsigned limit) 3316 { 3317 unsigned count = 0; 3318 unsigned i, prio; 3319 3320 if (xstats_names == NULL) 3321 return i40e_xstats_calc_num(); 3322 3323 /* Note: limit checked in rte_eth_xstats_names() */ 3324 3325 /* Get stats from i40e_eth_stats struct */ 3326 for (i = 0; i < I40E_NB_ETH_XSTATS; i++) { 3327 snprintf(xstats_names[count].name, 3328 sizeof(xstats_names[count].name), 3329 "%s", rte_i40e_stats_strings[i].name); 3330 count++; 3331 } 3332 3333 /* Get individiual stats from i40e_hw_port struct */ 3334 for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { 3335 snprintf(xstats_names[count].name, 3336 sizeof(xstats_names[count].name), 3337 "%s", rte_i40e_hw_port_strings[i].name); 3338 count++; 3339 } 3340 3341 for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { 3342 for (prio = 0; prio < 8; prio++) { 3343 snprintf(xstats_names[count].name, 3344 sizeof(xstats_names[count].name), 3345 "rx_priority%u_%s", prio, 3346 rte_i40e_rxq_prio_strings[i].name); 3347 count++; 3348 } 3349 } 3350 3351 for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { 3352 for (prio = 0; prio < 8; prio++) { 3353 snprintf(xstats_names[count].name, 3354 sizeof(xstats_names[count].name), 3355 "tx_priority%u_%s", prio, 3356 rte_i40e_txq_prio_strings[i].name); 3357 count++; 3358 } 3359 } 3360 return count; 3361 } 3362 3363 static int 3364 i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, 3365 unsigned n) 3366 { 3367 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3368 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3369 unsigned i, count, prio; 3370 struct i40e_hw_port_stats *hw_stats = &pf->stats; 3371 3372 count = i40e_xstats_calc_num(); 3373 if (n < count) 3374 return count; 3375 3376 i40e_read_stats_registers(pf, hw); 3377 3378 if (xstats == NULL) 3379 return 0; 3380 3381 count = 0; 3382 3383 /* Get stats from i40e_eth_stats struct */ 3384 for (i = 0; i < I40E_NB_ETH_XSTATS; i++) { 3385 xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) + 3386 rte_i40e_stats_strings[i].offset); 3387 xstats[count].id = count; 3388 count++; 3389 } 3390 3391 /* Get individiual stats from i40e_hw_port struct */ 3392 for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { 3393 xstats[count].value = *(uint64_t *)(((char *)hw_stats) + 3394 rte_i40e_hw_port_strings[i].offset); 3395 xstats[count].id = count; 3396 count++; 3397 } 3398 3399 for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { 3400 for (prio = 0; prio < 8; prio++) { 3401 xstats[count].value = 3402 *(uint64_t *)(((char *)hw_stats) + 3403 rte_i40e_rxq_prio_strings[i].offset + 3404 (sizeof(uint64_t) * prio)); 3405 xstats[count].id = count; 3406 count++; 3407 } 3408 } 3409 3410 for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { 3411 for (prio = 0; prio < 8; prio++) { 3412 xstats[count].value = 3413 *(uint64_t *)(((char *)hw_stats) + 3414 rte_i40e_txq_prio_strings[i].offset + 3415 (sizeof(uint64_t) * prio)); 3416 xstats[count].id = count; 3417 count++; 3418 } 3419 } 3420 3421 return count; 3422 } 3423 3424 static int 3425 i40e_dev_queue_stats_mapping_set(__rte_unused struct rte_eth_dev *dev, 3426 __rte_unused uint16_t queue_id, 3427 __rte_unused uint8_t stat_idx, 3428 __rte_unused uint8_t is_rx) 3429 { 3430 PMD_INIT_FUNC_TRACE(); 3431 3432 return -ENOSYS; 3433 } 3434 3435 static int 3436 i40e_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) 3437 { 3438 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3439 u32 full_ver; 3440 u8 ver, patch; 3441 u16 build; 3442 int ret; 3443 3444 full_ver = hw->nvm.oem_ver; 3445 ver = (u8)(full_ver >> 24); 3446 build = (u16)((full_ver >> 8) & 0xffff); 3447 patch = (u8)(full_ver & 0xff); 3448 3449 ret = snprintf(fw_version, fw_size, 3450 "%d.%d%d 0x%08x %d.%d.%d", 3451 ((hw->nvm.version >> 12) & 0xf), 3452 ((hw->nvm.version >> 4) & 0xff), 3453 (hw->nvm.version & 0xf), hw->nvm.eetrack, 3454 ver, build, patch); 3455 3456 ret += 1; /* add the size of '\0' */ 3457 if (fw_size < (u32)ret) 3458 return ret; 3459 else 3460 return 0; 3461 } 3462 3463 /* 3464 * When using NVM 6.01(for X710 XL710 XXV710)/3.33(for X722) or later, 3465 * the Rx data path does not hang if the FW LLDP is stopped. 3466 * return true if lldp need to stop 3467 * return false if we cannot disable the LLDP to avoid Rx data path blocking. 3468 */ 3469 static bool 3470 i40e_need_stop_lldp(struct rte_eth_dev *dev) 3471 { 3472 double nvm_ver; 3473 char ver_str[64] = {0}; 3474 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3475 3476 i40e_fw_version_get(dev, ver_str, 64); 3477 nvm_ver = atof(ver_str); 3478 if ((hw->mac.type == I40E_MAC_X722 || 3479 hw->mac.type == I40E_MAC_X722_VF) && 3480 ((uint32_t)(nvm_ver * 1000) >= (uint32_t)(3.33 * 1000))) 3481 return true; 3482 else if ((uint32_t)(nvm_ver * 1000) >= (uint32_t)(6.01 * 1000)) 3483 return true; 3484 3485 return false; 3486 } 3487 3488 static void 3489 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) 3490 { 3491 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3492 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3493 struct i40e_vsi *vsi = pf->main_vsi; 3494 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 3495 3496 dev_info->max_rx_queues = vsi->nb_qps; 3497 dev_info->max_tx_queues = vsi->nb_qps; 3498 dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN; 3499 dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX; 3500 dev_info->max_mac_addrs = vsi->max_macaddrs; 3501 dev_info->max_vfs = pci_dev->max_vfs; 3502 dev_info->max_mtu = dev_info->max_rx_pktlen - I40E_ETH_OVERHEAD; 3503 dev_info->min_mtu = ETHER_MIN_MTU; 3504 dev_info->rx_queue_offload_capa = 0; 3505 dev_info->rx_offload_capa = 3506 DEV_RX_OFFLOAD_VLAN_STRIP | 3507 DEV_RX_OFFLOAD_QINQ_STRIP | 3508 DEV_RX_OFFLOAD_IPV4_CKSUM | 3509 DEV_RX_OFFLOAD_UDP_CKSUM | 3510 DEV_RX_OFFLOAD_TCP_CKSUM | 3511 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | 3512 DEV_RX_OFFLOAD_KEEP_CRC | 3513 DEV_RX_OFFLOAD_SCATTER | 3514 DEV_RX_OFFLOAD_VLAN_EXTEND | 3515 DEV_RX_OFFLOAD_VLAN_FILTER | 3516 DEV_RX_OFFLOAD_JUMBO_FRAME; 3517 3518 dev_info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE; 3519 dev_info->tx_offload_capa = 3520 DEV_TX_OFFLOAD_VLAN_INSERT | 3521 DEV_TX_OFFLOAD_QINQ_INSERT | 3522 DEV_TX_OFFLOAD_IPV4_CKSUM | 3523 DEV_TX_OFFLOAD_UDP_CKSUM | 3524 DEV_TX_OFFLOAD_TCP_CKSUM | 3525 DEV_TX_OFFLOAD_SCTP_CKSUM | 3526 DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | 3527 DEV_TX_OFFLOAD_TCP_TSO | 3528 DEV_TX_OFFLOAD_VXLAN_TNL_TSO | 3529 DEV_TX_OFFLOAD_GRE_TNL_TSO | 3530 DEV_TX_OFFLOAD_IPIP_TNL_TSO | 3531 DEV_TX_OFFLOAD_GENEVE_TNL_TSO | 3532 DEV_TX_OFFLOAD_MULTI_SEGS | 3533 dev_info->tx_queue_offload_capa; 3534 dev_info->dev_capa = 3535 RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | 3536 RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; 3537 3538 dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) * 3539 sizeof(uint32_t); 3540 dev_info->reta_size = pf->hash_lut_size; 3541 dev_info->flow_type_rss_offloads = pf->adapter->flow_types_mask; 3542 3543 dev_info->default_rxconf = (struct rte_eth_rxconf) { 3544 .rx_thresh = { 3545 .pthresh = I40E_DEFAULT_RX_PTHRESH, 3546 .hthresh = I40E_DEFAULT_RX_HTHRESH, 3547 .wthresh = I40E_DEFAULT_RX_WTHRESH, 3548 }, 3549 .rx_free_thresh = I40E_DEFAULT_RX_FREE_THRESH, 3550 .rx_drop_en = 0, 3551 .offloads = 0, 3552 }; 3553 3554 dev_info->default_txconf = (struct rte_eth_txconf) { 3555 .tx_thresh = { 3556 .pthresh = I40E_DEFAULT_TX_PTHRESH, 3557 .hthresh = I40E_DEFAULT_TX_HTHRESH, 3558 .wthresh = I40E_DEFAULT_TX_WTHRESH, 3559 }, 3560 .tx_free_thresh = I40E_DEFAULT_TX_FREE_THRESH, 3561 .tx_rs_thresh = I40E_DEFAULT_TX_RSBIT_THRESH, 3562 .offloads = 0, 3563 }; 3564 3565 dev_info->rx_desc_lim = (struct rte_eth_desc_lim) { 3566 .nb_max = I40E_MAX_RING_DESC, 3567 .nb_min = I40E_MIN_RING_DESC, 3568 .nb_align = I40E_ALIGN_RING_DESC, 3569 }; 3570 3571 dev_info->tx_desc_lim = (struct rte_eth_desc_lim) { 3572 .nb_max = I40E_MAX_RING_DESC, 3573 .nb_min = I40E_MIN_RING_DESC, 3574 .nb_align = I40E_ALIGN_RING_DESC, 3575 .nb_seg_max = I40E_TX_MAX_SEG, 3576 .nb_mtu_seg_max = I40E_TX_MAX_MTU_SEG, 3577 }; 3578 3579 if (pf->flags & I40E_FLAG_VMDQ) { 3580 dev_info->max_vmdq_pools = pf->max_nb_vmdq_vsi; 3581 dev_info->vmdq_queue_base = dev_info->max_rx_queues; 3582 dev_info->vmdq_queue_num = pf->vmdq_nb_qps * 3583 pf->max_nb_vmdq_vsi; 3584 dev_info->vmdq_pool_base = I40E_VMDQ_POOL_BASE; 3585 dev_info->max_rx_queues += dev_info->vmdq_queue_num; 3586 dev_info->max_tx_queues += dev_info->vmdq_queue_num; 3587 } 3588 3589 if (I40E_PHY_TYPE_SUPPORT_40G(hw->phy.phy_types)) { 3590 /* For XL710 */ 3591 dev_info->speed_capa = ETH_LINK_SPEED_40G; 3592 dev_info->default_rxportconf.nb_queues = 2; 3593 dev_info->default_txportconf.nb_queues = 2; 3594 if (dev->data->nb_rx_queues == 1) 3595 dev_info->default_rxportconf.ring_size = 2048; 3596 else 3597 dev_info->default_rxportconf.ring_size = 1024; 3598 if (dev->data->nb_tx_queues == 1) 3599 dev_info->default_txportconf.ring_size = 1024; 3600 else 3601 dev_info->default_txportconf.ring_size = 512; 3602 3603 } else if (I40E_PHY_TYPE_SUPPORT_25G(hw->phy.phy_types)) { 3604 /* For XXV710 */ 3605 dev_info->speed_capa = ETH_LINK_SPEED_25G; 3606 dev_info->default_rxportconf.nb_queues = 1; 3607 dev_info->default_txportconf.nb_queues = 1; 3608 dev_info->default_rxportconf.ring_size = 256; 3609 dev_info->default_txportconf.ring_size = 256; 3610 } else { 3611 /* For X710 */ 3612 dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G; 3613 dev_info->default_rxportconf.nb_queues = 1; 3614 dev_info->default_txportconf.nb_queues = 1; 3615 if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_10G) { 3616 dev_info->default_rxportconf.ring_size = 512; 3617 dev_info->default_txportconf.ring_size = 256; 3618 } else { 3619 dev_info->default_rxportconf.ring_size = 256; 3620 dev_info->default_txportconf.ring_size = 256; 3621 } 3622 } 3623 dev_info->default_rxportconf.burst_size = 32; 3624 dev_info->default_txportconf.burst_size = 32; 3625 } 3626 3627 static int 3628 i40e_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) 3629 { 3630 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3631 struct i40e_vsi *vsi = pf->main_vsi; 3632 PMD_INIT_FUNC_TRACE(); 3633 3634 if (on) 3635 return i40e_vsi_add_vlan(vsi, vlan_id); 3636 else 3637 return i40e_vsi_delete_vlan(vsi, vlan_id); 3638 } 3639 3640 static int 3641 i40e_vlan_tpid_set_by_registers(struct rte_eth_dev *dev, 3642 enum rte_vlan_type vlan_type, 3643 uint16_t tpid, int qinq) 3644 { 3645 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3646 uint64_t reg_r = 0; 3647 uint64_t reg_w = 0; 3648 uint16_t reg_id = 3; 3649 int ret; 3650 3651 if (qinq) { 3652 if (vlan_type == ETH_VLAN_TYPE_OUTER) 3653 reg_id = 2; 3654 } 3655 3656 ret = i40e_aq_debug_read_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id), 3657 ®_r, NULL); 3658 if (ret != I40E_SUCCESS) { 3659 PMD_DRV_LOG(ERR, 3660 "Fail to debug read from I40E_GL_SWT_L2TAGCTRL[%d]", 3661 reg_id); 3662 return -EIO; 3663 } 3664 PMD_DRV_LOG(DEBUG, 3665 "Debug read from I40E_GL_SWT_L2TAGCTRL[%d]: 0x%08"PRIx64, 3666 reg_id, reg_r); 3667 3668 reg_w = reg_r & (~(I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK)); 3669 reg_w |= ((uint64_t)tpid << I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT); 3670 if (reg_r == reg_w) { 3671 PMD_DRV_LOG(DEBUG, "No need to write"); 3672 return 0; 3673 } 3674 3675 ret = i40e_aq_debug_write_global_register(hw, 3676 I40E_GL_SWT_L2TAGCTRL(reg_id), 3677 reg_w, NULL); 3678 if (ret != I40E_SUCCESS) { 3679 PMD_DRV_LOG(ERR, 3680 "Fail to debug write to I40E_GL_SWT_L2TAGCTRL[%d]", 3681 reg_id); 3682 return -EIO; 3683 } 3684 PMD_DRV_LOG(DEBUG, 3685 "Global register 0x%08x is changed with value 0x%08x", 3686 I40E_GL_SWT_L2TAGCTRL(reg_id), (uint32_t)reg_w); 3687 3688 return 0; 3689 } 3690 3691 static int 3692 i40e_vlan_tpid_set(struct rte_eth_dev *dev, 3693 enum rte_vlan_type vlan_type, 3694 uint16_t tpid) 3695 { 3696 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3697 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3698 int qinq = dev->data->dev_conf.rxmode.offloads & 3699 DEV_RX_OFFLOAD_VLAN_EXTEND; 3700 int ret = 0; 3701 3702 if ((vlan_type != ETH_VLAN_TYPE_INNER && 3703 vlan_type != ETH_VLAN_TYPE_OUTER) || 3704 (!qinq && vlan_type == ETH_VLAN_TYPE_INNER)) { 3705 PMD_DRV_LOG(ERR, 3706 "Unsupported vlan type."); 3707 return -EINVAL; 3708 } 3709 3710 if (pf->support_multi_driver) { 3711 PMD_DRV_LOG(ERR, "Setting TPID is not supported."); 3712 return -ENOTSUP; 3713 } 3714 3715 /* 802.1ad frames ability is added in NVM API 1.7*/ 3716 if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) { 3717 if (qinq) { 3718 if (vlan_type == ETH_VLAN_TYPE_OUTER) 3719 hw->first_tag = rte_cpu_to_le_16(tpid); 3720 else if (vlan_type == ETH_VLAN_TYPE_INNER) 3721 hw->second_tag = rte_cpu_to_le_16(tpid); 3722 } else { 3723 if (vlan_type == ETH_VLAN_TYPE_OUTER) 3724 hw->second_tag = rte_cpu_to_le_16(tpid); 3725 } 3726 ret = i40e_aq_set_switch_config(hw, 0, 0, 0, NULL); 3727 if (ret != I40E_SUCCESS) { 3728 PMD_DRV_LOG(ERR, 3729 "Set switch config failed aq_err: %d", 3730 hw->aq.asq_last_status); 3731 ret = -EIO; 3732 } 3733 } else 3734 /* If NVM API < 1.7, keep the register setting */ 3735 ret = i40e_vlan_tpid_set_by_registers(dev, vlan_type, 3736 tpid, qinq); 3737 3738 return ret; 3739 } 3740 3741 static int 3742 i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) 3743 { 3744 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3745 struct i40e_vsi *vsi = pf->main_vsi; 3746 struct rte_eth_rxmode *rxmode; 3747 3748 rxmode = &dev->data->dev_conf.rxmode; 3749 if (mask & ETH_VLAN_FILTER_MASK) { 3750 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) 3751 i40e_vsi_config_vlan_filter(vsi, TRUE); 3752 else 3753 i40e_vsi_config_vlan_filter(vsi, FALSE); 3754 } 3755 3756 if (mask & ETH_VLAN_STRIP_MASK) { 3757 /* Enable or disable VLAN stripping */ 3758 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) 3759 i40e_vsi_config_vlan_stripping(vsi, TRUE); 3760 else 3761 i40e_vsi_config_vlan_stripping(vsi, FALSE); 3762 } 3763 3764 if (mask & ETH_VLAN_EXTEND_MASK) { 3765 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) { 3766 i40e_vsi_config_double_vlan(vsi, TRUE); 3767 /* Set global registers with default ethertype. */ 3768 i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, 3769 ETHER_TYPE_VLAN); 3770 i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER, 3771 ETHER_TYPE_VLAN); 3772 } 3773 else 3774 i40e_vsi_config_double_vlan(vsi, FALSE); 3775 } 3776 3777 return 0; 3778 } 3779 3780 static void 3781 i40e_vlan_strip_queue_set(__rte_unused struct rte_eth_dev *dev, 3782 __rte_unused uint16_t queue, 3783 __rte_unused int on) 3784 { 3785 PMD_INIT_FUNC_TRACE(); 3786 } 3787 3788 static int 3789 i40e_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on) 3790 { 3791 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3792 struct i40e_vsi *vsi = pf->main_vsi; 3793 struct rte_eth_dev_data *data = I40E_VSI_TO_DEV_DATA(vsi); 3794 struct i40e_vsi_vlan_pvid_info info; 3795 3796 memset(&info, 0, sizeof(info)); 3797 info.on = on; 3798 if (info.on) 3799 info.config.pvid = pvid; 3800 else { 3801 info.config.reject.tagged = 3802 data->dev_conf.txmode.hw_vlan_reject_tagged; 3803 info.config.reject.untagged = 3804 data->dev_conf.txmode.hw_vlan_reject_untagged; 3805 } 3806 3807 return i40e_vsi_vlan_pvid_set(vsi, &info); 3808 } 3809 3810 static int 3811 i40e_dev_led_on(struct rte_eth_dev *dev) 3812 { 3813 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3814 uint32_t mode = i40e_led_get(hw); 3815 3816 if (mode == 0) 3817 i40e_led_set(hw, 0xf, true); /* 0xf means led always true */ 3818 3819 return 0; 3820 } 3821 3822 static int 3823 i40e_dev_led_off(struct rte_eth_dev *dev) 3824 { 3825 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3826 uint32_t mode = i40e_led_get(hw); 3827 3828 if (mode != 0) 3829 i40e_led_set(hw, 0, false); 3830 3831 return 0; 3832 } 3833 3834 static int 3835 i40e_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 3836 { 3837 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3838 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3839 3840 fc_conf->pause_time = pf->fc_conf.pause_time; 3841 3842 /* read out from register, in case they are modified by other port */ 3843 pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] = 3844 I40E_READ_REG(hw, I40E_GLRPB_GHW) >> I40E_KILOSHIFT; 3845 pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] = 3846 I40E_READ_REG(hw, I40E_GLRPB_GLW) >> I40E_KILOSHIFT; 3847 3848 fc_conf->high_water = pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]; 3849 fc_conf->low_water = pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]; 3850 3851 /* Return current mode according to actual setting*/ 3852 switch (hw->fc.current_mode) { 3853 case I40E_FC_FULL: 3854 fc_conf->mode = RTE_FC_FULL; 3855 break; 3856 case I40E_FC_TX_PAUSE: 3857 fc_conf->mode = RTE_FC_TX_PAUSE; 3858 break; 3859 case I40E_FC_RX_PAUSE: 3860 fc_conf->mode = RTE_FC_RX_PAUSE; 3861 break; 3862 case I40E_FC_NONE: 3863 default: 3864 fc_conf->mode = RTE_FC_NONE; 3865 }; 3866 3867 return 0; 3868 } 3869 3870 static int 3871 i40e_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 3872 { 3873 uint32_t mflcn_reg, fctrl_reg, reg; 3874 uint32_t max_high_water; 3875 uint8_t i, aq_failure; 3876 int err; 3877 struct i40e_hw *hw; 3878 struct i40e_pf *pf; 3879 enum i40e_fc_mode rte_fcmode_2_i40e_fcmode[] = { 3880 [RTE_FC_NONE] = I40E_FC_NONE, 3881 [RTE_FC_RX_PAUSE] = I40E_FC_RX_PAUSE, 3882 [RTE_FC_TX_PAUSE] = I40E_FC_TX_PAUSE, 3883 [RTE_FC_FULL] = I40E_FC_FULL 3884 }; 3885 3886 /* high_water field in the rte_eth_fc_conf using the kilobytes unit */ 3887 3888 max_high_water = I40E_RXPBSIZE >> I40E_KILOSHIFT; 3889 if ((fc_conf->high_water > max_high_water) || 3890 (fc_conf->high_water < fc_conf->low_water)) { 3891 PMD_INIT_LOG(ERR, 3892 "Invalid high/low water setup value in KB, High_water must be <= %d.", 3893 max_high_water); 3894 return -EINVAL; 3895 } 3896 3897 hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3898 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3899 hw->fc.requested_mode = rte_fcmode_2_i40e_fcmode[fc_conf->mode]; 3900 3901 pf->fc_conf.pause_time = fc_conf->pause_time; 3902 pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] = fc_conf->high_water; 3903 pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] = fc_conf->low_water; 3904 3905 PMD_INIT_FUNC_TRACE(); 3906 3907 /* All the link flow control related enable/disable register 3908 * configuration is handle by the F/W 3909 */ 3910 err = i40e_set_fc(hw, &aq_failure, true); 3911 if (err < 0) 3912 return -ENOSYS; 3913 3914 if (I40E_PHY_TYPE_SUPPORT_40G(hw->phy.phy_types)) { 3915 /* Configure flow control refresh threshold, 3916 * the value for stat_tx_pause_refresh_timer[8] 3917 * is used for global pause operation. 3918 */ 3919 3920 I40E_WRITE_REG(hw, 3921 I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(8), 3922 pf->fc_conf.pause_time); 3923 3924 /* configure the timer value included in transmitted pause 3925 * frame, 3926 * the value for stat_tx_pause_quanta[8] is used for global 3927 * pause operation 3928 */ 3929 I40E_WRITE_REG(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(8), 3930 pf->fc_conf.pause_time); 3931 3932 fctrl_reg = I40E_READ_REG(hw, 3933 I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL); 3934 3935 if (fc_conf->mac_ctrl_frame_fwd != 0) 3936 fctrl_reg |= I40E_PRTMAC_FWD_CTRL; 3937 else 3938 fctrl_reg &= ~I40E_PRTMAC_FWD_CTRL; 3939 3940 I40E_WRITE_REG(hw, I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL, 3941 fctrl_reg); 3942 } else { 3943 /* Configure pause time (2 TCs per register) */ 3944 reg = (uint32_t)pf->fc_conf.pause_time * (uint32_t)0x00010001; 3945 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS / 2; i++) 3946 I40E_WRITE_REG(hw, I40E_PRTDCB_FCTTVN(i), reg); 3947 3948 /* Configure flow control refresh threshold value */ 3949 I40E_WRITE_REG(hw, I40E_PRTDCB_FCRTV, 3950 pf->fc_conf.pause_time / 2); 3951 3952 mflcn_reg = I40E_READ_REG(hw, I40E_PRTDCB_MFLCN); 3953 3954 /* set or clear MFLCN.PMCF & MFLCN.DPF bits 3955 *depending on configuration 3956 */ 3957 if (fc_conf->mac_ctrl_frame_fwd != 0) { 3958 mflcn_reg |= I40E_PRTDCB_MFLCN_PMCF_MASK; 3959 mflcn_reg &= ~I40E_PRTDCB_MFLCN_DPF_MASK; 3960 } else { 3961 mflcn_reg &= ~I40E_PRTDCB_MFLCN_PMCF_MASK; 3962 mflcn_reg |= I40E_PRTDCB_MFLCN_DPF_MASK; 3963 } 3964 3965 I40E_WRITE_REG(hw, I40E_PRTDCB_MFLCN, mflcn_reg); 3966 } 3967 3968 if (!pf->support_multi_driver) { 3969 /* config water marker both based on the packets and bytes */ 3970 I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PHW, 3971 (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] 3972 << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE); 3973 I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PLW, 3974 (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] 3975 << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE); 3976 I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GHW, 3977 pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] 3978 << I40E_KILOSHIFT); 3979 I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GLW, 3980 pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] 3981 << I40E_KILOSHIFT); 3982 } else { 3983 PMD_DRV_LOG(ERR, 3984 "Water marker configuration is not supported."); 3985 } 3986 3987 I40E_WRITE_FLUSH(hw); 3988 3989 return 0; 3990 } 3991 3992 static int 3993 i40e_priority_flow_ctrl_set(__rte_unused struct rte_eth_dev *dev, 3994 __rte_unused struct rte_eth_pfc_conf *pfc_conf) 3995 { 3996 PMD_INIT_FUNC_TRACE(); 3997 3998 return -ENOSYS; 3999 } 4000 4001 /* Add a MAC address, and update filters */ 4002 static int 4003 i40e_macaddr_add(struct rte_eth_dev *dev, 4004 struct ether_addr *mac_addr, 4005 __rte_unused uint32_t index, 4006 uint32_t pool) 4007 { 4008 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4009 struct i40e_mac_filter_info mac_filter; 4010 struct i40e_vsi *vsi; 4011 struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; 4012 int ret; 4013 4014 /* If VMDQ not enabled or configured, return */ 4015 if (pool != 0 && (!(pf->flags & I40E_FLAG_VMDQ) || 4016 !pf->nb_cfg_vmdq_vsi)) { 4017 PMD_DRV_LOG(ERR, "VMDQ not %s, can't set mac to pool %u", 4018 pf->flags & I40E_FLAG_VMDQ ? "configured" : "enabled", 4019 pool); 4020 return -ENOTSUP; 4021 } 4022 4023 if (pool > pf->nb_cfg_vmdq_vsi) { 4024 PMD_DRV_LOG(ERR, "Pool number %u invalid. Max pool is %u", 4025 pool, pf->nb_cfg_vmdq_vsi); 4026 return -EINVAL; 4027 } 4028 4029 rte_memcpy(&mac_filter.mac_addr, mac_addr, ETHER_ADDR_LEN); 4030 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) 4031 mac_filter.filter_type = RTE_MACVLAN_PERFECT_MATCH; 4032 else 4033 mac_filter.filter_type = RTE_MAC_PERFECT_MATCH; 4034 4035 if (pool == 0) 4036 vsi = pf->main_vsi; 4037 else 4038 vsi = pf->vmdq[pool - 1].vsi; 4039 4040 ret = i40e_vsi_add_mac(vsi, &mac_filter); 4041 if (ret != I40E_SUCCESS) { 4042 PMD_DRV_LOG(ERR, "Failed to add MACVLAN filter"); 4043 return -ENODEV; 4044 } 4045 return 0; 4046 } 4047 4048 /* Remove a MAC address, and update filters */ 4049 static void 4050 i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index) 4051 { 4052 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4053 struct i40e_vsi *vsi; 4054 struct rte_eth_dev_data *data = dev->data; 4055 struct ether_addr *macaddr; 4056 int ret; 4057 uint32_t i; 4058 uint64_t pool_sel; 4059 4060 macaddr = &(data->mac_addrs[index]); 4061 4062 pool_sel = dev->data->mac_pool_sel[index]; 4063 4064 for (i = 0; i < sizeof(pool_sel) * CHAR_BIT; i++) { 4065 if (pool_sel & (1ULL << i)) { 4066 if (i == 0) 4067 vsi = pf->main_vsi; 4068 else { 4069 /* No VMDQ pool enabled or configured */ 4070 if (!(pf->flags & I40E_FLAG_VMDQ) || 4071 (i > pf->nb_cfg_vmdq_vsi)) { 4072 PMD_DRV_LOG(ERR, 4073 "No VMDQ pool enabled/configured"); 4074 return; 4075 } 4076 vsi = pf->vmdq[i - 1].vsi; 4077 } 4078 ret = i40e_vsi_delete_mac(vsi, macaddr); 4079 4080 if (ret) { 4081 PMD_DRV_LOG(ERR, "Failed to remove MACVLAN filter"); 4082 return; 4083 } 4084 } 4085 } 4086 } 4087 4088 /* Set perfect match or hash match of MAC and VLAN for a VF */ 4089 static int 4090 i40e_vf_mac_filter_set(struct i40e_pf *pf, 4091 struct rte_eth_mac_filter *filter, 4092 bool add) 4093 { 4094 struct i40e_hw *hw; 4095 struct i40e_mac_filter_info mac_filter; 4096 struct ether_addr old_mac; 4097 struct ether_addr *new_mac; 4098 struct i40e_pf_vf *vf = NULL; 4099 uint16_t vf_id; 4100 int ret; 4101 4102 if (pf == NULL) { 4103 PMD_DRV_LOG(ERR, "Invalid PF argument."); 4104 return -EINVAL; 4105 } 4106 hw = I40E_PF_TO_HW(pf); 4107 4108 if (filter == NULL) { 4109 PMD_DRV_LOG(ERR, "Invalid mac filter argument."); 4110 return -EINVAL; 4111 } 4112 4113 new_mac = &filter->mac_addr; 4114 4115 if (is_zero_ether_addr(new_mac)) { 4116 PMD_DRV_LOG(ERR, "Invalid ethernet address."); 4117 return -EINVAL; 4118 } 4119 4120 vf_id = filter->dst_id; 4121 4122 if (vf_id > pf->vf_num - 1 || !pf->vfs) { 4123 PMD_DRV_LOG(ERR, "Invalid argument."); 4124 return -EINVAL; 4125 } 4126 vf = &pf->vfs[vf_id]; 4127 4128 if (add && is_same_ether_addr(new_mac, &(pf->dev_addr))) { 4129 PMD_DRV_LOG(INFO, "Ignore adding permanent MAC address."); 4130 return -EINVAL; 4131 } 4132 4133 if (add) { 4134 rte_memcpy(&old_mac, hw->mac.addr, ETHER_ADDR_LEN); 4135 rte_memcpy(hw->mac.addr, new_mac->addr_bytes, 4136 ETHER_ADDR_LEN); 4137 rte_memcpy(&mac_filter.mac_addr, &filter->mac_addr, 4138 ETHER_ADDR_LEN); 4139 4140 mac_filter.filter_type = filter->filter_type; 4141 ret = i40e_vsi_add_mac(vf->vsi, &mac_filter); 4142 if (ret != I40E_SUCCESS) { 4143 PMD_DRV_LOG(ERR, "Failed to add MAC filter."); 4144 return -1; 4145 } 4146 ether_addr_copy(new_mac, &pf->dev_addr); 4147 } else { 4148 rte_memcpy(hw->mac.addr, hw->mac.perm_addr, 4149 ETHER_ADDR_LEN); 4150 ret = i40e_vsi_delete_mac(vf->vsi, &filter->mac_addr); 4151 if (ret != I40E_SUCCESS) { 4152 PMD_DRV_LOG(ERR, "Failed to delete MAC filter."); 4153 return -1; 4154 } 4155 4156 /* Clear device address as it has been removed */ 4157 if (is_same_ether_addr(&(pf->dev_addr), new_mac)) 4158 memset(&pf->dev_addr, 0, sizeof(struct ether_addr)); 4159 } 4160 4161 return 0; 4162 } 4163 4164 /* MAC filter handle */ 4165 static int 4166 i40e_mac_filter_handle(struct rte_eth_dev *dev, enum rte_filter_op filter_op, 4167 void *arg) 4168 { 4169 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4170 struct rte_eth_mac_filter *filter; 4171 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 4172 int ret = I40E_NOT_SUPPORTED; 4173 4174 filter = (struct rte_eth_mac_filter *)(arg); 4175 4176 switch (filter_op) { 4177 case RTE_ETH_FILTER_NOP: 4178 ret = I40E_SUCCESS; 4179 break; 4180 case RTE_ETH_FILTER_ADD: 4181 i40e_pf_disable_irq0(hw); 4182 if (filter->is_vf) 4183 ret = i40e_vf_mac_filter_set(pf, filter, 1); 4184 i40e_pf_enable_irq0(hw); 4185 break; 4186 case RTE_ETH_FILTER_DELETE: 4187 i40e_pf_disable_irq0(hw); 4188 if (filter->is_vf) 4189 ret = i40e_vf_mac_filter_set(pf, filter, 0); 4190 i40e_pf_enable_irq0(hw); 4191 break; 4192 default: 4193 PMD_DRV_LOG(ERR, "unknown operation %u", filter_op); 4194 ret = I40E_ERR_PARAM; 4195 break; 4196 } 4197 4198 return ret; 4199 } 4200 4201 static int 4202 i40e_get_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size) 4203 { 4204 struct i40e_pf *pf = I40E_VSI_TO_PF(vsi); 4205 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 4206 uint32_t reg; 4207 int ret; 4208 4209 if (!lut) 4210 return -EINVAL; 4211 4212 if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) { 4213 ret = i40e_aq_get_rss_lut(hw, vsi->vsi_id, 4214 vsi->type != I40E_VSI_SRIOV, 4215 lut, lut_size); 4216 if (ret) { 4217 PMD_DRV_LOG(ERR, "Failed to get RSS lookup table"); 4218 return ret; 4219 } 4220 } else { 4221 uint32_t *lut_dw = (uint32_t *)lut; 4222 uint16_t i, lut_size_dw = lut_size / 4; 4223 4224 if (vsi->type == I40E_VSI_SRIOV) { 4225 for (i = 0; i <= lut_size_dw; i++) { 4226 reg = I40E_VFQF_HLUT1(i, vsi->user_param); 4227 lut_dw[i] = i40e_read_rx_ctl(hw, reg); 4228 } 4229 } else { 4230 for (i = 0; i < lut_size_dw; i++) 4231 lut_dw[i] = I40E_READ_REG(hw, 4232 I40E_PFQF_HLUT(i)); 4233 } 4234 } 4235 4236 return 0; 4237 } 4238 4239 int 4240 i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size) 4241 { 4242 struct i40e_pf *pf; 4243 struct i40e_hw *hw; 4244 int ret; 4245 4246 if (!vsi || !lut) 4247 return -EINVAL; 4248 4249 pf = I40E_VSI_TO_PF(vsi); 4250 hw = I40E_VSI_TO_HW(vsi); 4251 4252 if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) { 4253 ret = i40e_aq_set_rss_lut(hw, vsi->vsi_id, 4254 vsi->type != I40E_VSI_SRIOV, 4255 lut, lut_size); 4256 if (ret) { 4257 PMD_DRV_LOG(ERR, "Failed to set RSS lookup table"); 4258 return ret; 4259 } 4260 } else { 4261 uint32_t *lut_dw = (uint32_t *)lut; 4262 uint16_t i, lut_size_dw = lut_size / 4; 4263 4264 if (vsi->type == I40E_VSI_SRIOV) { 4265 for (i = 0; i < lut_size_dw; i++) 4266 I40E_WRITE_REG( 4267 hw, 4268 I40E_VFQF_HLUT1(i, vsi->user_param), 4269 lut_dw[i]); 4270 } else { 4271 for (i = 0; i < lut_size_dw; i++) 4272 I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i), 4273 lut_dw[i]); 4274 } 4275 I40E_WRITE_FLUSH(hw); 4276 } 4277 4278 return 0; 4279 } 4280 4281 static int 4282 i40e_dev_rss_reta_update(struct rte_eth_dev *dev, 4283 struct rte_eth_rss_reta_entry64 *reta_conf, 4284 uint16_t reta_size) 4285 { 4286 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4287 uint16_t i, lut_size = pf->hash_lut_size; 4288 uint16_t idx, shift; 4289 uint8_t *lut; 4290 int ret; 4291 4292 if (reta_size != lut_size || 4293 reta_size > ETH_RSS_RETA_SIZE_512) { 4294 PMD_DRV_LOG(ERR, 4295 "The size of hash lookup table configured (%d) doesn't match the number hardware can supported (%d)", 4296 reta_size, lut_size); 4297 return -EINVAL; 4298 } 4299 4300 lut = rte_zmalloc("i40e_rss_lut", reta_size, 0); 4301 if (!lut) { 4302 PMD_DRV_LOG(ERR, "No memory can be allocated"); 4303 return -ENOMEM; 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 lut[i] = reta_conf[idx].reta[shift]; 4313 } 4314 ret = i40e_set_rss_lut(pf->main_vsi, lut, reta_size); 4315 4316 pf->adapter->rss_reta_updated = 1; 4317 4318 out: 4319 rte_free(lut); 4320 4321 return ret; 4322 } 4323 4324 static int 4325 i40e_dev_rss_reta_query(struct rte_eth_dev *dev, 4326 struct rte_eth_rss_reta_entry64 *reta_conf, 4327 uint16_t reta_size) 4328 { 4329 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4330 uint16_t i, lut_size = pf->hash_lut_size; 4331 uint16_t idx, shift; 4332 uint8_t *lut; 4333 int ret; 4334 4335 if (reta_size != lut_size || 4336 reta_size > ETH_RSS_RETA_SIZE_512) { 4337 PMD_DRV_LOG(ERR, 4338 "The size of hash lookup table configured (%d) doesn't match the number hardware can supported (%d)", 4339 reta_size, lut_size); 4340 return -EINVAL; 4341 } 4342 4343 lut = rte_zmalloc("i40e_rss_lut", reta_size, 0); 4344 if (!lut) { 4345 PMD_DRV_LOG(ERR, "No memory can be allocated"); 4346 return -ENOMEM; 4347 } 4348 4349 ret = i40e_get_rss_lut(pf->main_vsi, lut, reta_size); 4350 if (ret) 4351 goto out; 4352 for (i = 0; i < reta_size; i++) { 4353 idx = i / RTE_RETA_GROUP_SIZE; 4354 shift = i % RTE_RETA_GROUP_SIZE; 4355 if (reta_conf[idx].mask & (1ULL << shift)) 4356 reta_conf[idx].reta[shift] = lut[i]; 4357 } 4358 4359 out: 4360 rte_free(lut); 4361 4362 return ret; 4363 } 4364 4365 /** 4366 * i40e_allocate_dma_mem_d - specific memory alloc for shared code (base driver) 4367 * @hw: pointer to the HW structure 4368 * @mem: pointer to mem struct to fill out 4369 * @size: size of memory requested 4370 * @alignment: what to align the allocation to 4371 **/ 4372 enum i40e_status_code 4373 i40e_allocate_dma_mem_d(__attribute__((unused)) struct i40e_hw *hw, 4374 struct i40e_dma_mem *mem, 4375 u64 size, 4376 u32 alignment) 4377 { 4378 const struct rte_memzone *mz = NULL; 4379 char z_name[RTE_MEMZONE_NAMESIZE]; 4380 4381 if (!mem) 4382 return I40E_ERR_PARAM; 4383 4384 snprintf(z_name, sizeof(z_name), "i40e_dma_%"PRIu64, rte_rand()); 4385 mz = rte_memzone_reserve_bounded(z_name, size, SOCKET_ID_ANY, 4386 RTE_MEMZONE_IOVA_CONTIG, alignment, RTE_PGSIZE_2M); 4387 if (!mz) 4388 return I40E_ERR_NO_MEMORY; 4389 4390 mem->size = size; 4391 mem->va = mz->addr; 4392 mem->pa = mz->iova; 4393 mem->zone = (const void *)mz; 4394 PMD_DRV_LOG(DEBUG, 4395 "memzone %s allocated with physical address: %"PRIu64, 4396 mz->name, mem->pa); 4397 4398 return I40E_SUCCESS; 4399 } 4400 4401 /** 4402 * i40e_free_dma_mem_d - specific memory free for shared code (base driver) 4403 * @hw: pointer to the HW structure 4404 * @mem: ptr to mem struct to free 4405 **/ 4406 enum i40e_status_code 4407 i40e_free_dma_mem_d(__attribute__((unused)) struct i40e_hw *hw, 4408 struct i40e_dma_mem *mem) 4409 { 4410 if (!mem) 4411 return I40E_ERR_PARAM; 4412 4413 PMD_DRV_LOG(DEBUG, 4414 "memzone %s to be freed with physical address: %"PRIu64, 4415 ((const struct rte_memzone *)mem->zone)->name, mem->pa); 4416 rte_memzone_free((const struct rte_memzone *)mem->zone); 4417 mem->zone = NULL; 4418 mem->va = NULL; 4419 mem->pa = (u64)0; 4420 4421 return I40E_SUCCESS; 4422 } 4423 4424 /** 4425 * i40e_allocate_virt_mem_d - specific memory alloc for shared code (base driver) 4426 * @hw: pointer to the HW structure 4427 * @mem: pointer to mem struct to fill out 4428 * @size: size of memory requested 4429 **/ 4430 enum i40e_status_code 4431 i40e_allocate_virt_mem_d(__attribute__((unused)) struct i40e_hw *hw, 4432 struct i40e_virt_mem *mem, 4433 u32 size) 4434 { 4435 if (!mem) 4436 return I40E_ERR_PARAM; 4437 4438 mem->size = size; 4439 mem->va = rte_zmalloc("i40e", size, 0); 4440 4441 if (mem->va) 4442 return I40E_SUCCESS; 4443 else 4444 return I40E_ERR_NO_MEMORY; 4445 } 4446 4447 /** 4448 * i40e_free_virt_mem_d - specific memory free for shared code (base driver) 4449 * @hw: pointer to the HW structure 4450 * @mem: pointer to mem struct to free 4451 **/ 4452 enum i40e_status_code 4453 i40e_free_virt_mem_d(__attribute__((unused)) struct i40e_hw *hw, 4454 struct i40e_virt_mem *mem) 4455 { 4456 if (!mem) 4457 return I40E_ERR_PARAM; 4458 4459 rte_free(mem->va); 4460 mem->va = NULL; 4461 4462 return I40E_SUCCESS; 4463 } 4464 4465 void 4466 i40e_init_spinlock_d(struct i40e_spinlock *sp) 4467 { 4468 rte_spinlock_init(&sp->spinlock); 4469 } 4470 4471 void 4472 i40e_acquire_spinlock_d(struct i40e_spinlock *sp) 4473 { 4474 rte_spinlock_lock(&sp->spinlock); 4475 } 4476 4477 void 4478 i40e_release_spinlock_d(struct i40e_spinlock *sp) 4479 { 4480 rte_spinlock_unlock(&sp->spinlock); 4481 } 4482 4483 void 4484 i40e_destroy_spinlock_d(__attribute__((unused)) struct i40e_spinlock *sp) 4485 { 4486 return; 4487 } 4488 4489 /** 4490 * Get the hardware capabilities, which will be parsed 4491 * and saved into struct i40e_hw. 4492 */ 4493 static int 4494 i40e_get_cap(struct i40e_hw *hw) 4495 { 4496 struct i40e_aqc_list_capabilities_element_resp *buf; 4497 uint16_t len, size = 0; 4498 int ret; 4499 4500 /* Calculate a huge enough buff for saving response data temporarily */ 4501 len = sizeof(struct i40e_aqc_list_capabilities_element_resp) * 4502 I40E_MAX_CAP_ELE_NUM; 4503 buf = rte_zmalloc("i40e", len, 0); 4504 if (!buf) { 4505 PMD_DRV_LOG(ERR, "Failed to allocate memory"); 4506 return I40E_ERR_NO_MEMORY; 4507 } 4508 4509 /* Get, parse the capabilities and save it to hw */ 4510 ret = i40e_aq_discover_capabilities(hw, buf, len, &size, 4511 i40e_aqc_opc_list_func_capabilities, NULL); 4512 if (ret != I40E_SUCCESS) 4513 PMD_DRV_LOG(ERR, "Failed to discover capabilities"); 4514 4515 /* Free the temporary buffer after being used */ 4516 rte_free(buf); 4517 4518 return ret; 4519 } 4520 4521 #define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF 4 4522 4523 static int i40e_pf_parse_vf_queue_number_handler(const char *key, 4524 const char *value, 4525 void *opaque) 4526 { 4527 struct i40e_pf *pf; 4528 unsigned long num; 4529 char *end; 4530 4531 pf = (struct i40e_pf *)opaque; 4532 RTE_SET_USED(key); 4533 4534 errno = 0; 4535 num = strtoul(value, &end, 0); 4536 if (errno != 0 || end == value || *end != 0) { 4537 PMD_DRV_LOG(WARNING, "Wrong VF queue number = %s, Now it is " 4538 "kept the value = %hu", value, pf->vf_nb_qp_max); 4539 return -(EINVAL); 4540 } 4541 4542 if (num <= I40E_MAX_QP_NUM_PER_VF && rte_is_power_of_2(num)) 4543 pf->vf_nb_qp_max = (uint16_t)num; 4544 else 4545 /* here return 0 to make next valid same argument work */ 4546 PMD_DRV_LOG(WARNING, "Wrong VF queue number = %lu, it must be " 4547 "power of 2 and equal or less than 16 !, Now it is " 4548 "kept the value = %hu", num, pf->vf_nb_qp_max); 4549 4550 return 0; 4551 } 4552 4553 static int i40e_pf_config_vf_rxq_number(struct rte_eth_dev *dev) 4554 { 4555 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4556 struct rte_kvargs *kvlist; 4557 int kvargs_count; 4558 4559 /* set default queue number per VF as 4 */ 4560 pf->vf_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF; 4561 4562 if (dev->device->devargs == NULL) 4563 return 0; 4564 4565 kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys); 4566 if (kvlist == NULL) 4567 return -(EINVAL); 4568 4569 kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_QUEUE_NUM_PER_VF_ARG); 4570 if (!kvargs_count) { 4571 rte_kvargs_free(kvlist); 4572 return 0; 4573 } 4574 4575 if (kvargs_count > 1) 4576 PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only " 4577 "the first invalid or last valid one is used !", 4578 ETH_I40E_QUEUE_NUM_PER_VF_ARG); 4579 4580 rte_kvargs_process(kvlist, ETH_I40E_QUEUE_NUM_PER_VF_ARG, 4581 i40e_pf_parse_vf_queue_number_handler, pf); 4582 4583 rte_kvargs_free(kvlist); 4584 4585 return 0; 4586 } 4587 4588 static int 4589 i40e_pf_parameter_init(struct rte_eth_dev *dev) 4590 { 4591 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4592 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 4593 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 4594 uint16_t qp_count = 0, vsi_count = 0; 4595 4596 if (pci_dev->max_vfs && !hw->func_caps.sr_iov_1_1) { 4597 PMD_INIT_LOG(ERR, "HW configuration doesn't support SRIOV"); 4598 return -EINVAL; 4599 } 4600 4601 i40e_pf_config_vf_rxq_number(dev); 4602 4603 /* Add the parameter init for LFC */ 4604 pf->fc_conf.pause_time = I40E_DEFAULT_PAUSE_TIME; 4605 pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] = I40E_DEFAULT_HIGH_WATER; 4606 pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] = I40E_DEFAULT_LOW_WATER; 4607 4608 pf->flags = I40E_FLAG_HEADER_SPLIT_DISABLED; 4609 pf->max_num_vsi = hw->func_caps.num_vsis; 4610 pf->lan_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF; 4611 pf->vmdq_nb_qp_max = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM; 4612 4613 /* FDir queue/VSI allocation */ 4614 pf->fdir_qp_offset = 0; 4615 if (hw->func_caps.fd) { 4616 pf->flags |= I40E_FLAG_FDIR; 4617 pf->fdir_nb_qps = I40E_DEFAULT_QP_NUM_FDIR; 4618 } else { 4619 pf->fdir_nb_qps = 0; 4620 } 4621 qp_count += pf->fdir_nb_qps; 4622 vsi_count += 1; 4623 4624 /* LAN queue/VSI allocation */ 4625 pf->lan_qp_offset = pf->fdir_qp_offset + pf->fdir_nb_qps; 4626 if (!hw->func_caps.rss) { 4627 pf->lan_nb_qps = 1; 4628 } else { 4629 pf->flags |= I40E_FLAG_RSS; 4630 if (hw->mac.type == I40E_MAC_X722) 4631 pf->flags |= I40E_FLAG_RSS_AQ_CAPABLE; 4632 pf->lan_nb_qps = pf->lan_nb_qp_max; 4633 } 4634 qp_count += pf->lan_nb_qps; 4635 vsi_count += 1; 4636 4637 /* VF queue/VSI allocation */ 4638 pf->vf_qp_offset = pf->lan_qp_offset + pf->lan_nb_qps; 4639 if (hw->func_caps.sr_iov_1_1 && pci_dev->max_vfs) { 4640 pf->flags |= I40E_FLAG_SRIOV; 4641 pf->vf_nb_qps = pf->vf_nb_qp_max; 4642 pf->vf_num = pci_dev->max_vfs; 4643 PMD_DRV_LOG(DEBUG, 4644 "%u VF VSIs, %u queues per VF VSI, in total %u queues", 4645 pf->vf_num, pf->vf_nb_qps, pf->vf_nb_qps * pf->vf_num); 4646 } else { 4647 pf->vf_nb_qps = 0; 4648 pf->vf_num = 0; 4649 } 4650 qp_count += pf->vf_nb_qps * pf->vf_num; 4651 vsi_count += pf->vf_num; 4652 4653 /* VMDq queue/VSI allocation */ 4654 pf->vmdq_qp_offset = pf->vf_qp_offset + pf->vf_nb_qps * pf->vf_num; 4655 pf->vmdq_nb_qps = 0; 4656 pf->max_nb_vmdq_vsi = 0; 4657 if (hw->func_caps.vmdq) { 4658 if (qp_count < hw->func_caps.num_tx_qp && 4659 vsi_count < hw->func_caps.num_vsis) { 4660 pf->max_nb_vmdq_vsi = (hw->func_caps.num_tx_qp - 4661 qp_count) / pf->vmdq_nb_qp_max; 4662 4663 /* Limit the maximum number of VMDq vsi to the maximum 4664 * ethdev can support 4665 */ 4666 pf->max_nb_vmdq_vsi = RTE_MIN(pf->max_nb_vmdq_vsi, 4667 hw->func_caps.num_vsis - vsi_count); 4668 pf->max_nb_vmdq_vsi = RTE_MIN(pf->max_nb_vmdq_vsi, 4669 ETH_64_POOLS); 4670 if (pf->max_nb_vmdq_vsi) { 4671 pf->flags |= I40E_FLAG_VMDQ; 4672 pf->vmdq_nb_qps = pf->vmdq_nb_qp_max; 4673 PMD_DRV_LOG(DEBUG, 4674 "%u VMDQ VSIs, %u queues per VMDQ VSI, in total %u queues", 4675 pf->max_nb_vmdq_vsi, pf->vmdq_nb_qps, 4676 pf->vmdq_nb_qps * pf->max_nb_vmdq_vsi); 4677 } else { 4678 PMD_DRV_LOG(INFO, 4679 "No enough queues left for VMDq"); 4680 } 4681 } else { 4682 PMD_DRV_LOG(INFO, "No queue or VSI left for VMDq"); 4683 } 4684 } 4685 qp_count += pf->vmdq_nb_qps * pf->max_nb_vmdq_vsi; 4686 vsi_count += pf->max_nb_vmdq_vsi; 4687 4688 if (hw->func_caps.dcb) 4689 pf->flags |= I40E_FLAG_DCB; 4690 4691 if (qp_count > hw->func_caps.num_tx_qp) { 4692 PMD_DRV_LOG(ERR, 4693 "Failed to allocate %u queues, which exceeds the hardware maximum %u", 4694 qp_count, hw->func_caps.num_tx_qp); 4695 return -EINVAL; 4696 } 4697 if (vsi_count > hw->func_caps.num_vsis) { 4698 PMD_DRV_LOG(ERR, 4699 "Failed to allocate %u VSIs, which exceeds the hardware maximum %u", 4700 vsi_count, hw->func_caps.num_vsis); 4701 return -EINVAL; 4702 } 4703 4704 return 0; 4705 } 4706 4707 static int 4708 i40e_pf_get_switch_config(struct i40e_pf *pf) 4709 { 4710 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 4711 struct i40e_aqc_get_switch_config_resp *switch_config; 4712 struct i40e_aqc_switch_config_element_resp *element; 4713 uint16_t start_seid = 0, num_reported; 4714 int ret; 4715 4716 switch_config = (struct i40e_aqc_get_switch_config_resp *)\ 4717 rte_zmalloc("i40e", I40E_AQ_LARGE_BUF, 0); 4718 if (!switch_config) { 4719 PMD_DRV_LOG(ERR, "Failed to allocated memory"); 4720 return -ENOMEM; 4721 } 4722 4723 /* Get the switch configurations */ 4724 ret = i40e_aq_get_switch_config(hw, switch_config, 4725 I40E_AQ_LARGE_BUF, &start_seid, NULL); 4726 if (ret != I40E_SUCCESS) { 4727 PMD_DRV_LOG(ERR, "Failed to get switch configurations"); 4728 goto fail; 4729 } 4730 num_reported = rte_le_to_cpu_16(switch_config->header.num_reported); 4731 if (num_reported != 1) { /* The number should be 1 */ 4732 PMD_DRV_LOG(ERR, "Wrong number of switch config reported"); 4733 goto fail; 4734 } 4735 4736 /* Parse the switch configuration elements */ 4737 element = &(switch_config->element[0]); 4738 if (element->element_type == I40E_SWITCH_ELEMENT_TYPE_VSI) { 4739 pf->mac_seid = rte_le_to_cpu_16(element->uplink_seid); 4740 pf->main_vsi_seid = rte_le_to_cpu_16(element->seid); 4741 } else 4742 PMD_DRV_LOG(INFO, "Unknown element type"); 4743 4744 fail: 4745 rte_free(switch_config); 4746 4747 return ret; 4748 } 4749 4750 static int 4751 i40e_res_pool_init (struct i40e_res_pool_info *pool, uint32_t base, 4752 uint32_t num) 4753 { 4754 struct pool_entry *entry; 4755 4756 if (pool == NULL || num == 0) 4757 return -EINVAL; 4758 4759 entry = rte_zmalloc("i40e", sizeof(*entry), 0); 4760 if (entry == NULL) { 4761 PMD_DRV_LOG(ERR, "Failed to allocate memory for resource pool"); 4762 return -ENOMEM; 4763 } 4764 4765 /* queue heap initialize */ 4766 pool->num_free = num; 4767 pool->num_alloc = 0; 4768 pool->base = base; 4769 LIST_INIT(&pool->alloc_list); 4770 LIST_INIT(&pool->free_list); 4771 4772 /* Initialize element */ 4773 entry->base = 0; 4774 entry->len = num; 4775 4776 LIST_INSERT_HEAD(&pool->free_list, entry, next); 4777 return 0; 4778 } 4779 4780 static void 4781 i40e_res_pool_destroy(struct i40e_res_pool_info *pool) 4782 { 4783 struct pool_entry *entry, *next_entry; 4784 4785 if (pool == NULL) 4786 return; 4787 4788 for (entry = LIST_FIRST(&pool->alloc_list); 4789 entry && (next_entry = LIST_NEXT(entry, next), 1); 4790 entry = next_entry) { 4791 LIST_REMOVE(entry, next); 4792 rte_free(entry); 4793 } 4794 4795 for (entry = LIST_FIRST(&pool->free_list); 4796 entry && (next_entry = LIST_NEXT(entry, next), 1); 4797 entry = next_entry) { 4798 LIST_REMOVE(entry, next); 4799 rte_free(entry); 4800 } 4801 4802 pool->num_free = 0; 4803 pool->num_alloc = 0; 4804 pool->base = 0; 4805 LIST_INIT(&pool->alloc_list); 4806 LIST_INIT(&pool->free_list); 4807 } 4808 4809 static int 4810 i40e_res_pool_free(struct i40e_res_pool_info *pool, 4811 uint32_t base) 4812 { 4813 struct pool_entry *entry, *next, *prev, *valid_entry = NULL; 4814 uint32_t pool_offset; 4815 int insert; 4816 4817 if (pool == NULL) { 4818 PMD_DRV_LOG(ERR, "Invalid parameter"); 4819 return -EINVAL; 4820 } 4821 4822 pool_offset = base - pool->base; 4823 /* Lookup in alloc list */ 4824 LIST_FOREACH(entry, &pool->alloc_list, next) { 4825 if (entry->base == pool_offset) { 4826 valid_entry = entry; 4827 LIST_REMOVE(entry, next); 4828 break; 4829 } 4830 } 4831 4832 /* Not find, return */ 4833 if (valid_entry == NULL) { 4834 PMD_DRV_LOG(ERR, "Failed to find entry"); 4835 return -EINVAL; 4836 } 4837 4838 /** 4839 * Found it, move it to free list and try to merge. 4840 * In order to make merge easier, always sort it by qbase. 4841 * Find adjacent prev and last entries. 4842 */ 4843 prev = next = NULL; 4844 LIST_FOREACH(entry, &pool->free_list, next) { 4845 if (entry->base > valid_entry->base) { 4846 next = entry; 4847 break; 4848 } 4849 prev = entry; 4850 } 4851 4852 insert = 0; 4853 /* Try to merge with next one*/ 4854 if (next != NULL) { 4855 /* Merge with next one */ 4856 if (valid_entry->base + valid_entry->len == next->base) { 4857 next->base = valid_entry->base; 4858 next->len += valid_entry->len; 4859 rte_free(valid_entry); 4860 valid_entry = next; 4861 insert = 1; 4862 } 4863 } 4864 4865 if (prev != NULL) { 4866 /* Merge with previous one */ 4867 if (prev->base + prev->len == valid_entry->base) { 4868 prev->len += valid_entry->len; 4869 /* If it merge with next one, remove next node */ 4870 if (insert == 1) { 4871 LIST_REMOVE(valid_entry, next); 4872 rte_free(valid_entry); 4873 } else { 4874 rte_free(valid_entry); 4875 insert = 1; 4876 } 4877 } 4878 } 4879 4880 /* Not find any entry to merge, insert */ 4881 if (insert == 0) { 4882 if (prev != NULL) 4883 LIST_INSERT_AFTER(prev, valid_entry, next); 4884 else if (next != NULL) 4885 LIST_INSERT_BEFORE(next, valid_entry, next); 4886 else /* It's empty list, insert to head */ 4887 LIST_INSERT_HEAD(&pool->free_list, valid_entry, next); 4888 } 4889 4890 pool->num_free += valid_entry->len; 4891 pool->num_alloc -= valid_entry->len; 4892 4893 return 0; 4894 } 4895 4896 static int 4897 i40e_res_pool_alloc(struct i40e_res_pool_info *pool, 4898 uint16_t num) 4899 { 4900 struct pool_entry *entry, *valid_entry; 4901 4902 if (pool == NULL || num == 0) { 4903 PMD_DRV_LOG(ERR, "Invalid parameter"); 4904 return -EINVAL; 4905 } 4906 4907 if (pool->num_free < num) { 4908 PMD_DRV_LOG(ERR, "No resource. ask:%u, available:%u", 4909 num, pool->num_free); 4910 return -ENOMEM; 4911 } 4912 4913 valid_entry = NULL; 4914 /* Lookup in free list and find most fit one */ 4915 LIST_FOREACH(entry, &pool->free_list, next) { 4916 if (entry->len >= num) { 4917 /* Find best one */ 4918 if (entry->len == num) { 4919 valid_entry = entry; 4920 break; 4921 } 4922 if (valid_entry == NULL || valid_entry->len > entry->len) 4923 valid_entry = entry; 4924 } 4925 } 4926 4927 /* Not find one to satisfy the request, return */ 4928 if (valid_entry == NULL) { 4929 PMD_DRV_LOG(ERR, "No valid entry found"); 4930 return -ENOMEM; 4931 } 4932 /** 4933 * The entry have equal queue number as requested, 4934 * remove it from alloc_list. 4935 */ 4936 if (valid_entry->len == num) { 4937 LIST_REMOVE(valid_entry, next); 4938 } else { 4939 /** 4940 * The entry have more numbers than requested, 4941 * create a new entry for alloc_list and minus its 4942 * queue base and number in free_list. 4943 */ 4944 entry = rte_zmalloc("res_pool", sizeof(*entry), 0); 4945 if (entry == NULL) { 4946 PMD_DRV_LOG(ERR, 4947 "Failed to allocate memory for resource pool"); 4948 return -ENOMEM; 4949 } 4950 entry->base = valid_entry->base; 4951 entry->len = num; 4952 valid_entry->base += num; 4953 valid_entry->len -= num; 4954 valid_entry = entry; 4955 } 4956 4957 /* Insert it into alloc list, not sorted */ 4958 LIST_INSERT_HEAD(&pool->alloc_list, valid_entry, next); 4959 4960 pool->num_free -= valid_entry->len; 4961 pool->num_alloc += valid_entry->len; 4962 4963 return valid_entry->base + pool->base; 4964 } 4965 4966 /** 4967 * bitmap_is_subset - Check whether src2 is subset of src1 4968 **/ 4969 static inline int 4970 bitmap_is_subset(uint8_t src1, uint8_t src2) 4971 { 4972 return !((src1 ^ src2) & src2); 4973 } 4974 4975 static enum i40e_status_code 4976 validate_tcmap_parameter(struct i40e_vsi *vsi, uint8_t enabled_tcmap) 4977 { 4978 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 4979 4980 /* If DCB is not supported, only default TC is supported */ 4981 if (!hw->func_caps.dcb && enabled_tcmap != I40E_DEFAULT_TCMAP) { 4982 PMD_DRV_LOG(ERR, "DCB is not enabled, only TC0 is supported"); 4983 return I40E_NOT_SUPPORTED; 4984 } 4985 4986 if (!bitmap_is_subset(hw->func_caps.enabled_tcmap, enabled_tcmap)) { 4987 PMD_DRV_LOG(ERR, 4988 "Enabled TC map 0x%x not applicable to HW support 0x%x", 4989 hw->func_caps.enabled_tcmap, enabled_tcmap); 4990 return I40E_NOT_SUPPORTED; 4991 } 4992 return I40E_SUCCESS; 4993 } 4994 4995 int 4996 i40e_vsi_vlan_pvid_set(struct i40e_vsi *vsi, 4997 struct i40e_vsi_vlan_pvid_info *info) 4998 { 4999 struct i40e_hw *hw; 5000 struct i40e_vsi_context ctxt; 5001 uint8_t vlan_flags = 0; 5002 int ret; 5003 5004 if (vsi == NULL || info == NULL) { 5005 PMD_DRV_LOG(ERR, "invalid parameters"); 5006 return I40E_ERR_PARAM; 5007 } 5008 5009 if (info->on) { 5010 vsi->info.pvid = info->config.pvid; 5011 /** 5012 * If insert pvid is enabled, only tagged pkts are 5013 * allowed to be sent out. 5014 */ 5015 vlan_flags |= I40E_AQ_VSI_PVLAN_INSERT_PVID | 5016 I40E_AQ_VSI_PVLAN_MODE_TAGGED; 5017 } else { 5018 vsi->info.pvid = 0; 5019 if (info->config.reject.tagged == 0) 5020 vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_TAGGED; 5021 5022 if (info->config.reject.untagged == 0) 5023 vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_UNTAGGED; 5024 } 5025 vsi->info.port_vlan_flags &= ~(I40E_AQ_VSI_PVLAN_INSERT_PVID | 5026 I40E_AQ_VSI_PVLAN_MODE_MASK); 5027 vsi->info.port_vlan_flags |= vlan_flags; 5028 vsi->info.valid_sections = 5029 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID); 5030 memset(&ctxt, 0, sizeof(ctxt)); 5031 rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info)); 5032 ctxt.seid = vsi->seid; 5033 5034 hw = I40E_VSI_TO_HW(vsi); 5035 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); 5036 if (ret != I40E_SUCCESS) 5037 PMD_DRV_LOG(ERR, "Failed to update VSI params"); 5038 5039 return ret; 5040 } 5041 5042 static int 5043 i40e_vsi_update_tc_bandwidth(struct i40e_vsi *vsi, uint8_t enabled_tcmap) 5044 { 5045 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 5046 int i, ret; 5047 struct i40e_aqc_configure_vsi_tc_bw_data tc_bw_data; 5048 5049 ret = validate_tcmap_parameter(vsi, enabled_tcmap); 5050 if (ret != I40E_SUCCESS) 5051 return ret; 5052 5053 if (!vsi->seid) { 5054 PMD_DRV_LOG(ERR, "seid not valid"); 5055 return -EINVAL; 5056 } 5057 5058 memset(&tc_bw_data, 0, sizeof(tc_bw_data)); 5059 tc_bw_data.tc_valid_bits = enabled_tcmap; 5060 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) 5061 tc_bw_data.tc_bw_credits[i] = 5062 (enabled_tcmap & (1 << i)) ? 1 : 0; 5063 5064 ret = i40e_aq_config_vsi_tc_bw(hw, vsi->seid, &tc_bw_data, NULL); 5065 if (ret != I40E_SUCCESS) { 5066 PMD_DRV_LOG(ERR, "Failed to configure TC BW"); 5067 return ret; 5068 } 5069 5070 rte_memcpy(vsi->info.qs_handle, tc_bw_data.qs_handles, 5071 sizeof(vsi->info.qs_handle)); 5072 return I40E_SUCCESS; 5073 } 5074 5075 static enum i40e_status_code 5076 i40e_vsi_config_tc_queue_mapping(struct i40e_vsi *vsi, 5077 struct i40e_aqc_vsi_properties_data *info, 5078 uint8_t enabled_tcmap) 5079 { 5080 enum i40e_status_code ret; 5081 int i, total_tc = 0; 5082 uint16_t qpnum_per_tc, bsf, qp_idx; 5083 5084 ret = validate_tcmap_parameter(vsi, enabled_tcmap); 5085 if (ret != I40E_SUCCESS) 5086 return ret; 5087 5088 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) 5089 if (enabled_tcmap & (1 << i)) 5090 total_tc++; 5091 if (total_tc == 0) 5092 total_tc = 1; 5093 vsi->enabled_tc = enabled_tcmap; 5094 5095 /* Number of queues per enabled TC */ 5096 qpnum_per_tc = i40e_align_floor(vsi->nb_qps / total_tc); 5097 qpnum_per_tc = RTE_MIN(qpnum_per_tc, I40E_MAX_Q_PER_TC); 5098 bsf = rte_bsf32(qpnum_per_tc); 5099 5100 /* Adjust the queue number to actual queues that can be applied */ 5101 if (!(vsi->type == I40E_VSI_MAIN && total_tc == 1)) 5102 vsi->nb_qps = qpnum_per_tc * total_tc; 5103 5104 /** 5105 * Configure TC and queue mapping parameters, for enabled TC, 5106 * allocate qpnum_per_tc queues to this traffic. For disabled TC, 5107 * default queue will serve it. 5108 */ 5109 qp_idx = 0; 5110 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 5111 if (vsi->enabled_tc & (1 << i)) { 5112 info->tc_mapping[i] = rte_cpu_to_le_16((qp_idx << 5113 I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) | 5114 (bsf << I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT)); 5115 qp_idx += qpnum_per_tc; 5116 } else 5117 info->tc_mapping[i] = 0; 5118 } 5119 5120 /* Associate queue number with VSI */ 5121 if (vsi->type == I40E_VSI_SRIOV) { 5122 info->mapping_flags |= 5123 rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_NONCONTIG); 5124 for (i = 0; i < vsi->nb_qps; i++) 5125 info->queue_mapping[i] = 5126 rte_cpu_to_le_16(vsi->base_queue + i); 5127 } else { 5128 info->mapping_flags |= 5129 rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_CONTIG); 5130 info->queue_mapping[0] = rte_cpu_to_le_16(vsi->base_queue); 5131 } 5132 info->valid_sections |= 5133 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_QUEUE_MAP_VALID); 5134 5135 return I40E_SUCCESS; 5136 } 5137 5138 static int 5139 i40e_veb_release(struct i40e_veb *veb) 5140 { 5141 struct i40e_vsi *vsi; 5142 struct i40e_hw *hw; 5143 5144 if (veb == NULL) 5145 return -EINVAL; 5146 5147 if (!TAILQ_EMPTY(&veb->head)) { 5148 PMD_DRV_LOG(ERR, "VEB still has VSI attached, can't remove"); 5149 return -EACCES; 5150 } 5151 /* associate_vsi field is NULL for floating VEB */ 5152 if (veb->associate_vsi != NULL) { 5153 vsi = veb->associate_vsi; 5154 hw = I40E_VSI_TO_HW(vsi); 5155 5156 vsi->uplink_seid = veb->uplink_seid; 5157 vsi->veb = NULL; 5158 } else { 5159 veb->associate_pf->main_vsi->floating_veb = NULL; 5160 hw = I40E_VSI_TO_HW(veb->associate_pf->main_vsi); 5161 } 5162 5163 i40e_aq_delete_element(hw, veb->seid, NULL); 5164 rte_free(veb); 5165 return I40E_SUCCESS; 5166 } 5167 5168 /* Setup a veb */ 5169 static struct i40e_veb * 5170 i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi) 5171 { 5172 struct i40e_veb *veb; 5173 int ret; 5174 struct i40e_hw *hw; 5175 5176 if (pf == NULL) { 5177 PMD_DRV_LOG(ERR, 5178 "veb setup failed, associated PF shouldn't null"); 5179 return NULL; 5180 } 5181 hw = I40E_PF_TO_HW(pf); 5182 5183 veb = rte_zmalloc("i40e_veb", sizeof(struct i40e_veb), 0); 5184 if (!veb) { 5185 PMD_DRV_LOG(ERR, "Failed to allocate memory for veb"); 5186 goto fail; 5187 } 5188 5189 veb->associate_vsi = vsi; 5190 veb->associate_pf = pf; 5191 TAILQ_INIT(&veb->head); 5192 veb->uplink_seid = vsi ? vsi->uplink_seid : 0; 5193 5194 /* create floating veb if vsi is NULL */ 5195 if (vsi != NULL) { 5196 ret = i40e_aq_add_veb(hw, veb->uplink_seid, vsi->seid, 5197 I40E_DEFAULT_TCMAP, false, 5198 &veb->seid, false, NULL); 5199 } else { 5200 ret = i40e_aq_add_veb(hw, 0, 0, I40E_DEFAULT_TCMAP, 5201 true, &veb->seid, false, NULL); 5202 } 5203 5204 if (ret != I40E_SUCCESS) { 5205 PMD_DRV_LOG(ERR, "Add veb failed, aq_err: %d", 5206 hw->aq.asq_last_status); 5207 goto fail; 5208 } 5209 veb->enabled_tc = I40E_DEFAULT_TCMAP; 5210 5211 /* get statistics index */ 5212 ret = i40e_aq_get_veb_parameters(hw, veb->seid, NULL, NULL, 5213 &veb->stats_idx, NULL, NULL, NULL); 5214 if (ret != I40E_SUCCESS) { 5215 PMD_DRV_LOG(ERR, "Get veb statistics index failed, aq_err: %d", 5216 hw->aq.asq_last_status); 5217 goto fail; 5218 } 5219 /* Get VEB bandwidth, to be implemented */ 5220 /* Now associated vsi binding to the VEB, set uplink to this VEB */ 5221 if (vsi) 5222 vsi->uplink_seid = veb->seid; 5223 5224 return veb; 5225 fail: 5226 rte_free(veb); 5227 return NULL; 5228 } 5229 5230 int 5231 i40e_vsi_release(struct i40e_vsi *vsi) 5232 { 5233 struct i40e_pf *pf; 5234 struct i40e_hw *hw; 5235 struct i40e_vsi_list *vsi_list; 5236 void *temp; 5237 int ret; 5238 struct i40e_mac_filter *f; 5239 uint16_t user_param; 5240 5241 if (!vsi) 5242 return I40E_SUCCESS; 5243 5244 if (!vsi->adapter) 5245 return -EFAULT; 5246 5247 user_param = vsi->user_param; 5248 5249 pf = I40E_VSI_TO_PF(vsi); 5250 hw = I40E_VSI_TO_HW(vsi); 5251 5252 /* VSI has child to attach, release child first */ 5253 if (vsi->veb) { 5254 TAILQ_FOREACH_SAFE(vsi_list, &vsi->veb->head, list, temp) { 5255 if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS) 5256 return -1; 5257 } 5258 i40e_veb_release(vsi->veb); 5259 } 5260 5261 if (vsi->floating_veb) { 5262 TAILQ_FOREACH_SAFE(vsi_list, &vsi->floating_veb->head, list, temp) { 5263 if (i40e_vsi_release(vsi_list->vsi) != I40E_SUCCESS) 5264 return -1; 5265 } 5266 } 5267 5268 /* Remove all macvlan filters of the VSI */ 5269 i40e_vsi_remove_all_macvlan_filter(vsi); 5270 TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) 5271 rte_free(f); 5272 5273 if (vsi->type != I40E_VSI_MAIN && 5274 ((vsi->type != I40E_VSI_SRIOV) || 5275 !pf->floating_veb_list[user_param])) { 5276 /* Remove vsi from parent's sibling list */ 5277 if (vsi->parent_vsi == NULL || vsi->parent_vsi->veb == NULL) { 5278 PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL"); 5279 return I40E_ERR_PARAM; 5280 } 5281 TAILQ_REMOVE(&vsi->parent_vsi->veb->head, 5282 &vsi->sib_vsi_list, list); 5283 5284 /* Remove all switch element of the VSI */ 5285 ret = i40e_aq_delete_element(hw, vsi->seid, NULL); 5286 if (ret != I40E_SUCCESS) 5287 PMD_DRV_LOG(ERR, "Failed to delete element"); 5288 } 5289 5290 if ((vsi->type == I40E_VSI_SRIOV) && 5291 pf->floating_veb_list[user_param]) { 5292 /* Remove vsi from parent's sibling list */ 5293 if (vsi->parent_vsi == NULL || 5294 vsi->parent_vsi->floating_veb == NULL) { 5295 PMD_DRV_LOG(ERR, "VSI's parent VSI is NULL"); 5296 return I40E_ERR_PARAM; 5297 } 5298 TAILQ_REMOVE(&vsi->parent_vsi->floating_veb->head, 5299 &vsi->sib_vsi_list, list); 5300 5301 /* Remove all switch element of the VSI */ 5302 ret = i40e_aq_delete_element(hw, vsi->seid, NULL); 5303 if (ret != I40E_SUCCESS) 5304 PMD_DRV_LOG(ERR, "Failed to delete element"); 5305 } 5306 5307 i40e_res_pool_free(&pf->qp_pool, vsi->base_queue); 5308 5309 if (vsi->type != I40E_VSI_SRIOV) 5310 i40e_res_pool_free(&pf->msix_pool, vsi->msix_intr); 5311 rte_free(vsi); 5312 5313 return I40E_SUCCESS; 5314 } 5315 5316 static int 5317 i40e_update_default_filter_setting(struct i40e_vsi *vsi) 5318 { 5319 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 5320 struct i40e_aqc_remove_macvlan_element_data def_filter; 5321 struct i40e_mac_filter_info filter; 5322 int ret; 5323 5324 if (vsi->type != I40E_VSI_MAIN) 5325 return I40E_ERR_CONFIG; 5326 memset(&def_filter, 0, sizeof(def_filter)); 5327 rte_memcpy(def_filter.mac_addr, hw->mac.perm_addr, 5328 ETH_ADDR_LEN); 5329 def_filter.vlan_tag = 0; 5330 def_filter.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH | 5331 I40E_AQC_MACVLAN_DEL_IGNORE_VLAN; 5332 ret = i40e_aq_remove_macvlan(hw, vsi->seid, &def_filter, 1, NULL); 5333 if (ret != I40E_SUCCESS) { 5334 struct i40e_mac_filter *f; 5335 struct ether_addr *mac; 5336 5337 PMD_DRV_LOG(DEBUG, 5338 "Cannot remove the default macvlan filter"); 5339 /* It needs to add the permanent mac into mac list */ 5340 f = rte_zmalloc("macv_filter", sizeof(*f), 0); 5341 if (f == NULL) { 5342 PMD_DRV_LOG(ERR, "failed to allocate memory"); 5343 return I40E_ERR_NO_MEMORY; 5344 } 5345 mac = &f->mac_info.mac_addr; 5346 rte_memcpy(&mac->addr_bytes, hw->mac.perm_addr, 5347 ETH_ADDR_LEN); 5348 f->mac_info.filter_type = RTE_MACVLAN_PERFECT_MATCH; 5349 TAILQ_INSERT_TAIL(&vsi->mac_list, f, next); 5350 vsi->mac_num++; 5351 5352 return ret; 5353 } 5354 rte_memcpy(&filter.mac_addr, 5355 (struct ether_addr *)(hw->mac.perm_addr), ETH_ADDR_LEN); 5356 filter.filter_type = RTE_MACVLAN_PERFECT_MATCH; 5357 return i40e_vsi_add_mac(vsi, &filter); 5358 } 5359 5360 /* 5361 * i40e_vsi_get_bw_config - Query VSI BW Information 5362 * @vsi: the VSI to be queried 5363 * 5364 * Returns 0 on success, negative value on failure 5365 */ 5366 static enum i40e_status_code 5367 i40e_vsi_get_bw_config(struct i40e_vsi *vsi) 5368 { 5369 struct i40e_aqc_query_vsi_bw_config_resp bw_config; 5370 struct i40e_aqc_query_vsi_ets_sla_config_resp ets_sla_config; 5371 struct i40e_hw *hw = &vsi->adapter->hw; 5372 i40e_status ret; 5373 int i; 5374 uint32_t bw_max; 5375 5376 memset(&bw_config, 0, sizeof(bw_config)); 5377 ret = i40e_aq_query_vsi_bw_config(hw, vsi->seid, &bw_config, NULL); 5378 if (ret != I40E_SUCCESS) { 5379 PMD_DRV_LOG(ERR, "VSI failed to get bandwidth configuration %u", 5380 hw->aq.asq_last_status); 5381 return ret; 5382 } 5383 5384 memset(&ets_sla_config, 0, sizeof(ets_sla_config)); 5385 ret = i40e_aq_query_vsi_ets_sla_config(hw, vsi->seid, 5386 &ets_sla_config, NULL); 5387 if (ret != I40E_SUCCESS) { 5388 PMD_DRV_LOG(ERR, 5389 "VSI failed to get TC bandwdith configuration %u", 5390 hw->aq.asq_last_status); 5391 return ret; 5392 } 5393 5394 /* store and print out BW info */ 5395 vsi->bw_info.bw_limit = rte_le_to_cpu_16(bw_config.port_bw_limit); 5396 vsi->bw_info.bw_max = bw_config.max_bw; 5397 PMD_DRV_LOG(DEBUG, "VSI bw limit:%u", vsi->bw_info.bw_limit); 5398 PMD_DRV_LOG(DEBUG, "VSI max_bw:%u", vsi->bw_info.bw_max); 5399 bw_max = rte_le_to_cpu_16(ets_sla_config.tc_bw_max[0]) | 5400 (rte_le_to_cpu_16(ets_sla_config.tc_bw_max[1]) << 5401 I40E_16_BIT_WIDTH); 5402 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 5403 vsi->bw_info.bw_ets_share_credits[i] = 5404 ets_sla_config.share_credits[i]; 5405 vsi->bw_info.bw_ets_credits[i] = 5406 rte_le_to_cpu_16(ets_sla_config.credits[i]); 5407 /* 4 bits per TC, 4th bit is reserved */ 5408 vsi->bw_info.bw_ets_max[i] = 5409 (uint8_t)((bw_max >> (i * I40E_4_BIT_WIDTH)) & 5410 RTE_LEN2MASK(3, uint8_t)); 5411 PMD_DRV_LOG(DEBUG, "\tVSI TC%u:share credits %u", i, 5412 vsi->bw_info.bw_ets_share_credits[i]); 5413 PMD_DRV_LOG(DEBUG, "\tVSI TC%u:credits %u", i, 5414 vsi->bw_info.bw_ets_credits[i]); 5415 PMD_DRV_LOG(DEBUG, "\tVSI TC%u: max credits: %u", i, 5416 vsi->bw_info.bw_ets_max[i]); 5417 } 5418 5419 return I40E_SUCCESS; 5420 } 5421 5422 /* i40e_enable_pf_lb 5423 * @pf: pointer to the pf structure 5424 * 5425 * allow loopback on pf 5426 */ 5427 static inline void 5428 i40e_enable_pf_lb(struct i40e_pf *pf) 5429 { 5430 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 5431 struct i40e_vsi_context ctxt; 5432 int ret; 5433 5434 /* Use the FW API if FW >= v5.0 */ 5435 if (hw->aq.fw_maj_ver < 5 && hw->mac.type != I40E_MAC_X722) { 5436 PMD_INIT_LOG(ERR, "FW < v5.0, cannot enable loopback"); 5437 return; 5438 } 5439 5440 memset(&ctxt, 0, sizeof(ctxt)); 5441 ctxt.seid = pf->main_vsi_seid; 5442 ctxt.pf_num = hw->pf_id; 5443 ret = i40e_aq_get_vsi_params(hw, &ctxt, NULL); 5444 if (ret) { 5445 PMD_DRV_LOG(ERR, "cannot get pf vsi config, err %d, aq_err %d", 5446 ret, hw->aq.asq_last_status); 5447 return; 5448 } 5449 ctxt.flags = I40E_AQ_VSI_TYPE_PF; 5450 ctxt.info.valid_sections = 5451 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID); 5452 ctxt.info.switch_id |= 5453 rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB); 5454 5455 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); 5456 if (ret) 5457 PMD_DRV_LOG(ERR, "update vsi switch failed, aq_err=%d", 5458 hw->aq.asq_last_status); 5459 } 5460 5461 /* Setup a VSI */ 5462 struct i40e_vsi * 5463 i40e_vsi_setup(struct i40e_pf *pf, 5464 enum i40e_vsi_type type, 5465 struct i40e_vsi *uplink_vsi, 5466 uint16_t user_param) 5467 { 5468 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 5469 struct i40e_vsi *vsi; 5470 struct i40e_mac_filter_info filter; 5471 int ret; 5472 struct i40e_vsi_context ctxt; 5473 struct ether_addr broadcast = 5474 {.addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; 5475 5476 if (type != I40E_VSI_MAIN && type != I40E_VSI_SRIOV && 5477 uplink_vsi == NULL) { 5478 PMD_DRV_LOG(ERR, 5479 "VSI setup failed, VSI link shouldn't be NULL"); 5480 return NULL; 5481 } 5482 5483 if (type == I40E_VSI_MAIN && uplink_vsi != NULL) { 5484 PMD_DRV_LOG(ERR, 5485 "VSI setup failed, MAIN VSI uplink VSI should be NULL"); 5486 return NULL; 5487 } 5488 5489 /* two situations 5490 * 1.type is not MAIN and uplink vsi is not NULL 5491 * If uplink vsi didn't setup VEB, create one first under veb field 5492 * 2.type is SRIOV and the uplink is NULL 5493 * If floating VEB is NULL, create one veb under floating veb field 5494 */ 5495 5496 if (type != I40E_VSI_MAIN && uplink_vsi != NULL && 5497 uplink_vsi->veb == NULL) { 5498 uplink_vsi->veb = i40e_veb_setup(pf, uplink_vsi); 5499 5500 if (uplink_vsi->veb == NULL) { 5501 PMD_DRV_LOG(ERR, "VEB setup failed"); 5502 return NULL; 5503 } 5504 /* set ALLOWLOOPBACk on pf, when veb is created */ 5505 i40e_enable_pf_lb(pf); 5506 } 5507 5508 if (type == I40E_VSI_SRIOV && uplink_vsi == NULL && 5509 pf->main_vsi->floating_veb == NULL) { 5510 pf->main_vsi->floating_veb = i40e_veb_setup(pf, uplink_vsi); 5511 5512 if (pf->main_vsi->floating_veb == NULL) { 5513 PMD_DRV_LOG(ERR, "VEB setup failed"); 5514 return NULL; 5515 } 5516 } 5517 5518 vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0); 5519 if (!vsi) { 5520 PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi"); 5521 return NULL; 5522 } 5523 TAILQ_INIT(&vsi->mac_list); 5524 vsi->type = type; 5525 vsi->adapter = I40E_PF_TO_ADAPTER(pf); 5526 vsi->max_macaddrs = I40E_NUM_MACADDR_MAX; 5527 vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi; 5528 vsi->user_param = user_param; 5529 vsi->vlan_anti_spoof_on = 0; 5530 vsi->vlan_filter_on = 0; 5531 /* Allocate queues */ 5532 switch (vsi->type) { 5533 case I40E_VSI_MAIN : 5534 vsi->nb_qps = pf->lan_nb_qps; 5535 break; 5536 case I40E_VSI_SRIOV : 5537 vsi->nb_qps = pf->vf_nb_qps; 5538 break; 5539 case I40E_VSI_VMDQ2: 5540 vsi->nb_qps = pf->vmdq_nb_qps; 5541 break; 5542 case I40E_VSI_FDIR: 5543 vsi->nb_qps = pf->fdir_nb_qps; 5544 break; 5545 default: 5546 goto fail_mem; 5547 } 5548 /* 5549 * The filter status descriptor is reported in rx queue 0, 5550 * while the tx queue for fdir filter programming has no 5551 * such constraints, can be non-zero queues. 5552 * To simplify it, choose FDIR vsi use queue 0 pair. 5553 * To make sure it will use queue 0 pair, queue allocation 5554 * need be done before this function is called 5555 */ 5556 if (type != I40E_VSI_FDIR) { 5557 ret = i40e_res_pool_alloc(&pf->qp_pool, vsi->nb_qps); 5558 if (ret < 0) { 5559 PMD_DRV_LOG(ERR, "VSI %d allocate queue failed %d", 5560 vsi->seid, ret); 5561 goto fail_mem; 5562 } 5563 vsi->base_queue = ret; 5564 } else 5565 vsi->base_queue = I40E_FDIR_QUEUE_ID; 5566 5567 /* VF has MSIX interrupt in VF range, don't allocate here */ 5568 if (type == I40E_VSI_MAIN) { 5569 if (pf->support_multi_driver) { 5570 /* If support multi-driver, need to use INT0 instead of 5571 * allocating from msix pool. The Msix pool is init from 5572 * INT1, so it's OK just set msix_intr to 0 and nb_msix 5573 * to 1 without calling i40e_res_pool_alloc. 5574 */ 5575 vsi->msix_intr = 0; 5576 vsi->nb_msix = 1; 5577 } else { 5578 ret = i40e_res_pool_alloc(&pf->msix_pool, 5579 RTE_MIN(vsi->nb_qps, 5580 RTE_MAX_RXTX_INTR_VEC_ID)); 5581 if (ret < 0) { 5582 PMD_DRV_LOG(ERR, 5583 "VSI MAIN %d get heap failed %d", 5584 vsi->seid, ret); 5585 goto fail_queue_alloc; 5586 } 5587 vsi->msix_intr = ret; 5588 vsi->nb_msix = RTE_MIN(vsi->nb_qps, 5589 RTE_MAX_RXTX_INTR_VEC_ID); 5590 } 5591 } else if (type != I40E_VSI_SRIOV) { 5592 ret = i40e_res_pool_alloc(&pf->msix_pool, 1); 5593 if (ret < 0) { 5594 PMD_DRV_LOG(ERR, "VSI %d get heap failed %d", vsi->seid, ret); 5595 goto fail_queue_alloc; 5596 } 5597 vsi->msix_intr = ret; 5598 vsi->nb_msix = 1; 5599 } else { 5600 vsi->msix_intr = 0; 5601 vsi->nb_msix = 0; 5602 } 5603 5604 /* Add VSI */ 5605 if (type == I40E_VSI_MAIN) { 5606 /* For main VSI, no need to add since it's default one */ 5607 vsi->uplink_seid = pf->mac_seid; 5608 vsi->seid = pf->main_vsi_seid; 5609 /* Bind queues with specific MSIX interrupt */ 5610 /** 5611 * Needs 2 interrupt at least, one for misc cause which will 5612 * enabled from OS side, Another for queues binding the 5613 * interrupt from device side only. 5614 */ 5615 5616 /* Get default VSI parameters from hardware */ 5617 memset(&ctxt, 0, sizeof(ctxt)); 5618 ctxt.seid = vsi->seid; 5619 ctxt.pf_num = hw->pf_id; 5620 ctxt.uplink_seid = vsi->uplink_seid; 5621 ctxt.vf_num = 0; 5622 ret = i40e_aq_get_vsi_params(hw, &ctxt, NULL); 5623 if (ret != I40E_SUCCESS) { 5624 PMD_DRV_LOG(ERR, "Failed to get VSI params"); 5625 goto fail_msix_alloc; 5626 } 5627 rte_memcpy(&vsi->info, &ctxt.info, 5628 sizeof(struct i40e_aqc_vsi_properties_data)); 5629 vsi->vsi_id = ctxt.vsi_number; 5630 vsi->info.valid_sections = 0; 5631 5632 /* Configure tc, enabled TC0 only */ 5633 if (i40e_vsi_update_tc_bandwidth(vsi, I40E_DEFAULT_TCMAP) != 5634 I40E_SUCCESS) { 5635 PMD_DRV_LOG(ERR, "Failed to update TC bandwidth"); 5636 goto fail_msix_alloc; 5637 } 5638 5639 /* TC, queue mapping */ 5640 memset(&ctxt, 0, sizeof(ctxt)); 5641 vsi->info.valid_sections |= 5642 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID); 5643 vsi->info.port_vlan_flags = I40E_AQ_VSI_PVLAN_MODE_ALL | 5644 I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH; 5645 rte_memcpy(&ctxt.info, &vsi->info, 5646 sizeof(struct i40e_aqc_vsi_properties_data)); 5647 ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info, 5648 I40E_DEFAULT_TCMAP); 5649 if (ret != I40E_SUCCESS) { 5650 PMD_DRV_LOG(ERR, 5651 "Failed to configure TC queue mapping"); 5652 goto fail_msix_alloc; 5653 } 5654 ctxt.seid = vsi->seid; 5655 ctxt.pf_num = hw->pf_id; 5656 ctxt.uplink_seid = vsi->uplink_seid; 5657 ctxt.vf_num = 0; 5658 5659 /* Update VSI parameters */ 5660 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); 5661 if (ret != I40E_SUCCESS) { 5662 PMD_DRV_LOG(ERR, "Failed to update VSI params"); 5663 goto fail_msix_alloc; 5664 } 5665 5666 rte_memcpy(&vsi->info.tc_mapping, &ctxt.info.tc_mapping, 5667 sizeof(vsi->info.tc_mapping)); 5668 rte_memcpy(&vsi->info.queue_mapping, 5669 &ctxt.info.queue_mapping, 5670 sizeof(vsi->info.queue_mapping)); 5671 vsi->info.mapping_flags = ctxt.info.mapping_flags; 5672 vsi->info.valid_sections = 0; 5673 5674 rte_memcpy(pf->dev_addr.addr_bytes, hw->mac.perm_addr, 5675 ETH_ADDR_LEN); 5676 5677 /** 5678 * Updating default filter settings are necessary to prevent 5679 * reception of tagged packets. 5680 * Some old firmware configurations load a default macvlan 5681 * filter which accepts both tagged and untagged packets. 5682 * The updating is to use a normal filter instead if needed. 5683 * For NVM 4.2.2 or after, the updating is not needed anymore. 5684 * The firmware with correct configurations load the default 5685 * macvlan filter which is expected and cannot be removed. 5686 */ 5687 i40e_update_default_filter_setting(vsi); 5688 i40e_config_qinq(hw, vsi); 5689 } else if (type == I40E_VSI_SRIOV) { 5690 memset(&ctxt, 0, sizeof(ctxt)); 5691 /** 5692 * For other VSI, the uplink_seid equals to uplink VSI's 5693 * uplink_seid since they share same VEB 5694 */ 5695 if (uplink_vsi == NULL) 5696 vsi->uplink_seid = pf->main_vsi->floating_veb->seid; 5697 else 5698 vsi->uplink_seid = uplink_vsi->uplink_seid; 5699 ctxt.pf_num = hw->pf_id; 5700 ctxt.vf_num = hw->func_caps.vf_base_id + user_param; 5701 ctxt.uplink_seid = vsi->uplink_seid; 5702 ctxt.connection_type = 0x1; 5703 ctxt.flags = I40E_AQ_VSI_TYPE_VF; 5704 5705 /* Use the VEB configuration if FW >= v5.0 */ 5706 if (hw->aq.fw_maj_ver >= 5 || hw->mac.type == I40E_MAC_X722) { 5707 /* Configure switch ID */ 5708 ctxt.info.valid_sections |= 5709 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID); 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 hw->func_caps.enabled_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 5726 ctxt.info.up_enable_bits = hw->func_caps.enabled_tcmap; 5727 ctxt.info.valid_sections |= 5728 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SCHED_VALID); 5729 /** 5730 * Since VSI is not created yet, only configure parameter, 5731 * will add vsi below. 5732 */ 5733 5734 i40e_config_qinq(hw, vsi); 5735 } else if (type == I40E_VSI_VMDQ2) { 5736 memset(&ctxt, 0, sizeof(ctxt)); 5737 /* 5738 * For other VSI, the uplink_seid equals to uplink VSI's 5739 * uplink_seid since they share same VEB 5740 */ 5741 vsi->uplink_seid = uplink_vsi->uplink_seid; 5742 ctxt.pf_num = hw->pf_id; 5743 ctxt.vf_num = 0; 5744 ctxt.uplink_seid = vsi->uplink_seid; 5745 ctxt.connection_type = 0x1; 5746 ctxt.flags = I40E_AQ_VSI_TYPE_VMDQ2; 5747 5748 ctxt.info.valid_sections |= 5749 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID); 5750 /* user_param carries flag to enable loop back */ 5751 if (user_param) { 5752 ctxt.info.switch_id = 5753 rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB); 5754 ctxt.info.switch_id |= 5755 rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB); 5756 } 5757 5758 /* Configure port/vlan */ 5759 ctxt.info.valid_sections |= 5760 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID); 5761 ctxt.info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_ALL; 5762 ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info, 5763 I40E_DEFAULT_TCMAP); 5764 if (ret != I40E_SUCCESS) { 5765 PMD_DRV_LOG(ERR, 5766 "Failed to configure TC queue mapping"); 5767 goto fail_msix_alloc; 5768 } 5769 ctxt.info.up_enable_bits = I40E_DEFAULT_TCMAP; 5770 ctxt.info.valid_sections |= 5771 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SCHED_VALID); 5772 } else if (type == I40E_VSI_FDIR) { 5773 memset(&ctxt, 0, sizeof(ctxt)); 5774 vsi->uplink_seid = uplink_vsi->uplink_seid; 5775 ctxt.pf_num = hw->pf_id; 5776 ctxt.vf_num = 0; 5777 ctxt.uplink_seid = vsi->uplink_seid; 5778 ctxt.connection_type = 0x1; /* regular data port */ 5779 ctxt.flags = I40E_AQ_VSI_TYPE_PF; 5780 ret = i40e_vsi_config_tc_queue_mapping(vsi, &ctxt.info, 5781 I40E_DEFAULT_TCMAP); 5782 if (ret != I40E_SUCCESS) { 5783 PMD_DRV_LOG(ERR, 5784 "Failed to configure TC queue mapping."); 5785 goto fail_msix_alloc; 5786 } 5787 ctxt.info.up_enable_bits = I40E_DEFAULT_TCMAP; 5788 ctxt.info.valid_sections |= 5789 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SCHED_VALID); 5790 } else { 5791 PMD_DRV_LOG(ERR, "VSI: Not support other type VSI yet"); 5792 goto fail_msix_alloc; 5793 } 5794 5795 if (vsi->type != I40E_VSI_MAIN) { 5796 ret = i40e_aq_add_vsi(hw, &ctxt, NULL); 5797 if (ret != I40E_SUCCESS) { 5798 PMD_DRV_LOG(ERR, "add vsi failed, aq_err=%d", 5799 hw->aq.asq_last_status); 5800 goto fail_msix_alloc; 5801 } 5802 memcpy(&vsi->info, &ctxt.info, sizeof(ctxt.info)); 5803 vsi->info.valid_sections = 0; 5804 vsi->seid = ctxt.seid; 5805 vsi->vsi_id = ctxt.vsi_number; 5806 vsi->sib_vsi_list.vsi = vsi; 5807 if (vsi->type == I40E_VSI_SRIOV && uplink_vsi == NULL) { 5808 TAILQ_INSERT_TAIL(&pf->main_vsi->floating_veb->head, 5809 &vsi->sib_vsi_list, list); 5810 } else { 5811 TAILQ_INSERT_TAIL(&uplink_vsi->veb->head, 5812 &vsi->sib_vsi_list, list); 5813 } 5814 } 5815 5816 /* MAC/VLAN configuration */ 5817 rte_memcpy(&filter.mac_addr, &broadcast, ETHER_ADDR_LEN); 5818 filter.filter_type = RTE_MACVLAN_PERFECT_MATCH; 5819 5820 ret = i40e_vsi_add_mac(vsi, &filter); 5821 if (ret != I40E_SUCCESS) { 5822 PMD_DRV_LOG(ERR, "Failed to add MACVLAN filter"); 5823 goto fail_msix_alloc; 5824 } 5825 5826 /* Get VSI BW information */ 5827 i40e_vsi_get_bw_config(vsi); 5828 return vsi; 5829 fail_msix_alloc: 5830 i40e_res_pool_free(&pf->msix_pool,vsi->msix_intr); 5831 fail_queue_alloc: 5832 i40e_res_pool_free(&pf->qp_pool,vsi->base_queue); 5833 fail_mem: 5834 rte_free(vsi); 5835 return NULL; 5836 } 5837 5838 /* Configure vlan filter on or off */ 5839 int 5840 i40e_vsi_config_vlan_filter(struct i40e_vsi *vsi, bool on) 5841 { 5842 int i, num; 5843 struct i40e_mac_filter *f; 5844 void *temp; 5845 struct i40e_mac_filter_info *mac_filter; 5846 enum rte_mac_filter_type desired_filter; 5847 int ret = I40E_SUCCESS; 5848 5849 if (on) { 5850 /* Filter to match MAC and VLAN */ 5851 desired_filter = RTE_MACVLAN_PERFECT_MATCH; 5852 } else { 5853 /* Filter to match only MAC */ 5854 desired_filter = RTE_MAC_PERFECT_MATCH; 5855 } 5856 5857 num = vsi->mac_num; 5858 5859 mac_filter = rte_zmalloc("mac_filter_info_data", 5860 num * sizeof(*mac_filter), 0); 5861 if (mac_filter == NULL) { 5862 PMD_DRV_LOG(ERR, "failed to allocate memory"); 5863 return I40E_ERR_NO_MEMORY; 5864 } 5865 5866 i = 0; 5867 5868 /* Remove all existing mac */ 5869 TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) { 5870 mac_filter[i] = f->mac_info; 5871 ret = i40e_vsi_delete_mac(vsi, &f->mac_info.mac_addr); 5872 if (ret) { 5873 PMD_DRV_LOG(ERR, "Update VSI failed to %s vlan filter", 5874 on ? "enable" : "disable"); 5875 goto DONE; 5876 } 5877 i++; 5878 } 5879 5880 /* Override with new filter */ 5881 for (i = 0; i < num; i++) { 5882 mac_filter[i].filter_type = desired_filter; 5883 ret = i40e_vsi_add_mac(vsi, &mac_filter[i]); 5884 if (ret) { 5885 PMD_DRV_LOG(ERR, "Update VSI failed to %s vlan filter", 5886 on ? "enable" : "disable"); 5887 goto DONE; 5888 } 5889 } 5890 5891 DONE: 5892 rte_free(mac_filter); 5893 return ret; 5894 } 5895 5896 /* Configure vlan stripping on or off */ 5897 int 5898 i40e_vsi_config_vlan_stripping(struct i40e_vsi *vsi, bool on) 5899 { 5900 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 5901 struct i40e_vsi_context ctxt; 5902 uint8_t vlan_flags; 5903 int ret = I40E_SUCCESS; 5904 5905 /* Check if it has been already on or off */ 5906 if (vsi->info.valid_sections & 5907 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID)) { 5908 if (on) { 5909 if ((vsi->info.port_vlan_flags & 5910 I40E_AQ_VSI_PVLAN_EMOD_MASK) == 0) 5911 return 0; /* already on */ 5912 } else { 5913 if ((vsi->info.port_vlan_flags & 5914 I40E_AQ_VSI_PVLAN_EMOD_MASK) == 5915 I40E_AQ_VSI_PVLAN_EMOD_MASK) 5916 return 0; /* already off */ 5917 } 5918 } 5919 5920 if (on) 5921 vlan_flags = I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH; 5922 else 5923 vlan_flags = I40E_AQ_VSI_PVLAN_EMOD_NOTHING; 5924 vsi->info.valid_sections = 5925 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID); 5926 vsi->info.port_vlan_flags &= ~(I40E_AQ_VSI_PVLAN_EMOD_MASK); 5927 vsi->info.port_vlan_flags |= vlan_flags; 5928 ctxt.seid = vsi->seid; 5929 rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info)); 5930 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); 5931 if (ret) 5932 PMD_DRV_LOG(INFO, "Update VSI failed to %s vlan stripping", 5933 on ? "enable" : "disable"); 5934 5935 return ret; 5936 } 5937 5938 static int 5939 i40e_dev_init_vlan(struct rte_eth_dev *dev) 5940 { 5941 struct rte_eth_dev_data *data = dev->data; 5942 int ret; 5943 int mask = 0; 5944 5945 /* Apply vlan offload setting */ 5946 mask = ETH_VLAN_STRIP_MASK | 5947 ETH_VLAN_FILTER_MASK | 5948 ETH_VLAN_EXTEND_MASK; 5949 ret = i40e_vlan_offload_set(dev, mask); 5950 if (ret) { 5951 PMD_DRV_LOG(INFO, "Failed to update vlan offload"); 5952 return ret; 5953 } 5954 5955 /* Apply pvid setting */ 5956 ret = i40e_vlan_pvid_set(dev, data->dev_conf.txmode.pvid, 5957 data->dev_conf.txmode.hw_vlan_insert_pvid); 5958 if (ret) 5959 PMD_DRV_LOG(INFO, "Failed to update VSI params"); 5960 5961 return ret; 5962 } 5963 5964 static int 5965 i40e_vsi_config_double_vlan(struct i40e_vsi *vsi, int on) 5966 { 5967 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 5968 5969 return i40e_aq_set_port_parameters(hw, vsi->seid, 0, 1, on, NULL); 5970 } 5971 5972 static int 5973 i40e_update_flow_control(struct i40e_hw *hw) 5974 { 5975 #define I40E_LINK_PAUSE_RXTX (I40E_AQ_LINK_PAUSE_RX | I40E_AQ_LINK_PAUSE_TX) 5976 struct i40e_link_status link_status; 5977 uint32_t rxfc = 0, txfc = 0, reg; 5978 uint8_t an_info; 5979 int ret; 5980 5981 memset(&link_status, 0, sizeof(link_status)); 5982 ret = i40e_aq_get_link_info(hw, FALSE, &link_status, NULL); 5983 if (ret != I40E_SUCCESS) { 5984 PMD_DRV_LOG(ERR, "Failed to get link status information"); 5985 goto write_reg; /* Disable flow control */ 5986 } 5987 5988 an_info = hw->phy.link_info.an_info; 5989 if (!(an_info & I40E_AQ_AN_COMPLETED)) { 5990 PMD_DRV_LOG(INFO, "Link auto negotiation not completed"); 5991 ret = I40E_ERR_NOT_READY; 5992 goto write_reg; /* Disable flow control */ 5993 } 5994 /** 5995 * If link auto negotiation is enabled, flow control needs to 5996 * be configured according to it 5997 */ 5998 switch (an_info & I40E_LINK_PAUSE_RXTX) { 5999 case I40E_LINK_PAUSE_RXTX: 6000 rxfc = 1; 6001 txfc = 1; 6002 hw->fc.current_mode = I40E_FC_FULL; 6003 break; 6004 case I40E_AQ_LINK_PAUSE_RX: 6005 rxfc = 1; 6006 hw->fc.current_mode = I40E_FC_RX_PAUSE; 6007 break; 6008 case I40E_AQ_LINK_PAUSE_TX: 6009 txfc = 1; 6010 hw->fc.current_mode = I40E_FC_TX_PAUSE; 6011 break; 6012 default: 6013 hw->fc.current_mode = I40E_FC_NONE; 6014 break; 6015 } 6016 6017 write_reg: 6018 I40E_WRITE_REG(hw, I40E_PRTDCB_FCCFG, 6019 txfc << I40E_PRTDCB_FCCFG_TFCE_SHIFT); 6020 reg = I40E_READ_REG(hw, I40E_PRTDCB_MFLCN); 6021 reg &= ~I40E_PRTDCB_MFLCN_RFCE_MASK; 6022 reg |= rxfc << I40E_PRTDCB_MFLCN_RFCE_SHIFT; 6023 I40E_WRITE_REG(hw, I40E_PRTDCB_MFLCN, reg); 6024 6025 return ret; 6026 } 6027 6028 /* PF setup */ 6029 static int 6030 i40e_pf_setup(struct i40e_pf *pf) 6031 { 6032 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 6033 struct i40e_filter_control_settings settings; 6034 struct i40e_vsi *vsi; 6035 int ret; 6036 6037 /* Clear all stats counters */ 6038 pf->offset_loaded = FALSE; 6039 memset(&pf->stats, 0, sizeof(struct i40e_hw_port_stats)); 6040 memset(&pf->stats_offset, 0, sizeof(struct i40e_hw_port_stats)); 6041 memset(&pf->internal_stats, 0, sizeof(struct i40e_eth_stats)); 6042 memset(&pf->internal_stats_offset, 0, sizeof(struct i40e_eth_stats)); 6043 6044 ret = i40e_pf_get_switch_config(pf); 6045 if (ret != I40E_SUCCESS) { 6046 PMD_DRV_LOG(ERR, "Could not get switch config, err %d", ret); 6047 return ret; 6048 } 6049 6050 ret = rte_eth_switch_domain_alloc(&pf->switch_domain_id); 6051 if (ret) 6052 PMD_INIT_LOG(WARNING, 6053 "failed to allocate switch domain for device %d", ret); 6054 6055 if (pf->flags & I40E_FLAG_FDIR) { 6056 /* make queue allocated first, let FDIR use queue pair 0*/ 6057 ret = i40e_res_pool_alloc(&pf->qp_pool, I40E_DEFAULT_QP_NUM_FDIR); 6058 if (ret != I40E_FDIR_QUEUE_ID) { 6059 PMD_DRV_LOG(ERR, 6060 "queue allocation fails for FDIR: ret =%d", 6061 ret); 6062 pf->flags &= ~I40E_FLAG_FDIR; 6063 } 6064 } 6065 /* main VSI setup */ 6066 vsi = i40e_vsi_setup(pf, I40E_VSI_MAIN, NULL, 0); 6067 if (!vsi) { 6068 PMD_DRV_LOG(ERR, "Setup of main vsi failed"); 6069 return I40E_ERR_NOT_READY; 6070 } 6071 pf->main_vsi = vsi; 6072 6073 /* Configure filter control */ 6074 memset(&settings, 0, sizeof(settings)); 6075 if (hw->func_caps.rss_table_size == ETH_RSS_RETA_SIZE_128) 6076 settings.hash_lut_size = I40E_HASH_LUT_SIZE_128; 6077 else if (hw->func_caps.rss_table_size == ETH_RSS_RETA_SIZE_512) 6078 settings.hash_lut_size = I40E_HASH_LUT_SIZE_512; 6079 else { 6080 PMD_DRV_LOG(ERR, "Hash lookup table size (%u) not supported", 6081 hw->func_caps.rss_table_size); 6082 return I40E_ERR_PARAM; 6083 } 6084 PMD_DRV_LOG(INFO, "Hardware capability of hash lookup table size: %u", 6085 hw->func_caps.rss_table_size); 6086 pf->hash_lut_size = hw->func_caps.rss_table_size; 6087 6088 /* Enable ethtype and macvlan filters */ 6089 settings.enable_ethtype = TRUE; 6090 settings.enable_macvlan = TRUE; 6091 ret = i40e_set_filter_control(hw, &settings); 6092 if (ret) 6093 PMD_INIT_LOG(WARNING, "setup_pf_filter_control failed: %d", 6094 ret); 6095 6096 /* Update flow control according to the auto negotiation */ 6097 i40e_update_flow_control(hw); 6098 6099 return I40E_SUCCESS; 6100 } 6101 6102 int 6103 i40e_switch_tx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on) 6104 { 6105 uint32_t reg; 6106 uint16_t j; 6107 6108 /** 6109 * Set or clear TX Queue Disable flags, 6110 * which is required by hardware. 6111 */ 6112 i40e_pre_tx_queue_cfg(hw, q_idx, on); 6113 rte_delay_us(I40E_PRE_TX_Q_CFG_WAIT_US); 6114 6115 /* Wait until the request is finished */ 6116 for (j = 0; j < I40E_CHK_Q_ENA_COUNT; j++) { 6117 rte_delay_us(I40E_CHK_Q_ENA_INTERVAL_US); 6118 reg = I40E_READ_REG(hw, I40E_QTX_ENA(q_idx)); 6119 if (!(((reg >> I40E_QTX_ENA_QENA_REQ_SHIFT) & 0x1) ^ 6120 ((reg >> I40E_QTX_ENA_QENA_STAT_SHIFT) 6121 & 0x1))) { 6122 break; 6123 } 6124 } 6125 if (on) { 6126 if (reg & I40E_QTX_ENA_QENA_STAT_MASK) 6127 return I40E_SUCCESS; /* already on, skip next steps */ 6128 6129 I40E_WRITE_REG(hw, I40E_QTX_HEAD(q_idx), 0); 6130 reg |= I40E_QTX_ENA_QENA_REQ_MASK; 6131 } else { 6132 if (!(reg & I40E_QTX_ENA_QENA_STAT_MASK)) 6133 return I40E_SUCCESS; /* already off, skip next steps */ 6134 reg &= ~I40E_QTX_ENA_QENA_REQ_MASK; 6135 } 6136 /* Write the register */ 6137 I40E_WRITE_REG(hw, I40E_QTX_ENA(q_idx), reg); 6138 /* Check the result */ 6139 for (j = 0; j < I40E_CHK_Q_ENA_COUNT; j++) { 6140 rte_delay_us(I40E_CHK_Q_ENA_INTERVAL_US); 6141 reg = I40E_READ_REG(hw, I40E_QTX_ENA(q_idx)); 6142 if (on) { 6143 if ((reg & I40E_QTX_ENA_QENA_REQ_MASK) && 6144 (reg & I40E_QTX_ENA_QENA_STAT_MASK)) 6145 break; 6146 } else { 6147 if (!(reg & I40E_QTX_ENA_QENA_REQ_MASK) && 6148 !(reg & I40E_QTX_ENA_QENA_STAT_MASK)) 6149 break; 6150 } 6151 } 6152 /* Check if it is timeout */ 6153 if (j >= I40E_CHK_Q_ENA_COUNT) { 6154 PMD_DRV_LOG(ERR, "Failed to %s tx queue[%u]", 6155 (on ? "enable" : "disable"), q_idx); 6156 return I40E_ERR_TIMEOUT; 6157 } 6158 6159 return I40E_SUCCESS; 6160 } 6161 6162 /* Swith on or off the tx queues */ 6163 static int 6164 i40e_dev_switch_tx_queues(struct i40e_pf *pf, bool on) 6165 { 6166 struct rte_eth_dev_data *dev_data = pf->dev_data; 6167 struct i40e_tx_queue *txq; 6168 struct rte_eth_dev *dev = pf->adapter->eth_dev; 6169 uint16_t i; 6170 int ret; 6171 6172 for (i = 0; i < dev_data->nb_tx_queues; i++) { 6173 txq = dev_data->tx_queues[i]; 6174 /* Don't operate the queue if not configured or 6175 * if starting only per queue */ 6176 if (!txq || !txq->q_set || (on && txq->tx_deferred_start)) 6177 continue; 6178 if (on) 6179 ret = i40e_dev_tx_queue_start(dev, i); 6180 else 6181 ret = i40e_dev_tx_queue_stop(dev, i); 6182 if ( ret != I40E_SUCCESS) 6183 return ret; 6184 } 6185 6186 return I40E_SUCCESS; 6187 } 6188 6189 int 6190 i40e_switch_rx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on) 6191 { 6192 uint32_t reg; 6193 uint16_t j; 6194 6195 /* Wait until the request is finished */ 6196 for (j = 0; j < I40E_CHK_Q_ENA_COUNT; j++) { 6197 rte_delay_us(I40E_CHK_Q_ENA_INTERVAL_US); 6198 reg = I40E_READ_REG(hw, I40E_QRX_ENA(q_idx)); 6199 if (!((reg >> I40E_QRX_ENA_QENA_REQ_SHIFT) & 0x1) ^ 6200 ((reg >> I40E_QRX_ENA_QENA_STAT_SHIFT) & 0x1)) 6201 break; 6202 } 6203 6204 if (on) { 6205 if (reg & I40E_QRX_ENA_QENA_STAT_MASK) 6206 return I40E_SUCCESS; /* Already on, skip next steps */ 6207 reg |= I40E_QRX_ENA_QENA_REQ_MASK; 6208 } else { 6209 if (!(reg & I40E_QRX_ENA_QENA_STAT_MASK)) 6210 return I40E_SUCCESS; /* Already off, skip next steps */ 6211 reg &= ~I40E_QRX_ENA_QENA_REQ_MASK; 6212 } 6213 6214 /* Write the register */ 6215 I40E_WRITE_REG(hw, I40E_QRX_ENA(q_idx), reg); 6216 /* Check the result */ 6217 for (j = 0; j < I40E_CHK_Q_ENA_COUNT; j++) { 6218 rte_delay_us(I40E_CHK_Q_ENA_INTERVAL_US); 6219 reg = I40E_READ_REG(hw, I40E_QRX_ENA(q_idx)); 6220 if (on) { 6221 if ((reg & I40E_QRX_ENA_QENA_REQ_MASK) && 6222 (reg & I40E_QRX_ENA_QENA_STAT_MASK)) 6223 break; 6224 } else { 6225 if (!(reg & I40E_QRX_ENA_QENA_REQ_MASK) && 6226 !(reg & I40E_QRX_ENA_QENA_STAT_MASK)) 6227 break; 6228 } 6229 } 6230 6231 /* Check if it is timeout */ 6232 if (j >= I40E_CHK_Q_ENA_COUNT) { 6233 PMD_DRV_LOG(ERR, "Failed to %s rx queue[%u]", 6234 (on ? "enable" : "disable"), q_idx); 6235 return I40E_ERR_TIMEOUT; 6236 } 6237 6238 return I40E_SUCCESS; 6239 } 6240 /* Switch on or off the rx queues */ 6241 static int 6242 i40e_dev_switch_rx_queues(struct i40e_pf *pf, bool on) 6243 { 6244 struct rte_eth_dev_data *dev_data = pf->dev_data; 6245 struct i40e_rx_queue *rxq; 6246 struct rte_eth_dev *dev = pf->adapter->eth_dev; 6247 uint16_t i; 6248 int ret; 6249 6250 for (i = 0; i < dev_data->nb_rx_queues; i++) { 6251 rxq = dev_data->rx_queues[i]; 6252 /* Don't operate the queue if not configured or 6253 * if starting only per queue */ 6254 if (!rxq || !rxq->q_set || (on && rxq->rx_deferred_start)) 6255 continue; 6256 if (on) 6257 ret = i40e_dev_rx_queue_start(dev, i); 6258 else 6259 ret = i40e_dev_rx_queue_stop(dev, i); 6260 if (ret != I40E_SUCCESS) 6261 return ret; 6262 } 6263 6264 return I40E_SUCCESS; 6265 } 6266 6267 /* Switch on or off all the rx/tx queues */ 6268 int 6269 i40e_dev_switch_queues(struct i40e_pf *pf, bool on) 6270 { 6271 int ret; 6272 6273 if (on) { 6274 /* enable rx queues before enabling tx queues */ 6275 ret = i40e_dev_switch_rx_queues(pf, on); 6276 if (ret) { 6277 PMD_DRV_LOG(ERR, "Failed to switch rx queues"); 6278 return ret; 6279 } 6280 ret = i40e_dev_switch_tx_queues(pf, on); 6281 } else { 6282 /* Stop tx queues before stopping rx queues */ 6283 ret = i40e_dev_switch_tx_queues(pf, on); 6284 if (ret) { 6285 PMD_DRV_LOG(ERR, "Failed to switch tx queues"); 6286 return ret; 6287 } 6288 ret = i40e_dev_switch_rx_queues(pf, on); 6289 } 6290 6291 return ret; 6292 } 6293 6294 /* Initialize VSI for TX */ 6295 static int 6296 i40e_dev_tx_init(struct i40e_pf *pf) 6297 { 6298 struct rte_eth_dev_data *data = pf->dev_data; 6299 uint16_t i; 6300 uint32_t ret = I40E_SUCCESS; 6301 struct i40e_tx_queue *txq; 6302 6303 for (i = 0; i < data->nb_tx_queues; i++) { 6304 txq = data->tx_queues[i]; 6305 if (!txq || !txq->q_set) 6306 continue; 6307 ret = i40e_tx_queue_init(txq); 6308 if (ret != I40E_SUCCESS) 6309 break; 6310 } 6311 if (ret == I40E_SUCCESS) 6312 i40e_set_tx_function(container_of(pf, struct i40e_adapter, pf) 6313 ->eth_dev); 6314 6315 return ret; 6316 } 6317 6318 /* Initialize VSI for RX */ 6319 static int 6320 i40e_dev_rx_init(struct i40e_pf *pf) 6321 { 6322 struct rte_eth_dev_data *data = pf->dev_data; 6323 int ret = I40E_SUCCESS; 6324 uint16_t i; 6325 struct i40e_rx_queue *rxq; 6326 6327 i40e_pf_config_mq_rx(pf); 6328 for (i = 0; i < data->nb_rx_queues; i++) { 6329 rxq = data->rx_queues[i]; 6330 if (!rxq || !rxq->q_set) 6331 continue; 6332 6333 ret = i40e_rx_queue_init(rxq); 6334 if (ret != I40E_SUCCESS) { 6335 PMD_DRV_LOG(ERR, 6336 "Failed to do RX queue initialization"); 6337 break; 6338 } 6339 } 6340 if (ret == I40E_SUCCESS) 6341 i40e_set_rx_function(container_of(pf, struct i40e_adapter, pf) 6342 ->eth_dev); 6343 6344 return ret; 6345 } 6346 6347 static int 6348 i40e_dev_rxtx_init(struct i40e_pf *pf) 6349 { 6350 int err; 6351 6352 err = i40e_dev_tx_init(pf); 6353 if (err) { 6354 PMD_DRV_LOG(ERR, "Failed to do TX initialization"); 6355 return err; 6356 } 6357 err = i40e_dev_rx_init(pf); 6358 if (err) { 6359 PMD_DRV_LOG(ERR, "Failed to do RX initialization"); 6360 return err; 6361 } 6362 6363 return err; 6364 } 6365 6366 static int 6367 i40e_vmdq_setup(struct rte_eth_dev *dev) 6368 { 6369 struct rte_eth_conf *conf = &dev->data->dev_conf; 6370 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 6371 int i, err, conf_vsis, j, loop; 6372 struct i40e_vsi *vsi; 6373 struct i40e_vmdq_info *vmdq_info; 6374 struct rte_eth_vmdq_rx_conf *vmdq_conf; 6375 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 6376 6377 /* 6378 * Disable interrupt to avoid message from VF. Furthermore, it will 6379 * avoid race condition in VSI creation/destroy. 6380 */ 6381 i40e_pf_disable_irq0(hw); 6382 6383 if ((pf->flags & I40E_FLAG_VMDQ) == 0) { 6384 PMD_INIT_LOG(ERR, "FW doesn't support VMDQ"); 6385 return -ENOTSUP; 6386 } 6387 6388 conf_vsis = conf->rx_adv_conf.vmdq_rx_conf.nb_queue_pools; 6389 if (conf_vsis > pf->max_nb_vmdq_vsi) { 6390 PMD_INIT_LOG(ERR, "VMDQ config: %u, max support:%u", 6391 conf->rx_adv_conf.vmdq_rx_conf.nb_queue_pools, 6392 pf->max_nb_vmdq_vsi); 6393 return -ENOTSUP; 6394 } 6395 6396 if (pf->vmdq != NULL) { 6397 PMD_INIT_LOG(INFO, "VMDQ already configured"); 6398 return 0; 6399 } 6400 6401 pf->vmdq = rte_zmalloc("vmdq_info_struct", 6402 sizeof(*vmdq_info) * conf_vsis, 0); 6403 6404 if (pf->vmdq == NULL) { 6405 PMD_INIT_LOG(ERR, "Failed to allocate memory"); 6406 return -ENOMEM; 6407 } 6408 6409 vmdq_conf = &conf->rx_adv_conf.vmdq_rx_conf; 6410 6411 /* Create VMDQ VSI */ 6412 for (i = 0; i < conf_vsis; i++) { 6413 vsi = i40e_vsi_setup(pf, I40E_VSI_VMDQ2, pf->main_vsi, 6414 vmdq_conf->enable_loop_back); 6415 if (vsi == NULL) { 6416 PMD_INIT_LOG(ERR, "Failed to create VMDQ VSI"); 6417 err = -1; 6418 goto err_vsi_setup; 6419 } 6420 vmdq_info = &pf->vmdq[i]; 6421 vmdq_info->pf = pf; 6422 vmdq_info->vsi = vsi; 6423 } 6424 pf->nb_cfg_vmdq_vsi = conf_vsis; 6425 6426 /* Configure Vlan */ 6427 loop = sizeof(vmdq_conf->pool_map[0].pools) * CHAR_BIT; 6428 for (i = 0; i < vmdq_conf->nb_pool_maps; i++) { 6429 for (j = 0; j < loop && j < pf->nb_cfg_vmdq_vsi; j++) { 6430 if (vmdq_conf->pool_map[i].pools & (1UL << j)) { 6431 PMD_INIT_LOG(INFO, "Add vlan %u to vmdq pool %u", 6432 vmdq_conf->pool_map[i].vlan_id, j); 6433 6434 err = i40e_vsi_add_vlan(pf->vmdq[j].vsi, 6435 vmdq_conf->pool_map[i].vlan_id); 6436 if (err) { 6437 PMD_INIT_LOG(ERR, "Failed to add vlan"); 6438 err = -1; 6439 goto err_vsi_setup; 6440 } 6441 } 6442 } 6443 } 6444 6445 i40e_pf_enable_irq0(hw); 6446 6447 return 0; 6448 6449 err_vsi_setup: 6450 for (i = 0; i < conf_vsis; i++) 6451 if (pf->vmdq[i].vsi == NULL) 6452 break; 6453 else 6454 i40e_vsi_release(pf->vmdq[i].vsi); 6455 6456 rte_free(pf->vmdq); 6457 pf->vmdq = NULL; 6458 i40e_pf_enable_irq0(hw); 6459 return err; 6460 } 6461 6462 static void 6463 i40e_stat_update_32(struct i40e_hw *hw, 6464 uint32_t reg, 6465 bool offset_loaded, 6466 uint64_t *offset, 6467 uint64_t *stat) 6468 { 6469 uint64_t new_data; 6470 6471 new_data = (uint64_t)I40E_READ_REG(hw, reg); 6472 if (!offset_loaded) 6473 *offset = new_data; 6474 6475 if (new_data >= *offset) 6476 *stat = (uint64_t)(new_data - *offset); 6477 else 6478 *stat = (uint64_t)((new_data + 6479 ((uint64_t)1 << I40E_32_BIT_WIDTH)) - *offset); 6480 } 6481 6482 static void 6483 i40e_stat_update_48(struct i40e_hw *hw, 6484 uint32_t hireg, 6485 uint32_t loreg, 6486 bool offset_loaded, 6487 uint64_t *offset, 6488 uint64_t *stat) 6489 { 6490 uint64_t new_data; 6491 6492 new_data = (uint64_t)I40E_READ_REG(hw, loreg); 6493 new_data |= ((uint64_t)(I40E_READ_REG(hw, hireg) & 6494 I40E_16_BIT_MASK)) << I40E_32_BIT_WIDTH; 6495 6496 if (!offset_loaded) 6497 *offset = new_data; 6498 6499 if (new_data >= *offset) 6500 *stat = new_data - *offset; 6501 else 6502 *stat = (uint64_t)((new_data + 6503 ((uint64_t)1 << I40E_48_BIT_WIDTH)) - *offset); 6504 6505 *stat &= I40E_48_BIT_MASK; 6506 } 6507 6508 /* Disable IRQ0 */ 6509 void 6510 i40e_pf_disable_irq0(struct i40e_hw *hw) 6511 { 6512 /* Disable all interrupt types */ 6513 I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 6514 I40E_PFINT_DYN_CTL0_ITR_INDX_MASK); 6515 I40E_WRITE_FLUSH(hw); 6516 } 6517 6518 /* Enable IRQ0 */ 6519 void 6520 i40e_pf_enable_irq0(struct i40e_hw *hw) 6521 { 6522 I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 6523 I40E_PFINT_DYN_CTL0_INTENA_MASK | 6524 I40E_PFINT_DYN_CTL0_CLEARPBA_MASK | 6525 I40E_PFINT_DYN_CTL0_ITR_INDX_MASK); 6526 I40E_WRITE_FLUSH(hw); 6527 } 6528 6529 static void 6530 i40e_pf_config_irq0(struct i40e_hw *hw, bool no_queue) 6531 { 6532 /* read pending request and disable first */ 6533 i40e_pf_disable_irq0(hw); 6534 I40E_WRITE_REG(hw, I40E_PFINT_ICR0_ENA, I40E_PFINT_ICR0_ENA_MASK); 6535 I40E_WRITE_REG(hw, I40E_PFINT_STAT_CTL0, 6536 I40E_PFINT_STAT_CTL0_OTHER_ITR_INDX_MASK); 6537 6538 if (no_queue) 6539 /* Link no queues with irq0 */ 6540 I40E_WRITE_REG(hw, I40E_PFINT_LNKLST0, 6541 I40E_PFINT_LNKLST0_FIRSTQ_INDX_MASK); 6542 } 6543 6544 static void 6545 i40e_dev_handle_vfr_event(struct rte_eth_dev *dev) 6546 { 6547 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 6548 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 6549 int i; 6550 uint16_t abs_vf_id; 6551 uint32_t index, offset, val; 6552 6553 if (!pf->vfs) 6554 return; 6555 /** 6556 * Try to find which VF trigger a reset, use absolute VF id to access 6557 * since the reg is global register. 6558 */ 6559 for (i = 0; i < pf->vf_num; i++) { 6560 abs_vf_id = hw->func_caps.vf_base_id + i; 6561 index = abs_vf_id / I40E_UINT32_BIT_SIZE; 6562 offset = abs_vf_id % I40E_UINT32_BIT_SIZE; 6563 val = I40E_READ_REG(hw, I40E_GLGEN_VFLRSTAT(index)); 6564 /* VFR event occurred */ 6565 if (val & (0x1 << offset)) { 6566 int ret; 6567 6568 /* Clear the event first */ 6569 I40E_WRITE_REG(hw, I40E_GLGEN_VFLRSTAT(index), 6570 (0x1 << offset)); 6571 PMD_DRV_LOG(INFO, "VF %u reset occurred", abs_vf_id); 6572 /** 6573 * Only notify a VF reset event occurred, 6574 * don't trigger another SW reset 6575 */ 6576 ret = i40e_pf_host_vf_reset(&pf->vfs[i], 0); 6577 if (ret != I40E_SUCCESS) 6578 PMD_DRV_LOG(ERR, "Failed to do VF reset"); 6579 } 6580 } 6581 } 6582 6583 static void 6584 i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev) 6585 { 6586 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 6587 int i; 6588 6589 for (i = 0; i < pf->vf_num; i++) 6590 i40e_notify_vf_link_status(dev, &pf->vfs[i]); 6591 } 6592 6593 static void 6594 i40e_dev_handle_aq_msg(struct rte_eth_dev *dev) 6595 { 6596 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 6597 struct i40e_arq_event_info info; 6598 uint16_t pending, opcode; 6599 int ret; 6600 6601 info.buf_len = I40E_AQ_BUF_SZ; 6602 info.msg_buf = rte_zmalloc("msg_buffer", info.buf_len, 0); 6603 if (!info.msg_buf) { 6604 PMD_DRV_LOG(ERR, "Failed to allocate mem"); 6605 return; 6606 } 6607 6608 pending = 1; 6609 while (pending) { 6610 ret = i40e_clean_arq_element(hw, &info, &pending); 6611 6612 if (ret != I40E_SUCCESS) { 6613 PMD_DRV_LOG(INFO, 6614 "Failed to read msg from AdminQ, aq_err: %u", 6615 hw->aq.asq_last_status); 6616 break; 6617 } 6618 opcode = rte_le_to_cpu_16(info.desc.opcode); 6619 6620 switch (opcode) { 6621 case i40e_aqc_opc_send_msg_to_pf: 6622 /* Refer to i40e_aq_send_msg_to_pf() for argument layout*/ 6623 i40e_pf_host_handle_vf_msg(dev, 6624 rte_le_to_cpu_16(info.desc.retval), 6625 rte_le_to_cpu_32(info.desc.cookie_high), 6626 rte_le_to_cpu_32(info.desc.cookie_low), 6627 info.msg_buf, 6628 info.msg_len); 6629 break; 6630 case i40e_aqc_opc_get_link_status: 6631 ret = i40e_dev_link_update(dev, 0); 6632 if (!ret) 6633 _rte_eth_dev_callback_process(dev, 6634 RTE_ETH_EVENT_INTR_LSC, NULL); 6635 break; 6636 default: 6637 PMD_DRV_LOG(DEBUG, "Request %u is not supported yet", 6638 opcode); 6639 break; 6640 } 6641 } 6642 rte_free(info.msg_buf); 6643 } 6644 6645 /** 6646 * Interrupt handler triggered by NIC for handling 6647 * specific interrupt. 6648 * 6649 * @param handle 6650 * Pointer to interrupt handle. 6651 * @param param 6652 * The address of parameter (struct rte_eth_dev *) regsitered before. 6653 * 6654 * @return 6655 * void 6656 */ 6657 static void 6658 i40e_dev_interrupt_handler(void *param) 6659 { 6660 struct rte_eth_dev *dev = (struct rte_eth_dev *)param; 6661 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 6662 uint32_t icr0; 6663 6664 /* Disable interrupt */ 6665 i40e_pf_disable_irq0(hw); 6666 6667 /* read out interrupt causes */ 6668 icr0 = I40E_READ_REG(hw, I40E_PFINT_ICR0); 6669 6670 /* No interrupt event indicated */ 6671 if (!(icr0 & I40E_PFINT_ICR0_INTEVENT_MASK)) { 6672 PMD_DRV_LOG(INFO, "No interrupt event"); 6673 goto done; 6674 } 6675 if (icr0 & I40E_PFINT_ICR0_ECC_ERR_MASK) 6676 PMD_DRV_LOG(ERR, "ICR0: unrecoverable ECC error"); 6677 if (icr0 & I40E_PFINT_ICR0_MAL_DETECT_MASK) 6678 PMD_DRV_LOG(ERR, "ICR0: malicious programming detected"); 6679 if (icr0 & I40E_PFINT_ICR0_GRST_MASK) 6680 PMD_DRV_LOG(INFO, "ICR0: global reset requested"); 6681 if (icr0 & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK) 6682 PMD_DRV_LOG(INFO, "ICR0: PCI exception activated"); 6683 if (icr0 & I40E_PFINT_ICR0_STORM_DETECT_MASK) 6684 PMD_DRV_LOG(INFO, "ICR0: a change in the storm control state"); 6685 if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK) 6686 PMD_DRV_LOG(ERR, "ICR0: HMC error"); 6687 if (icr0 & I40E_PFINT_ICR0_PE_CRITERR_MASK) 6688 PMD_DRV_LOG(ERR, "ICR0: protocol engine critical error"); 6689 6690 if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) { 6691 PMD_DRV_LOG(INFO, "ICR0: VF reset detected"); 6692 i40e_dev_handle_vfr_event(dev); 6693 } 6694 if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) { 6695 PMD_DRV_LOG(INFO, "ICR0: adminq event"); 6696 i40e_dev_handle_aq_msg(dev); 6697 } 6698 6699 done: 6700 /* Enable interrupt */ 6701 i40e_pf_enable_irq0(hw); 6702 } 6703 6704 static void 6705 i40e_dev_alarm_handler(void *param) 6706 { 6707 struct rte_eth_dev *dev = (struct rte_eth_dev *)param; 6708 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 6709 uint32_t icr0; 6710 6711 /* Disable interrupt */ 6712 i40e_pf_disable_irq0(hw); 6713 6714 /* read out interrupt causes */ 6715 icr0 = I40E_READ_REG(hw, I40E_PFINT_ICR0); 6716 6717 /* No interrupt event indicated */ 6718 if (!(icr0 & I40E_PFINT_ICR0_INTEVENT_MASK)) 6719 goto done; 6720 if (icr0 & I40E_PFINT_ICR0_ECC_ERR_MASK) 6721 PMD_DRV_LOG(ERR, "ICR0: unrecoverable ECC error"); 6722 if (icr0 & I40E_PFINT_ICR0_MAL_DETECT_MASK) 6723 PMD_DRV_LOG(ERR, "ICR0: malicious programming detected"); 6724 if (icr0 & I40E_PFINT_ICR0_GRST_MASK) 6725 PMD_DRV_LOG(INFO, "ICR0: global reset requested"); 6726 if (icr0 & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK) 6727 PMD_DRV_LOG(INFO, "ICR0: PCI exception activated"); 6728 if (icr0 & I40E_PFINT_ICR0_STORM_DETECT_MASK) 6729 PMD_DRV_LOG(INFO, "ICR0: a change in the storm control state"); 6730 if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK) 6731 PMD_DRV_LOG(ERR, "ICR0: HMC error"); 6732 if (icr0 & I40E_PFINT_ICR0_PE_CRITERR_MASK) 6733 PMD_DRV_LOG(ERR, "ICR0: protocol engine critical error"); 6734 6735 if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) { 6736 PMD_DRV_LOG(INFO, "ICR0: VF reset detected"); 6737 i40e_dev_handle_vfr_event(dev); 6738 } 6739 if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) { 6740 PMD_DRV_LOG(INFO, "ICR0: adminq event"); 6741 i40e_dev_handle_aq_msg(dev); 6742 } 6743 6744 done: 6745 /* Enable interrupt */ 6746 i40e_pf_enable_irq0(hw); 6747 rte_eal_alarm_set(I40E_ALARM_INTERVAL, 6748 i40e_dev_alarm_handler, dev); 6749 } 6750 6751 int 6752 i40e_add_macvlan_filters(struct i40e_vsi *vsi, 6753 struct i40e_macvlan_filter *filter, 6754 int total) 6755 { 6756 int ele_num, ele_buff_size; 6757 int num, actual_num, i; 6758 uint16_t flags; 6759 int ret = I40E_SUCCESS; 6760 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 6761 struct i40e_aqc_add_macvlan_element_data *req_list; 6762 6763 if (filter == NULL || total == 0) 6764 return I40E_ERR_PARAM; 6765 ele_num = hw->aq.asq_buf_size / sizeof(*req_list); 6766 ele_buff_size = hw->aq.asq_buf_size; 6767 6768 req_list = rte_zmalloc("macvlan_add", ele_buff_size, 0); 6769 if (req_list == NULL) { 6770 PMD_DRV_LOG(ERR, "Fail to allocate memory"); 6771 return I40E_ERR_NO_MEMORY; 6772 } 6773 6774 num = 0; 6775 do { 6776 actual_num = (num + ele_num > total) ? (total - num) : ele_num; 6777 memset(req_list, 0, ele_buff_size); 6778 6779 for (i = 0; i < actual_num; i++) { 6780 rte_memcpy(req_list[i].mac_addr, 6781 &filter[num + i].macaddr, ETH_ADDR_LEN); 6782 req_list[i].vlan_tag = 6783 rte_cpu_to_le_16(filter[num + i].vlan_id); 6784 6785 switch (filter[num + i].filter_type) { 6786 case RTE_MAC_PERFECT_MATCH: 6787 flags = I40E_AQC_MACVLAN_ADD_PERFECT_MATCH | 6788 I40E_AQC_MACVLAN_ADD_IGNORE_VLAN; 6789 break; 6790 case RTE_MACVLAN_PERFECT_MATCH: 6791 flags = I40E_AQC_MACVLAN_ADD_PERFECT_MATCH; 6792 break; 6793 case RTE_MAC_HASH_MATCH: 6794 flags = I40E_AQC_MACVLAN_ADD_HASH_MATCH | 6795 I40E_AQC_MACVLAN_ADD_IGNORE_VLAN; 6796 break; 6797 case RTE_MACVLAN_HASH_MATCH: 6798 flags = I40E_AQC_MACVLAN_ADD_HASH_MATCH; 6799 break; 6800 default: 6801 PMD_DRV_LOG(ERR, "Invalid MAC match type"); 6802 ret = I40E_ERR_PARAM; 6803 goto DONE; 6804 } 6805 6806 req_list[i].queue_number = 0; 6807 6808 req_list[i].flags = rte_cpu_to_le_16(flags); 6809 } 6810 6811 ret = i40e_aq_add_macvlan(hw, vsi->seid, req_list, 6812 actual_num, NULL); 6813 if (ret != I40E_SUCCESS) { 6814 PMD_DRV_LOG(ERR, "Failed to add macvlan filter"); 6815 goto DONE; 6816 } 6817 num += actual_num; 6818 } while (num < total); 6819 6820 DONE: 6821 rte_free(req_list); 6822 return ret; 6823 } 6824 6825 int 6826 i40e_remove_macvlan_filters(struct i40e_vsi *vsi, 6827 struct i40e_macvlan_filter *filter, 6828 int total) 6829 { 6830 int ele_num, ele_buff_size; 6831 int num, actual_num, i; 6832 uint16_t flags; 6833 int ret = I40E_SUCCESS; 6834 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 6835 struct i40e_aqc_remove_macvlan_element_data *req_list; 6836 6837 if (filter == NULL || total == 0) 6838 return I40E_ERR_PARAM; 6839 6840 ele_num = hw->aq.asq_buf_size / sizeof(*req_list); 6841 ele_buff_size = hw->aq.asq_buf_size; 6842 6843 req_list = rte_zmalloc("macvlan_remove", ele_buff_size, 0); 6844 if (req_list == NULL) { 6845 PMD_DRV_LOG(ERR, "Fail to allocate memory"); 6846 return I40E_ERR_NO_MEMORY; 6847 } 6848 6849 num = 0; 6850 do { 6851 actual_num = (num + ele_num > total) ? (total - num) : ele_num; 6852 memset(req_list, 0, ele_buff_size); 6853 6854 for (i = 0; i < actual_num; i++) { 6855 rte_memcpy(req_list[i].mac_addr, 6856 &filter[num + i].macaddr, ETH_ADDR_LEN); 6857 req_list[i].vlan_tag = 6858 rte_cpu_to_le_16(filter[num + i].vlan_id); 6859 6860 switch (filter[num + i].filter_type) { 6861 case RTE_MAC_PERFECT_MATCH: 6862 flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH | 6863 I40E_AQC_MACVLAN_DEL_IGNORE_VLAN; 6864 break; 6865 case RTE_MACVLAN_PERFECT_MATCH: 6866 flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH; 6867 break; 6868 case RTE_MAC_HASH_MATCH: 6869 flags = I40E_AQC_MACVLAN_DEL_HASH_MATCH | 6870 I40E_AQC_MACVLAN_DEL_IGNORE_VLAN; 6871 break; 6872 case RTE_MACVLAN_HASH_MATCH: 6873 flags = I40E_AQC_MACVLAN_DEL_HASH_MATCH; 6874 break; 6875 default: 6876 PMD_DRV_LOG(ERR, "Invalid MAC filter type"); 6877 ret = I40E_ERR_PARAM; 6878 goto DONE; 6879 } 6880 req_list[i].flags = rte_cpu_to_le_16(flags); 6881 } 6882 6883 ret = i40e_aq_remove_macvlan(hw, vsi->seid, req_list, 6884 actual_num, NULL); 6885 if (ret != I40E_SUCCESS) { 6886 PMD_DRV_LOG(ERR, "Failed to remove macvlan filter"); 6887 goto DONE; 6888 } 6889 num += actual_num; 6890 } while (num < total); 6891 6892 DONE: 6893 rte_free(req_list); 6894 return ret; 6895 } 6896 6897 /* Find out specific MAC filter */ 6898 static struct i40e_mac_filter * 6899 i40e_find_mac_filter(struct i40e_vsi *vsi, 6900 struct ether_addr *macaddr) 6901 { 6902 struct i40e_mac_filter *f; 6903 6904 TAILQ_FOREACH(f, &vsi->mac_list, next) { 6905 if (is_same_ether_addr(macaddr, &f->mac_info.mac_addr)) 6906 return f; 6907 } 6908 6909 return NULL; 6910 } 6911 6912 static bool 6913 i40e_find_vlan_filter(struct i40e_vsi *vsi, 6914 uint16_t vlan_id) 6915 { 6916 uint32_t vid_idx, vid_bit; 6917 6918 if (vlan_id > ETH_VLAN_ID_MAX) 6919 return 0; 6920 6921 vid_idx = I40E_VFTA_IDX(vlan_id); 6922 vid_bit = I40E_VFTA_BIT(vlan_id); 6923 6924 if (vsi->vfta[vid_idx] & vid_bit) 6925 return 1; 6926 else 6927 return 0; 6928 } 6929 6930 static void 6931 i40e_store_vlan_filter(struct i40e_vsi *vsi, 6932 uint16_t vlan_id, bool on) 6933 { 6934 uint32_t vid_idx, vid_bit; 6935 6936 vid_idx = I40E_VFTA_IDX(vlan_id); 6937 vid_bit = I40E_VFTA_BIT(vlan_id); 6938 6939 if (on) 6940 vsi->vfta[vid_idx] |= vid_bit; 6941 else 6942 vsi->vfta[vid_idx] &= ~vid_bit; 6943 } 6944 6945 void 6946 i40e_set_vlan_filter(struct i40e_vsi *vsi, 6947 uint16_t vlan_id, bool on) 6948 { 6949 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 6950 struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0}; 6951 int ret; 6952 6953 if (vlan_id > ETH_VLAN_ID_MAX) 6954 return; 6955 6956 i40e_store_vlan_filter(vsi, vlan_id, on); 6957 6958 if ((!vsi->vlan_anti_spoof_on && !vsi->vlan_filter_on) || !vlan_id) 6959 return; 6960 6961 vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id); 6962 6963 if (on) { 6964 ret = i40e_aq_add_vlan(hw, vsi->seid, 6965 &vlan_data, 1, NULL); 6966 if (ret != I40E_SUCCESS) 6967 PMD_DRV_LOG(ERR, "Failed to add vlan filter"); 6968 } else { 6969 ret = i40e_aq_remove_vlan(hw, vsi->seid, 6970 &vlan_data, 1, NULL); 6971 if (ret != I40E_SUCCESS) 6972 PMD_DRV_LOG(ERR, 6973 "Failed to remove vlan filter"); 6974 } 6975 } 6976 6977 /** 6978 * Find all vlan options for specific mac addr, 6979 * return with actual vlan found. 6980 */ 6981 int 6982 i40e_find_all_vlan_for_mac(struct i40e_vsi *vsi, 6983 struct i40e_macvlan_filter *mv_f, 6984 int num, struct ether_addr *addr) 6985 { 6986 int i; 6987 uint32_t j, k; 6988 6989 /** 6990 * Not to use i40e_find_vlan_filter to decrease the loop time, 6991 * although the code looks complex. 6992 */ 6993 if (num < vsi->vlan_num) 6994 return I40E_ERR_PARAM; 6995 6996 i = 0; 6997 for (j = 0; j < I40E_VFTA_SIZE; j++) { 6998 if (vsi->vfta[j]) { 6999 for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) { 7000 if (vsi->vfta[j] & (1 << k)) { 7001 if (i > num - 1) { 7002 PMD_DRV_LOG(ERR, 7003 "vlan number doesn't match"); 7004 return I40E_ERR_PARAM; 7005 } 7006 rte_memcpy(&mv_f[i].macaddr, 7007 addr, ETH_ADDR_LEN); 7008 mv_f[i].vlan_id = 7009 j * I40E_UINT32_BIT_SIZE + k; 7010 i++; 7011 } 7012 } 7013 } 7014 } 7015 return I40E_SUCCESS; 7016 } 7017 7018 static inline int 7019 i40e_find_all_mac_for_vlan(struct i40e_vsi *vsi, 7020 struct i40e_macvlan_filter *mv_f, 7021 int num, 7022 uint16_t vlan) 7023 { 7024 int i = 0; 7025 struct i40e_mac_filter *f; 7026 7027 if (num < vsi->mac_num) 7028 return I40E_ERR_PARAM; 7029 7030 TAILQ_FOREACH(f, &vsi->mac_list, next) { 7031 if (i > num - 1) { 7032 PMD_DRV_LOG(ERR, "buffer number not match"); 7033 return I40E_ERR_PARAM; 7034 } 7035 rte_memcpy(&mv_f[i].macaddr, &f->mac_info.mac_addr, 7036 ETH_ADDR_LEN); 7037 mv_f[i].vlan_id = vlan; 7038 mv_f[i].filter_type = f->mac_info.filter_type; 7039 i++; 7040 } 7041 7042 return I40E_SUCCESS; 7043 } 7044 7045 static int 7046 i40e_vsi_remove_all_macvlan_filter(struct i40e_vsi *vsi) 7047 { 7048 int i, j, num; 7049 struct i40e_mac_filter *f; 7050 struct i40e_macvlan_filter *mv_f; 7051 int ret = I40E_SUCCESS; 7052 7053 if (vsi == NULL || vsi->mac_num == 0) 7054 return I40E_ERR_PARAM; 7055 7056 /* Case that no vlan is set */ 7057 if (vsi->vlan_num == 0) 7058 num = vsi->mac_num; 7059 else 7060 num = vsi->mac_num * vsi->vlan_num; 7061 7062 mv_f = rte_zmalloc("macvlan_data", num * sizeof(*mv_f), 0); 7063 if (mv_f == NULL) { 7064 PMD_DRV_LOG(ERR, "failed to allocate memory"); 7065 return I40E_ERR_NO_MEMORY; 7066 } 7067 7068 i = 0; 7069 if (vsi->vlan_num == 0) { 7070 TAILQ_FOREACH(f, &vsi->mac_list, next) { 7071 rte_memcpy(&mv_f[i].macaddr, 7072 &f->mac_info.mac_addr, ETH_ADDR_LEN); 7073 mv_f[i].filter_type = f->mac_info.filter_type; 7074 mv_f[i].vlan_id = 0; 7075 i++; 7076 } 7077 } else { 7078 TAILQ_FOREACH(f, &vsi->mac_list, next) { 7079 ret = i40e_find_all_vlan_for_mac(vsi,&mv_f[i], 7080 vsi->vlan_num, &f->mac_info.mac_addr); 7081 if (ret != I40E_SUCCESS) 7082 goto DONE; 7083 for (j = i; j < i + vsi->vlan_num; j++) 7084 mv_f[j].filter_type = f->mac_info.filter_type; 7085 i += vsi->vlan_num; 7086 } 7087 } 7088 7089 ret = i40e_remove_macvlan_filters(vsi, mv_f, num); 7090 DONE: 7091 rte_free(mv_f); 7092 7093 return ret; 7094 } 7095 7096 int 7097 i40e_vsi_add_vlan(struct i40e_vsi *vsi, uint16_t vlan) 7098 { 7099 struct i40e_macvlan_filter *mv_f; 7100 int mac_num; 7101 int ret = I40E_SUCCESS; 7102 7103 if (!vsi || vlan > ETHER_MAX_VLAN_ID) 7104 return I40E_ERR_PARAM; 7105 7106 /* If it's already set, just return */ 7107 if (i40e_find_vlan_filter(vsi,vlan)) 7108 return I40E_SUCCESS; 7109 7110 mac_num = vsi->mac_num; 7111 7112 if (mac_num == 0) { 7113 PMD_DRV_LOG(ERR, "Error! VSI doesn't have a mac addr"); 7114 return I40E_ERR_PARAM; 7115 } 7116 7117 mv_f = rte_zmalloc("macvlan_data", mac_num * sizeof(*mv_f), 0); 7118 7119 if (mv_f == NULL) { 7120 PMD_DRV_LOG(ERR, "failed to allocate memory"); 7121 return I40E_ERR_NO_MEMORY; 7122 } 7123 7124 ret = i40e_find_all_mac_for_vlan(vsi, mv_f, mac_num, vlan); 7125 7126 if (ret != I40E_SUCCESS) 7127 goto DONE; 7128 7129 ret = i40e_add_macvlan_filters(vsi, mv_f, mac_num); 7130 7131 if (ret != I40E_SUCCESS) 7132 goto DONE; 7133 7134 i40e_set_vlan_filter(vsi, vlan, 1); 7135 7136 vsi->vlan_num++; 7137 ret = I40E_SUCCESS; 7138 DONE: 7139 rte_free(mv_f); 7140 return ret; 7141 } 7142 7143 int 7144 i40e_vsi_delete_vlan(struct i40e_vsi *vsi, uint16_t vlan) 7145 { 7146 struct i40e_macvlan_filter *mv_f; 7147 int mac_num; 7148 int ret = I40E_SUCCESS; 7149 7150 /** 7151 * Vlan 0 is the generic filter for untagged packets 7152 * and can't be removed. 7153 */ 7154 if (!vsi || vlan == 0 || vlan > ETHER_MAX_VLAN_ID) 7155 return I40E_ERR_PARAM; 7156 7157 /* If can't find it, just return */ 7158 if (!i40e_find_vlan_filter(vsi, vlan)) 7159 return I40E_ERR_PARAM; 7160 7161 mac_num = vsi->mac_num; 7162 7163 if (mac_num == 0) { 7164 PMD_DRV_LOG(ERR, "Error! VSI doesn't have a mac addr"); 7165 return I40E_ERR_PARAM; 7166 } 7167 7168 mv_f = rte_zmalloc("macvlan_data", mac_num * sizeof(*mv_f), 0); 7169 7170 if (mv_f == NULL) { 7171 PMD_DRV_LOG(ERR, "failed to allocate memory"); 7172 return I40E_ERR_NO_MEMORY; 7173 } 7174 7175 ret = i40e_find_all_mac_for_vlan(vsi, mv_f, mac_num, vlan); 7176 7177 if (ret != I40E_SUCCESS) 7178 goto DONE; 7179 7180 ret = i40e_remove_macvlan_filters(vsi, mv_f, mac_num); 7181 7182 if (ret != I40E_SUCCESS) 7183 goto DONE; 7184 7185 /* This is last vlan to remove, replace all mac filter with vlan 0 */ 7186 if (vsi->vlan_num == 1) { 7187 ret = i40e_find_all_mac_for_vlan(vsi, mv_f, mac_num, 0); 7188 if (ret != I40E_SUCCESS) 7189 goto DONE; 7190 7191 ret = i40e_add_macvlan_filters(vsi, mv_f, mac_num); 7192 if (ret != I40E_SUCCESS) 7193 goto DONE; 7194 } 7195 7196 i40e_set_vlan_filter(vsi, vlan, 0); 7197 7198 vsi->vlan_num--; 7199 ret = I40E_SUCCESS; 7200 DONE: 7201 rte_free(mv_f); 7202 return ret; 7203 } 7204 7205 int 7206 i40e_vsi_add_mac(struct i40e_vsi *vsi, struct i40e_mac_filter_info *mac_filter) 7207 { 7208 struct i40e_mac_filter *f; 7209 struct i40e_macvlan_filter *mv_f; 7210 int i, vlan_num = 0; 7211 int ret = I40E_SUCCESS; 7212 7213 /* If it's add and we've config it, return */ 7214 f = i40e_find_mac_filter(vsi, &mac_filter->mac_addr); 7215 if (f != NULL) 7216 return I40E_SUCCESS; 7217 if ((mac_filter->filter_type == RTE_MACVLAN_PERFECT_MATCH) || 7218 (mac_filter->filter_type == RTE_MACVLAN_HASH_MATCH)) { 7219 7220 /** 7221 * If vlan_num is 0, that's the first time to add mac, 7222 * set mask for vlan_id 0. 7223 */ 7224 if (vsi->vlan_num == 0) { 7225 i40e_set_vlan_filter(vsi, 0, 1); 7226 vsi->vlan_num = 1; 7227 } 7228 vlan_num = vsi->vlan_num; 7229 } else if ((mac_filter->filter_type == RTE_MAC_PERFECT_MATCH) || 7230 (mac_filter->filter_type == RTE_MAC_HASH_MATCH)) 7231 vlan_num = 1; 7232 7233 mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0); 7234 if (mv_f == NULL) { 7235 PMD_DRV_LOG(ERR, "failed to allocate memory"); 7236 return I40E_ERR_NO_MEMORY; 7237 } 7238 7239 for (i = 0; i < vlan_num; i++) { 7240 mv_f[i].filter_type = mac_filter->filter_type; 7241 rte_memcpy(&mv_f[i].macaddr, &mac_filter->mac_addr, 7242 ETH_ADDR_LEN); 7243 } 7244 7245 if (mac_filter->filter_type == RTE_MACVLAN_PERFECT_MATCH || 7246 mac_filter->filter_type == RTE_MACVLAN_HASH_MATCH) { 7247 ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num, 7248 &mac_filter->mac_addr); 7249 if (ret != I40E_SUCCESS) 7250 goto DONE; 7251 } 7252 7253 ret = i40e_add_macvlan_filters(vsi, mv_f, vlan_num); 7254 if (ret != I40E_SUCCESS) 7255 goto DONE; 7256 7257 /* Add the mac addr into mac list */ 7258 f = rte_zmalloc("macv_filter", sizeof(*f), 0); 7259 if (f == NULL) { 7260 PMD_DRV_LOG(ERR, "failed to allocate memory"); 7261 ret = I40E_ERR_NO_MEMORY; 7262 goto DONE; 7263 } 7264 rte_memcpy(&f->mac_info.mac_addr, &mac_filter->mac_addr, 7265 ETH_ADDR_LEN); 7266 f->mac_info.filter_type = mac_filter->filter_type; 7267 TAILQ_INSERT_TAIL(&vsi->mac_list, f, next); 7268 vsi->mac_num++; 7269 7270 ret = I40E_SUCCESS; 7271 DONE: 7272 rte_free(mv_f); 7273 7274 return ret; 7275 } 7276 7277 int 7278 i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr) 7279 { 7280 struct i40e_mac_filter *f; 7281 struct i40e_macvlan_filter *mv_f; 7282 int i, vlan_num; 7283 enum rte_mac_filter_type filter_type; 7284 int ret = I40E_SUCCESS; 7285 7286 /* Can't find it, return an error */ 7287 f = i40e_find_mac_filter(vsi, addr); 7288 if (f == NULL) 7289 return I40E_ERR_PARAM; 7290 7291 vlan_num = vsi->vlan_num; 7292 filter_type = f->mac_info.filter_type; 7293 if (filter_type == RTE_MACVLAN_PERFECT_MATCH || 7294 filter_type == RTE_MACVLAN_HASH_MATCH) { 7295 if (vlan_num == 0) { 7296 PMD_DRV_LOG(ERR, "VLAN number shouldn't be 0"); 7297 return I40E_ERR_PARAM; 7298 } 7299 } else if (filter_type == RTE_MAC_PERFECT_MATCH || 7300 filter_type == RTE_MAC_HASH_MATCH) 7301 vlan_num = 1; 7302 7303 mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0); 7304 if (mv_f == NULL) { 7305 PMD_DRV_LOG(ERR, "failed to allocate memory"); 7306 return I40E_ERR_NO_MEMORY; 7307 } 7308 7309 for (i = 0; i < vlan_num; i++) { 7310 mv_f[i].filter_type = filter_type; 7311 rte_memcpy(&mv_f[i].macaddr, &f->mac_info.mac_addr, 7312 ETH_ADDR_LEN); 7313 } 7314 if (filter_type == RTE_MACVLAN_PERFECT_MATCH || 7315 filter_type == RTE_MACVLAN_HASH_MATCH) { 7316 ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num, addr); 7317 if (ret != I40E_SUCCESS) 7318 goto DONE; 7319 } 7320 7321 ret = i40e_remove_macvlan_filters(vsi, mv_f, vlan_num); 7322 if (ret != I40E_SUCCESS) 7323 goto DONE; 7324 7325 /* Remove the mac addr into mac list */ 7326 TAILQ_REMOVE(&vsi->mac_list, f, next); 7327 rte_free(f); 7328 vsi->mac_num--; 7329 7330 ret = I40E_SUCCESS; 7331 DONE: 7332 rte_free(mv_f); 7333 return ret; 7334 } 7335 7336 /* Configure hash enable flags for RSS */ 7337 uint64_t 7338 i40e_config_hena(const struct i40e_adapter *adapter, uint64_t flags) 7339 { 7340 uint64_t hena = 0; 7341 int i; 7342 7343 if (!flags) 7344 return hena; 7345 7346 for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < I40E_FLOW_TYPE_MAX; i++) { 7347 if (flags & (1ULL << i)) 7348 hena |= adapter->pctypes_tbl[i]; 7349 } 7350 7351 return hena; 7352 } 7353 7354 /* Parse the hash enable flags */ 7355 uint64_t 7356 i40e_parse_hena(const struct i40e_adapter *adapter, uint64_t flags) 7357 { 7358 uint64_t rss_hf = 0; 7359 7360 if (!flags) 7361 return rss_hf; 7362 int i; 7363 7364 for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < I40E_FLOW_TYPE_MAX; i++) { 7365 if (flags & adapter->pctypes_tbl[i]) 7366 rss_hf |= (1ULL << i); 7367 } 7368 return rss_hf; 7369 } 7370 7371 /* Disable RSS */ 7372 static void 7373 i40e_pf_disable_rss(struct i40e_pf *pf) 7374 { 7375 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 7376 7377 i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0); 7378 i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0); 7379 I40E_WRITE_FLUSH(hw); 7380 } 7381 7382 int 7383 i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len) 7384 { 7385 struct i40e_pf *pf = I40E_VSI_TO_PF(vsi); 7386 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 7387 uint16_t key_idx = (vsi->type == I40E_VSI_SRIOV) ? 7388 I40E_VFQF_HKEY_MAX_INDEX : 7389 I40E_PFQF_HKEY_MAX_INDEX; 7390 int ret = 0; 7391 7392 if (!key || key_len == 0) { 7393 PMD_DRV_LOG(DEBUG, "No key to be configured"); 7394 return 0; 7395 } else if (key_len != (key_idx + 1) * 7396 sizeof(uint32_t)) { 7397 PMD_DRV_LOG(ERR, "Invalid key length %u", key_len); 7398 return -EINVAL; 7399 } 7400 7401 if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) { 7402 struct i40e_aqc_get_set_rss_key_data *key_dw = 7403 (struct i40e_aqc_get_set_rss_key_data *)key; 7404 7405 ret = i40e_aq_set_rss_key(hw, vsi->vsi_id, key_dw); 7406 if (ret) 7407 PMD_INIT_LOG(ERR, "Failed to configure RSS key via AQ"); 7408 } else { 7409 uint32_t *hash_key = (uint32_t *)key; 7410 uint16_t i; 7411 7412 if (vsi->type == I40E_VSI_SRIOV) { 7413 for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) 7414 I40E_WRITE_REG( 7415 hw, 7416 I40E_VFQF_HKEY1(i, vsi->user_param), 7417 hash_key[i]); 7418 7419 } else { 7420 for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) 7421 I40E_WRITE_REG(hw, I40E_PFQF_HKEY(i), 7422 hash_key[i]); 7423 } 7424 I40E_WRITE_FLUSH(hw); 7425 } 7426 7427 return ret; 7428 } 7429 7430 static int 7431 i40e_get_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t *key_len) 7432 { 7433 struct i40e_pf *pf = I40E_VSI_TO_PF(vsi); 7434 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 7435 uint32_t reg; 7436 int ret; 7437 7438 if (!key || !key_len) 7439 return 0; 7440 7441 if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) { 7442 ret = i40e_aq_get_rss_key(hw, vsi->vsi_id, 7443 (struct i40e_aqc_get_set_rss_key_data *)key); 7444 if (ret) { 7445 PMD_INIT_LOG(ERR, "Failed to get RSS key via AQ"); 7446 return ret; 7447 } 7448 } else { 7449 uint32_t *key_dw = (uint32_t *)key; 7450 uint16_t i; 7451 7452 if (vsi->type == I40E_VSI_SRIOV) { 7453 for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) { 7454 reg = I40E_VFQF_HKEY1(i, vsi->user_param); 7455 key_dw[i] = i40e_read_rx_ctl(hw, reg); 7456 } 7457 *key_len = (I40E_VFQF_HKEY_MAX_INDEX + 1) * 7458 sizeof(uint32_t); 7459 } else { 7460 for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) { 7461 reg = I40E_PFQF_HKEY(i); 7462 key_dw[i] = i40e_read_rx_ctl(hw, reg); 7463 } 7464 *key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) * 7465 sizeof(uint32_t); 7466 } 7467 } 7468 return 0; 7469 } 7470 7471 static int 7472 i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf) 7473 { 7474 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 7475 uint64_t hena; 7476 int ret; 7477 7478 ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key, 7479 rss_conf->rss_key_len); 7480 if (ret) 7481 return ret; 7482 7483 hena = i40e_config_hena(pf->adapter, rss_conf->rss_hf); 7484 i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena); 7485 i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32)); 7486 I40E_WRITE_FLUSH(hw); 7487 7488 return 0; 7489 } 7490 7491 static int 7492 i40e_dev_rss_hash_update(struct rte_eth_dev *dev, 7493 struct rte_eth_rss_conf *rss_conf) 7494 { 7495 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 7496 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 7497 uint64_t rss_hf = rss_conf->rss_hf & pf->adapter->flow_types_mask; 7498 uint64_t hena; 7499 7500 hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)); 7501 hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32; 7502 7503 if (!(hena & pf->adapter->pctypes_mask)) { /* RSS disabled */ 7504 if (rss_hf != 0) /* Enable RSS */ 7505 return -EINVAL; 7506 return 0; /* Nothing to do */ 7507 } 7508 /* RSS enabled */ 7509 if (rss_hf == 0) /* Disable RSS */ 7510 return -EINVAL; 7511 7512 return i40e_hw_rss_hash_set(pf, rss_conf); 7513 } 7514 7515 static int 7516 i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 7517 struct rte_eth_rss_conf *rss_conf) 7518 { 7519 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 7520 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 7521 uint64_t hena; 7522 int ret; 7523 7524 if (!rss_conf) 7525 return -EINVAL; 7526 7527 ret = i40e_get_rss_key(pf->main_vsi, rss_conf->rss_key, 7528 &rss_conf->rss_key_len); 7529 if (ret) 7530 return ret; 7531 7532 hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)); 7533 hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32; 7534 rss_conf->rss_hf = i40e_parse_hena(pf->adapter, hena); 7535 7536 return 0; 7537 } 7538 7539 static int 7540 i40e_dev_get_filter_type(uint16_t filter_type, uint16_t *flag) 7541 { 7542 switch (filter_type) { 7543 case RTE_TUNNEL_FILTER_IMAC_IVLAN: 7544 *flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN; 7545 break; 7546 case RTE_TUNNEL_FILTER_IMAC_IVLAN_TENID: 7547 *flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID; 7548 break; 7549 case RTE_TUNNEL_FILTER_IMAC_TENID: 7550 *flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID; 7551 break; 7552 case RTE_TUNNEL_FILTER_OMAC_TENID_IMAC: 7553 *flag = I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC; 7554 break; 7555 case ETH_TUNNEL_FILTER_IMAC: 7556 *flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC; 7557 break; 7558 case ETH_TUNNEL_FILTER_OIP: 7559 *flag = I40E_AQC_ADD_CLOUD_FILTER_OIP; 7560 break; 7561 case ETH_TUNNEL_FILTER_IIP: 7562 *flag = I40E_AQC_ADD_CLOUD_FILTER_IIP; 7563 break; 7564 default: 7565 PMD_DRV_LOG(ERR, "invalid tunnel filter type"); 7566 return -EINVAL; 7567 } 7568 7569 return 0; 7570 } 7571 7572 /* Convert tunnel filter structure */ 7573 static int 7574 i40e_tunnel_filter_convert( 7575 struct i40e_aqc_cloud_filters_element_bb *cld_filter, 7576 struct i40e_tunnel_filter *tunnel_filter) 7577 { 7578 ether_addr_copy((struct ether_addr *)&cld_filter->element.outer_mac, 7579 (struct ether_addr *)&tunnel_filter->input.outer_mac); 7580 ether_addr_copy((struct ether_addr *)&cld_filter->element.inner_mac, 7581 (struct ether_addr *)&tunnel_filter->input.inner_mac); 7582 tunnel_filter->input.inner_vlan = cld_filter->element.inner_vlan; 7583 if ((rte_le_to_cpu_16(cld_filter->element.flags) & 7584 I40E_AQC_ADD_CLOUD_FLAGS_IPV6) == 7585 I40E_AQC_ADD_CLOUD_FLAGS_IPV6) 7586 tunnel_filter->input.ip_type = I40E_TUNNEL_IPTYPE_IPV6; 7587 else 7588 tunnel_filter->input.ip_type = I40E_TUNNEL_IPTYPE_IPV4; 7589 tunnel_filter->input.flags = cld_filter->element.flags; 7590 tunnel_filter->input.tenant_id = cld_filter->element.tenant_id; 7591 tunnel_filter->queue = cld_filter->element.queue_number; 7592 rte_memcpy(tunnel_filter->input.general_fields, 7593 cld_filter->general_fields, 7594 sizeof(cld_filter->general_fields)); 7595 7596 return 0; 7597 } 7598 7599 /* Check if there exists the tunnel filter */ 7600 struct i40e_tunnel_filter * 7601 i40e_sw_tunnel_filter_lookup(struct i40e_tunnel_rule *tunnel_rule, 7602 const struct i40e_tunnel_filter_input *input) 7603 { 7604 int ret; 7605 7606 ret = rte_hash_lookup(tunnel_rule->hash_table, (const void *)input); 7607 if (ret < 0) 7608 return NULL; 7609 7610 return tunnel_rule->hash_map[ret]; 7611 } 7612 7613 /* Add a tunnel filter into the SW list */ 7614 static int 7615 i40e_sw_tunnel_filter_insert(struct i40e_pf *pf, 7616 struct i40e_tunnel_filter *tunnel_filter) 7617 { 7618 struct i40e_tunnel_rule *rule = &pf->tunnel; 7619 int ret; 7620 7621 ret = rte_hash_add_key(rule->hash_table, &tunnel_filter->input); 7622 if (ret < 0) { 7623 PMD_DRV_LOG(ERR, 7624 "Failed to insert tunnel filter to hash table %d!", 7625 ret); 7626 return ret; 7627 } 7628 rule->hash_map[ret] = tunnel_filter; 7629 7630 TAILQ_INSERT_TAIL(&rule->tunnel_list, tunnel_filter, rules); 7631 7632 return 0; 7633 } 7634 7635 /* Delete a tunnel filter from the SW list */ 7636 int 7637 i40e_sw_tunnel_filter_del(struct i40e_pf *pf, 7638 struct i40e_tunnel_filter_input *input) 7639 { 7640 struct i40e_tunnel_rule *rule = &pf->tunnel; 7641 struct i40e_tunnel_filter *tunnel_filter; 7642 int ret; 7643 7644 ret = rte_hash_del_key(rule->hash_table, input); 7645 if (ret < 0) { 7646 PMD_DRV_LOG(ERR, 7647 "Failed to delete tunnel filter to hash table %d!", 7648 ret); 7649 return ret; 7650 } 7651 tunnel_filter = rule->hash_map[ret]; 7652 rule->hash_map[ret] = NULL; 7653 7654 TAILQ_REMOVE(&rule->tunnel_list, tunnel_filter, rules); 7655 rte_free(tunnel_filter); 7656 7657 return 0; 7658 } 7659 7660 int 7661 i40e_dev_tunnel_filter_set(struct i40e_pf *pf, 7662 struct rte_eth_tunnel_filter_conf *tunnel_filter, 7663 uint8_t add) 7664 { 7665 uint16_t ip_type; 7666 uint32_t ipv4_addr, ipv4_addr_le; 7667 uint8_t i, tun_type = 0; 7668 /* internal varialbe to convert ipv6 byte order */ 7669 uint32_t convert_ipv6[4]; 7670 int val, ret = 0; 7671 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 7672 struct i40e_vsi *vsi = pf->main_vsi; 7673 struct i40e_aqc_cloud_filters_element_bb *cld_filter; 7674 struct i40e_aqc_cloud_filters_element_bb *pfilter; 7675 struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel; 7676 struct i40e_tunnel_filter *tunnel, *node; 7677 struct i40e_tunnel_filter check_filter; /* Check if filter exists */ 7678 7679 cld_filter = rte_zmalloc("tunnel_filter", 7680 sizeof(struct i40e_aqc_add_rm_cloud_filt_elem_ext), 7681 0); 7682 7683 if (NULL == cld_filter) { 7684 PMD_DRV_LOG(ERR, "Failed to alloc memory."); 7685 return -ENOMEM; 7686 } 7687 pfilter = cld_filter; 7688 7689 ether_addr_copy(&tunnel_filter->outer_mac, 7690 (struct ether_addr *)&pfilter->element.outer_mac); 7691 ether_addr_copy(&tunnel_filter->inner_mac, 7692 (struct ether_addr *)&pfilter->element.inner_mac); 7693 7694 pfilter->element.inner_vlan = 7695 rte_cpu_to_le_16(tunnel_filter->inner_vlan); 7696 if (tunnel_filter->ip_type == RTE_TUNNEL_IPTYPE_IPV4) { 7697 ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV4; 7698 ipv4_addr = rte_be_to_cpu_32(tunnel_filter->ip_addr.ipv4_addr); 7699 ipv4_addr_le = rte_cpu_to_le_32(ipv4_addr); 7700 rte_memcpy(&pfilter->element.ipaddr.v4.data, 7701 &ipv4_addr_le, 7702 sizeof(pfilter->element.ipaddr.v4.data)); 7703 } else { 7704 ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV6; 7705 for (i = 0; i < 4; i++) { 7706 convert_ipv6[i] = 7707 rte_cpu_to_le_32(rte_be_to_cpu_32(tunnel_filter->ip_addr.ipv6_addr[i])); 7708 } 7709 rte_memcpy(&pfilter->element.ipaddr.v6.data, 7710 &convert_ipv6, 7711 sizeof(pfilter->element.ipaddr.v6.data)); 7712 } 7713 7714 /* check tunneled type */ 7715 switch (tunnel_filter->tunnel_type) { 7716 case RTE_TUNNEL_TYPE_VXLAN: 7717 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN; 7718 break; 7719 case RTE_TUNNEL_TYPE_NVGRE: 7720 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC; 7721 break; 7722 case RTE_TUNNEL_TYPE_IP_IN_GRE: 7723 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_IP; 7724 break; 7725 default: 7726 /* Other tunnel types is not supported. */ 7727 PMD_DRV_LOG(ERR, "tunnel type is not supported."); 7728 rte_free(cld_filter); 7729 return -EINVAL; 7730 } 7731 7732 val = i40e_dev_get_filter_type(tunnel_filter->filter_type, 7733 &pfilter->element.flags); 7734 if (val < 0) { 7735 rte_free(cld_filter); 7736 return -EINVAL; 7737 } 7738 7739 pfilter->element.flags |= rte_cpu_to_le_16( 7740 I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE | 7741 ip_type | (tun_type << I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT)); 7742 pfilter->element.tenant_id = rte_cpu_to_le_32(tunnel_filter->tenant_id); 7743 pfilter->element.queue_number = 7744 rte_cpu_to_le_16(tunnel_filter->queue_id); 7745 7746 /* Check if there is the filter in SW list */ 7747 memset(&check_filter, 0, sizeof(check_filter)); 7748 i40e_tunnel_filter_convert(cld_filter, &check_filter); 7749 node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &check_filter.input); 7750 if (add && node) { 7751 PMD_DRV_LOG(ERR, "Conflict with existing tunnel rules!"); 7752 rte_free(cld_filter); 7753 return -EINVAL; 7754 } 7755 7756 if (!add && !node) { 7757 PMD_DRV_LOG(ERR, "There's no corresponding tunnel filter!"); 7758 rte_free(cld_filter); 7759 return -EINVAL; 7760 } 7761 7762 if (add) { 7763 ret = i40e_aq_add_cloud_filters(hw, 7764 vsi->seid, &cld_filter->element, 1); 7765 if (ret < 0) { 7766 PMD_DRV_LOG(ERR, "Failed to add a tunnel filter."); 7767 rte_free(cld_filter); 7768 return -ENOTSUP; 7769 } 7770 tunnel = rte_zmalloc("tunnel_filter", sizeof(*tunnel), 0); 7771 if (tunnel == NULL) { 7772 PMD_DRV_LOG(ERR, "Failed to alloc memory."); 7773 rte_free(cld_filter); 7774 return -ENOMEM; 7775 } 7776 7777 rte_memcpy(tunnel, &check_filter, sizeof(check_filter)); 7778 ret = i40e_sw_tunnel_filter_insert(pf, tunnel); 7779 if (ret < 0) 7780 rte_free(tunnel); 7781 } else { 7782 ret = i40e_aq_rem_cloud_filters(hw, vsi->seid, 7783 &cld_filter->element, 1); 7784 if (ret < 0) { 7785 PMD_DRV_LOG(ERR, "Failed to delete a tunnel filter."); 7786 rte_free(cld_filter); 7787 return -ENOTSUP; 7788 } 7789 ret = i40e_sw_tunnel_filter_del(pf, &node->input); 7790 } 7791 7792 rte_free(cld_filter); 7793 return ret; 7794 } 7795 7796 #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_TR_WORD0 0x48 7797 #define I40E_TR_VXLAN_GRE_KEY_MASK 0x4 7798 #define I40E_TR_GENEVE_KEY_MASK 0x8 7799 #define I40E_TR_GENERIC_UDP_TUNNEL_MASK 0x40 7800 #define I40E_TR_GRE_KEY_MASK 0x400 7801 #define I40E_TR_GRE_KEY_WITH_XSUM_MASK 0x800 7802 #define I40E_TR_GRE_NO_KEY_MASK 0x8000 7803 7804 static enum 7805 i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf) 7806 { 7807 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 7808 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 7809 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 7810 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 7811 enum i40e_status_code status = I40E_SUCCESS; 7812 7813 if (pf->support_multi_driver) { 7814 PMD_DRV_LOG(ERR, "Replace l1 filter is not supported."); 7815 return I40E_NOT_SUPPORTED; 7816 } 7817 7818 memset(&filter_replace, 0, 7819 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 7820 memset(&filter_replace_buf, 0, 7821 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 7822 7823 /* create L1 filter */ 7824 filter_replace.old_filter_type = 7825 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC; 7826 filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X11; 7827 filter_replace.tr_bit = 0; 7828 7829 /* Prepare the buffer, 3 entries */ 7830 filter_replace_buf.data[0] = 7831 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0; 7832 filter_replace_buf.data[0] |= 7833 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7834 filter_replace_buf.data[2] = 0xFF; 7835 filter_replace_buf.data[3] = 0xFF; 7836 filter_replace_buf.data[4] = 7837 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1; 7838 filter_replace_buf.data[4] |= 7839 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7840 filter_replace_buf.data[7] = 0xF0; 7841 filter_replace_buf.data[8] 7842 = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_TR_WORD0; 7843 filter_replace_buf.data[8] |= 7844 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7845 filter_replace_buf.data[10] = I40E_TR_VXLAN_GRE_KEY_MASK | 7846 I40E_TR_GENEVE_KEY_MASK | 7847 I40E_TR_GENERIC_UDP_TUNNEL_MASK; 7848 filter_replace_buf.data[11] = (I40E_TR_GRE_KEY_MASK | 7849 I40E_TR_GRE_KEY_WITH_XSUM_MASK | 7850 I40E_TR_GRE_NO_KEY_MASK) >> 8; 7851 7852 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 7853 &filter_replace_buf); 7854 if (!status && (filter_replace.old_filter_type != 7855 filter_replace.new_filter_type)) 7856 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type." 7857 " original: 0x%x, new: 0x%x", 7858 dev->device->name, 7859 filter_replace.old_filter_type, 7860 filter_replace.new_filter_type); 7861 7862 return status; 7863 } 7864 7865 static enum 7866 i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf) 7867 { 7868 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 7869 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 7870 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 7871 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 7872 enum i40e_status_code status = I40E_SUCCESS; 7873 7874 if (pf->support_multi_driver) { 7875 PMD_DRV_LOG(ERR, "Replace cloud filter is not supported."); 7876 return I40E_NOT_SUPPORTED; 7877 } 7878 7879 /* For MPLSoUDP */ 7880 memset(&filter_replace, 0, 7881 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 7882 memset(&filter_replace_buf, 0, 7883 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 7884 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER | 7885 I40E_AQC_MIRROR_CLOUD_FILTER; 7886 filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IIP; 7887 filter_replace.new_filter_type = 7888 I40E_AQC_ADD_CLOUD_FILTER_0X11; 7889 /* Prepare the buffer, 2 entries */ 7890 filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 7891 filter_replace_buf.data[0] |= 7892 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7893 filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_0X11; 7894 filter_replace_buf.data[4] |= 7895 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7896 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 7897 &filter_replace_buf); 7898 if (status < 0) 7899 return status; 7900 if (filter_replace.old_filter_type != 7901 filter_replace.new_filter_type) 7902 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 7903 " original: 0x%x, new: 0x%x", 7904 dev->device->name, 7905 filter_replace.old_filter_type, 7906 filter_replace.new_filter_type); 7907 7908 /* For MPLSoGRE */ 7909 memset(&filter_replace, 0, 7910 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 7911 memset(&filter_replace_buf, 0, 7912 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 7913 7914 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER | 7915 I40E_AQC_MIRROR_CLOUD_FILTER; 7916 filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IMAC; 7917 filter_replace.new_filter_type = 7918 I40E_AQC_ADD_CLOUD_FILTER_0X12; 7919 /* Prepare the buffer, 2 entries */ 7920 filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 7921 filter_replace_buf.data[0] |= 7922 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7923 filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_0X11; 7924 filter_replace_buf.data[4] |= 7925 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7926 7927 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 7928 &filter_replace_buf); 7929 if (!status && (filter_replace.old_filter_type != 7930 filter_replace.new_filter_type)) 7931 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 7932 " original: 0x%x, new: 0x%x", 7933 dev->device->name, 7934 filter_replace.old_filter_type, 7935 filter_replace.new_filter_type); 7936 7937 return status; 7938 } 7939 7940 static enum i40e_status_code 7941 i40e_replace_gtp_l1_filter(struct i40e_pf *pf) 7942 { 7943 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 7944 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 7945 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 7946 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 7947 enum i40e_status_code status = I40E_SUCCESS; 7948 7949 if (pf->support_multi_driver) { 7950 PMD_DRV_LOG(ERR, "Replace l1 filter is not supported."); 7951 return I40E_NOT_SUPPORTED; 7952 } 7953 7954 /* For GTP-C */ 7955 memset(&filter_replace, 0, 7956 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 7957 memset(&filter_replace_buf, 0, 7958 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 7959 /* create L1 filter */ 7960 filter_replace.old_filter_type = 7961 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC; 7962 filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X12; 7963 filter_replace.tr_bit = I40E_AQC_NEW_TR_22 | 7964 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7965 /* Prepare the buffer, 2 entries */ 7966 filter_replace_buf.data[0] = 7967 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0; 7968 filter_replace_buf.data[0] |= 7969 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7970 filter_replace_buf.data[2] = 0xFF; 7971 filter_replace_buf.data[3] = 0xFF; 7972 filter_replace_buf.data[4] = 7973 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1; 7974 filter_replace_buf.data[4] |= 7975 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7976 filter_replace_buf.data[6] = 0xFF; 7977 filter_replace_buf.data[7] = 0xFF; 7978 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 7979 &filter_replace_buf); 7980 if (status < 0) 7981 return status; 7982 if (filter_replace.old_filter_type != 7983 filter_replace.new_filter_type) 7984 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type." 7985 " original: 0x%x, new: 0x%x", 7986 dev->device->name, 7987 filter_replace.old_filter_type, 7988 filter_replace.new_filter_type); 7989 7990 /* for GTP-U */ 7991 memset(&filter_replace, 0, 7992 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 7993 memset(&filter_replace_buf, 0, 7994 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 7995 /* create L1 filter */ 7996 filter_replace.old_filter_type = 7997 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TUNNLE_KEY; 7998 filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X13; 7999 filter_replace.tr_bit = I40E_AQC_NEW_TR_21 | 8000 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8001 /* Prepare the buffer, 2 entries */ 8002 filter_replace_buf.data[0] = 8003 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0; 8004 filter_replace_buf.data[0] |= 8005 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8006 filter_replace_buf.data[2] = 0xFF; 8007 filter_replace_buf.data[3] = 0xFF; 8008 filter_replace_buf.data[4] = 8009 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1; 8010 filter_replace_buf.data[4] |= 8011 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8012 filter_replace_buf.data[6] = 0xFF; 8013 filter_replace_buf.data[7] = 0xFF; 8014 8015 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 8016 &filter_replace_buf); 8017 if (!status && (filter_replace.old_filter_type != 8018 filter_replace.new_filter_type)) 8019 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type." 8020 " original: 0x%x, new: 0x%x", 8021 dev->device->name, 8022 filter_replace.old_filter_type, 8023 filter_replace.new_filter_type); 8024 8025 return status; 8026 } 8027 8028 static enum 8029 i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf) 8030 { 8031 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 8032 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 8033 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8034 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 8035 enum i40e_status_code status = I40E_SUCCESS; 8036 8037 if (pf->support_multi_driver) { 8038 PMD_DRV_LOG(ERR, "Replace cloud filter is not supported."); 8039 return I40E_NOT_SUPPORTED; 8040 } 8041 8042 /* for GTP-C */ 8043 memset(&filter_replace, 0, 8044 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 8045 memset(&filter_replace_buf, 0, 8046 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 8047 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER; 8048 filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN; 8049 filter_replace.new_filter_type = 8050 I40E_AQC_ADD_CLOUD_FILTER_0X11; 8051 /* Prepare the buffer, 2 entries */ 8052 filter_replace_buf.data[0] = I40E_AQC_ADD_L1_FILTER_0X12; 8053 filter_replace_buf.data[0] |= 8054 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8055 filter_replace_buf.data[4] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 8056 filter_replace_buf.data[4] |= 8057 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8058 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 8059 &filter_replace_buf); 8060 if (status < 0) 8061 return status; 8062 if (filter_replace.old_filter_type != 8063 filter_replace.new_filter_type) 8064 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 8065 " original: 0x%x, new: 0x%x", 8066 dev->device->name, 8067 filter_replace.old_filter_type, 8068 filter_replace.new_filter_type); 8069 8070 /* for GTP-U */ 8071 memset(&filter_replace, 0, 8072 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 8073 memset(&filter_replace_buf, 0, 8074 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 8075 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER; 8076 filter_replace.old_filter_type = 8077 I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID; 8078 filter_replace.new_filter_type = 8079 I40E_AQC_ADD_CLOUD_FILTER_0X12; 8080 /* Prepare the buffer, 2 entries */ 8081 filter_replace_buf.data[0] = I40E_AQC_ADD_L1_FILTER_0X13; 8082 filter_replace_buf.data[0] |= 8083 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8084 filter_replace_buf.data[4] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 8085 filter_replace_buf.data[4] |= 8086 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8087 8088 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 8089 &filter_replace_buf); 8090 if (!status && (filter_replace.old_filter_type != 8091 filter_replace.new_filter_type)) 8092 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 8093 " original: 0x%x, new: 0x%x", 8094 dev->device->name, 8095 filter_replace.old_filter_type, 8096 filter_replace.new_filter_type); 8097 8098 return status; 8099 } 8100 8101 int 8102 i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf, 8103 struct i40e_tunnel_filter_conf *tunnel_filter, 8104 uint8_t add) 8105 { 8106 uint16_t ip_type; 8107 uint32_t ipv4_addr, ipv4_addr_le; 8108 uint8_t i, tun_type = 0; 8109 /* internal variable to convert ipv6 byte order */ 8110 uint32_t convert_ipv6[4]; 8111 int val, ret = 0; 8112 struct i40e_pf_vf *vf = NULL; 8113 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8114 struct i40e_vsi *vsi; 8115 struct i40e_aqc_cloud_filters_element_bb *cld_filter; 8116 struct i40e_aqc_cloud_filters_element_bb *pfilter; 8117 struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel; 8118 struct i40e_tunnel_filter *tunnel, *node; 8119 struct i40e_tunnel_filter check_filter; /* Check if filter exists */ 8120 uint32_t teid_le; 8121 bool big_buffer = 0; 8122 8123 cld_filter = rte_zmalloc("tunnel_filter", 8124 sizeof(struct i40e_aqc_add_rm_cloud_filt_elem_ext), 8125 0); 8126 8127 if (cld_filter == NULL) { 8128 PMD_DRV_LOG(ERR, "Failed to alloc memory."); 8129 return -ENOMEM; 8130 } 8131 pfilter = cld_filter; 8132 8133 ether_addr_copy(&tunnel_filter->outer_mac, 8134 (struct ether_addr *)&pfilter->element.outer_mac); 8135 ether_addr_copy(&tunnel_filter->inner_mac, 8136 (struct ether_addr *)&pfilter->element.inner_mac); 8137 8138 pfilter->element.inner_vlan = 8139 rte_cpu_to_le_16(tunnel_filter->inner_vlan); 8140 if (tunnel_filter->ip_type == I40E_TUNNEL_IPTYPE_IPV4) { 8141 ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV4; 8142 ipv4_addr = rte_be_to_cpu_32(tunnel_filter->ip_addr.ipv4_addr); 8143 ipv4_addr_le = rte_cpu_to_le_32(ipv4_addr); 8144 rte_memcpy(&pfilter->element.ipaddr.v4.data, 8145 &ipv4_addr_le, 8146 sizeof(pfilter->element.ipaddr.v4.data)); 8147 } else { 8148 ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV6; 8149 for (i = 0; i < 4; i++) { 8150 convert_ipv6[i] = 8151 rte_cpu_to_le_32(rte_be_to_cpu_32( 8152 tunnel_filter->ip_addr.ipv6_addr[i])); 8153 } 8154 rte_memcpy(&pfilter->element.ipaddr.v6.data, 8155 &convert_ipv6, 8156 sizeof(pfilter->element.ipaddr.v6.data)); 8157 } 8158 8159 /* check tunneled type */ 8160 switch (tunnel_filter->tunnel_type) { 8161 case I40E_TUNNEL_TYPE_VXLAN: 8162 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN; 8163 break; 8164 case I40E_TUNNEL_TYPE_NVGRE: 8165 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC; 8166 break; 8167 case I40E_TUNNEL_TYPE_IP_IN_GRE: 8168 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_IP; 8169 break; 8170 case I40E_TUNNEL_TYPE_MPLSoUDP: 8171 if (!pf->mpls_replace_flag) { 8172 i40e_replace_mpls_l1_filter(pf); 8173 i40e_replace_mpls_cloud_filter(pf); 8174 pf->mpls_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_0X11_WORD0] = 8178 teid_le >> 4; 8179 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] = 8180 (teid_le & 0xF) << 12; 8181 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] = 8182 0x40; 8183 big_buffer = 1; 8184 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSOUDP; 8185 break; 8186 case I40E_TUNNEL_TYPE_MPLSoGRE: 8187 if (!pf->mpls_replace_flag) { 8188 i40e_replace_mpls_l1_filter(pf); 8189 i40e_replace_mpls_cloud_filter(pf); 8190 pf->mpls_replace_flag = 1; 8191 } 8192 teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8193 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0] = 8194 teid_le >> 4; 8195 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] = 8196 (teid_le & 0xF) << 12; 8197 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] = 8198 0x0; 8199 big_buffer = 1; 8200 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSOGRE; 8201 break; 8202 case I40E_TUNNEL_TYPE_GTPC: 8203 if (!pf->gtp_replace_flag) { 8204 i40e_replace_gtp_l1_filter(pf); 8205 i40e_replace_gtp_cloud_filter(pf); 8206 pf->gtp_replace_flag = 1; 8207 } 8208 teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8209 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD0] = 8210 (teid_le >> 16) & 0xFFFF; 8211 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD1] = 8212 teid_le & 0xFFFF; 8213 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD2] = 8214 0x0; 8215 big_buffer = 1; 8216 break; 8217 case I40E_TUNNEL_TYPE_GTPU: 8218 if (!pf->gtp_replace_flag) { 8219 i40e_replace_gtp_l1_filter(pf); 8220 i40e_replace_gtp_cloud_filter(pf); 8221 pf->gtp_replace_flag = 1; 8222 } 8223 teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8224 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD0] = 8225 (teid_le >> 16) & 0xFFFF; 8226 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD1] = 8227 teid_le & 0xFFFF; 8228 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD2] = 8229 0x0; 8230 big_buffer = 1; 8231 break; 8232 case I40E_TUNNEL_TYPE_QINQ: 8233 if (!pf->qinq_replace_flag) { 8234 ret = i40e_cloud_filter_qinq_create(pf); 8235 if (ret < 0) 8236 PMD_DRV_LOG(DEBUG, 8237 "QinQ tunnel filter already created."); 8238 pf->qinq_replace_flag = 1; 8239 } 8240 /* Add in the General fields the values of 8241 * the Outer and Inner VLAN 8242 * Big Buffer should be set, see changes in 8243 * i40e_aq_add_cloud_filters 8244 */ 8245 pfilter->general_fields[0] = tunnel_filter->inner_vlan; 8246 pfilter->general_fields[1] = tunnel_filter->outer_vlan; 8247 big_buffer = 1; 8248 break; 8249 default: 8250 /* Other tunnel types is not supported. */ 8251 PMD_DRV_LOG(ERR, "tunnel type is not supported."); 8252 rte_free(cld_filter); 8253 return -EINVAL; 8254 } 8255 8256 if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_MPLSoUDP) 8257 pfilter->element.flags = 8258 I40E_AQC_ADD_CLOUD_FILTER_0X11; 8259 else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_MPLSoGRE) 8260 pfilter->element.flags = 8261 I40E_AQC_ADD_CLOUD_FILTER_0X12; 8262 else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_GTPC) 8263 pfilter->element.flags = 8264 I40E_AQC_ADD_CLOUD_FILTER_0X11; 8265 else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_GTPU) 8266 pfilter->element.flags = 8267 I40E_AQC_ADD_CLOUD_FILTER_0X12; 8268 else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_QINQ) 8269 pfilter->element.flags |= 8270 I40E_AQC_ADD_CLOUD_FILTER_0X10; 8271 else { 8272 val = i40e_dev_get_filter_type(tunnel_filter->filter_type, 8273 &pfilter->element.flags); 8274 if (val < 0) { 8275 rte_free(cld_filter); 8276 return -EINVAL; 8277 } 8278 } 8279 8280 pfilter->element.flags |= rte_cpu_to_le_16( 8281 I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE | 8282 ip_type | (tun_type << I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT)); 8283 pfilter->element.tenant_id = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8284 pfilter->element.queue_number = 8285 rte_cpu_to_le_16(tunnel_filter->queue_id); 8286 8287 if (!tunnel_filter->is_to_vf) 8288 vsi = pf->main_vsi; 8289 else { 8290 if (tunnel_filter->vf_id >= pf->vf_num) { 8291 PMD_DRV_LOG(ERR, "Invalid argument."); 8292 rte_free(cld_filter); 8293 return -EINVAL; 8294 } 8295 vf = &pf->vfs[tunnel_filter->vf_id]; 8296 vsi = vf->vsi; 8297 } 8298 8299 /* Check if there is the filter in SW list */ 8300 memset(&check_filter, 0, sizeof(check_filter)); 8301 i40e_tunnel_filter_convert(cld_filter, &check_filter); 8302 check_filter.is_to_vf = tunnel_filter->is_to_vf; 8303 check_filter.vf_id = tunnel_filter->vf_id; 8304 node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &check_filter.input); 8305 if (add && node) { 8306 PMD_DRV_LOG(ERR, "Conflict with existing tunnel rules!"); 8307 rte_free(cld_filter); 8308 return -EINVAL; 8309 } 8310 8311 if (!add && !node) { 8312 PMD_DRV_LOG(ERR, "There's no corresponding tunnel filter!"); 8313 rte_free(cld_filter); 8314 return -EINVAL; 8315 } 8316 8317 if (add) { 8318 if (big_buffer) 8319 ret = i40e_aq_add_cloud_filters_bb(hw, 8320 vsi->seid, cld_filter, 1); 8321 else 8322 ret = i40e_aq_add_cloud_filters(hw, 8323 vsi->seid, &cld_filter->element, 1); 8324 if (ret < 0) { 8325 PMD_DRV_LOG(ERR, "Failed to add a tunnel filter."); 8326 rte_free(cld_filter); 8327 return -ENOTSUP; 8328 } 8329 tunnel = rte_zmalloc("tunnel_filter", sizeof(*tunnel), 0); 8330 if (tunnel == NULL) { 8331 PMD_DRV_LOG(ERR, "Failed to alloc memory."); 8332 rte_free(cld_filter); 8333 return -ENOMEM; 8334 } 8335 8336 rte_memcpy(tunnel, &check_filter, sizeof(check_filter)); 8337 ret = i40e_sw_tunnel_filter_insert(pf, tunnel); 8338 if (ret < 0) 8339 rte_free(tunnel); 8340 } else { 8341 if (big_buffer) 8342 ret = i40e_aq_rem_cloud_filters_bb( 8343 hw, vsi->seid, cld_filter, 1); 8344 else 8345 ret = i40e_aq_rem_cloud_filters(hw, vsi->seid, 8346 &cld_filter->element, 1); 8347 if (ret < 0) { 8348 PMD_DRV_LOG(ERR, "Failed to delete a tunnel filter."); 8349 rte_free(cld_filter); 8350 return -ENOTSUP; 8351 } 8352 ret = i40e_sw_tunnel_filter_del(pf, &node->input); 8353 } 8354 8355 rte_free(cld_filter); 8356 return ret; 8357 } 8358 8359 static int 8360 i40e_get_vxlan_port_idx(struct i40e_pf *pf, uint16_t port) 8361 { 8362 uint8_t i; 8363 8364 for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) { 8365 if (pf->vxlan_ports[i] == port) 8366 return i; 8367 } 8368 8369 return -1; 8370 } 8371 8372 static int 8373 i40e_add_vxlan_port(struct i40e_pf *pf, uint16_t port) 8374 { 8375 int idx, ret; 8376 uint8_t filter_idx; 8377 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8378 8379 idx = i40e_get_vxlan_port_idx(pf, port); 8380 8381 /* Check if port already exists */ 8382 if (idx >= 0) { 8383 PMD_DRV_LOG(ERR, "Port %d already offloaded", port); 8384 return -EINVAL; 8385 } 8386 8387 /* Now check if there is space to add the new port */ 8388 idx = i40e_get_vxlan_port_idx(pf, 0); 8389 if (idx < 0) { 8390 PMD_DRV_LOG(ERR, 8391 "Maximum number of UDP ports reached, not adding port %d", 8392 port); 8393 return -ENOSPC; 8394 } 8395 8396 ret = i40e_aq_add_udp_tunnel(hw, port, I40E_AQC_TUNNEL_TYPE_VXLAN, 8397 &filter_idx, NULL); 8398 if (ret < 0) { 8399 PMD_DRV_LOG(ERR, "Failed to add VXLAN UDP port %d", port); 8400 return -1; 8401 } 8402 8403 PMD_DRV_LOG(INFO, "Added port %d with AQ command with index %d", 8404 port, filter_idx); 8405 8406 /* New port: add it and mark its index in the bitmap */ 8407 pf->vxlan_ports[idx] = port; 8408 pf->vxlan_bitmap |= (1 << idx); 8409 8410 if (!(pf->flags & I40E_FLAG_VXLAN)) 8411 pf->flags |= I40E_FLAG_VXLAN; 8412 8413 return 0; 8414 } 8415 8416 static int 8417 i40e_del_vxlan_port(struct i40e_pf *pf, uint16_t port) 8418 { 8419 int idx; 8420 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8421 8422 if (!(pf->flags & I40E_FLAG_VXLAN)) { 8423 PMD_DRV_LOG(ERR, "VXLAN UDP port was not configured."); 8424 return -EINVAL; 8425 } 8426 8427 idx = i40e_get_vxlan_port_idx(pf, port); 8428 8429 if (idx < 0) { 8430 PMD_DRV_LOG(ERR, "Port %d doesn't exist", port); 8431 return -EINVAL; 8432 } 8433 8434 if (i40e_aq_del_udp_tunnel(hw, idx, NULL) < 0) { 8435 PMD_DRV_LOG(ERR, "Failed to delete VXLAN UDP port %d", port); 8436 return -1; 8437 } 8438 8439 PMD_DRV_LOG(INFO, "Deleted port %d with AQ command with index %d", 8440 port, idx); 8441 8442 pf->vxlan_ports[idx] = 0; 8443 pf->vxlan_bitmap &= ~(1 << idx); 8444 8445 if (!pf->vxlan_bitmap) 8446 pf->flags &= ~I40E_FLAG_VXLAN; 8447 8448 return 0; 8449 } 8450 8451 /* Add UDP tunneling port */ 8452 static int 8453 i40e_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, 8454 struct rte_eth_udp_tunnel *udp_tunnel) 8455 { 8456 int ret = 0; 8457 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 8458 8459 if (udp_tunnel == NULL) 8460 return -EINVAL; 8461 8462 switch (udp_tunnel->prot_type) { 8463 case RTE_TUNNEL_TYPE_VXLAN: 8464 ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port); 8465 break; 8466 8467 case RTE_TUNNEL_TYPE_GENEVE: 8468 case RTE_TUNNEL_TYPE_TEREDO: 8469 PMD_DRV_LOG(ERR, "Tunnel type is not supported now."); 8470 ret = -1; 8471 break; 8472 8473 default: 8474 PMD_DRV_LOG(ERR, "Invalid tunnel type"); 8475 ret = -1; 8476 break; 8477 } 8478 8479 return ret; 8480 } 8481 8482 /* Remove UDP tunneling port */ 8483 static int 8484 i40e_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, 8485 struct rte_eth_udp_tunnel *udp_tunnel) 8486 { 8487 int ret = 0; 8488 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 8489 8490 if (udp_tunnel == NULL) 8491 return -EINVAL; 8492 8493 switch (udp_tunnel->prot_type) { 8494 case RTE_TUNNEL_TYPE_VXLAN: 8495 ret = i40e_del_vxlan_port(pf, udp_tunnel->udp_port); 8496 break; 8497 case RTE_TUNNEL_TYPE_GENEVE: 8498 case RTE_TUNNEL_TYPE_TEREDO: 8499 PMD_DRV_LOG(ERR, "Tunnel type is not supported now."); 8500 ret = -1; 8501 break; 8502 default: 8503 PMD_DRV_LOG(ERR, "Invalid tunnel type"); 8504 ret = -1; 8505 break; 8506 } 8507 8508 return ret; 8509 } 8510 8511 /* Calculate the maximum number of contiguous PF queues that are configured */ 8512 static int 8513 i40e_pf_calc_configured_queues_num(struct i40e_pf *pf) 8514 { 8515 struct rte_eth_dev_data *data = pf->dev_data; 8516 int i, num; 8517 struct i40e_rx_queue *rxq; 8518 8519 num = 0; 8520 for (i = 0; i < pf->lan_nb_qps; i++) { 8521 rxq = data->rx_queues[i]; 8522 if (rxq && rxq->q_set) 8523 num++; 8524 else 8525 break; 8526 } 8527 8528 return num; 8529 } 8530 8531 /* Configure RSS */ 8532 static int 8533 i40e_pf_config_rss(struct i40e_pf *pf) 8534 { 8535 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8536 struct rte_eth_rss_conf rss_conf; 8537 uint32_t i, lut = 0; 8538 uint16_t j, num; 8539 8540 /* 8541 * If both VMDQ and RSS enabled, not all of PF queues are configured. 8542 * It's necessary to calculate the actual PF queues that are configured. 8543 */ 8544 if (pf->dev_data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_VMDQ_FLAG) 8545 num = i40e_pf_calc_configured_queues_num(pf); 8546 else 8547 num = pf->dev_data->nb_rx_queues; 8548 8549 num = RTE_MIN(num, I40E_MAX_Q_PER_TC); 8550 PMD_INIT_LOG(INFO, "Max of contiguous %u PF queues are configured", 8551 num); 8552 8553 if (num == 0) { 8554 PMD_INIT_LOG(ERR, "No PF queues are configured to enable RSS"); 8555 return -ENOTSUP; 8556 } 8557 8558 if (pf->adapter->rss_reta_updated == 0) { 8559 for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) { 8560 if (j == num) 8561 j = 0; 8562 lut = (lut << 8) | (j & ((0x1 << 8563 hw->func_caps.rss_table_entry_width) - 1)); 8564 if ((i & 3) == 3) 8565 I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), 8566 rte_bswap32(lut)); 8567 } 8568 } 8569 8570 rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf; 8571 if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0) { 8572 i40e_pf_disable_rss(pf); 8573 return 0; 8574 } 8575 if (rss_conf.rss_key == NULL || rss_conf.rss_key_len < 8576 (I40E_PFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t)) { 8577 /* Random default keys */ 8578 static uint32_t rss_key_default[] = {0x6b793944, 8579 0x23504cb5, 0x5bea75b6, 0x309f4f12, 0x3dc0a2b8, 8580 0x024ddcdf, 0x339b8ca0, 0x4c4af64a, 0x34fac605, 8581 0x55d85839, 0x3a58997d, 0x2ec938e1, 0x66031581}; 8582 8583 rss_conf.rss_key = (uint8_t *)rss_key_default; 8584 rss_conf.rss_key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) * 8585 sizeof(uint32_t); 8586 } 8587 8588 return i40e_hw_rss_hash_set(pf, &rss_conf); 8589 } 8590 8591 static int 8592 i40e_tunnel_filter_param_check(struct i40e_pf *pf, 8593 struct rte_eth_tunnel_filter_conf *filter) 8594 { 8595 if (pf == NULL || filter == NULL) { 8596 PMD_DRV_LOG(ERR, "Invalid parameter"); 8597 return -EINVAL; 8598 } 8599 8600 if (filter->queue_id >= pf->dev_data->nb_rx_queues) { 8601 PMD_DRV_LOG(ERR, "Invalid queue ID"); 8602 return -EINVAL; 8603 } 8604 8605 if (filter->inner_vlan > ETHER_MAX_VLAN_ID) { 8606 PMD_DRV_LOG(ERR, "Invalid inner VLAN ID"); 8607 return -EINVAL; 8608 } 8609 8610 if ((filter->filter_type & ETH_TUNNEL_FILTER_OMAC) && 8611 (is_zero_ether_addr(&filter->outer_mac))) { 8612 PMD_DRV_LOG(ERR, "Cannot add NULL outer MAC address"); 8613 return -EINVAL; 8614 } 8615 8616 if ((filter->filter_type & ETH_TUNNEL_FILTER_IMAC) && 8617 (is_zero_ether_addr(&filter->inner_mac))) { 8618 PMD_DRV_LOG(ERR, "Cannot add NULL inner MAC address"); 8619 return -EINVAL; 8620 } 8621 8622 return 0; 8623 } 8624 8625 #define I40E_GL_PRS_FVBM_MSK_ENA 0x80000000 8626 #define I40E_GL_PRS_FVBM(_i) (0x00269760 + ((_i) * 4)) 8627 static int 8628 i40e_dev_set_gre_key_len(struct i40e_hw *hw, uint8_t len) 8629 { 8630 struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf; 8631 uint32_t val, reg; 8632 int ret = -EINVAL; 8633 8634 if (pf->support_multi_driver) { 8635 PMD_DRV_LOG(ERR, "GRE key length configuration is unsupported"); 8636 return -ENOTSUP; 8637 } 8638 8639 val = I40E_READ_REG(hw, I40E_GL_PRS_FVBM(2)); 8640 PMD_DRV_LOG(DEBUG, "Read original GL_PRS_FVBM with 0x%08x", val); 8641 8642 if (len == 3) { 8643 reg = val | I40E_GL_PRS_FVBM_MSK_ENA; 8644 } else if (len == 4) { 8645 reg = val & ~I40E_GL_PRS_FVBM_MSK_ENA; 8646 } else { 8647 PMD_DRV_LOG(ERR, "Unsupported GRE key length of %u", len); 8648 return ret; 8649 } 8650 8651 if (reg != val) { 8652 ret = i40e_aq_debug_write_global_register(hw, 8653 I40E_GL_PRS_FVBM(2), 8654 reg, NULL); 8655 if (ret != 0) 8656 return ret; 8657 PMD_DRV_LOG(DEBUG, "Global register 0x%08x is changed " 8658 "with value 0x%08x", 8659 I40E_GL_PRS_FVBM(2), reg); 8660 } else { 8661 ret = 0; 8662 } 8663 PMD_DRV_LOG(DEBUG, "Read modified GL_PRS_FVBM with 0x%08x", 8664 I40E_READ_REG(hw, I40E_GL_PRS_FVBM(2))); 8665 8666 return ret; 8667 } 8668 8669 static int 8670 i40e_dev_global_config_set(struct i40e_hw *hw, struct rte_eth_global_cfg *cfg) 8671 { 8672 int ret = -EINVAL; 8673 8674 if (!hw || !cfg) 8675 return -EINVAL; 8676 8677 switch (cfg->cfg_type) { 8678 case RTE_ETH_GLOBAL_CFG_TYPE_GRE_KEY_LEN: 8679 ret = i40e_dev_set_gre_key_len(hw, cfg->cfg.gre_key_len); 8680 break; 8681 default: 8682 PMD_DRV_LOG(ERR, "Unknown config type %u", cfg->cfg_type); 8683 break; 8684 } 8685 8686 return ret; 8687 } 8688 8689 static int 8690 i40e_filter_ctrl_global_config(struct rte_eth_dev *dev, 8691 enum rte_filter_op filter_op, 8692 void *arg) 8693 { 8694 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 8695 int ret = I40E_ERR_PARAM; 8696 8697 switch (filter_op) { 8698 case RTE_ETH_FILTER_SET: 8699 ret = i40e_dev_global_config_set(hw, 8700 (struct rte_eth_global_cfg *)arg); 8701 break; 8702 default: 8703 PMD_DRV_LOG(ERR, "unknown operation %u", filter_op); 8704 break; 8705 } 8706 8707 return ret; 8708 } 8709 8710 static int 8711 i40e_tunnel_filter_handle(struct rte_eth_dev *dev, 8712 enum rte_filter_op filter_op, 8713 void *arg) 8714 { 8715 struct rte_eth_tunnel_filter_conf *filter; 8716 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 8717 int ret = I40E_SUCCESS; 8718 8719 filter = (struct rte_eth_tunnel_filter_conf *)(arg); 8720 8721 if (i40e_tunnel_filter_param_check(pf, filter) < 0) 8722 return I40E_ERR_PARAM; 8723 8724 switch (filter_op) { 8725 case RTE_ETH_FILTER_NOP: 8726 if (!(pf->flags & I40E_FLAG_VXLAN)) 8727 ret = I40E_NOT_SUPPORTED; 8728 break; 8729 case RTE_ETH_FILTER_ADD: 8730 ret = i40e_dev_tunnel_filter_set(pf, filter, 1); 8731 break; 8732 case RTE_ETH_FILTER_DELETE: 8733 ret = i40e_dev_tunnel_filter_set(pf, filter, 0); 8734 break; 8735 default: 8736 PMD_DRV_LOG(ERR, "unknown operation %u", filter_op); 8737 ret = I40E_ERR_PARAM; 8738 break; 8739 } 8740 8741 return ret; 8742 } 8743 8744 static int 8745 i40e_pf_config_mq_rx(struct i40e_pf *pf) 8746 { 8747 int ret = 0; 8748 enum rte_eth_rx_mq_mode mq_mode = pf->dev_data->dev_conf.rxmode.mq_mode; 8749 8750 /* RSS setup */ 8751 if (mq_mode & ETH_MQ_RX_RSS_FLAG) 8752 ret = i40e_pf_config_rss(pf); 8753 else 8754 i40e_pf_disable_rss(pf); 8755 8756 return ret; 8757 } 8758 8759 /* Get the symmetric hash enable configurations per port */ 8760 static void 8761 i40e_get_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t *enable) 8762 { 8763 uint32_t reg = i40e_read_rx_ctl(hw, I40E_PRTQF_CTL_0); 8764 8765 *enable = reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK ? 1 : 0; 8766 } 8767 8768 /* Set the symmetric hash enable configurations per port */ 8769 static void 8770 i40e_set_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t enable) 8771 { 8772 uint32_t reg = i40e_read_rx_ctl(hw, I40E_PRTQF_CTL_0); 8773 8774 if (enable > 0) { 8775 if (reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK) { 8776 PMD_DRV_LOG(INFO, 8777 "Symmetric hash has already been enabled"); 8778 return; 8779 } 8780 reg |= I40E_PRTQF_CTL_0_HSYM_ENA_MASK; 8781 } else { 8782 if (!(reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK)) { 8783 PMD_DRV_LOG(INFO, 8784 "Symmetric hash has already been disabled"); 8785 return; 8786 } 8787 reg &= ~I40E_PRTQF_CTL_0_HSYM_ENA_MASK; 8788 } 8789 i40e_write_rx_ctl(hw, I40E_PRTQF_CTL_0, reg); 8790 I40E_WRITE_FLUSH(hw); 8791 } 8792 8793 /* 8794 * Get global configurations of hash function type and symmetric hash enable 8795 * per flow type (pctype). Note that global configuration means it affects all 8796 * the ports on the same NIC. 8797 */ 8798 static int 8799 i40e_get_hash_filter_global_config(struct i40e_hw *hw, 8800 struct rte_eth_hash_global_conf *g_cfg) 8801 { 8802 struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back; 8803 uint32_t reg; 8804 uint16_t i, j; 8805 8806 memset(g_cfg, 0, sizeof(*g_cfg)); 8807 reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL); 8808 if (reg & I40E_GLQF_CTL_HTOEP_MASK) 8809 g_cfg->hash_func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 8810 else 8811 g_cfg->hash_func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 8812 PMD_DRV_LOG(DEBUG, "Hash function is %s", 8813 (reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR"); 8814 8815 /* 8816 * As i40e supports less than 64 flow types, only first 64 bits need to 8817 * be checked. 8818 */ 8819 for (i = 1; i < RTE_SYM_HASH_MASK_ARRAY_SIZE; i++) { 8820 g_cfg->valid_bit_mask[i] = 0ULL; 8821 g_cfg->sym_hash_enable_mask[i] = 0ULL; 8822 } 8823 8824 g_cfg->valid_bit_mask[0] = adapter->flow_types_mask; 8825 8826 for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT64_BIT; i++) { 8827 if (!adapter->pctypes_tbl[i]) 8828 continue; 8829 for (j = I40E_FILTER_PCTYPE_INVALID + 1; 8830 j < I40E_FILTER_PCTYPE_MAX; j++) { 8831 if (adapter->pctypes_tbl[i] & (1ULL << j)) { 8832 reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j)); 8833 if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) { 8834 g_cfg->sym_hash_enable_mask[0] |= 8835 (1ULL << i); 8836 } 8837 } 8838 } 8839 } 8840 8841 return 0; 8842 } 8843 8844 static int 8845 i40e_hash_global_config_check(const struct i40e_adapter *adapter, 8846 const struct rte_eth_hash_global_conf *g_cfg) 8847 { 8848 uint32_t i; 8849 uint64_t mask0, i40e_mask = adapter->flow_types_mask; 8850 8851 if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ && 8852 g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR && 8853 g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_DEFAULT) { 8854 PMD_DRV_LOG(ERR, "Unsupported hash function type %d", 8855 g_cfg->hash_func); 8856 return -EINVAL; 8857 } 8858 8859 /* 8860 * As i40e supports less than 64 flow types, only first 64 bits need to 8861 * be checked. 8862 */ 8863 mask0 = g_cfg->valid_bit_mask[0]; 8864 for (i = 0; i < RTE_SYM_HASH_MASK_ARRAY_SIZE; i++) { 8865 if (i == 0) { 8866 /* Check if any unsupported flow type configured */ 8867 if ((mask0 | i40e_mask) ^ i40e_mask) 8868 goto mask_err; 8869 } else { 8870 if (g_cfg->valid_bit_mask[i]) 8871 goto mask_err; 8872 } 8873 } 8874 8875 return 0; 8876 8877 mask_err: 8878 PMD_DRV_LOG(ERR, "i40e unsupported flow type bit(s) configured"); 8879 8880 return -EINVAL; 8881 } 8882 8883 /* 8884 * Set global configurations of hash function type and symmetric hash enable 8885 * per flow type (pctype). Note any modifying global configuration will affect 8886 * all the ports on the same NIC. 8887 */ 8888 static int 8889 i40e_set_hash_filter_global_config(struct i40e_hw *hw, 8890 struct rte_eth_hash_global_conf *g_cfg) 8891 { 8892 struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back; 8893 struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf; 8894 int ret; 8895 uint16_t i, j; 8896 uint32_t reg; 8897 uint64_t mask0 = g_cfg->valid_bit_mask[0] & adapter->flow_types_mask; 8898 8899 if (pf->support_multi_driver) { 8900 PMD_DRV_LOG(ERR, "Hash global configuration is not supported."); 8901 return -ENOTSUP; 8902 } 8903 8904 /* Check the input parameters */ 8905 ret = i40e_hash_global_config_check(adapter, g_cfg); 8906 if (ret < 0) 8907 return ret; 8908 8909 /* 8910 * As i40e supports less than 64 flow types, only first 64 bits need to 8911 * be configured. 8912 */ 8913 for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT64_BIT; i++) { 8914 if (mask0 & (1UL << i)) { 8915 reg = (g_cfg->sym_hash_enable_mask[0] & (1ULL << i)) ? 8916 I40E_GLQF_HSYM_SYMH_ENA_MASK : 0; 8917 8918 for (j = I40E_FILTER_PCTYPE_INVALID + 1; 8919 j < I40E_FILTER_PCTYPE_MAX; j++) { 8920 if (adapter->pctypes_tbl[i] & (1ULL << j)) 8921 i40e_write_global_rx_ctl(hw, 8922 I40E_GLQF_HSYM(j), 8923 reg); 8924 } 8925 } 8926 } 8927 8928 reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL); 8929 if (g_cfg->hash_func == RTE_ETH_HASH_FUNCTION_TOEPLITZ) { 8930 /* Toeplitz */ 8931 if (reg & I40E_GLQF_CTL_HTOEP_MASK) { 8932 PMD_DRV_LOG(DEBUG, 8933 "Hash function already set to Toeplitz"); 8934 goto out; 8935 } 8936 reg |= I40E_GLQF_CTL_HTOEP_MASK; 8937 } else if (g_cfg->hash_func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) { 8938 /* Simple XOR */ 8939 if (!(reg & I40E_GLQF_CTL_HTOEP_MASK)) { 8940 PMD_DRV_LOG(DEBUG, 8941 "Hash function already set to Simple XOR"); 8942 goto out; 8943 } 8944 reg &= ~I40E_GLQF_CTL_HTOEP_MASK; 8945 } else 8946 /* Use the default, and keep it as it is */ 8947 goto out; 8948 8949 i40e_write_global_rx_ctl(hw, I40E_GLQF_CTL, reg); 8950 8951 out: 8952 I40E_WRITE_FLUSH(hw); 8953 8954 return 0; 8955 } 8956 8957 /** 8958 * Valid input sets for hash and flow director filters per PCTYPE 8959 */ 8960 static uint64_t 8961 i40e_get_valid_input_set(enum i40e_filter_pctype pctype, 8962 enum rte_filter_type filter) 8963 { 8964 uint64_t valid; 8965 8966 static const uint64_t valid_hash_inset_table[] = { 8967 [I40E_FILTER_PCTYPE_FRAG_IPV4] = 8968 I40E_INSET_DMAC | I40E_INSET_SMAC | 8969 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 8970 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_SRC | 8971 I40E_INSET_IPV4_DST | I40E_INSET_IPV4_TOS | 8972 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 8973 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 8974 I40E_INSET_FLEX_PAYLOAD, 8975 [I40E_FILTER_PCTYPE_NONF_IPV4_UDP] = 8976 I40E_INSET_DMAC | I40E_INSET_SMAC | 8977 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 8978 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 8979 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 8980 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 8981 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 8982 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 8983 I40E_INSET_FLEX_PAYLOAD, 8984 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] = 8985 I40E_INSET_DMAC | I40E_INSET_SMAC | 8986 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 8987 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 8988 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 8989 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 8990 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 8991 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 8992 I40E_INSET_FLEX_PAYLOAD, 8993 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] = 8994 I40E_INSET_DMAC | I40E_INSET_SMAC | 8995 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 8996 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 8997 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 8998 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 8999 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9000 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9001 I40E_INSET_FLEX_PAYLOAD, 9002 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP] = 9003 I40E_INSET_DMAC | I40E_INSET_SMAC | 9004 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9005 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 9006 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 9007 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 9008 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9009 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9010 I40E_INSET_TCP_FLAGS | I40E_INSET_FLEX_PAYLOAD, 9011 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] = 9012 I40E_INSET_DMAC | I40E_INSET_SMAC | 9013 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9014 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 9015 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 9016 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 9017 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9018 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9019 I40E_INSET_TCP_FLAGS | I40E_INSET_FLEX_PAYLOAD, 9020 [I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] = 9021 I40E_INSET_DMAC | I40E_INSET_SMAC | 9022 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9023 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 9024 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 9025 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 9026 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9027 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9028 I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD, 9029 [I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] = 9030 I40E_INSET_DMAC | I40E_INSET_SMAC | 9031 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9032 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 9033 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 9034 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 9035 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9036 I40E_INSET_FLEX_PAYLOAD, 9037 [I40E_FILTER_PCTYPE_FRAG_IPV6] = 9038 I40E_INSET_DMAC | I40E_INSET_SMAC | 9039 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9040 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9041 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9042 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_TUNNEL_DMAC | 9043 I40E_INSET_TUNNEL_ID | I40E_INSET_IPV6_SRC | 9044 I40E_INSET_IPV6_DST | I40E_INSET_FLEX_PAYLOAD, 9045 [I40E_FILTER_PCTYPE_NONF_IPV6_UDP] = 9046 I40E_INSET_DMAC | I40E_INSET_SMAC | 9047 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9048 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9049 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9050 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9051 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9052 I40E_INSET_DST_PORT | I40E_INSET_FLEX_PAYLOAD, 9053 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] = 9054 I40E_INSET_DMAC | I40E_INSET_SMAC | 9055 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9056 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9057 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9058 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9059 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9060 I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS | 9061 I40E_INSET_FLEX_PAYLOAD, 9062 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] = 9063 I40E_INSET_DMAC | I40E_INSET_SMAC | 9064 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9065 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9066 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9067 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9068 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9069 I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS | 9070 I40E_INSET_FLEX_PAYLOAD, 9071 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP] = 9072 I40E_INSET_DMAC | I40E_INSET_SMAC | 9073 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9074 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9075 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9076 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9077 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9078 I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS | 9079 I40E_INSET_FLEX_PAYLOAD, 9080 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] = 9081 I40E_INSET_DMAC | I40E_INSET_SMAC | 9082 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9083 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9084 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9085 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9086 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9087 I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS | 9088 I40E_INSET_FLEX_PAYLOAD, 9089 [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] = 9090 I40E_INSET_DMAC | I40E_INSET_SMAC | 9091 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9092 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9093 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9094 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9095 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9096 I40E_INSET_DST_PORT | I40E_INSET_SCTP_VT | 9097 I40E_INSET_FLEX_PAYLOAD, 9098 [I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] = 9099 I40E_INSET_DMAC | I40E_INSET_SMAC | 9100 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9101 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9102 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9103 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9104 I40E_INSET_IPV6_DST | I40E_INSET_TUNNEL_ID | 9105 I40E_INSET_FLEX_PAYLOAD, 9106 [I40E_FILTER_PCTYPE_L2_PAYLOAD] = 9107 I40E_INSET_DMAC | I40E_INSET_SMAC | 9108 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9109 I40E_INSET_VLAN_TUNNEL | I40E_INSET_LAST_ETHER_TYPE | 9110 I40E_INSET_FLEX_PAYLOAD, 9111 }; 9112 9113 /** 9114 * Flow director supports only fields defined in 9115 * union rte_eth_fdir_flow. 9116 */ 9117 static const uint64_t valid_fdir_inset_table[] = { 9118 [I40E_FILTER_PCTYPE_FRAG_IPV4] = 9119 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9120 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9121 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | 9122 I40E_INSET_IPV4_TTL, 9123 [I40E_FILTER_PCTYPE_NONF_IPV4_UDP] = 9124 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9125 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9126 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9127 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9128 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] = 9129 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9130 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9131 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9132 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9133 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] = 9134 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9135 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9136 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9137 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9138 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP] = 9139 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9140 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9141 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9142 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9143 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] = 9144 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9145 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9146 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9147 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9148 [I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] = 9149 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9150 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9151 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9152 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9153 I40E_INSET_SCTP_VT, 9154 [I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] = 9155 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9156 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9157 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | 9158 I40E_INSET_IPV4_TTL, 9159 [I40E_FILTER_PCTYPE_FRAG_IPV6] = 9160 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9161 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9162 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR | 9163 I40E_INSET_IPV6_HOP_LIMIT, 9164 [I40E_FILTER_PCTYPE_NONF_IPV6_UDP] = 9165 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9166 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9167 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9168 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9169 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] = 9170 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9171 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9172 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9173 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9174 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] = 9175 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9176 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9177 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9178 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9179 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP] = 9180 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9181 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9182 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9183 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9184 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] = 9185 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9186 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9187 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9188 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9189 [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] = 9190 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9191 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9192 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9193 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9194 I40E_INSET_SCTP_VT, 9195 [I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] = 9196 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9197 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9198 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR | 9199 I40E_INSET_IPV6_HOP_LIMIT, 9200 [I40E_FILTER_PCTYPE_L2_PAYLOAD] = 9201 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9202 I40E_INSET_LAST_ETHER_TYPE, 9203 }; 9204 9205 if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) 9206 return 0; 9207 if (filter == RTE_ETH_FILTER_HASH) 9208 valid = valid_hash_inset_table[pctype]; 9209 else 9210 valid = valid_fdir_inset_table[pctype]; 9211 9212 return valid; 9213 } 9214 9215 /** 9216 * Validate if the input set is allowed for a specific PCTYPE 9217 */ 9218 int 9219 i40e_validate_input_set(enum i40e_filter_pctype pctype, 9220 enum rte_filter_type filter, uint64_t inset) 9221 { 9222 uint64_t valid; 9223 9224 valid = i40e_get_valid_input_set(pctype, filter); 9225 if (inset & (~valid)) 9226 return -EINVAL; 9227 9228 return 0; 9229 } 9230 9231 /* default input set fields combination per pctype */ 9232 uint64_t 9233 i40e_get_default_input_set(uint16_t pctype) 9234 { 9235 static const uint64_t default_inset_table[] = { 9236 [I40E_FILTER_PCTYPE_FRAG_IPV4] = 9237 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST, 9238 [I40E_FILTER_PCTYPE_NONF_IPV4_UDP] = 9239 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9240 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9241 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] = 9242 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9243 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9244 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] = 9245 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9246 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9247 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP] = 9248 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9249 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9250 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] = 9251 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9252 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9253 [I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] = 9254 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9255 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9256 I40E_INSET_SCTP_VT, 9257 [I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] = 9258 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST, 9259 [I40E_FILTER_PCTYPE_FRAG_IPV6] = 9260 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST, 9261 [I40E_FILTER_PCTYPE_NONF_IPV6_UDP] = 9262 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9263 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9264 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] = 9265 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9266 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9267 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] = 9268 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9269 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9270 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP] = 9271 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9272 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9273 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] = 9274 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9275 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9276 [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] = 9277 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9278 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9279 I40E_INSET_SCTP_VT, 9280 [I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] = 9281 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST, 9282 [I40E_FILTER_PCTYPE_L2_PAYLOAD] = 9283 I40E_INSET_LAST_ETHER_TYPE, 9284 }; 9285 9286 if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) 9287 return 0; 9288 9289 return default_inset_table[pctype]; 9290 } 9291 9292 /** 9293 * Parse the input set from index to logical bit masks 9294 */ 9295 static int 9296 i40e_parse_input_set(uint64_t *inset, 9297 enum i40e_filter_pctype pctype, 9298 enum rte_eth_input_set_field *field, 9299 uint16_t size) 9300 { 9301 uint16_t i, j; 9302 int ret = -EINVAL; 9303 9304 static const struct { 9305 enum rte_eth_input_set_field field; 9306 uint64_t inset; 9307 } inset_convert_table[] = { 9308 {RTE_ETH_INPUT_SET_NONE, I40E_INSET_NONE}, 9309 {RTE_ETH_INPUT_SET_L2_SRC_MAC, I40E_INSET_SMAC}, 9310 {RTE_ETH_INPUT_SET_L2_DST_MAC, I40E_INSET_DMAC}, 9311 {RTE_ETH_INPUT_SET_L2_OUTER_VLAN, I40E_INSET_VLAN_OUTER}, 9312 {RTE_ETH_INPUT_SET_L2_INNER_VLAN, I40E_INSET_VLAN_INNER}, 9313 {RTE_ETH_INPUT_SET_L2_ETHERTYPE, I40E_INSET_LAST_ETHER_TYPE}, 9314 {RTE_ETH_INPUT_SET_L3_SRC_IP4, I40E_INSET_IPV4_SRC}, 9315 {RTE_ETH_INPUT_SET_L3_DST_IP4, I40E_INSET_IPV4_DST}, 9316 {RTE_ETH_INPUT_SET_L3_IP4_TOS, I40E_INSET_IPV4_TOS}, 9317 {RTE_ETH_INPUT_SET_L3_IP4_PROTO, I40E_INSET_IPV4_PROTO}, 9318 {RTE_ETH_INPUT_SET_L3_IP4_TTL, I40E_INSET_IPV4_TTL}, 9319 {RTE_ETH_INPUT_SET_L3_SRC_IP6, I40E_INSET_IPV6_SRC}, 9320 {RTE_ETH_INPUT_SET_L3_DST_IP6, I40E_INSET_IPV6_DST}, 9321 {RTE_ETH_INPUT_SET_L3_IP6_TC, I40E_INSET_IPV6_TC}, 9322 {RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER, 9323 I40E_INSET_IPV6_NEXT_HDR}, 9324 {RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS, 9325 I40E_INSET_IPV6_HOP_LIMIT}, 9326 {RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT, I40E_INSET_SRC_PORT}, 9327 {RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT, I40E_INSET_SRC_PORT}, 9328 {RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT, I40E_INSET_SRC_PORT}, 9329 {RTE_ETH_INPUT_SET_L4_UDP_DST_PORT, I40E_INSET_DST_PORT}, 9330 {RTE_ETH_INPUT_SET_L4_TCP_DST_PORT, I40E_INSET_DST_PORT}, 9331 {RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT, I40E_INSET_DST_PORT}, 9332 {RTE_ETH_INPUT_SET_L4_SCTP_VERIFICATION_TAG, 9333 I40E_INSET_SCTP_VT}, 9334 {RTE_ETH_INPUT_SET_TUNNEL_L2_INNER_DST_MAC, 9335 I40E_INSET_TUNNEL_DMAC}, 9336 {RTE_ETH_INPUT_SET_TUNNEL_L2_INNER_VLAN, 9337 I40E_INSET_VLAN_TUNNEL}, 9338 {RTE_ETH_INPUT_SET_TUNNEL_L4_UDP_KEY, 9339 I40E_INSET_TUNNEL_ID}, 9340 {RTE_ETH_INPUT_SET_TUNNEL_GRE_KEY, I40E_INSET_TUNNEL_ID}, 9341 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_1ST_WORD, 9342 I40E_INSET_FLEX_PAYLOAD_W1}, 9343 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_2ND_WORD, 9344 I40E_INSET_FLEX_PAYLOAD_W2}, 9345 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_3RD_WORD, 9346 I40E_INSET_FLEX_PAYLOAD_W3}, 9347 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_4TH_WORD, 9348 I40E_INSET_FLEX_PAYLOAD_W4}, 9349 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_5TH_WORD, 9350 I40E_INSET_FLEX_PAYLOAD_W5}, 9351 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_6TH_WORD, 9352 I40E_INSET_FLEX_PAYLOAD_W6}, 9353 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_7TH_WORD, 9354 I40E_INSET_FLEX_PAYLOAD_W7}, 9355 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_8TH_WORD, 9356 I40E_INSET_FLEX_PAYLOAD_W8}, 9357 }; 9358 9359 if (!inset || !field || size > RTE_ETH_INSET_SIZE_MAX) 9360 return ret; 9361 9362 /* Only one item allowed for default or all */ 9363 if (size == 1) { 9364 if (field[0] == RTE_ETH_INPUT_SET_DEFAULT) { 9365 *inset = i40e_get_default_input_set(pctype); 9366 return 0; 9367 } else if (field[0] == RTE_ETH_INPUT_SET_NONE) { 9368 *inset = I40E_INSET_NONE; 9369 return 0; 9370 } 9371 } 9372 9373 for (i = 0, *inset = 0; i < size; i++) { 9374 for (j = 0; j < RTE_DIM(inset_convert_table); j++) { 9375 if (field[i] == inset_convert_table[j].field) { 9376 *inset |= inset_convert_table[j].inset; 9377 break; 9378 } 9379 } 9380 9381 /* It contains unsupported input set, return immediately */ 9382 if (j == RTE_DIM(inset_convert_table)) 9383 return ret; 9384 } 9385 9386 return 0; 9387 } 9388 9389 /** 9390 * Translate the input set from bit masks to register aware bit masks 9391 * and vice versa 9392 */ 9393 uint64_t 9394 i40e_translate_input_set_reg(enum i40e_mac_type type, uint64_t input) 9395 { 9396 uint64_t val = 0; 9397 uint16_t i; 9398 9399 struct inset_map { 9400 uint64_t inset; 9401 uint64_t inset_reg; 9402 }; 9403 9404 static const struct inset_map inset_map_common[] = { 9405 {I40E_INSET_DMAC, I40E_REG_INSET_L2_DMAC}, 9406 {I40E_INSET_SMAC, I40E_REG_INSET_L2_SMAC}, 9407 {I40E_INSET_VLAN_OUTER, I40E_REG_INSET_L2_OUTER_VLAN}, 9408 {I40E_INSET_VLAN_INNER, I40E_REG_INSET_L2_INNER_VLAN}, 9409 {I40E_INSET_LAST_ETHER_TYPE, I40E_REG_INSET_LAST_ETHER_TYPE}, 9410 {I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS}, 9411 {I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6}, 9412 {I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6}, 9413 {I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC}, 9414 {I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR}, 9415 {I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT}, 9416 {I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT}, 9417 {I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT}, 9418 {I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG}, 9419 {I40E_INSET_TUNNEL_ID, I40E_REG_INSET_TUNNEL_ID}, 9420 {I40E_INSET_TUNNEL_DMAC, 9421 I40E_REG_INSET_TUNNEL_L2_INNER_DST_MAC}, 9422 {I40E_INSET_TUNNEL_IPV4_DST, I40E_REG_INSET_TUNNEL_L3_DST_IP4}, 9423 {I40E_INSET_TUNNEL_IPV6_DST, I40E_REG_INSET_TUNNEL_L3_DST_IP6}, 9424 {I40E_INSET_TUNNEL_SRC_PORT, 9425 I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT}, 9426 {I40E_INSET_TUNNEL_DST_PORT, 9427 I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT}, 9428 {I40E_INSET_VLAN_TUNNEL, I40E_REG_INSET_TUNNEL_VLAN}, 9429 {I40E_INSET_FLEX_PAYLOAD_W1, I40E_REG_INSET_FLEX_PAYLOAD_WORD1}, 9430 {I40E_INSET_FLEX_PAYLOAD_W2, I40E_REG_INSET_FLEX_PAYLOAD_WORD2}, 9431 {I40E_INSET_FLEX_PAYLOAD_W3, I40E_REG_INSET_FLEX_PAYLOAD_WORD3}, 9432 {I40E_INSET_FLEX_PAYLOAD_W4, I40E_REG_INSET_FLEX_PAYLOAD_WORD4}, 9433 {I40E_INSET_FLEX_PAYLOAD_W5, I40E_REG_INSET_FLEX_PAYLOAD_WORD5}, 9434 {I40E_INSET_FLEX_PAYLOAD_W6, I40E_REG_INSET_FLEX_PAYLOAD_WORD6}, 9435 {I40E_INSET_FLEX_PAYLOAD_W7, I40E_REG_INSET_FLEX_PAYLOAD_WORD7}, 9436 {I40E_INSET_FLEX_PAYLOAD_W8, I40E_REG_INSET_FLEX_PAYLOAD_WORD8}, 9437 }; 9438 9439 /* some different registers map in x722*/ 9440 static const struct inset_map inset_map_diff_x722[] = { 9441 {I40E_INSET_IPV4_SRC, I40E_X722_REG_INSET_L3_SRC_IP4}, 9442 {I40E_INSET_IPV4_DST, I40E_X722_REG_INSET_L3_DST_IP4}, 9443 {I40E_INSET_IPV4_PROTO, I40E_X722_REG_INSET_L3_IP4_PROTO}, 9444 {I40E_INSET_IPV4_TTL, I40E_X722_REG_INSET_L3_IP4_TTL}, 9445 }; 9446 9447 static const struct inset_map inset_map_diff_not_x722[] = { 9448 {I40E_INSET_IPV4_SRC, I40E_REG_INSET_L3_SRC_IP4}, 9449 {I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4}, 9450 {I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO}, 9451 {I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL}, 9452 }; 9453 9454 if (input == 0) 9455 return val; 9456 9457 /* Translate input set to register aware inset */ 9458 if (type == I40E_MAC_X722) { 9459 for (i = 0; i < RTE_DIM(inset_map_diff_x722); i++) { 9460 if (input & inset_map_diff_x722[i].inset) 9461 val |= inset_map_diff_x722[i].inset_reg; 9462 } 9463 } else { 9464 for (i = 0; i < RTE_DIM(inset_map_diff_not_x722); i++) { 9465 if (input & inset_map_diff_not_x722[i].inset) 9466 val |= inset_map_diff_not_x722[i].inset_reg; 9467 } 9468 } 9469 9470 for (i = 0; i < RTE_DIM(inset_map_common); i++) { 9471 if (input & inset_map_common[i].inset) 9472 val |= inset_map_common[i].inset_reg; 9473 } 9474 9475 return val; 9476 } 9477 9478 int 9479 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem) 9480 { 9481 uint8_t i, idx = 0; 9482 uint64_t inset_need_mask = inset; 9483 9484 static const struct { 9485 uint64_t inset; 9486 uint32_t mask; 9487 } inset_mask_map[] = { 9488 {I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK}, 9489 {I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0}, 9490 {I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK}, 9491 {I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK}, 9492 {I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK}, 9493 {I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0}, 9494 {I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK}, 9495 {I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK}, 9496 }; 9497 9498 if (!inset || !mask || !nb_elem) 9499 return 0; 9500 9501 for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) { 9502 /* Clear the inset bit, if no MASK is required, 9503 * for example proto + ttl 9504 */ 9505 if ((inset & inset_mask_map[i].inset) == 9506 inset_mask_map[i].inset && inset_mask_map[i].mask == 0) 9507 inset_need_mask &= ~inset_mask_map[i].inset; 9508 if (!inset_need_mask) 9509 return 0; 9510 } 9511 for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) { 9512 if ((inset_need_mask & inset_mask_map[i].inset) == 9513 inset_mask_map[i].inset) { 9514 if (idx >= nb_elem) { 9515 PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks"); 9516 return -EINVAL; 9517 } 9518 mask[idx] = inset_mask_map[i].mask; 9519 idx++; 9520 } 9521 } 9522 9523 return idx; 9524 } 9525 9526 void 9527 i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val) 9528 { 9529 uint32_t reg = i40e_read_rx_ctl(hw, addr); 9530 9531 PMD_DRV_LOG(DEBUG, "[0x%08x] original: 0x%08x", addr, reg); 9532 if (reg != val) 9533 i40e_write_rx_ctl(hw, addr, val); 9534 PMD_DRV_LOG(DEBUG, "[0x%08x] after: 0x%08x", addr, 9535 (uint32_t)i40e_read_rx_ctl(hw, addr)); 9536 } 9537 9538 void 9539 i40e_check_write_global_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val) 9540 { 9541 uint32_t reg = i40e_read_rx_ctl(hw, addr); 9542 struct rte_eth_dev *dev; 9543 9544 dev = ((struct i40e_adapter *)hw->back)->eth_dev; 9545 if (reg != val) { 9546 i40e_write_rx_ctl(hw, addr, val); 9547 PMD_DRV_LOG(WARNING, 9548 "i40e device %s changed global register [0x%08x]." 9549 " original: 0x%08x, new: 0x%08x", 9550 dev->device->name, addr, reg, 9551 (uint32_t)i40e_read_rx_ctl(hw, addr)); 9552 } 9553 } 9554 9555 static void 9556 i40e_filter_input_set_init(struct i40e_pf *pf) 9557 { 9558 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 9559 enum i40e_filter_pctype pctype; 9560 uint64_t input_set, inset_reg; 9561 uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0}; 9562 int num, i; 9563 uint16_t flow_type; 9564 9565 for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP; 9566 pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) { 9567 flow_type = i40e_pctype_to_flowtype(pf->adapter, pctype); 9568 9569 if (flow_type == RTE_ETH_FLOW_UNKNOWN) 9570 continue; 9571 9572 input_set = i40e_get_default_input_set(pctype); 9573 9574 num = i40e_generate_inset_mask_reg(input_set, mask_reg, 9575 I40E_INSET_MASK_NUM_REG); 9576 if (num < 0) 9577 return; 9578 if (pf->support_multi_driver && num > 0) { 9579 PMD_DRV_LOG(ERR, "Input set setting is not supported."); 9580 return; 9581 } 9582 inset_reg = i40e_translate_input_set_reg(hw->mac.type, 9583 input_set); 9584 9585 i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0), 9586 (uint32_t)(inset_reg & UINT32_MAX)); 9587 i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1), 9588 (uint32_t)((inset_reg >> 9589 I40E_32_BIT_WIDTH) & UINT32_MAX)); 9590 if (!pf->support_multi_driver) { 9591 i40e_check_write_global_reg(hw, 9592 I40E_GLQF_HASH_INSET(0, pctype), 9593 (uint32_t)(inset_reg & UINT32_MAX)); 9594 i40e_check_write_global_reg(hw, 9595 I40E_GLQF_HASH_INSET(1, pctype), 9596 (uint32_t)((inset_reg >> 9597 I40E_32_BIT_WIDTH) & UINT32_MAX)); 9598 9599 for (i = 0; i < num; i++) { 9600 i40e_check_write_global_reg(hw, 9601 I40E_GLQF_FD_MSK(i, pctype), 9602 mask_reg[i]); 9603 i40e_check_write_global_reg(hw, 9604 I40E_GLQF_HASH_MSK(i, pctype), 9605 mask_reg[i]); 9606 } 9607 /*clear unused mask registers of the pctype */ 9608 for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) { 9609 i40e_check_write_global_reg(hw, 9610 I40E_GLQF_FD_MSK(i, pctype), 9611 0); 9612 i40e_check_write_global_reg(hw, 9613 I40E_GLQF_HASH_MSK(i, pctype), 9614 0); 9615 } 9616 } else { 9617 PMD_DRV_LOG(ERR, "Input set setting is not supported."); 9618 } 9619 I40E_WRITE_FLUSH(hw); 9620 9621 /* store the default input set */ 9622 if (!pf->support_multi_driver) 9623 pf->hash_input_set[pctype] = input_set; 9624 pf->fdir.input_set[pctype] = input_set; 9625 } 9626 } 9627 9628 int 9629 i40e_hash_filter_inset_select(struct i40e_hw *hw, 9630 struct rte_eth_input_set_conf *conf) 9631 { 9632 struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf; 9633 enum i40e_filter_pctype pctype; 9634 uint64_t input_set, inset_reg = 0; 9635 uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0}; 9636 int ret, i, num; 9637 9638 if (!conf) { 9639 PMD_DRV_LOG(ERR, "Invalid pointer"); 9640 return -EFAULT; 9641 } 9642 if (conf->op != RTE_ETH_INPUT_SET_SELECT && 9643 conf->op != RTE_ETH_INPUT_SET_ADD) { 9644 PMD_DRV_LOG(ERR, "Unsupported input set operation"); 9645 return -EINVAL; 9646 } 9647 9648 if (pf->support_multi_driver) { 9649 PMD_DRV_LOG(ERR, "Hash input set setting is not supported."); 9650 return -ENOTSUP; 9651 } 9652 9653 pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type); 9654 if (pctype == I40E_FILTER_PCTYPE_INVALID) { 9655 PMD_DRV_LOG(ERR, "invalid flow_type input."); 9656 return -EINVAL; 9657 } 9658 9659 if (hw->mac.type == I40E_MAC_X722) { 9660 /* get translated pctype value in fd pctype register */ 9661 pctype = (enum i40e_filter_pctype)i40e_read_rx_ctl(hw, 9662 I40E_GLQF_FD_PCTYPES((int)pctype)); 9663 } 9664 9665 ret = i40e_parse_input_set(&input_set, pctype, conf->field, 9666 conf->inset_size); 9667 if (ret) { 9668 PMD_DRV_LOG(ERR, "Failed to parse input set"); 9669 return -EINVAL; 9670 } 9671 9672 if (conf->op == RTE_ETH_INPUT_SET_ADD) { 9673 /* get inset value in register */ 9674 inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype)); 9675 inset_reg <<= I40E_32_BIT_WIDTH; 9676 inset_reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype)); 9677 input_set |= pf->hash_input_set[pctype]; 9678 } 9679 num = i40e_generate_inset_mask_reg(input_set, mask_reg, 9680 I40E_INSET_MASK_NUM_REG); 9681 if (num < 0) 9682 return -EINVAL; 9683 9684 inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set); 9685 9686 i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(0, pctype), 9687 (uint32_t)(inset_reg & UINT32_MAX)); 9688 i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(1, pctype), 9689 (uint32_t)((inset_reg >> 9690 I40E_32_BIT_WIDTH) & UINT32_MAX)); 9691 9692 for (i = 0; i < num; i++) 9693 i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype), 9694 mask_reg[i]); 9695 /*clear unused mask registers of the pctype */ 9696 for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) 9697 i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype), 9698 0); 9699 I40E_WRITE_FLUSH(hw); 9700 9701 pf->hash_input_set[pctype] = input_set; 9702 return 0; 9703 } 9704 9705 int 9706 i40e_fdir_filter_inset_select(struct i40e_pf *pf, 9707 struct rte_eth_input_set_conf *conf) 9708 { 9709 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 9710 enum i40e_filter_pctype pctype; 9711 uint64_t input_set, inset_reg = 0; 9712 uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0}; 9713 int ret, i, num; 9714 9715 if (!hw || !conf) { 9716 PMD_DRV_LOG(ERR, "Invalid pointer"); 9717 return -EFAULT; 9718 } 9719 if (conf->op != RTE_ETH_INPUT_SET_SELECT && 9720 conf->op != RTE_ETH_INPUT_SET_ADD) { 9721 PMD_DRV_LOG(ERR, "Unsupported input set operation"); 9722 return -EINVAL; 9723 } 9724 9725 pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type); 9726 9727 if (pctype == I40E_FILTER_PCTYPE_INVALID) { 9728 PMD_DRV_LOG(ERR, "invalid flow_type input."); 9729 return -EINVAL; 9730 } 9731 9732 ret = i40e_parse_input_set(&input_set, pctype, conf->field, 9733 conf->inset_size); 9734 if (ret) { 9735 PMD_DRV_LOG(ERR, "Failed to parse input set"); 9736 return -EINVAL; 9737 } 9738 9739 /* get inset value in register */ 9740 inset_reg = i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1)); 9741 inset_reg <<= I40E_32_BIT_WIDTH; 9742 inset_reg |= i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0)); 9743 9744 /* Can not change the inset reg for flex payload for fdir, 9745 * it is done by writing I40E_PRTQF_FD_FLXINSET 9746 * in i40e_set_flex_mask_on_pctype. 9747 */ 9748 if (conf->op == RTE_ETH_INPUT_SET_SELECT) 9749 inset_reg &= I40E_REG_INSET_FLEX_PAYLOAD_WORDS; 9750 else 9751 input_set |= pf->fdir.input_set[pctype]; 9752 num = i40e_generate_inset_mask_reg(input_set, mask_reg, 9753 I40E_INSET_MASK_NUM_REG); 9754 if (num < 0) 9755 return -EINVAL; 9756 if (pf->support_multi_driver && num > 0) { 9757 PMD_DRV_LOG(ERR, "FDIR bit mask is not supported."); 9758 return -ENOTSUP; 9759 } 9760 9761 inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set); 9762 9763 i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0), 9764 (uint32_t)(inset_reg & UINT32_MAX)); 9765 i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1), 9766 (uint32_t)((inset_reg >> 9767 I40E_32_BIT_WIDTH) & UINT32_MAX)); 9768 9769 if (!pf->support_multi_driver) { 9770 for (i = 0; i < num; i++) 9771 i40e_check_write_global_reg(hw, 9772 I40E_GLQF_FD_MSK(i, pctype), 9773 mask_reg[i]); 9774 /*clear unused mask registers of the pctype */ 9775 for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) 9776 i40e_check_write_global_reg(hw, 9777 I40E_GLQF_FD_MSK(i, pctype), 9778 0); 9779 } else { 9780 PMD_DRV_LOG(ERR, "FDIR bit mask is not supported."); 9781 } 9782 I40E_WRITE_FLUSH(hw); 9783 9784 pf->fdir.input_set[pctype] = input_set; 9785 return 0; 9786 } 9787 9788 static int 9789 i40e_hash_filter_get(struct i40e_hw *hw, struct rte_eth_hash_filter_info *info) 9790 { 9791 int ret = 0; 9792 9793 if (!hw || !info) { 9794 PMD_DRV_LOG(ERR, "Invalid pointer"); 9795 return -EFAULT; 9796 } 9797 9798 switch (info->info_type) { 9799 case RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT: 9800 i40e_get_symmetric_hash_enable_per_port(hw, 9801 &(info->info.enable)); 9802 break; 9803 case RTE_ETH_HASH_FILTER_GLOBAL_CONFIG: 9804 ret = i40e_get_hash_filter_global_config(hw, 9805 &(info->info.global_conf)); 9806 break; 9807 default: 9808 PMD_DRV_LOG(ERR, "Hash filter info type (%d) not supported", 9809 info->info_type); 9810 ret = -EINVAL; 9811 break; 9812 } 9813 9814 return ret; 9815 } 9816 9817 static int 9818 i40e_hash_filter_set(struct i40e_hw *hw, struct rte_eth_hash_filter_info *info) 9819 { 9820 int ret = 0; 9821 9822 if (!hw || !info) { 9823 PMD_DRV_LOG(ERR, "Invalid pointer"); 9824 return -EFAULT; 9825 } 9826 9827 switch (info->info_type) { 9828 case RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT: 9829 i40e_set_symmetric_hash_enable_per_port(hw, info->info.enable); 9830 break; 9831 case RTE_ETH_HASH_FILTER_GLOBAL_CONFIG: 9832 ret = i40e_set_hash_filter_global_config(hw, 9833 &(info->info.global_conf)); 9834 break; 9835 case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT: 9836 ret = i40e_hash_filter_inset_select(hw, 9837 &(info->info.input_set_conf)); 9838 break; 9839 9840 default: 9841 PMD_DRV_LOG(ERR, "Hash filter info type (%d) not supported", 9842 info->info_type); 9843 ret = -EINVAL; 9844 break; 9845 } 9846 9847 return ret; 9848 } 9849 9850 /* Operations for hash function */ 9851 static int 9852 i40e_hash_filter_ctrl(struct rte_eth_dev *dev, 9853 enum rte_filter_op filter_op, 9854 void *arg) 9855 { 9856 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 9857 int ret = 0; 9858 9859 switch (filter_op) { 9860 case RTE_ETH_FILTER_NOP: 9861 break; 9862 case RTE_ETH_FILTER_GET: 9863 ret = i40e_hash_filter_get(hw, 9864 (struct rte_eth_hash_filter_info *)arg); 9865 break; 9866 case RTE_ETH_FILTER_SET: 9867 ret = i40e_hash_filter_set(hw, 9868 (struct rte_eth_hash_filter_info *)arg); 9869 break; 9870 default: 9871 PMD_DRV_LOG(WARNING, "Filter operation (%d) not supported", 9872 filter_op); 9873 ret = -ENOTSUP; 9874 break; 9875 } 9876 9877 return ret; 9878 } 9879 9880 /* Convert ethertype filter structure */ 9881 static int 9882 i40e_ethertype_filter_convert(const struct rte_eth_ethertype_filter *input, 9883 struct i40e_ethertype_filter *filter) 9884 { 9885 rte_memcpy(&filter->input.mac_addr, &input->mac_addr, ETHER_ADDR_LEN); 9886 filter->input.ether_type = input->ether_type; 9887 filter->flags = input->flags; 9888 filter->queue = input->queue; 9889 9890 return 0; 9891 } 9892 9893 /* Check if there exists the ehtertype filter */ 9894 struct i40e_ethertype_filter * 9895 i40e_sw_ethertype_filter_lookup(struct i40e_ethertype_rule *ethertype_rule, 9896 const struct i40e_ethertype_filter_input *input) 9897 { 9898 int ret; 9899 9900 ret = rte_hash_lookup(ethertype_rule->hash_table, (const void *)input); 9901 if (ret < 0) 9902 return NULL; 9903 9904 return ethertype_rule->hash_map[ret]; 9905 } 9906 9907 /* Add ethertype filter in SW list */ 9908 static int 9909 i40e_sw_ethertype_filter_insert(struct i40e_pf *pf, 9910 struct i40e_ethertype_filter *filter) 9911 { 9912 struct i40e_ethertype_rule *rule = &pf->ethertype; 9913 int ret; 9914 9915 ret = rte_hash_add_key(rule->hash_table, &filter->input); 9916 if (ret < 0) { 9917 PMD_DRV_LOG(ERR, 9918 "Failed to insert ethertype filter" 9919 " to hash table %d!", 9920 ret); 9921 return ret; 9922 } 9923 rule->hash_map[ret] = filter; 9924 9925 TAILQ_INSERT_TAIL(&rule->ethertype_list, filter, rules); 9926 9927 return 0; 9928 } 9929 9930 /* Delete ethertype filter in SW list */ 9931 int 9932 i40e_sw_ethertype_filter_del(struct i40e_pf *pf, 9933 struct i40e_ethertype_filter_input *input) 9934 { 9935 struct i40e_ethertype_rule *rule = &pf->ethertype; 9936 struct i40e_ethertype_filter *filter; 9937 int ret; 9938 9939 ret = rte_hash_del_key(rule->hash_table, input); 9940 if (ret < 0) { 9941 PMD_DRV_LOG(ERR, 9942 "Failed to delete ethertype filter" 9943 " to hash table %d!", 9944 ret); 9945 return ret; 9946 } 9947 filter = rule->hash_map[ret]; 9948 rule->hash_map[ret] = NULL; 9949 9950 TAILQ_REMOVE(&rule->ethertype_list, filter, rules); 9951 rte_free(filter); 9952 9953 return 0; 9954 } 9955 9956 /* 9957 * Configure ethertype filter, which can director packet by filtering 9958 * with mac address and ether_type or only ether_type 9959 */ 9960 int 9961 i40e_ethertype_filter_set(struct i40e_pf *pf, 9962 struct rte_eth_ethertype_filter *filter, 9963 bool add) 9964 { 9965 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 9966 struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype; 9967 struct i40e_ethertype_filter *ethertype_filter, *node; 9968 struct i40e_ethertype_filter check_filter; 9969 struct i40e_control_filter_stats stats; 9970 uint16_t flags = 0; 9971 int ret; 9972 9973 if (filter->queue >= pf->dev_data->nb_rx_queues) { 9974 PMD_DRV_LOG(ERR, "Invalid queue ID"); 9975 return -EINVAL; 9976 } 9977 if (filter->ether_type == ETHER_TYPE_IPv4 || 9978 filter->ether_type == ETHER_TYPE_IPv6) { 9979 PMD_DRV_LOG(ERR, 9980 "unsupported ether_type(0x%04x) in control packet filter.", 9981 filter->ether_type); 9982 return -EINVAL; 9983 } 9984 if (filter->ether_type == ETHER_TYPE_VLAN) 9985 PMD_DRV_LOG(WARNING, 9986 "filter vlan ether_type in first tag is not supported."); 9987 9988 /* Check if there is the filter in SW list */ 9989 memset(&check_filter, 0, sizeof(check_filter)); 9990 i40e_ethertype_filter_convert(filter, &check_filter); 9991 node = i40e_sw_ethertype_filter_lookup(ethertype_rule, 9992 &check_filter.input); 9993 if (add && node) { 9994 PMD_DRV_LOG(ERR, "Conflict with existing ethertype rules!"); 9995 return -EINVAL; 9996 } 9997 9998 if (!add && !node) { 9999 PMD_DRV_LOG(ERR, "There's no corresponding ethertype filter!"); 10000 return -EINVAL; 10001 } 10002 10003 if (!(filter->flags & RTE_ETHTYPE_FLAGS_MAC)) 10004 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC; 10005 if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) 10006 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP; 10007 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE; 10008 10009 memset(&stats, 0, sizeof(stats)); 10010 ret = i40e_aq_add_rem_control_packet_filter(hw, 10011 filter->mac_addr.addr_bytes, 10012 filter->ether_type, flags, 10013 pf->main_vsi->seid, 10014 filter->queue, add, &stats, NULL); 10015 10016 PMD_DRV_LOG(INFO, 10017 "add/rem control packet filter, return %d, mac_etype_used = %u, etype_used = %u, mac_etype_free = %u, etype_free = %u", 10018 ret, stats.mac_etype_used, stats.etype_used, 10019 stats.mac_etype_free, stats.etype_free); 10020 if (ret < 0) 10021 return -ENOSYS; 10022 10023 /* Add or delete a filter in SW list */ 10024 if (add) { 10025 ethertype_filter = rte_zmalloc("ethertype_filter", 10026 sizeof(*ethertype_filter), 0); 10027 if (ethertype_filter == NULL) { 10028 PMD_DRV_LOG(ERR, "Failed to alloc memory."); 10029 return -ENOMEM; 10030 } 10031 10032 rte_memcpy(ethertype_filter, &check_filter, 10033 sizeof(check_filter)); 10034 ret = i40e_sw_ethertype_filter_insert(pf, ethertype_filter); 10035 if (ret < 0) 10036 rte_free(ethertype_filter); 10037 } else { 10038 ret = i40e_sw_ethertype_filter_del(pf, &node->input); 10039 } 10040 10041 return ret; 10042 } 10043 10044 /* 10045 * Handle operations for ethertype filter. 10046 */ 10047 static int 10048 i40e_ethertype_filter_handle(struct rte_eth_dev *dev, 10049 enum rte_filter_op filter_op, 10050 void *arg) 10051 { 10052 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 10053 int ret = 0; 10054 10055 if (filter_op == RTE_ETH_FILTER_NOP) 10056 return ret; 10057 10058 if (arg == NULL) { 10059 PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u", 10060 filter_op); 10061 return -EINVAL; 10062 } 10063 10064 switch (filter_op) { 10065 case RTE_ETH_FILTER_ADD: 10066 ret = i40e_ethertype_filter_set(pf, 10067 (struct rte_eth_ethertype_filter *)arg, 10068 TRUE); 10069 break; 10070 case RTE_ETH_FILTER_DELETE: 10071 ret = i40e_ethertype_filter_set(pf, 10072 (struct rte_eth_ethertype_filter *)arg, 10073 FALSE); 10074 break; 10075 default: 10076 PMD_DRV_LOG(ERR, "unsupported operation %u", filter_op); 10077 ret = -ENOSYS; 10078 break; 10079 } 10080 return ret; 10081 } 10082 10083 static int 10084 i40e_dev_filter_ctrl(struct rte_eth_dev *dev, 10085 enum rte_filter_type filter_type, 10086 enum rte_filter_op filter_op, 10087 void *arg) 10088 { 10089 int ret = 0; 10090 10091 if (dev == NULL) 10092 return -EINVAL; 10093 10094 switch (filter_type) { 10095 case RTE_ETH_FILTER_NONE: 10096 /* For global configuration */ 10097 ret = i40e_filter_ctrl_global_config(dev, filter_op, arg); 10098 break; 10099 case RTE_ETH_FILTER_HASH: 10100 ret = i40e_hash_filter_ctrl(dev, filter_op, arg); 10101 break; 10102 case RTE_ETH_FILTER_MACVLAN: 10103 ret = i40e_mac_filter_handle(dev, filter_op, arg); 10104 break; 10105 case RTE_ETH_FILTER_ETHERTYPE: 10106 ret = i40e_ethertype_filter_handle(dev, filter_op, arg); 10107 break; 10108 case RTE_ETH_FILTER_TUNNEL: 10109 ret = i40e_tunnel_filter_handle(dev, filter_op, arg); 10110 break; 10111 case RTE_ETH_FILTER_FDIR: 10112 ret = i40e_fdir_ctrl_func(dev, filter_op, arg); 10113 break; 10114 case RTE_ETH_FILTER_GENERIC: 10115 if (filter_op != RTE_ETH_FILTER_GET) 10116 return -EINVAL; 10117 *(const void **)arg = &i40e_flow_ops; 10118 break; 10119 default: 10120 PMD_DRV_LOG(WARNING, "Filter type (%d) not supported", 10121 filter_type); 10122 ret = -EINVAL; 10123 break; 10124 } 10125 10126 return ret; 10127 } 10128 10129 /* 10130 * Check and enable Extended Tag. 10131 * Enabling Extended Tag is important for 40G performance. 10132 */ 10133 static void 10134 i40e_enable_extended_tag(struct rte_eth_dev *dev) 10135 { 10136 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 10137 uint32_t buf = 0; 10138 int ret; 10139 10140 ret = rte_pci_read_config(pci_dev, &buf, sizeof(buf), 10141 PCI_DEV_CAP_REG); 10142 if (ret < 0) { 10143 PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x", 10144 PCI_DEV_CAP_REG); 10145 return; 10146 } 10147 if (!(buf & PCI_DEV_CAP_EXT_TAG_MASK)) { 10148 PMD_DRV_LOG(ERR, "Does not support Extended Tag"); 10149 return; 10150 } 10151 10152 buf = 0; 10153 ret = rte_pci_read_config(pci_dev, &buf, sizeof(buf), 10154 PCI_DEV_CTRL_REG); 10155 if (ret < 0) { 10156 PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x", 10157 PCI_DEV_CTRL_REG); 10158 return; 10159 } 10160 if (buf & PCI_DEV_CTRL_EXT_TAG_MASK) { 10161 PMD_DRV_LOG(DEBUG, "Extended Tag has already been enabled"); 10162 return; 10163 } 10164 buf |= PCI_DEV_CTRL_EXT_TAG_MASK; 10165 ret = rte_pci_write_config(pci_dev, &buf, sizeof(buf), 10166 PCI_DEV_CTRL_REG); 10167 if (ret < 0) { 10168 PMD_DRV_LOG(ERR, "Failed to write PCI offset 0x%x", 10169 PCI_DEV_CTRL_REG); 10170 return; 10171 } 10172 } 10173 10174 /* 10175 * As some registers wouldn't be reset unless a global hardware reset, 10176 * hardware initialization is needed to put those registers into an 10177 * expected initial state. 10178 */ 10179 static void 10180 i40e_hw_init(struct rte_eth_dev *dev) 10181 { 10182 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10183 10184 i40e_enable_extended_tag(dev); 10185 10186 /* clear the PF Queue Filter control register */ 10187 i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, 0); 10188 10189 /* Disable symmetric hash per port */ 10190 i40e_set_symmetric_hash_enable_per_port(hw, 0); 10191 } 10192 10193 /* 10194 * For X722 it is possible to have multiple pctypes mapped to the same flowtype 10195 * however this function will return only one highest pctype index, 10196 * which is not quite correct. This is known problem of i40e driver 10197 * and needs to be fixed later. 10198 */ 10199 enum i40e_filter_pctype 10200 i40e_flowtype_to_pctype(const struct i40e_adapter *adapter, uint16_t flow_type) 10201 { 10202 int i; 10203 uint64_t pctype_mask; 10204 10205 if (flow_type < I40E_FLOW_TYPE_MAX) { 10206 pctype_mask = adapter->pctypes_tbl[flow_type]; 10207 for (i = I40E_FILTER_PCTYPE_MAX - 1; i > 0; i--) { 10208 if (pctype_mask & (1ULL << i)) 10209 return (enum i40e_filter_pctype)i; 10210 } 10211 } 10212 return I40E_FILTER_PCTYPE_INVALID; 10213 } 10214 10215 uint16_t 10216 i40e_pctype_to_flowtype(const struct i40e_adapter *adapter, 10217 enum i40e_filter_pctype pctype) 10218 { 10219 uint16_t flowtype; 10220 uint64_t pctype_mask = 1ULL << pctype; 10221 10222 for (flowtype = RTE_ETH_FLOW_UNKNOWN + 1; flowtype < I40E_FLOW_TYPE_MAX; 10223 flowtype++) { 10224 if (adapter->pctypes_tbl[flowtype] & pctype_mask) 10225 return flowtype; 10226 } 10227 10228 return RTE_ETH_FLOW_UNKNOWN; 10229 } 10230 10231 /* 10232 * On X710, performance number is far from the expectation on recent firmware 10233 * versions; on XL710, performance number is also far from the expectation on 10234 * recent firmware versions, if promiscuous mode is disabled, or promiscuous 10235 * mode is enabled and port MAC address is equal to the packet destination MAC 10236 * address. The fix for this issue may not be integrated in the following 10237 * firmware version. So the workaround in software driver is needed. It needs 10238 * to modify the initial values of 3 internal only registers for both X710 and 10239 * XL710. Note that the values for X710 or XL710 could be different, and the 10240 * workaround can be removed when it is fixed in firmware in the future. 10241 */ 10242 10243 /* For both X710 and XL710 */ 10244 #define I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_1 0x10000200 10245 #define I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_2 0x203F0200 10246 #define I40E_GL_SWR_PRI_JOIN_MAP_0 0x26CE00 10247 10248 #define I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE 0x011f0200 10249 #define I40E_GL_SWR_PRI_JOIN_MAP_2 0x26CE08 10250 10251 /* For X722 */ 10252 #define I40E_X722_GL_SWR_PRI_JOIN_MAP_0_VALUE 0x20000200 10253 #define I40E_X722_GL_SWR_PRI_JOIN_MAP_2_VALUE 0x013F0200 10254 10255 /* For X710 */ 10256 #define I40E_GL_SWR_PM_UP_THR_EF_VALUE 0x03030303 10257 /* For XL710 */ 10258 #define I40E_GL_SWR_PM_UP_THR_SF_VALUE 0x06060606 10259 #define I40E_GL_SWR_PM_UP_THR 0x269FBC 10260 10261 /* 10262 * GL_SWR_PM_UP_THR: 10263 * The value is not impacted from the link speed, its value is set according 10264 * to the total number of ports for a better pipe-monitor configuration. 10265 */ 10266 static bool 10267 i40e_get_swr_pm_cfg(struct i40e_hw *hw, uint32_t *value) 10268 { 10269 #define I40E_GL_SWR_PM_EF_DEVICE(dev) \ 10270 .device_id = (dev), \ 10271 .val = I40E_GL_SWR_PM_UP_THR_EF_VALUE 10272 10273 #define I40E_GL_SWR_PM_SF_DEVICE(dev) \ 10274 .device_id = (dev), \ 10275 .val = I40E_GL_SWR_PM_UP_THR_SF_VALUE 10276 10277 static const struct { 10278 uint16_t device_id; 10279 uint32_t val; 10280 } swr_pm_table[] = { 10281 { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_SFP_XL710) }, 10282 { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_KX_C) }, 10283 { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T) }, 10284 { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T4) }, 10285 10286 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_KX_B) }, 10287 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_A) }, 10288 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_B) }, 10289 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_20G_KR2) }, 10290 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_20G_KR2_A) }, 10291 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_25G_B) }, 10292 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_25G_SFP28) }, 10293 }; 10294 uint32_t i; 10295 10296 if (value == NULL) { 10297 PMD_DRV_LOG(ERR, "value is NULL"); 10298 return false; 10299 } 10300 10301 for (i = 0; i < RTE_DIM(swr_pm_table); i++) { 10302 if (hw->device_id == swr_pm_table[i].device_id) { 10303 *value = swr_pm_table[i].val; 10304 10305 PMD_DRV_LOG(DEBUG, "Device 0x%x with GL_SWR_PM_UP_THR " 10306 "value - 0x%08x", 10307 hw->device_id, *value); 10308 return true; 10309 } 10310 } 10311 10312 return false; 10313 } 10314 10315 static int 10316 i40e_dev_sync_phy_type(struct i40e_hw *hw) 10317 { 10318 enum i40e_status_code status; 10319 struct i40e_aq_get_phy_abilities_resp phy_ab; 10320 int ret = -ENOTSUP; 10321 int retries = 0; 10322 10323 status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_ab, 10324 NULL); 10325 10326 while (status) { 10327 PMD_INIT_LOG(WARNING, "Failed to sync phy type: status=%d", 10328 status); 10329 retries++; 10330 rte_delay_us(100000); 10331 if (retries < 5) 10332 status = i40e_aq_get_phy_capabilities(hw, false, 10333 true, &phy_ab, NULL); 10334 else 10335 return ret; 10336 } 10337 return 0; 10338 } 10339 10340 static void 10341 i40e_configure_registers(struct i40e_hw *hw) 10342 { 10343 static struct { 10344 uint32_t addr; 10345 uint64_t val; 10346 } reg_table[] = { 10347 {I40E_GL_SWR_PRI_JOIN_MAP_0, 0}, 10348 {I40E_GL_SWR_PRI_JOIN_MAP_2, 0}, 10349 {I40E_GL_SWR_PM_UP_THR, 0}, /* Compute value dynamically */ 10350 }; 10351 uint64_t reg; 10352 uint32_t i; 10353 int ret; 10354 10355 for (i = 0; i < RTE_DIM(reg_table); i++) { 10356 if (reg_table[i].addr == I40E_GL_SWR_PRI_JOIN_MAP_0) { 10357 if (hw->mac.type == I40E_MAC_X722) /* For X722 */ 10358 reg_table[i].val = 10359 I40E_X722_GL_SWR_PRI_JOIN_MAP_0_VALUE; 10360 else /* For X710/XL710/XXV710 */ 10361 if (hw->aq.fw_maj_ver < 6) 10362 reg_table[i].val = 10363 I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_1; 10364 else 10365 reg_table[i].val = 10366 I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_2; 10367 } 10368 10369 if (reg_table[i].addr == I40E_GL_SWR_PRI_JOIN_MAP_2) { 10370 if (hw->mac.type == I40E_MAC_X722) /* For X722 */ 10371 reg_table[i].val = 10372 I40E_X722_GL_SWR_PRI_JOIN_MAP_2_VALUE; 10373 else /* For X710/XL710/XXV710 */ 10374 reg_table[i].val = 10375 I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE; 10376 } 10377 10378 if (reg_table[i].addr == I40E_GL_SWR_PM_UP_THR) { 10379 uint32_t cfg_val; 10380 10381 if (!i40e_get_swr_pm_cfg(hw, &cfg_val)) { 10382 PMD_DRV_LOG(DEBUG, "Device 0x%x skips " 10383 "GL_SWR_PM_UP_THR value fixup", 10384 hw->device_id); 10385 continue; 10386 } 10387 10388 reg_table[i].val = cfg_val; 10389 } 10390 10391 ret = i40e_aq_debug_read_register(hw, reg_table[i].addr, 10392 ®, NULL); 10393 if (ret < 0) { 10394 PMD_DRV_LOG(ERR, "Failed to read from 0x%"PRIx32, 10395 reg_table[i].addr); 10396 break; 10397 } 10398 PMD_DRV_LOG(DEBUG, "Read from 0x%"PRIx32": 0x%"PRIx64, 10399 reg_table[i].addr, reg); 10400 if (reg == reg_table[i].val) 10401 continue; 10402 10403 ret = i40e_aq_debug_write_register(hw, reg_table[i].addr, 10404 reg_table[i].val, NULL); 10405 if (ret < 0) { 10406 PMD_DRV_LOG(ERR, 10407 "Failed to write 0x%"PRIx64" to the address of 0x%"PRIx32, 10408 reg_table[i].val, reg_table[i].addr); 10409 break; 10410 } 10411 PMD_DRV_LOG(DEBUG, "Write 0x%"PRIx64" to the address of " 10412 "0x%"PRIx32, reg_table[i].val, reg_table[i].addr); 10413 } 10414 } 10415 10416 #define I40E_VSI_TSR(_i) (0x00050800 + ((_i) * 4)) 10417 #define I40E_VSI_TSR_QINQ_CONFIG 0xc030 10418 #define I40E_VSI_L2TAGSTXVALID(_i) (0x00042800 + ((_i) * 4)) 10419 #define I40E_VSI_L2TAGSTXVALID_QINQ 0xab 10420 static int 10421 i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi) 10422 { 10423 uint32_t reg; 10424 int ret; 10425 10426 if (vsi->vsi_id >= I40E_MAX_NUM_VSIS) { 10427 PMD_DRV_LOG(ERR, "VSI ID exceeds the maximum"); 10428 return -EINVAL; 10429 } 10430 10431 /* Configure for double VLAN RX stripping */ 10432 reg = I40E_READ_REG(hw, I40E_VSI_TSR(vsi->vsi_id)); 10433 if ((reg & I40E_VSI_TSR_QINQ_CONFIG) != I40E_VSI_TSR_QINQ_CONFIG) { 10434 reg |= I40E_VSI_TSR_QINQ_CONFIG; 10435 ret = i40e_aq_debug_write_register(hw, 10436 I40E_VSI_TSR(vsi->vsi_id), 10437 reg, NULL); 10438 if (ret < 0) { 10439 PMD_DRV_LOG(ERR, "Failed to update VSI_TSR[%d]", 10440 vsi->vsi_id); 10441 return I40E_ERR_CONFIG; 10442 } 10443 } 10444 10445 /* Configure for double VLAN TX insertion */ 10446 reg = I40E_READ_REG(hw, I40E_VSI_L2TAGSTXVALID(vsi->vsi_id)); 10447 if ((reg & 0xff) != I40E_VSI_L2TAGSTXVALID_QINQ) { 10448 reg = I40E_VSI_L2TAGSTXVALID_QINQ; 10449 ret = i40e_aq_debug_write_register(hw, 10450 I40E_VSI_L2TAGSTXVALID( 10451 vsi->vsi_id), reg, NULL); 10452 if (ret < 0) { 10453 PMD_DRV_LOG(ERR, 10454 "Failed to update VSI_L2TAGSTXVALID[%d]", 10455 vsi->vsi_id); 10456 return I40E_ERR_CONFIG; 10457 } 10458 } 10459 10460 return 0; 10461 } 10462 10463 /** 10464 * i40e_aq_add_mirror_rule 10465 * @hw: pointer to the hardware structure 10466 * @seid: VEB seid to add mirror rule to 10467 * @dst_id: destination vsi seid 10468 * @entries: Buffer which contains the entities to be mirrored 10469 * @count: number of entities contained in the buffer 10470 * @rule_id:the rule_id of the rule to be added 10471 * 10472 * Add a mirror rule for a given veb. 10473 * 10474 **/ 10475 static enum i40e_status_code 10476 i40e_aq_add_mirror_rule(struct i40e_hw *hw, 10477 uint16_t seid, uint16_t dst_id, 10478 uint16_t rule_type, uint16_t *entries, 10479 uint16_t count, uint16_t *rule_id) 10480 { 10481 struct i40e_aq_desc desc; 10482 struct i40e_aqc_add_delete_mirror_rule cmd; 10483 struct i40e_aqc_add_delete_mirror_rule_completion *resp = 10484 (struct i40e_aqc_add_delete_mirror_rule_completion *) 10485 &desc.params.raw; 10486 uint16_t buff_len; 10487 enum i40e_status_code status; 10488 10489 i40e_fill_default_direct_cmd_desc(&desc, 10490 i40e_aqc_opc_add_mirror_rule); 10491 memset(&cmd, 0, sizeof(cmd)); 10492 10493 buff_len = sizeof(uint16_t) * count; 10494 desc.datalen = rte_cpu_to_le_16(buff_len); 10495 if (buff_len > 0) 10496 desc.flags |= rte_cpu_to_le_16( 10497 (uint16_t)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); 10498 cmd.rule_type = rte_cpu_to_le_16(rule_type << 10499 I40E_AQC_MIRROR_RULE_TYPE_SHIFT); 10500 cmd.num_entries = rte_cpu_to_le_16(count); 10501 cmd.seid = rte_cpu_to_le_16(seid); 10502 cmd.destination = rte_cpu_to_le_16(dst_id); 10503 10504 rte_memcpy(&desc.params.raw, &cmd, sizeof(cmd)); 10505 status = i40e_asq_send_command(hw, &desc, entries, buff_len, NULL); 10506 PMD_DRV_LOG(INFO, 10507 "i40e_aq_add_mirror_rule, aq_status %d, rule_id = %u mirror_rules_used = %u, mirror_rules_free = %u,", 10508 hw->aq.asq_last_status, resp->rule_id, 10509 resp->mirror_rules_used, resp->mirror_rules_free); 10510 *rule_id = rte_le_to_cpu_16(resp->rule_id); 10511 10512 return status; 10513 } 10514 10515 /** 10516 * i40e_aq_del_mirror_rule 10517 * @hw: pointer to the hardware structure 10518 * @seid: VEB seid to add mirror rule to 10519 * @entries: Buffer which contains the entities to be mirrored 10520 * @count: number of entities contained in the buffer 10521 * @rule_id:the rule_id of the rule to be delete 10522 * 10523 * Delete a mirror rule for a given veb. 10524 * 10525 **/ 10526 static enum i40e_status_code 10527 i40e_aq_del_mirror_rule(struct i40e_hw *hw, 10528 uint16_t seid, uint16_t rule_type, uint16_t *entries, 10529 uint16_t count, uint16_t rule_id) 10530 { 10531 struct i40e_aq_desc desc; 10532 struct i40e_aqc_add_delete_mirror_rule cmd; 10533 uint16_t buff_len = 0; 10534 enum i40e_status_code status; 10535 void *buff = NULL; 10536 10537 i40e_fill_default_direct_cmd_desc(&desc, 10538 i40e_aqc_opc_delete_mirror_rule); 10539 memset(&cmd, 0, sizeof(cmd)); 10540 if (rule_type == I40E_AQC_MIRROR_RULE_TYPE_VLAN) { 10541 desc.flags |= rte_cpu_to_le_16((uint16_t)(I40E_AQ_FLAG_BUF | 10542 I40E_AQ_FLAG_RD)); 10543 cmd.num_entries = count; 10544 buff_len = sizeof(uint16_t) * count; 10545 desc.datalen = rte_cpu_to_le_16(buff_len); 10546 buff = (void *)entries; 10547 } else 10548 /* rule id is filled in destination field for deleting mirror rule */ 10549 cmd.destination = rte_cpu_to_le_16(rule_id); 10550 10551 cmd.rule_type = rte_cpu_to_le_16(rule_type << 10552 I40E_AQC_MIRROR_RULE_TYPE_SHIFT); 10553 cmd.seid = rte_cpu_to_le_16(seid); 10554 10555 rte_memcpy(&desc.params.raw, &cmd, sizeof(cmd)); 10556 status = i40e_asq_send_command(hw, &desc, buff, buff_len, NULL); 10557 10558 return status; 10559 } 10560 10561 /** 10562 * i40e_mirror_rule_set 10563 * @dev: pointer to the hardware structure 10564 * @mirror_conf: mirror rule info 10565 * @sw_id: mirror rule's sw_id 10566 * @on: enable/disable 10567 * 10568 * set a mirror rule. 10569 * 10570 **/ 10571 static int 10572 i40e_mirror_rule_set(struct rte_eth_dev *dev, 10573 struct rte_eth_mirror_conf *mirror_conf, 10574 uint8_t sw_id, uint8_t on) 10575 { 10576 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 10577 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10578 struct i40e_mirror_rule *it, *mirr_rule = NULL; 10579 struct i40e_mirror_rule *parent = NULL; 10580 uint16_t seid, dst_seid, rule_id; 10581 uint16_t i, j = 0; 10582 int ret; 10583 10584 PMD_DRV_LOG(DEBUG, "i40e_mirror_rule_set: sw_id = %d.", sw_id); 10585 10586 if (pf->main_vsi->veb == NULL || pf->vfs == NULL) { 10587 PMD_DRV_LOG(ERR, 10588 "mirror rule can not be configured without veb or vfs."); 10589 return -ENOSYS; 10590 } 10591 if (pf->nb_mirror_rule > I40E_MAX_MIRROR_RULES) { 10592 PMD_DRV_LOG(ERR, "mirror table is full."); 10593 return -ENOSPC; 10594 } 10595 if (mirror_conf->dst_pool > pf->vf_num) { 10596 PMD_DRV_LOG(ERR, "invalid destination pool %u.", 10597 mirror_conf->dst_pool); 10598 return -EINVAL; 10599 } 10600 10601 seid = pf->main_vsi->veb->seid; 10602 10603 TAILQ_FOREACH(it, &pf->mirror_list, rules) { 10604 if (sw_id <= it->index) { 10605 mirr_rule = it; 10606 break; 10607 } 10608 parent = it; 10609 } 10610 if (mirr_rule && sw_id == mirr_rule->index) { 10611 if (on) { 10612 PMD_DRV_LOG(ERR, "mirror rule exists."); 10613 return -EEXIST; 10614 } else { 10615 ret = i40e_aq_del_mirror_rule(hw, seid, 10616 mirr_rule->rule_type, 10617 mirr_rule->entries, 10618 mirr_rule->num_entries, mirr_rule->id); 10619 if (ret < 0) { 10620 PMD_DRV_LOG(ERR, 10621 "failed to remove mirror rule: ret = %d, aq_err = %d.", 10622 ret, hw->aq.asq_last_status); 10623 return -ENOSYS; 10624 } 10625 TAILQ_REMOVE(&pf->mirror_list, mirr_rule, rules); 10626 rte_free(mirr_rule); 10627 pf->nb_mirror_rule--; 10628 return 0; 10629 } 10630 } else if (!on) { 10631 PMD_DRV_LOG(ERR, "mirror rule doesn't exist."); 10632 return -ENOENT; 10633 } 10634 10635 mirr_rule = rte_zmalloc("i40e_mirror_rule", 10636 sizeof(struct i40e_mirror_rule) , 0); 10637 if (!mirr_rule) { 10638 PMD_DRV_LOG(ERR, "failed to allocate memory"); 10639 return I40E_ERR_NO_MEMORY; 10640 } 10641 switch (mirror_conf->rule_type) { 10642 case ETH_MIRROR_VLAN: 10643 for (i = 0, j = 0; i < ETH_MIRROR_MAX_VLANS; i++) { 10644 if (mirror_conf->vlan.vlan_mask & (1ULL << i)) { 10645 mirr_rule->entries[j] = 10646 mirror_conf->vlan.vlan_id[i]; 10647 j++; 10648 } 10649 } 10650 if (j == 0) { 10651 PMD_DRV_LOG(ERR, "vlan is not specified."); 10652 rte_free(mirr_rule); 10653 return -EINVAL; 10654 } 10655 mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_VLAN; 10656 break; 10657 case ETH_MIRROR_VIRTUAL_POOL_UP: 10658 case ETH_MIRROR_VIRTUAL_POOL_DOWN: 10659 /* check if the specified pool bit is out of range */ 10660 if (mirror_conf->pool_mask > (uint64_t)(1ULL << (pf->vf_num + 1))) { 10661 PMD_DRV_LOG(ERR, "pool mask is out of range."); 10662 rte_free(mirr_rule); 10663 return -EINVAL; 10664 } 10665 for (i = 0, j = 0; i < pf->vf_num; i++) { 10666 if (mirror_conf->pool_mask & (1ULL << i)) { 10667 mirr_rule->entries[j] = pf->vfs[i].vsi->seid; 10668 j++; 10669 } 10670 } 10671 if (mirror_conf->pool_mask & (1ULL << pf->vf_num)) { 10672 /* add pf vsi to entries */ 10673 mirr_rule->entries[j] = pf->main_vsi_seid; 10674 j++; 10675 } 10676 if (j == 0) { 10677 PMD_DRV_LOG(ERR, "pool is not specified."); 10678 rte_free(mirr_rule); 10679 return -EINVAL; 10680 } 10681 /* egress and ingress in aq commands means from switch but not port */ 10682 mirr_rule->rule_type = 10683 (mirror_conf->rule_type == ETH_MIRROR_VIRTUAL_POOL_UP) ? 10684 I40E_AQC_MIRROR_RULE_TYPE_VPORT_EGRESS : 10685 I40E_AQC_MIRROR_RULE_TYPE_VPORT_INGRESS; 10686 break; 10687 case ETH_MIRROR_UPLINK_PORT: 10688 /* egress and ingress in aq commands means from switch but not port*/ 10689 mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS; 10690 break; 10691 case ETH_MIRROR_DOWNLINK_PORT: 10692 mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS; 10693 break; 10694 default: 10695 PMD_DRV_LOG(ERR, "unsupported mirror type %d.", 10696 mirror_conf->rule_type); 10697 rte_free(mirr_rule); 10698 return -EINVAL; 10699 } 10700 10701 /* If the dst_pool is equal to vf_num, consider it as PF */ 10702 if (mirror_conf->dst_pool == pf->vf_num) 10703 dst_seid = pf->main_vsi_seid; 10704 else 10705 dst_seid = pf->vfs[mirror_conf->dst_pool].vsi->seid; 10706 10707 ret = i40e_aq_add_mirror_rule(hw, seid, dst_seid, 10708 mirr_rule->rule_type, mirr_rule->entries, 10709 j, &rule_id); 10710 if (ret < 0) { 10711 PMD_DRV_LOG(ERR, 10712 "failed to add mirror rule: ret = %d, aq_err = %d.", 10713 ret, hw->aq.asq_last_status); 10714 rte_free(mirr_rule); 10715 return -ENOSYS; 10716 } 10717 10718 mirr_rule->index = sw_id; 10719 mirr_rule->num_entries = j; 10720 mirr_rule->id = rule_id; 10721 mirr_rule->dst_vsi_seid = dst_seid; 10722 10723 if (parent) 10724 TAILQ_INSERT_AFTER(&pf->mirror_list, parent, mirr_rule, rules); 10725 else 10726 TAILQ_INSERT_HEAD(&pf->mirror_list, mirr_rule, rules); 10727 10728 pf->nb_mirror_rule++; 10729 return 0; 10730 } 10731 10732 /** 10733 * i40e_mirror_rule_reset 10734 * @dev: pointer to the device 10735 * @sw_id: mirror rule's sw_id 10736 * 10737 * reset a mirror rule. 10738 * 10739 **/ 10740 static int 10741 i40e_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t sw_id) 10742 { 10743 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 10744 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10745 struct i40e_mirror_rule *it, *mirr_rule = NULL; 10746 uint16_t seid; 10747 int ret; 10748 10749 PMD_DRV_LOG(DEBUG, "i40e_mirror_rule_reset: sw_id = %d.", sw_id); 10750 10751 seid = pf->main_vsi->veb->seid; 10752 10753 TAILQ_FOREACH(it, &pf->mirror_list, rules) { 10754 if (sw_id == it->index) { 10755 mirr_rule = it; 10756 break; 10757 } 10758 } 10759 if (mirr_rule) { 10760 ret = i40e_aq_del_mirror_rule(hw, seid, 10761 mirr_rule->rule_type, 10762 mirr_rule->entries, 10763 mirr_rule->num_entries, mirr_rule->id); 10764 if (ret < 0) { 10765 PMD_DRV_LOG(ERR, 10766 "failed to remove mirror rule: status = %d, aq_err = %d.", 10767 ret, hw->aq.asq_last_status); 10768 return -ENOSYS; 10769 } 10770 TAILQ_REMOVE(&pf->mirror_list, mirr_rule, rules); 10771 rte_free(mirr_rule); 10772 pf->nb_mirror_rule--; 10773 } else { 10774 PMD_DRV_LOG(ERR, "mirror rule doesn't exist."); 10775 return -ENOENT; 10776 } 10777 return 0; 10778 } 10779 10780 static uint64_t 10781 i40e_read_systime_cyclecounter(struct rte_eth_dev *dev) 10782 { 10783 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10784 uint64_t systim_cycles; 10785 10786 systim_cycles = (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TIME_L); 10787 systim_cycles |= (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TIME_H) 10788 << 32; 10789 10790 return systim_cycles; 10791 } 10792 10793 static uint64_t 10794 i40e_read_rx_tstamp_cyclecounter(struct rte_eth_dev *dev, uint8_t index) 10795 { 10796 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10797 uint64_t rx_tstamp; 10798 10799 rx_tstamp = (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_L(index)); 10800 rx_tstamp |= (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(index)) 10801 << 32; 10802 10803 return rx_tstamp; 10804 } 10805 10806 static uint64_t 10807 i40e_read_tx_tstamp_cyclecounter(struct rte_eth_dev *dev) 10808 { 10809 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10810 uint64_t tx_tstamp; 10811 10812 tx_tstamp = (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TXTIME_L); 10813 tx_tstamp |= (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TXTIME_H) 10814 << 32; 10815 10816 return tx_tstamp; 10817 } 10818 10819 static void 10820 i40e_start_timecounters(struct rte_eth_dev *dev) 10821 { 10822 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10823 struct i40e_adapter *adapter = 10824 (struct i40e_adapter *)dev->data->dev_private; 10825 struct rte_eth_link link; 10826 uint32_t tsync_inc_l; 10827 uint32_t tsync_inc_h; 10828 10829 /* Get current link speed. */ 10830 i40e_dev_link_update(dev, 1); 10831 rte_eth_linkstatus_get(dev, &link); 10832 10833 switch (link.link_speed) { 10834 case ETH_SPEED_NUM_40G: 10835 case ETH_SPEED_NUM_25G: 10836 tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF; 10837 tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32; 10838 break; 10839 case ETH_SPEED_NUM_10G: 10840 tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF; 10841 tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32; 10842 break; 10843 case ETH_SPEED_NUM_1G: 10844 tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF; 10845 tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32; 10846 break; 10847 default: 10848 tsync_inc_l = 0x0; 10849 tsync_inc_h = 0x0; 10850 } 10851 10852 /* Set the timesync increment value. */ 10853 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_L, tsync_inc_l); 10854 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_H, tsync_inc_h); 10855 10856 memset(&adapter->systime_tc, 0, sizeof(struct rte_timecounter)); 10857 memset(&adapter->rx_tstamp_tc, 0, sizeof(struct rte_timecounter)); 10858 memset(&adapter->tx_tstamp_tc, 0, sizeof(struct rte_timecounter)); 10859 10860 adapter->systime_tc.cc_mask = I40E_CYCLECOUNTER_MASK; 10861 adapter->systime_tc.cc_shift = 0; 10862 adapter->systime_tc.nsec_mask = 0; 10863 10864 adapter->rx_tstamp_tc.cc_mask = I40E_CYCLECOUNTER_MASK; 10865 adapter->rx_tstamp_tc.cc_shift = 0; 10866 adapter->rx_tstamp_tc.nsec_mask = 0; 10867 10868 adapter->tx_tstamp_tc.cc_mask = I40E_CYCLECOUNTER_MASK; 10869 adapter->tx_tstamp_tc.cc_shift = 0; 10870 adapter->tx_tstamp_tc.nsec_mask = 0; 10871 } 10872 10873 static int 10874 i40e_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta) 10875 { 10876 struct i40e_adapter *adapter = 10877 (struct i40e_adapter *)dev->data->dev_private; 10878 10879 adapter->systime_tc.nsec += delta; 10880 adapter->rx_tstamp_tc.nsec += delta; 10881 adapter->tx_tstamp_tc.nsec += delta; 10882 10883 return 0; 10884 } 10885 10886 static int 10887 i40e_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts) 10888 { 10889 uint64_t ns; 10890 struct i40e_adapter *adapter = 10891 (struct i40e_adapter *)dev->data->dev_private; 10892 10893 ns = rte_timespec_to_ns(ts); 10894 10895 /* Set the timecounters to a new value. */ 10896 adapter->systime_tc.nsec = ns; 10897 adapter->rx_tstamp_tc.nsec = ns; 10898 adapter->tx_tstamp_tc.nsec = ns; 10899 10900 return 0; 10901 } 10902 10903 static int 10904 i40e_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts) 10905 { 10906 uint64_t ns, systime_cycles; 10907 struct i40e_adapter *adapter = 10908 (struct i40e_adapter *)dev->data->dev_private; 10909 10910 systime_cycles = i40e_read_systime_cyclecounter(dev); 10911 ns = rte_timecounter_update(&adapter->systime_tc, systime_cycles); 10912 *ts = rte_ns_to_timespec(ns); 10913 10914 return 0; 10915 } 10916 10917 static int 10918 i40e_timesync_enable(struct rte_eth_dev *dev) 10919 { 10920 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10921 uint32_t tsync_ctl_l; 10922 uint32_t tsync_ctl_h; 10923 10924 /* Stop the timesync system time. */ 10925 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_L, 0x0); 10926 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_H, 0x0); 10927 /* Reset the timesync system time value. */ 10928 I40E_WRITE_REG(hw, I40E_PRTTSYN_TIME_L, 0x0); 10929 I40E_WRITE_REG(hw, I40E_PRTTSYN_TIME_H, 0x0); 10930 10931 i40e_start_timecounters(dev); 10932 10933 /* Clear timesync registers. */ 10934 I40E_READ_REG(hw, I40E_PRTTSYN_STAT_0); 10935 I40E_READ_REG(hw, I40E_PRTTSYN_TXTIME_H); 10936 I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(0)); 10937 I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(1)); 10938 I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(2)); 10939 I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(3)); 10940 10941 /* Enable timestamping of PTP packets. */ 10942 tsync_ctl_l = I40E_READ_REG(hw, I40E_PRTTSYN_CTL0); 10943 tsync_ctl_l |= I40E_PRTTSYN_TSYNENA; 10944 10945 tsync_ctl_h = I40E_READ_REG(hw, I40E_PRTTSYN_CTL1); 10946 tsync_ctl_h |= I40E_PRTTSYN_TSYNENA; 10947 tsync_ctl_h |= I40E_PRTTSYN_TSYNTYPE; 10948 10949 I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL0, tsync_ctl_l); 10950 I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL1, tsync_ctl_h); 10951 10952 return 0; 10953 } 10954 10955 static int 10956 i40e_timesync_disable(struct rte_eth_dev *dev) 10957 { 10958 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10959 uint32_t tsync_ctl_l; 10960 uint32_t tsync_ctl_h; 10961 10962 /* Disable timestamping of transmitted PTP packets. */ 10963 tsync_ctl_l = I40E_READ_REG(hw, I40E_PRTTSYN_CTL0); 10964 tsync_ctl_l &= ~I40E_PRTTSYN_TSYNENA; 10965 10966 tsync_ctl_h = I40E_READ_REG(hw, I40E_PRTTSYN_CTL1); 10967 tsync_ctl_h &= ~I40E_PRTTSYN_TSYNENA; 10968 10969 I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL0, tsync_ctl_l); 10970 I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL1, tsync_ctl_h); 10971 10972 /* Reset the timesync increment value. */ 10973 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_L, 0x0); 10974 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_H, 0x0); 10975 10976 return 0; 10977 } 10978 10979 static int 10980 i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev, 10981 struct timespec *timestamp, uint32_t flags) 10982 { 10983 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10984 struct i40e_adapter *adapter = 10985 (struct i40e_adapter *)dev->data->dev_private; 10986 10987 uint32_t sync_status; 10988 uint32_t index = flags & 0x03; 10989 uint64_t rx_tstamp_cycles; 10990 uint64_t ns; 10991 10992 sync_status = I40E_READ_REG(hw, I40E_PRTTSYN_STAT_1); 10993 if ((sync_status & (1 << index)) == 0) 10994 return -EINVAL; 10995 10996 rx_tstamp_cycles = i40e_read_rx_tstamp_cyclecounter(dev, index); 10997 ns = rte_timecounter_update(&adapter->rx_tstamp_tc, rx_tstamp_cycles); 10998 *timestamp = rte_ns_to_timespec(ns); 10999 11000 return 0; 11001 } 11002 11003 static int 11004 i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev, 11005 struct timespec *timestamp) 11006 { 11007 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11008 struct i40e_adapter *adapter = 11009 (struct i40e_adapter *)dev->data->dev_private; 11010 11011 uint32_t sync_status; 11012 uint64_t tx_tstamp_cycles; 11013 uint64_t ns; 11014 11015 sync_status = I40E_READ_REG(hw, I40E_PRTTSYN_STAT_0); 11016 if ((sync_status & I40E_PRTTSYN_STAT_0_TXTIME_MASK) == 0) 11017 return -EINVAL; 11018 11019 tx_tstamp_cycles = i40e_read_tx_tstamp_cyclecounter(dev); 11020 ns = rte_timecounter_update(&adapter->tx_tstamp_tc, tx_tstamp_cycles); 11021 *timestamp = rte_ns_to_timespec(ns); 11022 11023 return 0; 11024 } 11025 11026 /* 11027 * i40e_parse_dcb_configure - parse dcb configure from user 11028 * @dev: the device being configured 11029 * @dcb_cfg: pointer of the result of parse 11030 * @*tc_map: bit map of enabled traffic classes 11031 * 11032 * Returns 0 on success, negative value on failure 11033 */ 11034 static int 11035 i40e_parse_dcb_configure(struct rte_eth_dev *dev, 11036 struct i40e_dcbx_config *dcb_cfg, 11037 uint8_t *tc_map) 11038 { 11039 struct rte_eth_dcb_rx_conf *dcb_rx_conf; 11040 uint8_t i, tc_bw, bw_lf; 11041 11042 memset(dcb_cfg, 0, sizeof(struct i40e_dcbx_config)); 11043 11044 dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; 11045 if (dcb_rx_conf->nb_tcs > I40E_MAX_TRAFFIC_CLASS) { 11046 PMD_INIT_LOG(ERR, "number of tc exceeds max."); 11047 return -EINVAL; 11048 } 11049 11050 /* assume each tc has the same bw */ 11051 tc_bw = I40E_MAX_PERCENT / dcb_rx_conf->nb_tcs; 11052 for (i = 0; i < dcb_rx_conf->nb_tcs; i++) 11053 dcb_cfg->etscfg.tcbwtable[i] = tc_bw; 11054 /* to ensure the sum of tcbw is equal to 100 */ 11055 bw_lf = I40E_MAX_PERCENT % dcb_rx_conf->nb_tcs; 11056 for (i = 0; i < bw_lf; i++) 11057 dcb_cfg->etscfg.tcbwtable[i]++; 11058 11059 /* assume each tc has the same Transmission Selection Algorithm */ 11060 for (i = 0; i < dcb_rx_conf->nb_tcs; i++) 11061 dcb_cfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS; 11062 11063 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) 11064 dcb_cfg->etscfg.prioritytable[i] = 11065 dcb_rx_conf->dcb_tc[i]; 11066 11067 /* FW needs one App to configure HW */ 11068 dcb_cfg->numapps = I40E_DEFAULT_DCB_APP_NUM; 11069 dcb_cfg->app[0].selector = I40E_APP_SEL_ETHTYPE; 11070 dcb_cfg->app[0].priority = I40E_DEFAULT_DCB_APP_PRIO; 11071 dcb_cfg->app[0].protocolid = I40E_APP_PROTOID_FCOE; 11072 11073 if (dcb_rx_conf->nb_tcs == 0) 11074 *tc_map = 1; /* tc0 only */ 11075 else 11076 *tc_map = RTE_LEN2MASK(dcb_rx_conf->nb_tcs, uint8_t); 11077 11078 if (dev->data->dev_conf.dcb_capability_en & ETH_DCB_PFC_SUPPORT) { 11079 dcb_cfg->pfc.willing = 0; 11080 dcb_cfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS; 11081 dcb_cfg->pfc.pfcenable = *tc_map; 11082 } 11083 return 0; 11084 } 11085 11086 11087 static enum i40e_status_code 11088 i40e_vsi_update_queue_mapping(struct i40e_vsi *vsi, 11089 struct i40e_aqc_vsi_properties_data *info, 11090 uint8_t enabled_tcmap) 11091 { 11092 enum i40e_status_code ret; 11093 int i, total_tc = 0; 11094 uint16_t qpnum_per_tc, bsf, qp_idx; 11095 struct rte_eth_dev_data *dev_data = I40E_VSI_TO_DEV_DATA(vsi); 11096 struct i40e_pf *pf = I40E_VSI_TO_PF(vsi); 11097 uint16_t used_queues; 11098 11099 ret = validate_tcmap_parameter(vsi, enabled_tcmap); 11100 if (ret != I40E_SUCCESS) 11101 return ret; 11102 11103 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 11104 if (enabled_tcmap & (1 << i)) 11105 total_tc++; 11106 } 11107 if (total_tc == 0) 11108 total_tc = 1; 11109 vsi->enabled_tc = enabled_tcmap; 11110 11111 /* different VSI has different queues assigned */ 11112 if (vsi->type == I40E_VSI_MAIN) 11113 used_queues = dev_data->nb_rx_queues - 11114 pf->nb_cfg_vmdq_vsi * RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM; 11115 else if (vsi->type == I40E_VSI_VMDQ2) 11116 used_queues = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM; 11117 else { 11118 PMD_INIT_LOG(ERR, "unsupported VSI type."); 11119 return I40E_ERR_NO_AVAILABLE_VSI; 11120 } 11121 11122 qpnum_per_tc = used_queues / total_tc; 11123 /* Number of queues per enabled TC */ 11124 if (qpnum_per_tc == 0) { 11125 PMD_INIT_LOG(ERR, " number of queues is less that tcs."); 11126 return I40E_ERR_INVALID_QP_ID; 11127 } 11128 qpnum_per_tc = RTE_MIN(i40e_align_floor(qpnum_per_tc), 11129 I40E_MAX_Q_PER_TC); 11130 bsf = rte_bsf32(qpnum_per_tc); 11131 11132 /** 11133 * Configure TC and queue mapping parameters, for enabled TC, 11134 * allocate qpnum_per_tc queues to this traffic. For disabled TC, 11135 * default queue will serve it. 11136 */ 11137 qp_idx = 0; 11138 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 11139 if (vsi->enabled_tc & (1 << i)) { 11140 info->tc_mapping[i] = rte_cpu_to_le_16((qp_idx << 11141 I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) | 11142 (bsf << I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT)); 11143 qp_idx += qpnum_per_tc; 11144 } else 11145 info->tc_mapping[i] = 0; 11146 } 11147 11148 /* Associate queue number with VSI, Keep vsi->nb_qps unchanged */ 11149 if (vsi->type == I40E_VSI_SRIOV) { 11150 info->mapping_flags |= 11151 rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_NONCONTIG); 11152 for (i = 0; i < vsi->nb_qps; i++) 11153 info->queue_mapping[i] = 11154 rte_cpu_to_le_16(vsi->base_queue + i); 11155 } else { 11156 info->mapping_flags |= 11157 rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_CONTIG); 11158 info->queue_mapping[0] = rte_cpu_to_le_16(vsi->base_queue); 11159 } 11160 info->valid_sections |= 11161 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_QUEUE_MAP_VALID); 11162 11163 return I40E_SUCCESS; 11164 } 11165 11166 /* 11167 * i40e_config_switch_comp_tc - Configure VEB tc setting for given TC map 11168 * @veb: VEB to be configured 11169 * @tc_map: enabled TC bitmap 11170 * 11171 * Returns 0 on success, negative value on failure 11172 */ 11173 static enum i40e_status_code 11174 i40e_config_switch_comp_tc(struct i40e_veb *veb, uint8_t tc_map) 11175 { 11176 struct i40e_aqc_configure_switching_comp_bw_config_data veb_bw; 11177 struct i40e_aqc_query_switching_comp_bw_config_resp bw_query; 11178 struct i40e_aqc_query_switching_comp_ets_config_resp ets_query; 11179 struct i40e_hw *hw = I40E_VSI_TO_HW(veb->associate_vsi); 11180 enum i40e_status_code ret = I40E_SUCCESS; 11181 int i; 11182 uint32_t bw_max; 11183 11184 /* Check if enabled_tc is same as existing or new TCs */ 11185 if (veb->enabled_tc == tc_map) 11186 return ret; 11187 11188 /* configure tc bandwidth */ 11189 memset(&veb_bw, 0, sizeof(veb_bw)); 11190 veb_bw.tc_valid_bits = tc_map; 11191 /* Enable ETS TCs with equal BW Share for now across all VSIs */ 11192 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 11193 if (tc_map & BIT_ULL(i)) 11194 veb_bw.tc_bw_share_credits[i] = 1; 11195 } 11196 ret = i40e_aq_config_switch_comp_bw_config(hw, veb->seid, 11197 &veb_bw, NULL); 11198 if (ret) { 11199 PMD_INIT_LOG(ERR, 11200 "AQ command Config switch_comp BW allocation per TC failed = %d", 11201 hw->aq.asq_last_status); 11202 return ret; 11203 } 11204 11205 memset(&ets_query, 0, sizeof(ets_query)); 11206 ret = i40e_aq_query_switch_comp_ets_config(hw, veb->seid, 11207 &ets_query, NULL); 11208 if (ret != I40E_SUCCESS) { 11209 PMD_DRV_LOG(ERR, 11210 "Failed to get switch_comp ETS configuration %u", 11211 hw->aq.asq_last_status); 11212 return ret; 11213 } 11214 memset(&bw_query, 0, sizeof(bw_query)); 11215 ret = i40e_aq_query_switch_comp_bw_config(hw, veb->seid, 11216 &bw_query, NULL); 11217 if (ret != I40E_SUCCESS) { 11218 PMD_DRV_LOG(ERR, 11219 "Failed to get switch_comp bandwidth configuration %u", 11220 hw->aq.asq_last_status); 11221 return ret; 11222 } 11223 11224 /* store and print out BW info */ 11225 veb->bw_info.bw_limit = rte_le_to_cpu_16(ets_query.port_bw_limit); 11226 veb->bw_info.bw_max = ets_query.tc_bw_max; 11227 PMD_DRV_LOG(DEBUG, "switch_comp bw limit:%u", veb->bw_info.bw_limit); 11228 PMD_DRV_LOG(DEBUG, "switch_comp max_bw:%u", veb->bw_info.bw_max); 11229 bw_max = rte_le_to_cpu_16(bw_query.tc_bw_max[0]) | 11230 (rte_le_to_cpu_16(bw_query.tc_bw_max[1]) << 11231 I40E_16_BIT_WIDTH); 11232 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 11233 veb->bw_info.bw_ets_share_credits[i] = 11234 bw_query.tc_bw_share_credits[i]; 11235 veb->bw_info.bw_ets_credits[i] = 11236 rte_le_to_cpu_16(bw_query.tc_bw_limits[i]); 11237 /* 4 bits per TC, 4th bit is reserved */ 11238 veb->bw_info.bw_ets_max[i] = 11239 (uint8_t)((bw_max >> (i * I40E_4_BIT_WIDTH)) & 11240 RTE_LEN2MASK(3, uint8_t)); 11241 PMD_DRV_LOG(DEBUG, "\tVEB TC%u:share credits %u", i, 11242 veb->bw_info.bw_ets_share_credits[i]); 11243 PMD_DRV_LOG(DEBUG, "\tVEB TC%u:credits %u", i, 11244 veb->bw_info.bw_ets_credits[i]); 11245 PMD_DRV_LOG(DEBUG, "\tVEB TC%u: max credits: %u", i, 11246 veb->bw_info.bw_ets_max[i]); 11247 } 11248 11249 veb->enabled_tc = tc_map; 11250 11251 return ret; 11252 } 11253 11254 11255 /* 11256 * i40e_vsi_config_tc - Configure VSI tc setting for given TC map 11257 * @vsi: VSI to be configured 11258 * @tc_map: enabled TC bitmap 11259 * 11260 * Returns 0 on success, negative value on failure 11261 */ 11262 static enum i40e_status_code 11263 i40e_vsi_config_tc(struct i40e_vsi *vsi, uint8_t tc_map) 11264 { 11265 struct i40e_aqc_configure_vsi_tc_bw_data bw_data; 11266 struct i40e_vsi_context ctxt; 11267 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 11268 enum i40e_status_code ret = I40E_SUCCESS; 11269 int i; 11270 11271 /* Check if enabled_tc is same as existing or new TCs */ 11272 if (vsi->enabled_tc == tc_map) 11273 return ret; 11274 11275 /* configure tc bandwidth */ 11276 memset(&bw_data, 0, sizeof(bw_data)); 11277 bw_data.tc_valid_bits = tc_map; 11278 /* Enable ETS TCs with equal BW Share for now across all VSIs */ 11279 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 11280 if (tc_map & BIT_ULL(i)) 11281 bw_data.tc_bw_credits[i] = 1; 11282 } 11283 ret = i40e_aq_config_vsi_tc_bw(hw, vsi->seid, &bw_data, NULL); 11284 if (ret) { 11285 PMD_INIT_LOG(ERR, 11286 "AQ command Config VSI BW allocation per TC failed = %d", 11287 hw->aq.asq_last_status); 11288 goto out; 11289 } 11290 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) 11291 vsi->info.qs_handle[i] = bw_data.qs_handles[i]; 11292 11293 /* Update Queue Pairs Mapping for currently enabled UPs */ 11294 ctxt.seid = vsi->seid; 11295 ctxt.pf_num = hw->pf_id; 11296 ctxt.vf_num = 0; 11297 ctxt.uplink_seid = vsi->uplink_seid; 11298 ctxt.info = vsi->info; 11299 i40e_get_cap(hw); 11300 ret = i40e_vsi_update_queue_mapping(vsi, &ctxt.info, tc_map); 11301 if (ret) 11302 goto out; 11303 11304 /* Update the VSI after updating the VSI queue-mapping information */ 11305 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); 11306 if (ret) { 11307 PMD_INIT_LOG(ERR, "Failed to configure TC queue mapping = %d", 11308 hw->aq.asq_last_status); 11309 goto out; 11310 } 11311 /* update the local VSI info with updated queue map */ 11312 rte_memcpy(&vsi->info.tc_mapping, &ctxt.info.tc_mapping, 11313 sizeof(vsi->info.tc_mapping)); 11314 rte_memcpy(&vsi->info.queue_mapping, 11315 &ctxt.info.queue_mapping, 11316 sizeof(vsi->info.queue_mapping)); 11317 vsi->info.mapping_flags = ctxt.info.mapping_flags; 11318 vsi->info.valid_sections = 0; 11319 11320 /* query and update current VSI BW information */ 11321 ret = i40e_vsi_get_bw_config(vsi); 11322 if (ret) { 11323 PMD_INIT_LOG(ERR, 11324 "Failed updating vsi bw info, err %s aq_err %s", 11325 i40e_stat_str(hw, ret), 11326 i40e_aq_str(hw, hw->aq.asq_last_status)); 11327 goto out; 11328 } 11329 11330 vsi->enabled_tc = tc_map; 11331 11332 out: 11333 return ret; 11334 } 11335 11336 /* 11337 * i40e_dcb_hw_configure - program the dcb setting to hw 11338 * @pf: pf the configuration is taken on 11339 * @new_cfg: new configuration 11340 * @tc_map: enabled TC bitmap 11341 * 11342 * Returns 0 on success, negative value on failure 11343 */ 11344 static enum i40e_status_code 11345 i40e_dcb_hw_configure(struct i40e_pf *pf, 11346 struct i40e_dcbx_config *new_cfg, 11347 uint8_t tc_map) 11348 { 11349 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 11350 struct i40e_dcbx_config *old_cfg = &hw->local_dcbx_config; 11351 struct i40e_vsi *main_vsi = pf->main_vsi; 11352 struct i40e_vsi_list *vsi_list; 11353 enum i40e_status_code ret; 11354 int i; 11355 uint32_t val; 11356 11357 /* Use the FW API if FW > v4.4*/ 11358 if (!(((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver >= 4)) || 11359 (hw->aq.fw_maj_ver >= 5))) { 11360 PMD_INIT_LOG(ERR, 11361 "FW < v4.4, can not use FW LLDP API to configure DCB"); 11362 return I40E_ERR_FIRMWARE_API_VERSION; 11363 } 11364 11365 /* Check if need reconfiguration */ 11366 if (!memcmp(new_cfg, old_cfg, sizeof(struct i40e_dcbx_config))) { 11367 PMD_INIT_LOG(ERR, "No Change in DCB Config required."); 11368 return I40E_SUCCESS; 11369 } 11370 11371 /* Copy the new config to the current config */ 11372 *old_cfg = *new_cfg; 11373 old_cfg->etsrec = old_cfg->etscfg; 11374 ret = i40e_set_dcb_config(hw); 11375 if (ret) { 11376 PMD_INIT_LOG(ERR, "Set DCB Config failed, err %s aq_err %s", 11377 i40e_stat_str(hw, ret), 11378 i40e_aq_str(hw, hw->aq.asq_last_status)); 11379 return ret; 11380 } 11381 /* set receive Arbiter to RR mode and ETS scheme by default */ 11382 for (i = 0; i <= I40E_PRTDCB_RETSTCC_MAX_INDEX; i++) { 11383 val = I40E_READ_REG(hw, I40E_PRTDCB_RETSTCC(i)); 11384 val &= ~(I40E_PRTDCB_RETSTCC_BWSHARE_MASK | 11385 I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK | 11386 I40E_PRTDCB_RETSTCC_ETSTC_SHIFT); 11387 val |= ((uint32_t)old_cfg->etscfg.tcbwtable[i] << 11388 I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT) & 11389 I40E_PRTDCB_RETSTCC_BWSHARE_MASK; 11390 val |= ((uint32_t)1 << I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT) & 11391 I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK; 11392 val |= ((uint32_t)1 << I40E_PRTDCB_RETSTCC_ETSTC_SHIFT) & 11393 I40E_PRTDCB_RETSTCC_ETSTC_MASK; 11394 I40E_WRITE_REG(hw, I40E_PRTDCB_RETSTCC(i), val); 11395 } 11396 /* get local mib to check whether it is configured correctly */ 11397 /* IEEE mode */ 11398 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE; 11399 /* Get Local DCB Config */ 11400 i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0, 11401 &hw->local_dcbx_config); 11402 11403 /* if Veb is created, need to update TC of it at first */ 11404 if (main_vsi->veb) { 11405 ret = i40e_config_switch_comp_tc(main_vsi->veb, tc_map); 11406 if (ret) 11407 PMD_INIT_LOG(WARNING, 11408 "Failed configuring TC for VEB seid=%d", 11409 main_vsi->veb->seid); 11410 } 11411 /* Update each VSI */ 11412 i40e_vsi_config_tc(main_vsi, tc_map); 11413 if (main_vsi->veb) { 11414 TAILQ_FOREACH(vsi_list, &main_vsi->veb->head, list) { 11415 /* Beside main VSI and VMDQ VSIs, only enable default 11416 * TC for other VSIs 11417 */ 11418 if (vsi_list->vsi->type == I40E_VSI_VMDQ2) 11419 ret = i40e_vsi_config_tc(vsi_list->vsi, 11420 tc_map); 11421 else 11422 ret = i40e_vsi_config_tc(vsi_list->vsi, 11423 I40E_DEFAULT_TCMAP); 11424 if (ret) 11425 PMD_INIT_LOG(WARNING, 11426 "Failed configuring TC for VSI seid=%d", 11427 vsi_list->vsi->seid); 11428 /* continue */ 11429 } 11430 } 11431 return I40E_SUCCESS; 11432 } 11433 11434 /* 11435 * i40e_dcb_init_configure - initial dcb config 11436 * @dev: device being configured 11437 * @sw_dcb: indicate whether dcb is sw configured or hw offload 11438 * 11439 * Returns 0 on success, negative value on failure 11440 */ 11441 int 11442 i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb) 11443 { 11444 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11445 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11446 int i, ret = 0; 11447 11448 if ((pf->flags & I40E_FLAG_DCB) == 0) { 11449 PMD_INIT_LOG(ERR, "HW doesn't support DCB"); 11450 return -ENOTSUP; 11451 } 11452 11453 /* DCB initialization: 11454 * Update DCB configuration from the Firmware and configure 11455 * LLDP MIB change event. 11456 */ 11457 if (sw_dcb == TRUE) { 11458 if (i40e_need_stop_lldp(dev)) { 11459 ret = i40e_aq_stop_lldp(hw, TRUE, NULL); 11460 if (ret != I40E_SUCCESS) 11461 PMD_INIT_LOG(DEBUG, "Failed to stop lldp"); 11462 } 11463 11464 ret = i40e_init_dcb(hw); 11465 /* If lldp agent is stopped, the return value from 11466 * i40e_init_dcb we expect is failure with I40E_AQ_RC_EPERM 11467 * adminq status. Otherwise, it should return success. 11468 */ 11469 if ((ret == I40E_SUCCESS) || (ret != I40E_SUCCESS && 11470 hw->aq.asq_last_status == I40E_AQ_RC_EPERM)) { 11471 memset(&hw->local_dcbx_config, 0, 11472 sizeof(struct i40e_dcbx_config)); 11473 /* set dcb default configuration */ 11474 hw->local_dcbx_config.etscfg.willing = 0; 11475 hw->local_dcbx_config.etscfg.maxtcs = 0; 11476 hw->local_dcbx_config.etscfg.tcbwtable[0] = 100; 11477 hw->local_dcbx_config.etscfg.tsatable[0] = 11478 I40E_IEEE_TSA_ETS; 11479 /* all UPs mapping to TC0 */ 11480 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) 11481 hw->local_dcbx_config.etscfg.prioritytable[i] = 0; 11482 hw->local_dcbx_config.etsrec = 11483 hw->local_dcbx_config.etscfg; 11484 hw->local_dcbx_config.pfc.willing = 0; 11485 hw->local_dcbx_config.pfc.pfccap = 11486 I40E_MAX_TRAFFIC_CLASS; 11487 /* FW needs one App to configure HW */ 11488 hw->local_dcbx_config.numapps = 1; 11489 hw->local_dcbx_config.app[0].selector = 11490 I40E_APP_SEL_ETHTYPE; 11491 hw->local_dcbx_config.app[0].priority = 3; 11492 hw->local_dcbx_config.app[0].protocolid = 11493 I40E_APP_PROTOID_FCOE; 11494 ret = i40e_set_dcb_config(hw); 11495 if (ret) { 11496 PMD_INIT_LOG(ERR, 11497 "default dcb config fails. err = %d, aq_err = %d.", 11498 ret, hw->aq.asq_last_status); 11499 return -ENOSYS; 11500 } 11501 } else { 11502 PMD_INIT_LOG(ERR, 11503 "DCB initialization in FW fails, err = %d, aq_err = %d.", 11504 ret, hw->aq.asq_last_status); 11505 return -ENOTSUP; 11506 } 11507 } else { 11508 ret = i40e_aq_start_lldp(hw, NULL); 11509 if (ret != I40E_SUCCESS) 11510 PMD_INIT_LOG(DEBUG, "Failed to start lldp"); 11511 11512 ret = i40e_init_dcb(hw); 11513 if (!ret) { 11514 if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) { 11515 PMD_INIT_LOG(ERR, 11516 "HW doesn't support DCBX offload."); 11517 return -ENOTSUP; 11518 } 11519 } else { 11520 PMD_INIT_LOG(ERR, 11521 "DCBX configuration failed, err = %d, aq_err = %d.", 11522 ret, hw->aq.asq_last_status); 11523 return -ENOTSUP; 11524 } 11525 } 11526 return 0; 11527 } 11528 11529 /* 11530 * i40e_dcb_setup - setup dcb related config 11531 * @dev: device being configured 11532 * 11533 * Returns 0 on success, negative value on failure 11534 */ 11535 static int 11536 i40e_dcb_setup(struct rte_eth_dev *dev) 11537 { 11538 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11539 struct i40e_dcbx_config dcb_cfg; 11540 uint8_t tc_map = 0; 11541 int ret = 0; 11542 11543 if ((pf->flags & I40E_FLAG_DCB) == 0) { 11544 PMD_INIT_LOG(ERR, "HW doesn't support DCB"); 11545 return -ENOTSUP; 11546 } 11547 11548 if (pf->vf_num != 0) 11549 PMD_INIT_LOG(DEBUG, " DCB only works on pf and vmdq vsis."); 11550 11551 ret = i40e_parse_dcb_configure(dev, &dcb_cfg, &tc_map); 11552 if (ret) { 11553 PMD_INIT_LOG(ERR, "invalid dcb config"); 11554 return -EINVAL; 11555 } 11556 ret = i40e_dcb_hw_configure(pf, &dcb_cfg, tc_map); 11557 if (ret) { 11558 PMD_INIT_LOG(ERR, "dcb sw configure fails"); 11559 return -ENOSYS; 11560 } 11561 11562 return 0; 11563 } 11564 11565 static int 11566 i40e_dev_get_dcb_info(struct rte_eth_dev *dev, 11567 struct rte_eth_dcb_info *dcb_info) 11568 { 11569 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11570 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11571 struct i40e_vsi *vsi = pf->main_vsi; 11572 struct i40e_dcbx_config *dcb_cfg = &hw->local_dcbx_config; 11573 uint16_t bsf, tc_mapping; 11574 int i, j = 0; 11575 11576 if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_DCB_FLAG) 11577 dcb_info->nb_tcs = rte_bsf32(vsi->enabled_tc + 1); 11578 else 11579 dcb_info->nb_tcs = 1; 11580 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) 11581 dcb_info->prio_tc[i] = dcb_cfg->etscfg.prioritytable[i]; 11582 for (i = 0; i < dcb_info->nb_tcs; i++) 11583 dcb_info->tc_bws[i] = dcb_cfg->etscfg.tcbwtable[i]; 11584 11585 /* get queue mapping if vmdq is disabled */ 11586 if (!pf->nb_cfg_vmdq_vsi) { 11587 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 11588 if (!(vsi->enabled_tc & (1 << i))) 11589 continue; 11590 tc_mapping = rte_le_to_cpu_16(vsi->info.tc_mapping[i]); 11591 dcb_info->tc_queue.tc_rxq[j][i].base = 11592 (tc_mapping & I40E_AQ_VSI_TC_QUE_OFFSET_MASK) >> 11593 I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT; 11594 dcb_info->tc_queue.tc_txq[j][i].base = 11595 dcb_info->tc_queue.tc_rxq[j][i].base; 11596 bsf = (tc_mapping & I40E_AQ_VSI_TC_QUE_NUMBER_MASK) >> 11597 I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT; 11598 dcb_info->tc_queue.tc_rxq[j][i].nb_queue = 1 << bsf; 11599 dcb_info->tc_queue.tc_txq[j][i].nb_queue = 11600 dcb_info->tc_queue.tc_rxq[j][i].nb_queue; 11601 } 11602 return 0; 11603 } 11604 11605 /* get queue mapping if vmdq is enabled */ 11606 do { 11607 vsi = pf->vmdq[j].vsi; 11608 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 11609 if (!(vsi->enabled_tc & (1 << i))) 11610 continue; 11611 tc_mapping = rte_le_to_cpu_16(vsi->info.tc_mapping[i]); 11612 dcb_info->tc_queue.tc_rxq[j][i].base = 11613 (tc_mapping & I40E_AQ_VSI_TC_QUE_OFFSET_MASK) >> 11614 I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT; 11615 dcb_info->tc_queue.tc_txq[j][i].base = 11616 dcb_info->tc_queue.tc_rxq[j][i].base; 11617 bsf = (tc_mapping & I40E_AQ_VSI_TC_QUE_NUMBER_MASK) >> 11618 I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT; 11619 dcb_info->tc_queue.tc_rxq[j][i].nb_queue = 1 << bsf; 11620 dcb_info->tc_queue.tc_txq[j][i].nb_queue = 11621 dcb_info->tc_queue.tc_rxq[j][i].nb_queue; 11622 } 11623 j++; 11624 } while (j < RTE_MIN(pf->nb_cfg_vmdq_vsi, ETH_MAX_VMDQ_POOL)); 11625 return 0; 11626 } 11627 11628 static int 11629 i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id) 11630 { 11631 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 11632 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 11633 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11634 uint16_t msix_intr; 11635 11636 msix_intr = intr_handle->intr_vec[queue_id]; 11637 if (msix_intr == I40E_MISC_VEC_ID) 11638 I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 11639 I40E_PFINT_DYN_CTL0_INTENA_MASK | 11640 I40E_PFINT_DYN_CTL0_CLEARPBA_MASK | 11641 I40E_PFINT_DYN_CTL0_ITR_INDX_MASK); 11642 else 11643 I40E_WRITE_REG(hw, 11644 I40E_PFINT_DYN_CTLN(msix_intr - 11645 I40E_RX_VEC_START), 11646 I40E_PFINT_DYN_CTLN_INTENA_MASK | 11647 I40E_PFINT_DYN_CTLN_CLEARPBA_MASK | 11648 I40E_PFINT_DYN_CTLN_ITR_INDX_MASK); 11649 11650 I40E_WRITE_FLUSH(hw); 11651 rte_intr_enable(&pci_dev->intr_handle); 11652 11653 return 0; 11654 } 11655 11656 static int 11657 i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id) 11658 { 11659 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 11660 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 11661 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11662 uint16_t msix_intr; 11663 11664 msix_intr = intr_handle->intr_vec[queue_id]; 11665 if (msix_intr == I40E_MISC_VEC_ID) 11666 I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 11667 I40E_PFINT_DYN_CTL0_ITR_INDX_MASK); 11668 else 11669 I40E_WRITE_REG(hw, 11670 I40E_PFINT_DYN_CTLN(msix_intr - 11671 I40E_RX_VEC_START), 11672 I40E_PFINT_DYN_CTLN_ITR_INDX_MASK); 11673 I40E_WRITE_FLUSH(hw); 11674 11675 return 0; 11676 } 11677 11678 /** 11679 * This function is used to check if the register is valid. 11680 * Below is the valid registers list for X722 only: 11681 * 0x2b800--0x2bb00 11682 * 0x38700--0x38a00 11683 * 0x3d800--0x3db00 11684 * 0x208e00--0x209000 11685 * 0x20be00--0x20c000 11686 * 0x263c00--0x264000 11687 * 0x265c00--0x266000 11688 */ 11689 static inline int i40e_valid_regs(enum i40e_mac_type type, uint32_t reg_offset) 11690 { 11691 if ((type != I40E_MAC_X722) && 11692 ((reg_offset >= 0x2b800 && reg_offset <= 0x2bb00) || 11693 (reg_offset >= 0x38700 && reg_offset <= 0x38a00) || 11694 (reg_offset >= 0x3d800 && reg_offset <= 0x3db00) || 11695 (reg_offset >= 0x208e00 && reg_offset <= 0x209000) || 11696 (reg_offset >= 0x20be00 && reg_offset <= 0x20c000) || 11697 (reg_offset >= 0x263c00 && reg_offset <= 0x264000) || 11698 (reg_offset >= 0x265c00 && reg_offset <= 0x266000))) 11699 return 0; 11700 else 11701 return 1; 11702 } 11703 11704 static int i40e_get_regs(struct rte_eth_dev *dev, 11705 struct rte_dev_reg_info *regs) 11706 { 11707 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11708 uint32_t *ptr_data = regs->data; 11709 uint32_t reg_idx, arr_idx, arr_idx2, reg_offset; 11710 const struct i40e_reg_info *reg_info; 11711 11712 if (ptr_data == NULL) { 11713 regs->length = I40E_GLGEN_STAT_CLEAR + 4; 11714 regs->width = sizeof(uint32_t); 11715 return 0; 11716 } 11717 11718 /* The first few registers have to be read using AQ operations */ 11719 reg_idx = 0; 11720 while (i40e_regs_adminq[reg_idx].name) { 11721 reg_info = &i40e_regs_adminq[reg_idx++]; 11722 for (arr_idx = 0; arr_idx <= reg_info->count1; arr_idx++) 11723 for (arr_idx2 = 0; 11724 arr_idx2 <= reg_info->count2; 11725 arr_idx2++) { 11726 reg_offset = arr_idx * reg_info->stride1 + 11727 arr_idx2 * reg_info->stride2; 11728 reg_offset += reg_info->base_addr; 11729 ptr_data[reg_offset >> 2] = 11730 i40e_read_rx_ctl(hw, reg_offset); 11731 } 11732 } 11733 11734 /* The remaining registers can be read using primitives */ 11735 reg_idx = 0; 11736 while (i40e_regs_others[reg_idx].name) { 11737 reg_info = &i40e_regs_others[reg_idx++]; 11738 for (arr_idx = 0; arr_idx <= reg_info->count1; arr_idx++) 11739 for (arr_idx2 = 0; 11740 arr_idx2 <= reg_info->count2; 11741 arr_idx2++) { 11742 reg_offset = arr_idx * reg_info->stride1 + 11743 arr_idx2 * reg_info->stride2; 11744 reg_offset += reg_info->base_addr; 11745 if (!i40e_valid_regs(hw->mac.type, reg_offset)) 11746 ptr_data[reg_offset >> 2] = 0; 11747 else 11748 ptr_data[reg_offset >> 2] = 11749 I40E_READ_REG(hw, reg_offset); 11750 } 11751 } 11752 11753 return 0; 11754 } 11755 11756 static int i40e_get_eeprom_length(struct rte_eth_dev *dev) 11757 { 11758 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11759 11760 /* Convert word count to byte count */ 11761 return hw->nvm.sr_size << 1; 11762 } 11763 11764 static int i40e_get_eeprom(struct rte_eth_dev *dev, 11765 struct rte_dev_eeprom_info *eeprom) 11766 { 11767 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11768 uint16_t *data = eeprom->data; 11769 uint16_t offset, length, cnt_words; 11770 int ret_code; 11771 11772 offset = eeprom->offset >> 1; 11773 length = eeprom->length >> 1; 11774 cnt_words = length; 11775 11776 if (offset > hw->nvm.sr_size || 11777 offset + length > hw->nvm.sr_size) { 11778 PMD_DRV_LOG(ERR, "Requested EEPROM bytes out of range."); 11779 return -EINVAL; 11780 } 11781 11782 eeprom->magic = hw->vendor_id | (hw->device_id << 16); 11783 11784 ret_code = i40e_read_nvm_buffer(hw, offset, &cnt_words, data); 11785 if (ret_code != I40E_SUCCESS || cnt_words != length) { 11786 PMD_DRV_LOG(ERR, "EEPROM read failed."); 11787 return -EIO; 11788 } 11789 11790 return 0; 11791 } 11792 11793 static int i40e_get_module_info(struct rte_eth_dev *dev, 11794 struct rte_eth_dev_module_info *modinfo) 11795 { 11796 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11797 uint32_t sff8472_comp = 0; 11798 uint32_t sff8472_swap = 0; 11799 uint32_t sff8636_rev = 0; 11800 i40e_status status; 11801 uint32_t type = 0; 11802 11803 /* Check if firmware supports reading module EEPROM. */ 11804 if (!(hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE)) { 11805 PMD_DRV_LOG(ERR, 11806 "Module EEPROM memory read not supported. " 11807 "Please update the NVM image.\n"); 11808 return -EINVAL; 11809 } 11810 11811 status = i40e_update_link_info(hw); 11812 if (status) 11813 return -EIO; 11814 11815 if (hw->phy.link_info.phy_type == I40E_PHY_TYPE_EMPTY) { 11816 PMD_DRV_LOG(ERR, 11817 "Cannot read module EEPROM memory. " 11818 "No module connected.\n"); 11819 return -EINVAL; 11820 } 11821 11822 type = hw->phy.link_info.module_type[0]; 11823 11824 switch (type) { 11825 case I40E_MODULE_TYPE_SFP: 11826 status = i40e_aq_get_phy_register(hw, 11827 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, 11828 I40E_I2C_EEPROM_DEV_ADDR, 1, 11829 I40E_MODULE_SFF_8472_COMP, 11830 &sff8472_comp, NULL); 11831 if (status) 11832 return -EIO; 11833 11834 status = i40e_aq_get_phy_register(hw, 11835 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, 11836 I40E_I2C_EEPROM_DEV_ADDR, 1, 11837 I40E_MODULE_SFF_8472_SWAP, 11838 &sff8472_swap, NULL); 11839 if (status) 11840 return -EIO; 11841 11842 /* Check if the module requires address swap to access 11843 * the other EEPROM memory page. 11844 */ 11845 if (sff8472_swap & I40E_MODULE_SFF_ADDR_MODE) { 11846 PMD_DRV_LOG(WARNING, 11847 "Module address swap to access " 11848 "page 0xA2 is not supported.\n"); 11849 modinfo->type = RTE_ETH_MODULE_SFF_8079; 11850 modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN; 11851 } else if (sff8472_comp == 0x00) { 11852 /* Module is not SFF-8472 compliant */ 11853 modinfo->type = RTE_ETH_MODULE_SFF_8079; 11854 modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN; 11855 } else { 11856 modinfo->type = RTE_ETH_MODULE_SFF_8472; 11857 modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN; 11858 } 11859 break; 11860 case I40E_MODULE_TYPE_QSFP_PLUS: 11861 /* Read from memory page 0. */ 11862 status = i40e_aq_get_phy_register(hw, 11863 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, 11864 0, 1, 11865 I40E_MODULE_REVISION_ADDR, 11866 &sff8636_rev, NULL); 11867 if (status) 11868 return -EIO; 11869 /* Determine revision compliance byte */ 11870 if (sff8636_rev > 0x02) { 11871 /* Module is SFF-8636 compliant */ 11872 modinfo->type = RTE_ETH_MODULE_SFF_8636; 11873 modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN; 11874 } else { 11875 modinfo->type = RTE_ETH_MODULE_SFF_8436; 11876 modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN; 11877 } 11878 break; 11879 case I40E_MODULE_TYPE_QSFP28: 11880 modinfo->type = RTE_ETH_MODULE_SFF_8636; 11881 modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN; 11882 break; 11883 default: 11884 PMD_DRV_LOG(ERR, "Module type unrecognized\n"); 11885 return -EINVAL; 11886 } 11887 return 0; 11888 } 11889 11890 static int i40e_get_module_eeprom(struct rte_eth_dev *dev, 11891 struct rte_dev_eeprom_info *info) 11892 { 11893 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11894 bool is_sfp = false; 11895 i40e_status status; 11896 uint8_t *data = info->data; 11897 uint32_t value = 0; 11898 uint32_t i; 11899 11900 if (!info || !info->length || !data) 11901 return -EINVAL; 11902 11903 if (hw->phy.link_info.module_type[0] == I40E_MODULE_TYPE_SFP) 11904 is_sfp = true; 11905 11906 for (i = 0; i < info->length; i++) { 11907 u32 offset = i + info->offset; 11908 u32 addr = is_sfp ? I40E_I2C_EEPROM_DEV_ADDR : 0; 11909 11910 /* Check if we need to access the other memory page */ 11911 if (is_sfp) { 11912 if (offset >= RTE_ETH_MODULE_SFF_8079_LEN) { 11913 offset -= RTE_ETH_MODULE_SFF_8079_LEN; 11914 addr = I40E_I2C_EEPROM_DEV_ADDR2; 11915 } 11916 } else { 11917 while (offset >= RTE_ETH_MODULE_SFF_8436_LEN) { 11918 /* Compute memory page number and offset. */ 11919 offset -= RTE_ETH_MODULE_SFF_8436_LEN / 2; 11920 addr++; 11921 } 11922 } 11923 status = i40e_aq_get_phy_register(hw, 11924 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, 11925 addr, offset, 1, &value, NULL); 11926 if (status) 11927 return -EIO; 11928 data[i] = (uint8_t)value; 11929 } 11930 return 0; 11931 } 11932 11933 static int i40e_set_default_mac_addr(struct rte_eth_dev *dev, 11934 struct ether_addr *mac_addr) 11935 { 11936 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11937 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11938 struct i40e_vsi *vsi = pf->main_vsi; 11939 struct i40e_mac_filter_info mac_filter; 11940 struct i40e_mac_filter *f; 11941 int ret; 11942 11943 if (!is_valid_assigned_ether_addr(mac_addr)) { 11944 PMD_DRV_LOG(ERR, "Tried to set invalid MAC address."); 11945 return -EINVAL; 11946 } 11947 11948 TAILQ_FOREACH(f, &vsi->mac_list, next) { 11949 if (is_same_ether_addr(&pf->dev_addr, &f->mac_info.mac_addr)) 11950 break; 11951 } 11952 11953 if (f == NULL) { 11954 PMD_DRV_LOG(ERR, "Failed to find filter for default mac"); 11955 return -EIO; 11956 } 11957 11958 mac_filter = f->mac_info; 11959 ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr); 11960 if (ret != I40E_SUCCESS) { 11961 PMD_DRV_LOG(ERR, "Failed to delete mac filter"); 11962 return -EIO; 11963 } 11964 memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN); 11965 ret = i40e_vsi_add_mac(vsi, &mac_filter); 11966 if (ret != I40E_SUCCESS) { 11967 PMD_DRV_LOG(ERR, "Failed to add mac filter"); 11968 return -EIO; 11969 } 11970 memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN); 11971 11972 ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL, 11973 mac_addr->addr_bytes, NULL); 11974 if (ret != I40E_SUCCESS) { 11975 PMD_DRV_LOG(ERR, "Failed to change mac"); 11976 return -EIO; 11977 } 11978 11979 return 0; 11980 } 11981 11982 static int 11983 i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 11984 { 11985 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11986 struct rte_eth_dev_data *dev_data = pf->dev_data; 11987 uint32_t frame_size = mtu + I40E_ETH_OVERHEAD; 11988 int ret = 0; 11989 11990 /* check if mtu is within the allowed range */ 11991 if ((mtu < ETHER_MIN_MTU) || (frame_size > I40E_FRAME_SIZE_MAX)) 11992 return -EINVAL; 11993 11994 /* mtu setting is forbidden if port is start */ 11995 if (dev_data->dev_started) { 11996 PMD_DRV_LOG(ERR, "port %d must be stopped before configuration", 11997 dev_data->port_id); 11998 return -EBUSY; 11999 } 12000 12001 if (frame_size > ETHER_MAX_LEN) 12002 dev_data->dev_conf.rxmode.offloads |= 12003 DEV_RX_OFFLOAD_JUMBO_FRAME; 12004 else 12005 dev_data->dev_conf.rxmode.offloads &= 12006 ~DEV_RX_OFFLOAD_JUMBO_FRAME; 12007 12008 dev_data->dev_conf.rxmode.max_rx_pkt_len = frame_size; 12009 12010 return ret; 12011 } 12012 12013 /* Restore ethertype filter */ 12014 static void 12015 i40e_ethertype_filter_restore(struct i40e_pf *pf) 12016 { 12017 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12018 struct i40e_ethertype_filter_list 12019 *ethertype_list = &pf->ethertype.ethertype_list; 12020 struct i40e_ethertype_filter *f; 12021 struct i40e_control_filter_stats stats; 12022 uint16_t flags; 12023 12024 TAILQ_FOREACH(f, ethertype_list, rules) { 12025 flags = 0; 12026 if (!(f->flags & RTE_ETHTYPE_FLAGS_MAC)) 12027 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC; 12028 if (f->flags & RTE_ETHTYPE_FLAGS_DROP) 12029 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP; 12030 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE; 12031 12032 memset(&stats, 0, sizeof(stats)); 12033 i40e_aq_add_rem_control_packet_filter(hw, 12034 f->input.mac_addr.addr_bytes, 12035 f->input.ether_type, 12036 flags, pf->main_vsi->seid, 12037 f->queue, 1, &stats, NULL); 12038 } 12039 PMD_DRV_LOG(INFO, "Ethertype filter:" 12040 " mac_etype_used = %u, etype_used = %u," 12041 " mac_etype_free = %u, etype_free = %u", 12042 stats.mac_etype_used, stats.etype_used, 12043 stats.mac_etype_free, stats.etype_free); 12044 } 12045 12046 /* Restore tunnel filter */ 12047 static void 12048 i40e_tunnel_filter_restore(struct i40e_pf *pf) 12049 { 12050 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12051 struct i40e_vsi *vsi; 12052 struct i40e_pf_vf *vf; 12053 struct i40e_tunnel_filter_list 12054 *tunnel_list = &pf->tunnel.tunnel_list; 12055 struct i40e_tunnel_filter *f; 12056 struct i40e_aqc_cloud_filters_element_bb cld_filter; 12057 bool big_buffer = 0; 12058 12059 TAILQ_FOREACH(f, tunnel_list, rules) { 12060 if (!f->is_to_vf) 12061 vsi = pf->main_vsi; 12062 else { 12063 vf = &pf->vfs[f->vf_id]; 12064 vsi = vf->vsi; 12065 } 12066 memset(&cld_filter, 0, sizeof(cld_filter)); 12067 ether_addr_copy((struct ether_addr *)&f->input.outer_mac, 12068 (struct ether_addr *)&cld_filter.element.outer_mac); 12069 ether_addr_copy((struct ether_addr *)&f->input.inner_mac, 12070 (struct ether_addr *)&cld_filter.element.inner_mac); 12071 cld_filter.element.inner_vlan = f->input.inner_vlan; 12072 cld_filter.element.flags = f->input.flags; 12073 cld_filter.element.tenant_id = f->input.tenant_id; 12074 cld_filter.element.queue_number = f->queue; 12075 rte_memcpy(cld_filter.general_fields, 12076 f->input.general_fields, 12077 sizeof(f->input.general_fields)); 12078 12079 if (((f->input.flags & 12080 I40E_AQC_ADD_CLOUD_FILTER_0X11) == 12081 I40E_AQC_ADD_CLOUD_FILTER_0X11) || 12082 ((f->input.flags & 12083 I40E_AQC_ADD_CLOUD_FILTER_0X12) == 12084 I40E_AQC_ADD_CLOUD_FILTER_0X12) || 12085 ((f->input.flags & 12086 I40E_AQC_ADD_CLOUD_FILTER_0X10) == 12087 I40E_AQC_ADD_CLOUD_FILTER_0X10)) 12088 big_buffer = 1; 12089 12090 if (big_buffer) 12091 i40e_aq_add_cloud_filters_bb(hw, 12092 vsi->seid, &cld_filter, 1); 12093 else 12094 i40e_aq_add_cloud_filters(hw, vsi->seid, 12095 &cld_filter.element, 1); 12096 } 12097 } 12098 12099 /* Restore rss filter */ 12100 static inline void 12101 i40e_rss_filter_restore(struct i40e_pf *pf) 12102 { 12103 struct i40e_rte_flow_rss_conf *conf = 12104 &pf->rss_info; 12105 if (conf->conf.queue_num) 12106 i40e_config_rss_filter(pf, conf, TRUE); 12107 } 12108 12109 static void 12110 i40e_filter_restore(struct i40e_pf *pf) 12111 { 12112 i40e_ethertype_filter_restore(pf); 12113 i40e_tunnel_filter_restore(pf); 12114 i40e_fdir_filter_restore(pf); 12115 i40e_rss_filter_restore(pf); 12116 } 12117 12118 static bool 12119 is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv) 12120 { 12121 if (strcmp(dev->device->driver->name, drv->driver.name)) 12122 return false; 12123 12124 return true; 12125 } 12126 12127 bool 12128 is_i40e_supported(struct rte_eth_dev *dev) 12129 { 12130 return is_device_supported(dev, &rte_i40e_pmd); 12131 } 12132 12133 struct i40e_customized_pctype* 12134 i40e_find_customized_pctype(struct i40e_pf *pf, uint8_t index) 12135 { 12136 int i; 12137 12138 for (i = 0; i < I40E_CUSTOMIZED_MAX; i++) { 12139 if (pf->customized_pctype[i].index == index) 12140 return &pf->customized_pctype[i]; 12141 } 12142 return NULL; 12143 } 12144 12145 static int 12146 i40e_update_customized_pctype(struct rte_eth_dev *dev, uint8_t *pkg, 12147 uint32_t pkg_size, uint32_t proto_num, 12148 struct rte_pmd_i40e_proto_info *proto, 12149 enum rte_pmd_i40e_package_op op) 12150 { 12151 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 12152 uint32_t pctype_num; 12153 struct rte_pmd_i40e_ptype_info *pctype; 12154 uint32_t buff_size; 12155 struct i40e_customized_pctype *new_pctype = NULL; 12156 uint8_t proto_id; 12157 uint8_t pctype_value; 12158 char name[64]; 12159 uint32_t i, j, n; 12160 int ret; 12161 12162 if (op != RTE_PMD_I40E_PKG_OP_WR_ADD && 12163 op != RTE_PMD_I40E_PKG_OP_WR_DEL) { 12164 PMD_DRV_LOG(ERR, "Unsupported operation."); 12165 return -1; 12166 } 12167 12168 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 12169 (uint8_t *)&pctype_num, sizeof(pctype_num), 12170 RTE_PMD_I40E_PKG_INFO_PCTYPE_NUM); 12171 if (ret) { 12172 PMD_DRV_LOG(ERR, "Failed to get pctype number"); 12173 return -1; 12174 } 12175 if (!pctype_num) { 12176 PMD_DRV_LOG(INFO, "No new pctype added"); 12177 return -1; 12178 } 12179 12180 buff_size = pctype_num * sizeof(struct rte_pmd_i40e_proto_info); 12181 pctype = rte_zmalloc("new_pctype", buff_size, 0); 12182 if (!pctype) { 12183 PMD_DRV_LOG(ERR, "Failed to allocate memory"); 12184 return -1; 12185 } 12186 /* get information about new pctype list */ 12187 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 12188 (uint8_t *)pctype, buff_size, 12189 RTE_PMD_I40E_PKG_INFO_PCTYPE_LIST); 12190 if (ret) { 12191 PMD_DRV_LOG(ERR, "Failed to get pctype list"); 12192 rte_free(pctype); 12193 return -1; 12194 } 12195 12196 /* Update customized pctype. */ 12197 for (i = 0; i < pctype_num; i++) { 12198 pctype_value = pctype[i].ptype_id; 12199 memset(name, 0, sizeof(name)); 12200 for (j = 0; j < RTE_PMD_I40E_PROTO_NUM; j++) { 12201 proto_id = pctype[i].protocols[j]; 12202 if (proto_id == RTE_PMD_I40E_PROTO_UNUSED) 12203 continue; 12204 for (n = 0; n < proto_num; n++) { 12205 if (proto[n].proto_id != proto_id) 12206 continue; 12207 strlcat(name, proto[n].name, sizeof(name)); 12208 strlcat(name, "_", sizeof(name)); 12209 break; 12210 } 12211 } 12212 name[strlen(name) - 1] = '\0'; 12213 if (!strcmp(name, "GTPC")) 12214 new_pctype = 12215 i40e_find_customized_pctype(pf, 12216 I40E_CUSTOMIZED_GTPC); 12217 else if (!strcmp(name, "GTPU_IPV4")) 12218 new_pctype = 12219 i40e_find_customized_pctype(pf, 12220 I40E_CUSTOMIZED_GTPU_IPV4); 12221 else if (!strcmp(name, "GTPU_IPV6")) 12222 new_pctype = 12223 i40e_find_customized_pctype(pf, 12224 I40E_CUSTOMIZED_GTPU_IPV6); 12225 else if (!strcmp(name, "GTPU")) 12226 new_pctype = 12227 i40e_find_customized_pctype(pf, 12228 I40E_CUSTOMIZED_GTPU); 12229 if (new_pctype) { 12230 if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) { 12231 new_pctype->pctype = pctype_value; 12232 new_pctype->valid = true; 12233 } else { 12234 new_pctype->pctype = I40E_FILTER_PCTYPE_INVALID; 12235 new_pctype->valid = false; 12236 } 12237 } 12238 } 12239 12240 rte_free(pctype); 12241 return 0; 12242 } 12243 12244 static int 12245 i40e_update_customized_ptype(struct rte_eth_dev *dev, uint8_t *pkg, 12246 uint32_t pkg_size, uint32_t proto_num, 12247 struct rte_pmd_i40e_proto_info *proto, 12248 enum rte_pmd_i40e_package_op op) 12249 { 12250 struct rte_pmd_i40e_ptype_mapping *ptype_mapping; 12251 uint16_t port_id = dev->data->port_id; 12252 uint32_t ptype_num; 12253 struct rte_pmd_i40e_ptype_info *ptype; 12254 uint32_t buff_size; 12255 uint8_t proto_id; 12256 char name[RTE_PMD_I40E_DDP_NAME_SIZE]; 12257 uint32_t i, j, n; 12258 bool in_tunnel; 12259 int ret; 12260 12261 if (op != RTE_PMD_I40E_PKG_OP_WR_ADD && 12262 op != RTE_PMD_I40E_PKG_OP_WR_DEL) { 12263 PMD_DRV_LOG(ERR, "Unsupported operation."); 12264 return -1; 12265 } 12266 12267 if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) { 12268 rte_pmd_i40e_ptype_mapping_reset(port_id); 12269 return 0; 12270 } 12271 12272 /* get information about new ptype num */ 12273 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 12274 (uint8_t *)&ptype_num, sizeof(ptype_num), 12275 RTE_PMD_I40E_PKG_INFO_PTYPE_NUM); 12276 if (ret) { 12277 PMD_DRV_LOG(ERR, "Failed to get ptype number"); 12278 return ret; 12279 } 12280 if (!ptype_num) { 12281 PMD_DRV_LOG(INFO, "No new ptype added"); 12282 return -1; 12283 } 12284 12285 buff_size = ptype_num * sizeof(struct rte_pmd_i40e_ptype_info); 12286 ptype = rte_zmalloc("new_ptype", buff_size, 0); 12287 if (!ptype) { 12288 PMD_DRV_LOG(ERR, "Failed to allocate memory"); 12289 return -1; 12290 } 12291 12292 /* get information about new ptype list */ 12293 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 12294 (uint8_t *)ptype, buff_size, 12295 RTE_PMD_I40E_PKG_INFO_PTYPE_LIST); 12296 if (ret) { 12297 PMD_DRV_LOG(ERR, "Failed to get ptype list"); 12298 rte_free(ptype); 12299 return ret; 12300 } 12301 12302 buff_size = ptype_num * sizeof(struct rte_pmd_i40e_ptype_mapping); 12303 ptype_mapping = rte_zmalloc("ptype_mapping", buff_size, 0); 12304 if (!ptype_mapping) { 12305 PMD_DRV_LOG(ERR, "Failed to allocate memory"); 12306 rte_free(ptype); 12307 return -1; 12308 } 12309 12310 /* Update ptype mapping table. */ 12311 for (i = 0; i < ptype_num; i++) { 12312 ptype_mapping[i].hw_ptype = ptype[i].ptype_id; 12313 ptype_mapping[i].sw_ptype = 0; 12314 in_tunnel = false; 12315 for (j = 0; j < RTE_PMD_I40E_PROTO_NUM; j++) { 12316 proto_id = ptype[i].protocols[j]; 12317 if (proto_id == RTE_PMD_I40E_PROTO_UNUSED) 12318 continue; 12319 for (n = 0; n < proto_num; n++) { 12320 if (proto[n].proto_id != proto_id) 12321 continue; 12322 memset(name, 0, sizeof(name)); 12323 strcpy(name, proto[n].name); 12324 if (!strncasecmp(name, "PPPOE", 5)) 12325 ptype_mapping[i].sw_ptype |= 12326 RTE_PTYPE_L2_ETHER_PPPOE; 12327 else if (!strncasecmp(name, "IPV4FRAG", 8) && 12328 !in_tunnel) { 12329 ptype_mapping[i].sw_ptype |= 12330 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; 12331 ptype_mapping[i].sw_ptype |= 12332 RTE_PTYPE_L4_FRAG; 12333 } else if (!strncasecmp(name, "IPV4FRAG", 8) && 12334 in_tunnel) { 12335 ptype_mapping[i].sw_ptype |= 12336 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN; 12337 ptype_mapping[i].sw_ptype |= 12338 RTE_PTYPE_INNER_L4_FRAG; 12339 } else if (!strncasecmp(name, "OIPV4", 5)) { 12340 ptype_mapping[i].sw_ptype |= 12341 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; 12342 in_tunnel = true; 12343 } else if (!strncasecmp(name, "IPV4", 4) && 12344 !in_tunnel) 12345 ptype_mapping[i].sw_ptype |= 12346 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; 12347 else if (!strncasecmp(name, "IPV4", 4) && 12348 in_tunnel) 12349 ptype_mapping[i].sw_ptype |= 12350 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN; 12351 else if (!strncasecmp(name, "IPV6FRAG", 8) && 12352 !in_tunnel) { 12353 ptype_mapping[i].sw_ptype |= 12354 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; 12355 ptype_mapping[i].sw_ptype |= 12356 RTE_PTYPE_L4_FRAG; 12357 } else if (!strncasecmp(name, "IPV6FRAG", 8) && 12358 in_tunnel) { 12359 ptype_mapping[i].sw_ptype |= 12360 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN; 12361 ptype_mapping[i].sw_ptype |= 12362 RTE_PTYPE_INNER_L4_FRAG; 12363 } else if (!strncasecmp(name, "OIPV6", 5)) { 12364 ptype_mapping[i].sw_ptype |= 12365 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; 12366 in_tunnel = true; 12367 } else if (!strncasecmp(name, "IPV6", 4) && 12368 !in_tunnel) 12369 ptype_mapping[i].sw_ptype |= 12370 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; 12371 else if (!strncasecmp(name, "IPV6", 4) && 12372 in_tunnel) 12373 ptype_mapping[i].sw_ptype |= 12374 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN; 12375 else if (!strncasecmp(name, "UDP", 3) && 12376 !in_tunnel) 12377 ptype_mapping[i].sw_ptype |= 12378 RTE_PTYPE_L4_UDP; 12379 else if (!strncasecmp(name, "UDP", 3) && 12380 in_tunnel) 12381 ptype_mapping[i].sw_ptype |= 12382 RTE_PTYPE_INNER_L4_UDP; 12383 else if (!strncasecmp(name, "TCP", 3) && 12384 !in_tunnel) 12385 ptype_mapping[i].sw_ptype |= 12386 RTE_PTYPE_L4_TCP; 12387 else if (!strncasecmp(name, "TCP", 3) && 12388 in_tunnel) 12389 ptype_mapping[i].sw_ptype |= 12390 RTE_PTYPE_INNER_L4_TCP; 12391 else if (!strncasecmp(name, "SCTP", 4) && 12392 !in_tunnel) 12393 ptype_mapping[i].sw_ptype |= 12394 RTE_PTYPE_L4_SCTP; 12395 else if (!strncasecmp(name, "SCTP", 4) && 12396 in_tunnel) 12397 ptype_mapping[i].sw_ptype |= 12398 RTE_PTYPE_INNER_L4_SCTP; 12399 else if ((!strncasecmp(name, "ICMP", 4) || 12400 !strncasecmp(name, "ICMPV6", 6)) && 12401 !in_tunnel) 12402 ptype_mapping[i].sw_ptype |= 12403 RTE_PTYPE_L4_ICMP; 12404 else if ((!strncasecmp(name, "ICMP", 4) || 12405 !strncasecmp(name, "ICMPV6", 6)) && 12406 in_tunnel) 12407 ptype_mapping[i].sw_ptype |= 12408 RTE_PTYPE_INNER_L4_ICMP; 12409 else if (!strncasecmp(name, "GTPC", 4)) { 12410 ptype_mapping[i].sw_ptype |= 12411 RTE_PTYPE_TUNNEL_GTPC; 12412 in_tunnel = true; 12413 } else if (!strncasecmp(name, "GTPU", 4)) { 12414 ptype_mapping[i].sw_ptype |= 12415 RTE_PTYPE_TUNNEL_GTPU; 12416 in_tunnel = true; 12417 } else if (!strncasecmp(name, "GRENAT", 6)) { 12418 ptype_mapping[i].sw_ptype |= 12419 RTE_PTYPE_TUNNEL_GRENAT; 12420 in_tunnel = true; 12421 } else if (!strncasecmp(name, "L2TPV2CTL", 9) || 12422 !strncasecmp(name, "L2TPV2", 6)) { 12423 ptype_mapping[i].sw_ptype |= 12424 RTE_PTYPE_TUNNEL_L2TP; 12425 in_tunnel = true; 12426 } 12427 12428 break; 12429 } 12430 } 12431 } 12432 12433 ret = rte_pmd_i40e_ptype_mapping_update(port_id, ptype_mapping, 12434 ptype_num, 0); 12435 if (ret) 12436 PMD_DRV_LOG(ERR, "Failed to update mapping table."); 12437 12438 rte_free(ptype_mapping); 12439 rte_free(ptype); 12440 return ret; 12441 } 12442 12443 void 12444 i40e_update_customized_info(struct rte_eth_dev *dev, uint8_t *pkg, 12445 uint32_t pkg_size, enum rte_pmd_i40e_package_op op) 12446 { 12447 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 12448 uint32_t proto_num; 12449 struct rte_pmd_i40e_proto_info *proto; 12450 uint32_t buff_size; 12451 uint32_t i; 12452 int ret; 12453 12454 if (op != RTE_PMD_I40E_PKG_OP_WR_ADD && 12455 op != RTE_PMD_I40E_PKG_OP_WR_DEL) { 12456 PMD_DRV_LOG(ERR, "Unsupported operation."); 12457 return; 12458 } 12459 12460 /* get information about protocol number */ 12461 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 12462 (uint8_t *)&proto_num, sizeof(proto_num), 12463 RTE_PMD_I40E_PKG_INFO_PROTOCOL_NUM); 12464 if (ret) { 12465 PMD_DRV_LOG(ERR, "Failed to get protocol number"); 12466 return; 12467 } 12468 if (!proto_num) { 12469 PMD_DRV_LOG(INFO, "No new protocol added"); 12470 return; 12471 } 12472 12473 buff_size = proto_num * sizeof(struct rte_pmd_i40e_proto_info); 12474 proto = rte_zmalloc("new_proto", buff_size, 0); 12475 if (!proto) { 12476 PMD_DRV_LOG(ERR, "Failed to allocate memory"); 12477 return; 12478 } 12479 12480 /* get information about protocol list */ 12481 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 12482 (uint8_t *)proto, buff_size, 12483 RTE_PMD_I40E_PKG_INFO_PROTOCOL_LIST); 12484 if (ret) { 12485 PMD_DRV_LOG(ERR, "Failed to get protocol list"); 12486 rte_free(proto); 12487 return; 12488 } 12489 12490 /* Check if GTP is supported. */ 12491 for (i = 0; i < proto_num; i++) { 12492 if (!strncmp(proto[i].name, "GTP", 3)) { 12493 if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) 12494 pf->gtp_support = true; 12495 else 12496 pf->gtp_support = false; 12497 break; 12498 } 12499 } 12500 12501 /* Update customized pctype info */ 12502 ret = i40e_update_customized_pctype(dev, pkg, pkg_size, 12503 proto_num, proto, op); 12504 if (ret) 12505 PMD_DRV_LOG(INFO, "No pctype is updated."); 12506 12507 /* Update customized ptype info */ 12508 ret = i40e_update_customized_ptype(dev, pkg, pkg_size, 12509 proto_num, proto, op); 12510 if (ret) 12511 PMD_DRV_LOG(INFO, "No ptype is updated."); 12512 12513 rte_free(proto); 12514 } 12515 12516 /* Create a QinQ cloud filter 12517 * 12518 * The Fortville NIC has limited resources for tunnel filters, 12519 * so we can only reuse existing filters. 12520 * 12521 * In step 1 we define which Field Vector fields can be used for 12522 * filter types. 12523 * As we do not have the inner tag defined as a field, 12524 * we have to define it first, by reusing one of L1 entries. 12525 * 12526 * In step 2 we are replacing one of existing filter types with 12527 * a new one for QinQ. 12528 * As we reusing L1 and replacing L2, some of the default filter 12529 * types will disappear,which depends on L1 and L2 entries we reuse. 12530 * 12531 * Step 1: Create L1 filter of outer vlan (12b) + inner vlan (12b) 12532 * 12533 * 1. Create L1 filter of outer vlan (12b) which will be in use 12534 * later when we define the cloud filter. 12535 * a. Valid_flags.replace_cloud = 0 12536 * b. Old_filter = 10 (Stag_Inner_Vlan) 12537 * c. New_filter = 0x10 12538 * d. TR bit = 0xff (optional, not used here) 12539 * e. Buffer – 2 entries: 12540 * i. Byte 0 = 8 (outer vlan FV index). 12541 * Byte 1 = 0 (rsv) 12542 * Byte 2-3 = 0x0fff 12543 * ii. Byte 0 = 37 (inner vlan FV index). 12544 * Byte 1 =0 (rsv) 12545 * Byte 2-3 = 0x0fff 12546 * 12547 * Step 2: 12548 * 2. Create cloud filter using two L1 filters entries: stag and 12549 * new filter(outer vlan+ inner vlan) 12550 * a. Valid_flags.replace_cloud = 1 12551 * b. Old_filter = 1 (instead of outer IP) 12552 * c. New_filter = 0x10 12553 * d. Buffer – 2 entries: 12554 * i. Byte 0 = 0x80 | 7 (valid | Stag). 12555 * Byte 1-3 = 0 (rsv) 12556 * ii. Byte 8 = 0x80 | 0x10 (valid | new l1 filter step1) 12557 * Byte 9-11 = 0 (rsv) 12558 */ 12559 static int 12560 i40e_cloud_filter_qinq_create(struct i40e_pf *pf) 12561 { 12562 int ret = -ENOTSUP; 12563 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 12564 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 12565 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12566 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 12567 12568 if (pf->support_multi_driver) { 12569 PMD_DRV_LOG(ERR, "Replace cloud filter is not supported."); 12570 return ret; 12571 } 12572 12573 /* Init */ 12574 memset(&filter_replace, 0, 12575 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 12576 memset(&filter_replace_buf, 0, 12577 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 12578 12579 /* create L1 filter */ 12580 filter_replace.old_filter_type = 12581 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_IVLAN; 12582 filter_replace.new_filter_type = I40E_AQC_ADD_CLOUD_FILTER_0X10; 12583 filter_replace.tr_bit = 0; 12584 12585 /* Prepare the buffer, 2 entries */ 12586 filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_VLAN; 12587 filter_replace_buf.data[0] |= 12588 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 12589 /* Field Vector 12b mask */ 12590 filter_replace_buf.data[2] = 0xff; 12591 filter_replace_buf.data[3] = 0x0f; 12592 filter_replace_buf.data[4] = 12593 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_INNER_VLAN; 12594 filter_replace_buf.data[4] |= 12595 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 12596 /* Field Vector 12b mask */ 12597 filter_replace_buf.data[6] = 0xff; 12598 filter_replace_buf.data[7] = 0x0f; 12599 ret = i40e_aq_replace_cloud_filters(hw, &filter_replace, 12600 &filter_replace_buf); 12601 if (ret != I40E_SUCCESS) 12602 return ret; 12603 12604 if (filter_replace.old_filter_type != 12605 filter_replace.new_filter_type) 12606 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type." 12607 " original: 0x%x, new: 0x%x", 12608 dev->device->name, 12609 filter_replace.old_filter_type, 12610 filter_replace.new_filter_type); 12611 12612 /* Apply the second L2 cloud filter */ 12613 memset(&filter_replace, 0, 12614 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 12615 memset(&filter_replace_buf, 0, 12616 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 12617 12618 /* create L2 filter, input for L2 filter will be L1 filter */ 12619 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER; 12620 filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_OIP; 12621 filter_replace.new_filter_type = I40E_AQC_ADD_CLOUD_FILTER_0X10; 12622 12623 /* Prepare the buffer, 2 entries */ 12624 filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 12625 filter_replace_buf.data[0] |= 12626 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 12627 filter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_0X10; 12628 filter_replace_buf.data[4] |= 12629 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 12630 ret = i40e_aq_replace_cloud_filters(hw, &filter_replace, 12631 &filter_replace_buf); 12632 if (!ret && (filter_replace.old_filter_type != 12633 filter_replace.new_filter_type)) 12634 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 12635 " original: 0x%x, new: 0x%x", 12636 dev->device->name, 12637 filter_replace.old_filter_type, 12638 filter_replace.new_filter_type); 12639 12640 return ret; 12641 } 12642 12643 int 12644 i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out, 12645 const struct rte_flow_action_rss *in) 12646 { 12647 if (in->key_len > RTE_DIM(out->key) || 12648 in->queue_num > RTE_DIM(out->queue)) 12649 return -EINVAL; 12650 if (!in->key && in->key_len) 12651 return -EINVAL; 12652 out->conf = (struct rte_flow_action_rss){ 12653 .func = in->func, 12654 .level = in->level, 12655 .types = in->types, 12656 .key_len = in->key_len, 12657 .queue_num = in->queue_num, 12658 .queue = memcpy(out->queue, in->queue, 12659 sizeof(*in->queue) * in->queue_num), 12660 }; 12661 if (in->key) 12662 out->conf.key = memcpy(out->key, in->key, in->key_len); 12663 return 0; 12664 } 12665 12666 int 12667 i40e_action_rss_same(const struct rte_flow_action_rss *comp, 12668 const struct rte_flow_action_rss *with) 12669 { 12670 return (comp->func == with->func && 12671 comp->level == with->level && 12672 comp->types == with->types && 12673 comp->key_len == with->key_len && 12674 comp->queue_num == with->queue_num && 12675 !memcmp(comp->key, with->key, with->key_len) && 12676 !memcmp(comp->queue, with->queue, 12677 sizeof(*with->queue) * with->queue_num)); 12678 } 12679 12680 int 12681 i40e_config_rss_filter(struct i40e_pf *pf, 12682 struct i40e_rte_flow_rss_conf *conf, bool add) 12683 { 12684 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12685 uint32_t i, lut = 0; 12686 uint16_t j, num; 12687 struct rte_eth_rss_conf rss_conf = { 12688 .rss_key = conf->conf.key_len ? 12689 (void *)(uintptr_t)conf->conf.key : NULL, 12690 .rss_key_len = conf->conf.key_len, 12691 .rss_hf = conf->conf.types, 12692 }; 12693 struct i40e_rte_flow_rss_conf *rss_info = &pf->rss_info; 12694 12695 if (!add) { 12696 if (i40e_action_rss_same(&rss_info->conf, &conf->conf)) { 12697 i40e_pf_disable_rss(pf); 12698 memset(rss_info, 0, 12699 sizeof(struct i40e_rte_flow_rss_conf)); 12700 return 0; 12701 } 12702 return -EINVAL; 12703 } 12704 12705 if (rss_info->conf.queue_num) 12706 return -EINVAL; 12707 12708 /* If both VMDQ and RSS enabled, not all of PF queues are configured. 12709 * It's necessary to calculate the actual PF queues that are configured. 12710 */ 12711 if (pf->dev_data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_VMDQ_FLAG) 12712 num = i40e_pf_calc_configured_queues_num(pf); 12713 else 12714 num = pf->dev_data->nb_rx_queues; 12715 12716 num = RTE_MIN(num, conf->conf.queue_num); 12717 PMD_DRV_LOG(INFO, "Max of contiguous %u PF queues are configured", 12718 num); 12719 12720 if (num == 0) { 12721 PMD_DRV_LOG(ERR, "No PF queues are configured to enable RSS"); 12722 return -ENOTSUP; 12723 } 12724 12725 /* Fill in redirection table */ 12726 for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) { 12727 if (j == num) 12728 j = 0; 12729 lut = (lut << 8) | (conf->conf.queue[j] & ((0x1 << 12730 hw->func_caps.rss_table_entry_width) - 1)); 12731 if ((i & 3) == 3) 12732 I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut); 12733 } 12734 12735 if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0) { 12736 i40e_pf_disable_rss(pf); 12737 return 0; 12738 } 12739 if (rss_conf.rss_key == NULL || rss_conf.rss_key_len < 12740 (I40E_PFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t)) { 12741 /* Random default keys */ 12742 static uint32_t rss_key_default[] = {0x6b793944, 12743 0x23504cb5, 0x5bea75b6, 0x309f4f12, 0x3dc0a2b8, 12744 0x024ddcdf, 0x339b8ca0, 0x4c4af64a, 0x34fac605, 12745 0x55d85839, 0x3a58997d, 0x2ec938e1, 0x66031581}; 12746 12747 rss_conf.rss_key = (uint8_t *)rss_key_default; 12748 rss_conf.rss_key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) * 12749 sizeof(uint32_t); 12750 PMD_DRV_LOG(INFO, 12751 "No valid RSS key config for i40e, using default\n"); 12752 } 12753 12754 i40e_hw_rss_hash_set(pf, &rss_conf); 12755 12756 if (i40e_rss_conf_init(rss_info, &conf->conf)) 12757 return -EINVAL; 12758 12759 return 0; 12760 } 12761 12762 RTE_INIT(i40e_init_log) 12763 { 12764 i40e_logtype_init = rte_log_register("pmd.net.i40e.init"); 12765 if (i40e_logtype_init >= 0) 12766 rte_log_set_level(i40e_logtype_init, RTE_LOG_NOTICE); 12767 i40e_logtype_driver = rte_log_register("pmd.net.i40e.driver"); 12768 if (i40e_logtype_driver >= 0) 12769 rte_log_set_level(i40e_logtype_driver, RTE_LOG_NOTICE); 12770 } 12771 12772 RTE_PMD_REGISTER_PARAM_STRING(net_i40e, 12773 ETH_I40E_FLOATING_VEB_ARG "=1" 12774 ETH_I40E_FLOATING_VEB_LIST_ARG "=<string>" 12775 ETH_I40E_QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16" 12776 ETH_I40E_SUPPORT_MULTI_DRIVER "=1" 12777 ETH_I40E_USE_LATEST_VEC "=0|1"); 12778