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