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