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