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