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