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