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