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 43 #define ETH_I40E_FLOATING_VEB_ARG "enable_floating_veb" 44 #define ETH_I40E_FLOATING_VEB_LIST_ARG "floating_veb_list" 45 #define ETH_I40E_SUPPORT_MULTI_DRIVER "support-multi-driver" 46 #define ETH_I40E_QUEUE_NUM_PER_VF_ARG "queue-num-per-vf" 47 #define ETH_I40E_USE_LATEST_VEC "use-latest-supported-vec" 48 #define ETH_I40E_VF_MSG_CFG "vf_msg_cfg" 49 50 #define I40E_CLEAR_PXE_WAIT_MS 200 51 #define I40E_VSI_TSR_QINQ_STRIP 0x4010 52 #define I40E_VSI_TSR(_i) (0x00050800 + ((_i) * 4)) 53 54 /* Maximun number of capability elements */ 55 #define I40E_MAX_CAP_ELE_NUM 128 56 57 /* Wait count and interval */ 58 #define I40E_CHK_Q_ENA_COUNT 1000 59 #define I40E_CHK_Q_ENA_INTERVAL_US 1000 60 61 /* Maximun number of VSI */ 62 #define I40E_MAX_NUM_VSIS (384UL) 63 64 #define I40E_PRE_TX_Q_CFG_WAIT_US 10 /* 10 us */ 65 66 /* Flow control default timer */ 67 #define I40E_DEFAULT_PAUSE_TIME 0xFFFFU 68 69 /* Flow control enable fwd bit */ 70 #define I40E_PRTMAC_FWD_CTRL 0x00000001 71 72 /* Receive Packet Buffer size */ 73 #define I40E_RXPBSIZE (968 * 1024) 74 75 /* Kilobytes shift */ 76 #define I40E_KILOSHIFT 10 77 78 /* Flow control default high water */ 79 #define I40E_DEFAULT_HIGH_WATER (0xF2000 >> I40E_KILOSHIFT) 80 81 /* Flow control default low water */ 82 #define I40E_DEFAULT_LOW_WATER (0xF2000 >> I40E_KILOSHIFT) 83 84 /* Receive Average Packet Size in Byte*/ 85 #define I40E_PACKET_AVERAGE_SIZE 128 86 87 /* Mask of PF interrupt causes */ 88 #define I40E_PFINT_ICR0_ENA_MASK ( \ 89 I40E_PFINT_ICR0_ENA_ECC_ERR_MASK | \ 90 I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK | \ 91 I40E_PFINT_ICR0_ENA_GRST_MASK | \ 92 I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK | \ 93 I40E_PFINT_ICR0_ENA_STORM_DETECT_MASK | \ 94 I40E_PFINT_ICR0_ENA_HMC_ERR_MASK | \ 95 I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK | \ 96 I40E_PFINT_ICR0_ENA_VFLR_MASK | \ 97 I40E_PFINT_ICR0_ENA_ADMINQ_MASK) 98 99 #define I40E_FLOW_TYPES ( \ 100 (1UL << RTE_ETH_FLOW_FRAG_IPV4) | \ 101 (1UL << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \ 102 (1UL << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \ 103 (1UL << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \ 104 (1UL << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \ 105 (1UL << RTE_ETH_FLOW_FRAG_IPV6) | \ 106 (1UL << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \ 107 (1UL << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \ 108 (1UL << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \ 109 (1UL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER) | \ 110 (1UL << RTE_ETH_FLOW_L2_PAYLOAD)) 111 112 /* Additional timesync values. */ 113 #define I40E_PTP_40GB_INCVAL 0x0199999999ULL 114 #define I40E_PTP_10GB_INCVAL 0x0333333333ULL 115 #define I40E_PTP_1GB_INCVAL 0x2000000000ULL 116 #define I40E_PRTTSYN_TSYNENA 0x80000000 117 #define I40E_PRTTSYN_TSYNTYPE 0x0e000000 118 #define I40E_CYCLECOUNTER_MASK 0xffffffffffffffffULL 119 120 /** 121 * Below are values for writing un-exposed registers suggested 122 * by silicon experts 123 */ 124 /* Destination MAC address */ 125 #define I40E_REG_INSET_L2_DMAC 0xE000000000000000ULL 126 /* Source MAC address */ 127 #define I40E_REG_INSET_L2_SMAC 0x1C00000000000000ULL 128 /* Outer (S-Tag) VLAN tag in the outer L2 header */ 129 #define I40E_REG_INSET_L2_OUTER_VLAN 0x0000000004000000ULL 130 /* Inner (C-Tag) or single VLAN tag in the outer L2 header */ 131 #define I40E_REG_INSET_L2_INNER_VLAN 0x0080000000000000ULL 132 /* Single VLAN tag in the inner L2 header */ 133 #define I40E_REG_INSET_TUNNEL_VLAN 0x0100000000000000ULL 134 /* Source IPv4 address */ 135 #define I40E_REG_INSET_L3_SRC_IP4 0x0001800000000000ULL 136 /* Destination IPv4 address */ 137 #define I40E_REG_INSET_L3_DST_IP4 0x0000001800000000ULL 138 /* Source IPv4 address for X722 */ 139 #define I40E_X722_REG_INSET_L3_SRC_IP4 0x0006000000000000ULL 140 /* Destination IPv4 address for X722 */ 141 #define I40E_X722_REG_INSET_L3_DST_IP4 0x0000060000000000ULL 142 /* IPv4 Protocol for X722 */ 143 #define I40E_X722_REG_INSET_L3_IP4_PROTO 0x0010000000000000ULL 144 /* IPv4 Time to Live for X722 */ 145 #define I40E_X722_REG_INSET_L3_IP4_TTL 0x0010000000000000ULL 146 /* IPv4 Type of Service (TOS) */ 147 #define I40E_REG_INSET_L3_IP4_TOS 0x0040000000000000ULL 148 /* IPv4 Protocol */ 149 #define I40E_REG_INSET_L3_IP4_PROTO 0x0004000000000000ULL 150 /* IPv4 Time to Live */ 151 #define I40E_REG_INSET_L3_IP4_TTL 0x0004000000000000ULL 152 /* Source IPv6 address */ 153 #define I40E_REG_INSET_L3_SRC_IP6 0x0007F80000000000ULL 154 /* Destination IPv6 address */ 155 #define I40E_REG_INSET_L3_DST_IP6 0x000007F800000000ULL 156 /* IPv6 Traffic Class (TC) */ 157 #define I40E_REG_INSET_L3_IP6_TC 0x0040000000000000ULL 158 /* IPv6 Next Header */ 159 #define I40E_REG_INSET_L3_IP6_NEXT_HDR 0x0008000000000000ULL 160 /* IPv6 Hop Limit */ 161 #define I40E_REG_INSET_L3_IP6_HOP_LIMIT 0x0008000000000000ULL 162 /* Source L4 port */ 163 #define I40E_REG_INSET_L4_SRC_PORT 0x0000000400000000ULL 164 /* Destination L4 port */ 165 #define I40E_REG_INSET_L4_DST_PORT 0x0000000200000000ULL 166 /* SCTP verification tag */ 167 #define I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG 0x0000000180000000ULL 168 /* Inner destination MAC address (MAC-in-UDP/MAC-in-GRE)*/ 169 #define I40E_REG_INSET_TUNNEL_L2_INNER_DST_MAC 0x0000000001C00000ULL 170 /* Source port of tunneling UDP */ 171 #define I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT 0x0000000000200000ULL 172 /* Destination port of tunneling UDP */ 173 #define I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT 0x0000000000100000ULL 174 /* UDP Tunneling ID, NVGRE/GRE key */ 175 #define I40E_REG_INSET_TUNNEL_ID 0x00000000000C0000ULL 176 /* Last ether type */ 177 #define I40E_REG_INSET_LAST_ETHER_TYPE 0x0000000000004000ULL 178 /* Tunneling outer destination IPv4 address */ 179 #define I40E_REG_INSET_TUNNEL_L3_DST_IP4 0x00000000000000C0ULL 180 /* Tunneling outer destination IPv6 address */ 181 #define I40E_REG_INSET_TUNNEL_L3_DST_IP6 0x0000000000003FC0ULL 182 /* 1st word of flex payload */ 183 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD1 0x0000000000002000ULL 184 /* 2nd word of flex payload */ 185 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD2 0x0000000000001000ULL 186 /* 3rd word of flex payload */ 187 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD3 0x0000000000000800ULL 188 /* 4th word of flex payload */ 189 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD4 0x0000000000000400ULL 190 /* 5th word of flex payload */ 191 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD5 0x0000000000000200ULL 192 /* 6th word of flex payload */ 193 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD6 0x0000000000000100ULL 194 /* 7th word of flex payload */ 195 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD7 0x0000000000000080ULL 196 /* 8th word of flex payload */ 197 #define I40E_REG_INSET_FLEX_PAYLOAD_WORD8 0x0000000000000040ULL 198 /* all 8 words flex payload */ 199 #define I40E_REG_INSET_FLEX_PAYLOAD_WORDS 0x0000000000003FC0ULL 200 #define I40E_REG_INSET_MASK_DEFAULT 0x0000000000000000ULL 201 202 #define I40E_TRANSLATE_INSET 0 203 #define I40E_TRANSLATE_REG 1 204 205 #define I40E_INSET_IPV4_TOS_MASK 0x0009FF00UL 206 #define I40E_INSET_IPv4_TTL_MASK 0x000D00FFUL 207 #define I40E_INSET_IPV4_PROTO_MASK 0x000DFF00UL 208 #define I40E_INSET_IPV6_TC_MASK 0x0009F00FUL 209 #define I40E_INSET_IPV6_HOP_LIMIT_MASK 0x000CFF00UL 210 #define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL 211 212 /* PCI offset for querying capability */ 213 #define PCI_DEV_CAP_REG 0xA4 214 /* PCI offset for enabling/disabling Extended Tag */ 215 #define PCI_DEV_CTRL_REG 0xA8 216 /* Bit mask of Extended Tag capability */ 217 #define PCI_DEV_CAP_EXT_TAG_MASK 0x20 218 /* Bit shift of Extended Tag enable/disable */ 219 #define PCI_DEV_CTRL_EXT_TAG_SHIFT 8 220 /* Bit mask of Extended Tag enable/disable */ 221 #define PCI_DEV_CTRL_EXT_TAG_MASK (1 << PCI_DEV_CTRL_EXT_TAG_SHIFT) 222 223 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev, void *init_params); 224 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev); 225 static int i40e_dev_configure(struct rte_eth_dev *dev); 226 static int i40e_dev_start(struct rte_eth_dev *dev); 227 static int i40e_dev_stop(struct rte_eth_dev *dev); 228 static int i40e_dev_close(struct rte_eth_dev *dev); 229 static int i40e_dev_reset(struct rte_eth_dev *dev); 230 static int i40e_dev_promiscuous_enable(struct rte_eth_dev *dev); 231 static int i40e_dev_promiscuous_disable(struct rte_eth_dev *dev); 232 static int i40e_dev_allmulticast_enable(struct rte_eth_dev *dev); 233 static int i40e_dev_allmulticast_disable(struct rte_eth_dev *dev); 234 static int i40e_dev_set_link_up(struct rte_eth_dev *dev); 235 static int i40e_dev_set_link_down(struct rte_eth_dev *dev); 236 static int i40e_dev_stats_get(struct rte_eth_dev *dev, 237 struct rte_eth_stats *stats); 238 static int i40e_dev_xstats_get(struct rte_eth_dev *dev, 239 struct rte_eth_xstat *xstats, unsigned n); 240 static int i40e_dev_xstats_get_names(struct rte_eth_dev *dev, 241 struct rte_eth_xstat_name *xstats_names, 242 unsigned limit); 243 static int i40e_dev_stats_reset(struct rte_eth_dev *dev); 244 static int i40e_fw_version_get(struct rte_eth_dev *dev, 245 char *fw_version, size_t fw_size); 246 static int i40e_dev_info_get(struct rte_eth_dev *dev, 247 struct rte_eth_dev_info *dev_info); 248 static int i40e_vlan_filter_set(struct rte_eth_dev *dev, 249 uint16_t vlan_id, 250 int on); 251 static int i40e_vlan_tpid_set(struct rte_eth_dev *dev, 252 enum rte_vlan_type vlan_type, 253 uint16_t tpid); 254 static int i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask); 255 static void i40e_vlan_strip_queue_set(struct rte_eth_dev *dev, 256 uint16_t queue, 257 int on); 258 static int i40e_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on); 259 static int i40e_dev_led_on(struct rte_eth_dev *dev); 260 static int i40e_dev_led_off(struct rte_eth_dev *dev); 261 static int i40e_flow_ctrl_get(struct rte_eth_dev *dev, 262 struct rte_eth_fc_conf *fc_conf); 263 static int i40e_flow_ctrl_set(struct rte_eth_dev *dev, 264 struct rte_eth_fc_conf *fc_conf); 265 static int i40e_priority_flow_ctrl_set(struct rte_eth_dev *dev, 266 struct rte_eth_pfc_conf *pfc_conf); 267 static int i40e_macaddr_add(struct rte_eth_dev *dev, 268 struct rte_ether_addr *mac_addr, 269 uint32_t index, 270 uint32_t pool); 271 static void i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index); 272 static int i40e_dev_rss_reta_update(struct rte_eth_dev *dev, 273 struct rte_eth_rss_reta_entry64 *reta_conf, 274 uint16_t reta_size); 275 static int i40e_dev_rss_reta_query(struct rte_eth_dev *dev, 276 struct rte_eth_rss_reta_entry64 *reta_conf, 277 uint16_t reta_size); 278 279 static int i40e_get_cap(struct i40e_hw *hw); 280 static int i40e_pf_parameter_init(struct rte_eth_dev *dev); 281 static int i40e_pf_setup(struct i40e_pf *pf); 282 static int i40e_dev_rxtx_init(struct i40e_pf *pf); 283 static int i40e_vmdq_setup(struct rte_eth_dev *dev); 284 static int i40e_dcb_setup(struct rte_eth_dev *dev); 285 static void i40e_stat_update_32(struct i40e_hw *hw, uint32_t reg, 286 bool offset_loaded, uint64_t *offset, uint64_t *stat); 287 static void i40e_stat_update_48(struct i40e_hw *hw, 288 uint32_t hireg, 289 uint32_t loreg, 290 bool offset_loaded, 291 uint64_t *offset, 292 uint64_t *stat); 293 static void i40e_pf_config_irq0(struct i40e_hw *hw, bool no_queue); 294 static void i40e_dev_interrupt_handler(void *param); 295 static void i40e_dev_alarm_handler(void *param); 296 static int i40e_res_pool_init(struct i40e_res_pool_info *pool, 297 uint32_t base, uint32_t num); 298 static void i40e_res_pool_destroy(struct i40e_res_pool_info *pool); 299 static int i40e_res_pool_free(struct i40e_res_pool_info *pool, 300 uint32_t base); 301 static int i40e_res_pool_alloc(struct i40e_res_pool_info *pool, 302 uint16_t num); 303 static int i40e_dev_init_vlan(struct rte_eth_dev *dev); 304 static int i40e_veb_release(struct i40e_veb *veb); 305 static struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, 306 struct i40e_vsi *vsi); 307 static int i40e_vsi_config_double_vlan(struct i40e_vsi *vsi, int on); 308 static inline int i40e_find_all_mac_for_vlan(struct i40e_vsi *vsi, 309 struct i40e_macvlan_filter *mv_f, 310 int num, 311 uint16_t vlan); 312 static int i40e_vsi_remove_all_macvlan_filter(struct i40e_vsi *vsi); 313 static int i40e_dev_rss_hash_update(struct rte_eth_dev *dev, 314 struct rte_eth_rss_conf *rss_conf); 315 static int i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 316 struct rte_eth_rss_conf *rss_conf); 317 static int i40e_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, 318 struct rte_eth_udp_tunnel *udp_tunnel); 319 static int i40e_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, 320 struct rte_eth_udp_tunnel *udp_tunnel); 321 static void i40e_filter_input_set_init(struct i40e_pf *pf); 322 static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev, 323 enum rte_filter_type filter_type, 324 enum rte_filter_op filter_op, 325 void *arg); 326 static int i40e_dev_get_dcb_info(struct rte_eth_dev *dev, 327 struct rte_eth_dcb_info *dcb_info); 328 static int i40e_dev_sync_phy_type(struct i40e_hw *hw); 329 static void i40e_configure_registers(struct i40e_hw *hw); 330 static void i40e_hw_init(struct rte_eth_dev *dev); 331 static int i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi); 332 static enum i40e_status_code i40e_aq_del_mirror_rule(struct i40e_hw *hw, 333 uint16_t seid, 334 uint16_t rule_type, 335 uint16_t *entries, 336 uint16_t count, 337 uint16_t rule_id); 338 static int i40e_mirror_rule_set(struct rte_eth_dev *dev, 339 struct rte_eth_mirror_conf *mirror_conf, 340 uint8_t sw_id, uint8_t on); 341 static int i40e_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t sw_id); 342 343 static int i40e_timesync_enable(struct rte_eth_dev *dev); 344 static int i40e_timesync_disable(struct rte_eth_dev *dev); 345 static int i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev, 346 struct timespec *timestamp, 347 uint32_t flags); 348 static int i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev, 349 struct timespec *timestamp); 350 static void i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw); 351 352 static int i40e_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta); 353 354 static int i40e_timesync_read_time(struct rte_eth_dev *dev, 355 struct timespec *timestamp); 356 static int i40e_timesync_write_time(struct rte_eth_dev *dev, 357 const struct timespec *timestamp); 358 359 static int i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, 360 uint16_t queue_id); 361 static int i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, 362 uint16_t queue_id); 363 364 static int i40e_get_regs(struct rte_eth_dev *dev, 365 struct rte_dev_reg_info *regs); 366 367 static int i40e_get_eeprom_length(struct rte_eth_dev *dev); 368 369 static int i40e_get_eeprom(struct rte_eth_dev *dev, 370 struct rte_dev_eeprom_info *eeprom); 371 372 static int i40e_get_module_info(struct rte_eth_dev *dev, 373 struct rte_eth_dev_module_info *modinfo); 374 static int i40e_get_module_eeprom(struct rte_eth_dev *dev, 375 struct rte_dev_eeprom_info *info); 376 377 static int i40e_set_default_mac_addr(struct rte_eth_dev *dev, 378 struct rte_ether_addr *mac_addr); 379 380 static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); 381 382 static int i40e_ethertype_filter_convert( 383 const struct rte_eth_ethertype_filter *input, 384 struct i40e_ethertype_filter *filter); 385 static int i40e_sw_ethertype_filter_insert(struct i40e_pf *pf, 386 struct i40e_ethertype_filter *filter); 387 388 static int i40e_tunnel_filter_convert( 389 struct i40e_aqc_cloud_filters_element_bb *cld_filter, 390 struct i40e_tunnel_filter *tunnel_filter); 391 static int i40e_sw_tunnel_filter_insert(struct i40e_pf *pf, 392 struct i40e_tunnel_filter *tunnel_filter); 393 static int i40e_cloud_filter_qinq_create(struct i40e_pf *pf); 394 395 static void i40e_ethertype_filter_restore(struct i40e_pf *pf); 396 static void i40e_tunnel_filter_restore(struct i40e_pf *pf); 397 static void i40e_filter_restore(struct i40e_pf *pf); 398 static void i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev); 399 static int i40e_pf_config_rss(struct i40e_pf *pf); 400 401 static const char *const valid_keys[] = { 402 ETH_I40E_FLOATING_VEB_ARG, 403 ETH_I40E_FLOATING_VEB_LIST_ARG, 404 ETH_I40E_SUPPORT_MULTI_DRIVER, 405 ETH_I40E_QUEUE_NUM_PER_VF_ARG, 406 ETH_I40E_USE_LATEST_VEC, 407 ETH_I40E_VF_MSG_CFG, 408 NULL}; 409 410 static const struct rte_pci_id pci_id_i40e_map[] = { 411 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_XL710) }, 412 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QEMU) }, 413 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_B) }, 414 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_C) }, 415 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_A) }, 416 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_B) }, 417 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_C) }, 418 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T) }, 419 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_20G_KR2) }, 420 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_20G_KR2_A) }, 421 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T4) }, 422 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_25G_B) }, 423 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_25G_SFP28) }, 424 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X722_A0) }, 425 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_X722) }, 426 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_X722) }, 427 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_X722) }, 428 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_1G_BASE_T_X722) }, 429 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_X722) }, 430 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_I_X722) }, 431 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X710_N3000) }, 432 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_XXV710_N3000) }, 433 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_BC) }, 434 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_5G_BASE_T_BC) }, 435 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_B) }, 436 { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_SFP) }, 437 { .vendor_id = 0, /* sentinel */ }, 438 }; 439 440 static const struct eth_dev_ops i40e_eth_dev_ops = { 441 .dev_configure = i40e_dev_configure, 442 .dev_start = i40e_dev_start, 443 .dev_stop = i40e_dev_stop, 444 .dev_close = i40e_dev_close, 445 .dev_reset = i40e_dev_reset, 446 .promiscuous_enable = i40e_dev_promiscuous_enable, 447 .promiscuous_disable = i40e_dev_promiscuous_disable, 448 .allmulticast_enable = i40e_dev_allmulticast_enable, 449 .allmulticast_disable = i40e_dev_allmulticast_disable, 450 .dev_set_link_up = i40e_dev_set_link_up, 451 .dev_set_link_down = i40e_dev_set_link_down, 452 .link_update = i40e_dev_link_update, 453 .stats_get = i40e_dev_stats_get, 454 .xstats_get = i40e_dev_xstats_get, 455 .xstats_get_names = i40e_dev_xstats_get_names, 456 .stats_reset = i40e_dev_stats_reset, 457 .xstats_reset = i40e_dev_stats_reset, 458 .fw_version_get = i40e_fw_version_get, 459 .dev_infos_get = i40e_dev_info_get, 460 .dev_supported_ptypes_get = i40e_dev_supported_ptypes_get, 461 .vlan_filter_set = i40e_vlan_filter_set, 462 .vlan_tpid_set = i40e_vlan_tpid_set, 463 .vlan_offload_set = i40e_vlan_offload_set, 464 .vlan_strip_queue_set = i40e_vlan_strip_queue_set, 465 .vlan_pvid_set = i40e_vlan_pvid_set, 466 .rx_queue_start = i40e_dev_rx_queue_start, 467 .rx_queue_stop = i40e_dev_rx_queue_stop, 468 .tx_queue_start = i40e_dev_tx_queue_start, 469 .tx_queue_stop = i40e_dev_tx_queue_stop, 470 .rx_queue_setup = i40e_dev_rx_queue_setup, 471 .rx_queue_intr_enable = i40e_dev_rx_queue_intr_enable, 472 .rx_queue_intr_disable = i40e_dev_rx_queue_intr_disable, 473 .rx_queue_release = i40e_dev_rx_queue_release, 474 .tx_queue_setup = i40e_dev_tx_queue_setup, 475 .tx_queue_release = i40e_dev_tx_queue_release, 476 .dev_led_on = i40e_dev_led_on, 477 .dev_led_off = i40e_dev_led_off, 478 .flow_ctrl_get = i40e_flow_ctrl_get, 479 .flow_ctrl_set = i40e_flow_ctrl_set, 480 .priority_flow_ctrl_set = i40e_priority_flow_ctrl_set, 481 .mac_addr_add = i40e_macaddr_add, 482 .mac_addr_remove = i40e_macaddr_remove, 483 .reta_update = i40e_dev_rss_reta_update, 484 .reta_query = i40e_dev_rss_reta_query, 485 .rss_hash_update = i40e_dev_rss_hash_update, 486 .rss_hash_conf_get = i40e_dev_rss_hash_conf_get, 487 .udp_tunnel_port_add = i40e_dev_udp_tunnel_port_add, 488 .udp_tunnel_port_del = i40e_dev_udp_tunnel_port_del, 489 .filter_ctrl = i40e_dev_filter_ctrl, 490 .rxq_info_get = i40e_rxq_info_get, 491 .txq_info_get = i40e_txq_info_get, 492 .rx_burst_mode_get = i40e_rx_burst_mode_get, 493 .tx_burst_mode_get = i40e_tx_burst_mode_get, 494 .mirror_rule_set = i40e_mirror_rule_set, 495 .mirror_rule_reset = i40e_mirror_rule_reset, 496 .timesync_enable = i40e_timesync_enable, 497 .timesync_disable = i40e_timesync_disable, 498 .timesync_read_rx_timestamp = i40e_timesync_read_rx_timestamp, 499 .timesync_read_tx_timestamp = i40e_timesync_read_tx_timestamp, 500 .get_dcb_info = i40e_dev_get_dcb_info, 501 .timesync_adjust_time = i40e_timesync_adjust_time, 502 .timesync_read_time = i40e_timesync_read_time, 503 .timesync_write_time = i40e_timesync_write_time, 504 .get_reg = i40e_get_regs, 505 .get_eeprom_length = i40e_get_eeprom_length, 506 .get_eeprom = i40e_get_eeprom, 507 .get_module_info = i40e_get_module_info, 508 .get_module_eeprom = i40e_get_module_eeprom, 509 .mac_addr_set = i40e_set_default_mac_addr, 510 .mtu_set = i40e_dev_mtu_set, 511 .tm_ops_get = i40e_tm_ops_get, 512 .tx_done_cleanup = i40e_tx_done_cleanup, 513 }; 514 515 /* store statistics names and its offset in stats structure */ 516 struct rte_i40e_xstats_name_off { 517 char name[RTE_ETH_XSTATS_NAME_SIZE]; 518 unsigned offset; 519 }; 520 521 static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = { 522 {"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)}, 523 {"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)}, 524 {"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)}, 525 {"rx_dropped_packets", offsetof(struct i40e_eth_stats, rx_discards)}, 526 {"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats, 527 rx_unknown_protocol)}, 528 {"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_unicast)}, 529 {"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_multicast)}, 530 {"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_broadcast)}, 531 {"tx_dropped_packets", offsetof(struct i40e_eth_stats, tx_discards)}, 532 }; 533 534 #define I40E_NB_ETH_XSTATS (sizeof(rte_i40e_stats_strings) / \ 535 sizeof(rte_i40e_stats_strings[0])) 536 537 static const struct rte_i40e_xstats_name_off rte_i40e_hw_port_strings[] = { 538 {"tx_link_down_dropped", offsetof(struct i40e_hw_port_stats, 539 tx_dropped_link_down)}, 540 {"rx_crc_errors", offsetof(struct i40e_hw_port_stats, crc_errors)}, 541 {"rx_illegal_byte_errors", offsetof(struct i40e_hw_port_stats, 542 illegal_bytes)}, 543 {"rx_error_bytes", offsetof(struct i40e_hw_port_stats, error_bytes)}, 544 {"mac_local_errors", offsetof(struct i40e_hw_port_stats, 545 mac_local_faults)}, 546 {"mac_remote_errors", offsetof(struct i40e_hw_port_stats, 547 mac_remote_faults)}, 548 {"rx_length_errors", offsetof(struct i40e_hw_port_stats, 549 rx_length_errors)}, 550 {"tx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_tx)}, 551 {"rx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_rx)}, 552 {"tx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_tx)}, 553 {"rx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_rx)}, 554 {"rx_size_64_packets", offsetof(struct i40e_hw_port_stats, rx_size_64)}, 555 {"rx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats, 556 rx_size_127)}, 557 {"rx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats, 558 rx_size_255)}, 559 {"rx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats, 560 rx_size_511)}, 561 {"rx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats, 562 rx_size_1023)}, 563 {"rx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats, 564 rx_size_1522)}, 565 {"rx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats, 566 rx_size_big)}, 567 {"rx_undersized_errors", offsetof(struct i40e_hw_port_stats, 568 rx_undersize)}, 569 {"rx_oversize_errors", offsetof(struct i40e_hw_port_stats, 570 rx_oversize)}, 571 {"rx_mac_short_dropped", offsetof(struct i40e_hw_port_stats, 572 mac_short_packet_dropped)}, 573 {"rx_fragmented_errors", offsetof(struct i40e_hw_port_stats, 574 rx_fragments)}, 575 {"rx_jabber_errors", offsetof(struct i40e_hw_port_stats, rx_jabber)}, 576 {"tx_size_64_packets", offsetof(struct i40e_hw_port_stats, tx_size_64)}, 577 {"tx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats, 578 tx_size_127)}, 579 {"tx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats, 580 tx_size_255)}, 581 {"tx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats, 582 tx_size_511)}, 583 {"tx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats, 584 tx_size_1023)}, 585 {"tx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats, 586 tx_size_1522)}, 587 {"tx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats, 588 tx_size_big)}, 589 {"rx_flow_director_atr_match_packets", 590 offsetof(struct i40e_hw_port_stats, fd_atr_match)}, 591 {"rx_flow_director_sb_match_packets", 592 offsetof(struct i40e_hw_port_stats, fd_sb_match)}, 593 {"tx_low_power_idle_status", offsetof(struct i40e_hw_port_stats, 594 tx_lpi_status)}, 595 {"rx_low_power_idle_status", offsetof(struct i40e_hw_port_stats, 596 rx_lpi_status)}, 597 {"tx_low_power_idle_count", offsetof(struct i40e_hw_port_stats, 598 tx_lpi_count)}, 599 {"rx_low_power_idle_count", offsetof(struct i40e_hw_port_stats, 600 rx_lpi_count)}, 601 }; 602 603 #define I40E_NB_HW_PORT_XSTATS (sizeof(rte_i40e_hw_port_strings) / \ 604 sizeof(rte_i40e_hw_port_strings[0])) 605 606 static const struct rte_i40e_xstats_name_off rte_i40e_rxq_prio_strings[] = { 607 {"xon_packets", offsetof(struct i40e_hw_port_stats, 608 priority_xon_rx)}, 609 {"xoff_packets", offsetof(struct i40e_hw_port_stats, 610 priority_xoff_rx)}, 611 }; 612 613 #define I40E_NB_RXQ_PRIO_XSTATS (sizeof(rte_i40e_rxq_prio_strings) / \ 614 sizeof(rte_i40e_rxq_prio_strings[0])) 615 616 static const struct rte_i40e_xstats_name_off rte_i40e_txq_prio_strings[] = { 617 {"xon_packets", offsetof(struct i40e_hw_port_stats, 618 priority_xon_tx)}, 619 {"xoff_packets", offsetof(struct i40e_hw_port_stats, 620 priority_xoff_tx)}, 621 {"xon_to_xoff_packets", offsetof(struct i40e_hw_port_stats, 622 priority_xon_2_xoff)}, 623 }; 624 625 #define I40E_NB_TXQ_PRIO_XSTATS (sizeof(rte_i40e_txq_prio_strings) / \ 626 sizeof(rte_i40e_txq_prio_strings[0])) 627 628 static int 629 eth_i40e_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 630 struct rte_pci_device *pci_dev) 631 { 632 char name[RTE_ETH_NAME_MAX_LEN]; 633 struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 }; 634 int i, retval; 635 636 if (pci_dev->device.devargs) { 637 retval = rte_eth_devargs_parse(pci_dev->device.devargs->args, 638 ð_da); 639 if (retval) 640 return retval; 641 } 642 643 retval = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, 644 sizeof(struct i40e_adapter), 645 eth_dev_pci_specific_init, pci_dev, 646 eth_i40e_dev_init, NULL); 647 648 if (retval || eth_da.nb_representor_ports < 1) 649 return retval; 650 651 /* probe VF representor ports */ 652 struct rte_eth_dev *pf_ethdev = rte_eth_dev_allocated( 653 pci_dev->device.name); 654 655 if (pf_ethdev == NULL) 656 return -ENODEV; 657 658 for (i = 0; i < eth_da.nb_representor_ports; i++) { 659 struct i40e_vf_representor representor = { 660 .vf_id = eth_da.representor_ports[i], 661 .switch_domain_id = I40E_DEV_PRIVATE_TO_PF( 662 pf_ethdev->data->dev_private)->switch_domain_id, 663 .adapter = I40E_DEV_PRIVATE_TO_ADAPTER( 664 pf_ethdev->data->dev_private) 665 }; 666 667 /* representor port net_bdf_port */ 668 snprintf(name, sizeof(name), "net_%s_representor_%d", 669 pci_dev->device.name, eth_da.representor_ports[i]); 670 671 retval = rte_eth_dev_create(&pci_dev->device, name, 672 sizeof(struct i40e_vf_representor), NULL, NULL, 673 i40e_vf_representor_init, &representor); 674 675 if (retval) 676 PMD_DRV_LOG(ERR, "failed to create i40e vf " 677 "representor %s.", name); 678 } 679 680 return 0; 681 } 682 683 static int eth_i40e_pci_remove(struct rte_pci_device *pci_dev) 684 { 685 struct rte_eth_dev *ethdev; 686 687 ethdev = rte_eth_dev_allocated(pci_dev->device.name); 688 if (!ethdev) 689 return 0; 690 691 if (ethdev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) 692 return rte_eth_dev_pci_generic_remove(pci_dev, 693 i40e_vf_representor_uninit); 694 else 695 return rte_eth_dev_pci_generic_remove(pci_dev, 696 eth_i40e_dev_uninit); 697 } 698 699 static struct rte_pci_driver rte_i40e_pmd = { 700 .id_table = pci_id_i40e_map, 701 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 702 .probe = eth_i40e_pci_probe, 703 .remove = eth_i40e_pci_remove, 704 }; 705 706 static inline void 707 i40e_write_global_rx_ctl(struct i40e_hw *hw, uint32_t reg_addr, 708 uint32_t reg_val) 709 { 710 uint32_t ori_reg_val; 711 struct rte_eth_dev *dev; 712 713 ori_reg_val = i40e_read_rx_ctl(hw, reg_addr); 714 dev = ((struct i40e_adapter *)hw->back)->eth_dev; 715 i40e_write_rx_ctl(hw, reg_addr, reg_val); 716 if (ori_reg_val != reg_val) 717 PMD_DRV_LOG(WARNING, 718 "i40e device %s changed global register [0x%08x]." 719 " original: 0x%08x, new: 0x%08x", 720 dev->device->name, reg_addr, ori_reg_val, reg_val); 721 } 722 723 RTE_PMD_REGISTER_PCI(net_i40e, rte_i40e_pmd); 724 RTE_PMD_REGISTER_PCI_TABLE(net_i40e, pci_id_i40e_map); 725 RTE_PMD_REGISTER_KMOD_DEP(net_i40e, "* igb_uio | uio_pci_generic | vfio-pci"); 726 727 #ifndef I40E_GLQF_ORT 728 #define I40E_GLQF_ORT(_i) (0x00268900 + ((_i) * 4)) 729 #endif 730 #ifndef I40E_GLQF_PIT 731 #define I40E_GLQF_PIT(_i) (0x00268C80 + ((_i) * 4)) 732 #endif 733 #ifndef I40E_GLQF_L3_MAP 734 #define I40E_GLQF_L3_MAP(_i) (0x0026C700 + ((_i) * 4)) 735 #endif 736 737 static inline void i40e_GLQF_reg_init(struct i40e_hw *hw) 738 { 739 /* 740 * Initialize registers for parsing packet type of QinQ 741 * This should be removed from code once proper 742 * configuration API is added to avoid configuration conflicts 743 * between ports of the same device. 744 */ 745 I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(40), 0x00000029); 746 I40E_WRITE_GLB_REG(hw, I40E_GLQF_PIT(9), 0x00009420); 747 } 748 749 static inline void i40e_config_automask(struct i40e_pf *pf) 750 { 751 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 752 uint32_t val; 753 754 /* INTENA flag is not auto-cleared for interrupt */ 755 val = I40E_READ_REG(hw, I40E_GLINT_CTL); 756 val |= I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK | 757 I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK; 758 759 /* If support multi-driver, PF will use INT0. */ 760 if (!pf->support_multi_driver) 761 val |= I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK; 762 763 I40E_WRITE_REG(hw, I40E_GLINT_CTL, val); 764 } 765 766 static inline void i40e_clear_automask(struct i40e_pf *pf) 767 { 768 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 769 uint32_t val; 770 771 val = I40E_READ_REG(hw, I40E_GLINT_CTL); 772 val &= ~(I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK | 773 I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK); 774 775 if (!pf->support_multi_driver) 776 val &= ~I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK; 777 778 I40E_WRITE_REG(hw, I40E_GLINT_CTL, val); 779 } 780 781 #define I40E_FLOW_CONTROL_ETHERTYPE 0x8808 782 783 /* 784 * Add a ethertype filter to drop all flow control frames transmitted 785 * from VSIs. 786 */ 787 static void 788 i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf) 789 { 790 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 791 uint16_t flags = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC | 792 I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP | 793 I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX; 794 int ret; 795 796 ret = i40e_aq_add_rem_control_packet_filter(hw, NULL, 797 I40E_FLOW_CONTROL_ETHERTYPE, flags, 798 pf->main_vsi_seid, 0, 799 TRUE, NULL, NULL); 800 if (ret) 801 PMD_INIT_LOG(ERR, 802 "Failed to add filter to drop flow control frames from VSIs."); 803 } 804 805 static int 806 floating_veb_list_handler(__rte_unused const char *key, 807 const char *floating_veb_value, 808 void *opaque) 809 { 810 int idx = 0; 811 unsigned int count = 0; 812 char *end = NULL; 813 int min, max; 814 bool *vf_floating_veb = opaque; 815 816 while (isblank(*floating_veb_value)) 817 floating_veb_value++; 818 819 /* Reset floating VEB configuration for VFs */ 820 for (idx = 0; idx < I40E_MAX_VF; idx++) 821 vf_floating_veb[idx] = false; 822 823 min = I40E_MAX_VF; 824 do { 825 while (isblank(*floating_veb_value)) 826 floating_veb_value++; 827 if (*floating_veb_value == '\0') 828 return -1; 829 errno = 0; 830 idx = strtoul(floating_veb_value, &end, 10); 831 if (errno || end == NULL) 832 return -1; 833 while (isblank(*end)) 834 end++; 835 if (*end == '-') { 836 min = idx; 837 } else if ((*end == ';') || (*end == '\0')) { 838 max = idx; 839 if (min == I40E_MAX_VF) 840 min = idx; 841 if (max >= I40E_MAX_VF) 842 max = I40E_MAX_VF - 1; 843 for (idx = min; idx <= max; idx++) { 844 vf_floating_veb[idx] = true; 845 count++; 846 } 847 min = I40E_MAX_VF; 848 } else { 849 return -1; 850 } 851 floating_veb_value = end + 1; 852 } while (*end != '\0'); 853 854 if (count == 0) 855 return -1; 856 857 return 0; 858 } 859 860 static void 861 config_vf_floating_veb(struct rte_devargs *devargs, 862 uint16_t floating_veb, 863 bool *vf_floating_veb) 864 { 865 struct rte_kvargs *kvlist; 866 int i; 867 const char *floating_veb_list = ETH_I40E_FLOATING_VEB_LIST_ARG; 868 869 if (!floating_veb) 870 return; 871 /* All the VFs attach to the floating VEB by default 872 * when the floating VEB is enabled. 873 */ 874 for (i = 0; i < I40E_MAX_VF; i++) 875 vf_floating_veb[i] = true; 876 877 if (devargs == NULL) 878 return; 879 880 kvlist = rte_kvargs_parse(devargs->args, valid_keys); 881 if (kvlist == NULL) 882 return; 883 884 if (!rte_kvargs_count(kvlist, floating_veb_list)) { 885 rte_kvargs_free(kvlist); 886 return; 887 } 888 /* When the floating_veb_list parameter exists, all the VFs 889 * will attach to the legacy VEB firstly, then configure VFs 890 * to the floating VEB according to the floating_veb_list. 891 */ 892 if (rte_kvargs_process(kvlist, floating_veb_list, 893 floating_veb_list_handler, 894 vf_floating_veb) < 0) { 895 rte_kvargs_free(kvlist); 896 return; 897 } 898 rte_kvargs_free(kvlist); 899 } 900 901 static int 902 i40e_check_floating_handler(__rte_unused const char *key, 903 const char *value, 904 __rte_unused void *opaque) 905 { 906 if (strcmp(value, "1")) 907 return -1; 908 909 return 0; 910 } 911 912 static int 913 is_floating_veb_supported(struct rte_devargs *devargs) 914 { 915 struct rte_kvargs *kvlist; 916 const char *floating_veb_key = ETH_I40E_FLOATING_VEB_ARG; 917 918 if (devargs == NULL) 919 return 0; 920 921 kvlist = rte_kvargs_parse(devargs->args, valid_keys); 922 if (kvlist == NULL) 923 return 0; 924 925 if (!rte_kvargs_count(kvlist, floating_veb_key)) { 926 rte_kvargs_free(kvlist); 927 return 0; 928 } 929 /* Floating VEB is enabled when there's key-value: 930 * enable_floating_veb=1 931 */ 932 if (rte_kvargs_process(kvlist, floating_veb_key, 933 i40e_check_floating_handler, NULL) < 0) { 934 rte_kvargs_free(kvlist); 935 return 0; 936 } 937 rte_kvargs_free(kvlist); 938 939 return 1; 940 } 941 942 static void 943 config_floating_veb(struct rte_eth_dev *dev) 944 { 945 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 946 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 947 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 948 949 memset(pf->floating_veb_list, 0, sizeof(pf->floating_veb_list)); 950 951 if (hw->aq.fw_maj_ver >= FLOATING_VEB_SUPPORTED_FW_MAJ) { 952 pf->floating_veb = 953 is_floating_veb_supported(pci_dev->device.devargs); 954 config_vf_floating_veb(pci_dev->device.devargs, 955 pf->floating_veb, 956 pf->floating_veb_list); 957 } else { 958 pf->floating_veb = false; 959 } 960 } 961 962 #define I40E_L2_TAGS_S_TAG_SHIFT 1 963 #define I40E_L2_TAGS_S_TAG_MASK I40E_MASK(0x1, I40E_L2_TAGS_S_TAG_SHIFT) 964 965 static int 966 i40e_init_ethtype_filter_list(struct rte_eth_dev *dev) 967 { 968 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 969 struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype; 970 char ethertype_hash_name[RTE_HASH_NAMESIZE]; 971 int ret; 972 973 struct rte_hash_parameters ethertype_hash_params = { 974 .name = ethertype_hash_name, 975 .entries = I40E_MAX_ETHERTYPE_FILTER_NUM, 976 .key_len = sizeof(struct i40e_ethertype_filter_input), 977 .hash_func = rte_hash_crc, 978 .hash_func_init_val = 0, 979 .socket_id = rte_socket_id(), 980 }; 981 982 /* Initialize ethertype filter rule list and hash */ 983 TAILQ_INIT(ðertype_rule->ethertype_list); 984 snprintf(ethertype_hash_name, RTE_HASH_NAMESIZE, 985 "ethertype_%s", dev->device->name); 986 ethertype_rule->hash_table = rte_hash_create(ðertype_hash_params); 987 if (!ethertype_rule->hash_table) { 988 PMD_INIT_LOG(ERR, "Failed to create ethertype hash table!"); 989 return -EINVAL; 990 } 991 ethertype_rule->hash_map = rte_zmalloc("i40e_ethertype_hash_map", 992 sizeof(struct i40e_ethertype_filter *) * 993 I40E_MAX_ETHERTYPE_FILTER_NUM, 994 0); 995 if (!ethertype_rule->hash_map) { 996 PMD_INIT_LOG(ERR, 997 "Failed to allocate memory for ethertype hash map!"); 998 ret = -ENOMEM; 999 goto err_ethertype_hash_map_alloc; 1000 } 1001 1002 return 0; 1003 1004 err_ethertype_hash_map_alloc: 1005 rte_hash_free(ethertype_rule->hash_table); 1006 1007 return ret; 1008 } 1009 1010 static int 1011 i40e_init_tunnel_filter_list(struct rte_eth_dev *dev) 1012 { 1013 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 1014 struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel; 1015 char tunnel_hash_name[RTE_HASH_NAMESIZE]; 1016 int ret; 1017 1018 struct rte_hash_parameters tunnel_hash_params = { 1019 .name = tunnel_hash_name, 1020 .entries = I40E_MAX_TUNNEL_FILTER_NUM, 1021 .key_len = sizeof(struct i40e_tunnel_filter_input), 1022 .hash_func = rte_hash_crc, 1023 .hash_func_init_val = 0, 1024 .socket_id = rte_socket_id(), 1025 }; 1026 1027 /* Initialize tunnel filter rule list and hash */ 1028 TAILQ_INIT(&tunnel_rule->tunnel_list); 1029 snprintf(tunnel_hash_name, RTE_HASH_NAMESIZE, 1030 "tunnel_%s", dev->device->name); 1031 tunnel_rule->hash_table = rte_hash_create(&tunnel_hash_params); 1032 if (!tunnel_rule->hash_table) { 1033 PMD_INIT_LOG(ERR, "Failed to create tunnel hash table!"); 1034 return -EINVAL; 1035 } 1036 tunnel_rule->hash_map = rte_zmalloc("i40e_tunnel_hash_map", 1037 sizeof(struct i40e_tunnel_filter *) * 1038 I40E_MAX_TUNNEL_FILTER_NUM, 1039 0); 1040 if (!tunnel_rule->hash_map) { 1041 PMD_INIT_LOG(ERR, 1042 "Failed to allocate memory for tunnel hash map!"); 1043 ret = -ENOMEM; 1044 goto err_tunnel_hash_map_alloc; 1045 } 1046 1047 return 0; 1048 1049 err_tunnel_hash_map_alloc: 1050 rte_hash_free(tunnel_rule->hash_table); 1051 1052 return ret; 1053 } 1054 1055 static int 1056 i40e_init_fdir_filter_list(struct rte_eth_dev *dev) 1057 { 1058 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 1059 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 1060 struct i40e_fdir_info *fdir_info = &pf->fdir; 1061 char fdir_hash_name[RTE_HASH_NAMESIZE]; 1062 uint32_t alloc = hw->func_caps.fd_filters_guaranteed; 1063 uint32_t best = hw->func_caps.fd_filters_best_effort; 1064 struct rte_bitmap *bmp = NULL; 1065 uint32_t bmp_size; 1066 void *mem = NULL; 1067 uint32_t i = 0; 1068 int ret; 1069 1070 struct rte_hash_parameters fdir_hash_params = { 1071 .name = fdir_hash_name, 1072 .entries = I40E_MAX_FDIR_FILTER_NUM, 1073 .key_len = sizeof(struct i40e_fdir_input), 1074 .hash_func = rte_hash_crc, 1075 .hash_func_init_val = 0, 1076 .socket_id = rte_socket_id(), 1077 }; 1078 1079 /* Initialize flow director filter rule list and hash */ 1080 TAILQ_INIT(&fdir_info->fdir_list); 1081 snprintf(fdir_hash_name, RTE_HASH_NAMESIZE, 1082 "fdir_%s", dev->device->name); 1083 fdir_info->hash_table = rte_hash_create(&fdir_hash_params); 1084 if (!fdir_info->hash_table) { 1085 PMD_INIT_LOG(ERR, "Failed to create fdir hash table!"); 1086 return -EINVAL; 1087 } 1088 1089 fdir_info->hash_map = rte_zmalloc("i40e_fdir_hash_map", 1090 sizeof(struct i40e_fdir_filter *) * 1091 I40E_MAX_FDIR_FILTER_NUM, 1092 0); 1093 if (!fdir_info->hash_map) { 1094 PMD_INIT_LOG(ERR, 1095 "Failed to allocate memory for fdir hash map!"); 1096 ret = -ENOMEM; 1097 goto err_fdir_hash_map_alloc; 1098 } 1099 1100 fdir_info->fdir_filter_array = rte_zmalloc("fdir_filter", 1101 sizeof(struct i40e_fdir_filter) * 1102 I40E_MAX_FDIR_FILTER_NUM, 1103 0); 1104 1105 if (!fdir_info->fdir_filter_array) { 1106 PMD_INIT_LOG(ERR, 1107 "Failed to allocate memory for fdir filter array!"); 1108 ret = -ENOMEM; 1109 goto err_fdir_filter_array_alloc; 1110 } 1111 1112 fdir_info->fdir_space_size = alloc + best; 1113 fdir_info->fdir_actual_cnt = 0; 1114 fdir_info->fdir_guarantee_total_space = alloc; 1115 fdir_info->fdir_guarantee_free_space = 1116 fdir_info->fdir_guarantee_total_space; 1117 1118 PMD_DRV_LOG(INFO, "FDIR guarantee space: %u, best_effort space %u.", alloc, best); 1119 1120 fdir_info->fdir_flow_pool.pool = 1121 rte_zmalloc("i40e_fdir_entry", 1122 sizeof(struct i40e_fdir_entry) * 1123 fdir_info->fdir_space_size, 1124 0); 1125 1126 if (!fdir_info->fdir_flow_pool.pool) { 1127 PMD_INIT_LOG(ERR, 1128 "Failed to allocate memory for bitmap flow!"); 1129 ret = -ENOMEM; 1130 goto err_fdir_bitmap_flow_alloc; 1131 } 1132 1133 for (i = 0; i < fdir_info->fdir_space_size; i++) 1134 fdir_info->fdir_flow_pool.pool[i].idx = i; 1135 1136 bmp_size = 1137 rte_bitmap_get_memory_footprint(fdir_info->fdir_space_size); 1138 mem = rte_zmalloc("fdir_bmap", bmp_size, RTE_CACHE_LINE_SIZE); 1139 if (mem == NULL) { 1140 PMD_INIT_LOG(ERR, 1141 "Failed to allocate memory for fdir bitmap!"); 1142 ret = -ENOMEM; 1143 goto err_fdir_mem_alloc; 1144 } 1145 bmp = rte_bitmap_init(fdir_info->fdir_space_size, mem, bmp_size); 1146 if (bmp == NULL) { 1147 PMD_INIT_LOG(ERR, 1148 "Failed to initialization fdir bitmap!"); 1149 ret = -ENOMEM; 1150 goto err_fdir_bmp_alloc; 1151 } 1152 for (i = 0; i < fdir_info->fdir_space_size; i++) 1153 rte_bitmap_set(bmp, i); 1154 1155 fdir_info->fdir_flow_pool.bitmap = bmp; 1156 1157 return 0; 1158 1159 err_fdir_bmp_alloc: 1160 rte_free(mem); 1161 err_fdir_mem_alloc: 1162 rte_free(fdir_info->fdir_flow_pool.pool); 1163 err_fdir_bitmap_flow_alloc: 1164 rte_free(fdir_info->fdir_filter_array); 1165 err_fdir_filter_array_alloc: 1166 rte_free(fdir_info->hash_map); 1167 err_fdir_hash_map_alloc: 1168 rte_hash_free(fdir_info->hash_table); 1169 1170 return ret; 1171 } 1172 1173 static void 1174 i40e_init_customized_info(struct i40e_pf *pf) 1175 { 1176 int i; 1177 1178 /* Initialize customized pctype */ 1179 for (i = I40E_CUSTOMIZED_GTPC; i < I40E_CUSTOMIZED_MAX; i++) { 1180 pf->customized_pctype[i].index = i; 1181 pf->customized_pctype[i].pctype = I40E_FILTER_PCTYPE_INVALID; 1182 pf->customized_pctype[i].valid = false; 1183 } 1184 1185 pf->gtp_support = false; 1186 pf->esp_support = false; 1187 } 1188 1189 static void 1190 i40e_init_filter_invalidation(struct i40e_pf *pf) 1191 { 1192 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 1193 struct i40e_fdir_info *fdir_info = &pf->fdir; 1194 uint32_t glqf_ctl_reg = 0; 1195 1196 glqf_ctl_reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL); 1197 if (!pf->support_multi_driver) { 1198 fdir_info->fdir_invalprio = 1; 1199 glqf_ctl_reg |= I40E_GLQF_CTL_INVALPRIO_MASK; 1200 PMD_DRV_LOG(INFO, "FDIR INVALPRIO set to guaranteed first"); 1201 i40e_write_rx_ctl(hw, I40E_GLQF_CTL, glqf_ctl_reg); 1202 } else { 1203 if (glqf_ctl_reg & I40E_GLQF_CTL_INVALPRIO_MASK) { 1204 fdir_info->fdir_invalprio = 1; 1205 PMD_DRV_LOG(INFO, "FDIR INVALPRIO is: guaranteed first"); 1206 } else { 1207 fdir_info->fdir_invalprio = 0; 1208 PMD_DRV_LOG(INFO, "FDIR INVALPRIO is: shared first"); 1209 } 1210 } 1211 } 1212 1213 void 1214 i40e_init_queue_region_conf(struct rte_eth_dev *dev) 1215 { 1216 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 1217 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 1218 struct i40e_queue_regions *info = &pf->queue_region; 1219 uint16_t i; 1220 1221 for (i = 0; i < I40E_PFQF_HREGION_MAX_INDEX; i++) 1222 i40e_write_rx_ctl(hw, I40E_PFQF_HREGION(i), 0); 1223 1224 memset(info, 0, sizeof(struct i40e_queue_regions)); 1225 } 1226 1227 static int 1228 i40e_parse_multi_drv_handler(__rte_unused const char *key, 1229 const char *value, 1230 void *opaque) 1231 { 1232 struct i40e_pf *pf; 1233 unsigned long support_multi_driver; 1234 char *end; 1235 1236 pf = (struct i40e_pf *)opaque; 1237 1238 errno = 0; 1239 support_multi_driver = strtoul(value, &end, 10); 1240 if (errno != 0 || end == value || *end != 0) { 1241 PMD_DRV_LOG(WARNING, "Wrong global configuration"); 1242 return -(EINVAL); 1243 } 1244 1245 if (support_multi_driver == 1 || support_multi_driver == 0) 1246 pf->support_multi_driver = (bool)support_multi_driver; 1247 else 1248 PMD_DRV_LOG(WARNING, "%s must be 1 or 0,", 1249 "enable global configuration by default." 1250 ETH_I40E_SUPPORT_MULTI_DRIVER); 1251 return 0; 1252 } 1253 1254 static int 1255 i40e_support_multi_driver(struct rte_eth_dev *dev) 1256 { 1257 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 1258 struct rte_kvargs *kvlist; 1259 int kvargs_count; 1260 1261 /* Enable global configuration by default */ 1262 pf->support_multi_driver = false; 1263 1264 if (!dev->device->devargs) 1265 return 0; 1266 1267 kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys); 1268 if (!kvlist) 1269 return -EINVAL; 1270 1271 kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER); 1272 if (!kvargs_count) { 1273 rte_kvargs_free(kvlist); 1274 return 0; 1275 } 1276 1277 if (kvargs_count > 1) 1278 PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only " 1279 "the first invalid or last valid one is used !", 1280 ETH_I40E_SUPPORT_MULTI_DRIVER); 1281 1282 if (rte_kvargs_process(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER, 1283 i40e_parse_multi_drv_handler, pf) < 0) { 1284 rte_kvargs_free(kvlist); 1285 return -EINVAL; 1286 } 1287 1288 rte_kvargs_free(kvlist); 1289 return 0; 1290 } 1291 1292 static int 1293 i40e_aq_debug_write_global_register(struct i40e_hw *hw, 1294 uint32_t reg_addr, uint64_t reg_val, 1295 struct i40e_asq_cmd_details *cmd_details) 1296 { 1297 uint64_t ori_reg_val; 1298 struct rte_eth_dev *dev; 1299 int ret; 1300 1301 ret = i40e_aq_debug_read_register(hw, reg_addr, &ori_reg_val, NULL); 1302 if (ret != I40E_SUCCESS) { 1303 PMD_DRV_LOG(ERR, 1304 "Fail to debug read from 0x%08x", 1305 reg_addr); 1306 return -EIO; 1307 } 1308 dev = ((struct i40e_adapter *)hw->back)->eth_dev; 1309 1310 if (ori_reg_val != reg_val) 1311 PMD_DRV_LOG(WARNING, 1312 "i40e device %s changed global register [0x%08x]." 1313 " original: 0x%"PRIx64", after: 0x%"PRIx64, 1314 dev->device->name, reg_addr, ori_reg_val, reg_val); 1315 1316 return i40e_aq_debug_write_register(hw, reg_addr, reg_val, cmd_details); 1317 } 1318 1319 static int 1320 i40e_parse_latest_vec_handler(__rte_unused const char *key, 1321 const char *value, 1322 void *opaque) 1323 { 1324 struct i40e_adapter *ad = opaque; 1325 int use_latest_vec; 1326 1327 use_latest_vec = atoi(value); 1328 1329 if (use_latest_vec != 0 && use_latest_vec != 1) 1330 PMD_DRV_LOG(WARNING, "Value should be 0 or 1, set it as 1!"); 1331 1332 ad->use_latest_vec = (uint8_t)use_latest_vec; 1333 1334 return 0; 1335 } 1336 1337 static int 1338 i40e_use_latest_vec(struct rte_eth_dev *dev) 1339 { 1340 struct i40e_adapter *ad = 1341 I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); 1342 struct rte_kvargs *kvlist; 1343 int kvargs_count; 1344 1345 ad->use_latest_vec = false; 1346 1347 if (!dev->device->devargs) 1348 return 0; 1349 1350 kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys); 1351 if (!kvlist) 1352 return -EINVAL; 1353 1354 kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_USE_LATEST_VEC); 1355 if (!kvargs_count) { 1356 rte_kvargs_free(kvlist); 1357 return 0; 1358 } 1359 1360 if (kvargs_count > 1) 1361 PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only " 1362 "the first invalid or last valid one is used !", 1363 ETH_I40E_USE_LATEST_VEC); 1364 1365 if (rte_kvargs_process(kvlist, ETH_I40E_USE_LATEST_VEC, 1366 i40e_parse_latest_vec_handler, ad) < 0) { 1367 rte_kvargs_free(kvlist); 1368 return -EINVAL; 1369 } 1370 1371 rte_kvargs_free(kvlist); 1372 return 0; 1373 } 1374 1375 static int 1376 read_vf_msg_config(__rte_unused const char *key, 1377 const char *value, 1378 void *opaque) 1379 { 1380 struct i40e_vf_msg_cfg *cfg = opaque; 1381 1382 if (sscanf(value, "%u@%u:%u", &cfg->max_msg, &cfg->period, 1383 &cfg->ignore_second) != 3) { 1384 memset(cfg, 0, sizeof(*cfg)); 1385 PMD_DRV_LOG(ERR, "format error! example: " 1386 "%s=60@120:180", ETH_I40E_VF_MSG_CFG); 1387 return -EINVAL; 1388 } 1389 1390 /* 1391 * If the message validation function been enabled, the 'period' 1392 * and 'ignore_second' must greater than 0. 1393 */ 1394 if (cfg->max_msg && (!cfg->period || !cfg->ignore_second)) { 1395 memset(cfg, 0, sizeof(*cfg)); 1396 PMD_DRV_LOG(ERR, "%s error! the second and third" 1397 " number must be greater than 0!", 1398 ETH_I40E_VF_MSG_CFG); 1399 return -EINVAL; 1400 } 1401 1402 return 0; 1403 } 1404 1405 static int 1406 i40e_parse_vf_msg_config(struct rte_eth_dev *dev, 1407 struct i40e_vf_msg_cfg *msg_cfg) 1408 { 1409 struct rte_kvargs *kvlist; 1410 int kvargs_count; 1411 int ret = 0; 1412 1413 memset(msg_cfg, 0, sizeof(*msg_cfg)); 1414 1415 if (!dev->device->devargs) 1416 return ret; 1417 1418 kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys); 1419 if (!kvlist) 1420 return -EINVAL; 1421 1422 kvargs_count = rte_kvargs_count(kvlist, ETH_I40E_VF_MSG_CFG); 1423 if (!kvargs_count) 1424 goto free_end; 1425 1426 if (kvargs_count > 1) { 1427 PMD_DRV_LOG(ERR, "More than one argument \"%s\"!", 1428 ETH_I40E_VF_MSG_CFG); 1429 ret = -EINVAL; 1430 goto free_end; 1431 } 1432 1433 if (rte_kvargs_process(kvlist, ETH_I40E_VF_MSG_CFG, 1434 read_vf_msg_config, msg_cfg) < 0) 1435 ret = -EINVAL; 1436 1437 free_end: 1438 rte_kvargs_free(kvlist); 1439 return ret; 1440 } 1441 1442 #define I40E_ALARM_INTERVAL 50000 /* us */ 1443 1444 static int 1445 eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) 1446 { 1447 struct rte_pci_device *pci_dev; 1448 struct rte_intr_handle *intr_handle; 1449 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 1450 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 1451 struct i40e_vsi *vsi; 1452 int ret; 1453 uint32_t len, val; 1454 uint8_t aq_fail = 0; 1455 1456 PMD_INIT_FUNC_TRACE(); 1457 1458 dev->dev_ops = &i40e_eth_dev_ops; 1459 dev->rx_queue_count = i40e_dev_rx_queue_count; 1460 dev->rx_descriptor_done = i40e_dev_rx_descriptor_done; 1461 dev->rx_descriptor_status = i40e_dev_rx_descriptor_status; 1462 dev->tx_descriptor_status = i40e_dev_tx_descriptor_status; 1463 dev->rx_pkt_burst = i40e_recv_pkts; 1464 dev->tx_pkt_burst = i40e_xmit_pkts; 1465 dev->tx_pkt_prepare = i40e_prep_pkts; 1466 1467 /* for secondary processes, we don't initialise any further as primary 1468 * has already done this work. Only check we don't need a different 1469 * RX function */ 1470 if (rte_eal_process_type() != RTE_PROC_PRIMARY){ 1471 i40e_set_rx_function(dev); 1472 i40e_set_tx_function(dev); 1473 return 0; 1474 } 1475 i40e_set_default_ptype_table(dev); 1476 pci_dev = RTE_ETH_DEV_TO_PCI(dev); 1477 intr_handle = &pci_dev->intr_handle; 1478 1479 rte_eth_copy_pci_info(dev, pci_dev); 1480 dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; 1481 1482 pf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); 1483 pf->adapter->eth_dev = dev; 1484 pf->dev_data = dev->data; 1485 1486 hw->back = I40E_PF_TO_ADAPTER(pf); 1487 hw->hw_addr = (uint8_t *)(pci_dev->mem_resource[0].addr); 1488 if (!hw->hw_addr) { 1489 PMD_INIT_LOG(ERR, 1490 "Hardware is not available, as address is NULL"); 1491 return -ENODEV; 1492 } 1493 1494 hw->vendor_id = pci_dev->id.vendor_id; 1495 hw->device_id = pci_dev->id.device_id; 1496 hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id; 1497 hw->subsystem_device_id = pci_dev->id.subsystem_device_id; 1498 hw->bus.device = pci_dev->addr.devid; 1499 hw->bus.func = pci_dev->addr.function; 1500 hw->adapter_stopped = 0; 1501 hw->adapter_closed = 0; 1502 1503 /* Init switch device pointer */ 1504 hw->switch_dev = NULL; 1505 1506 /* 1507 * Switch Tag value should not be identical to either the First Tag 1508 * or Second Tag values. So set something other than common Ethertype 1509 * for internal switching. 1510 */ 1511 hw->switch_tag = 0xffff; 1512 1513 val = I40E_READ_REG(hw, I40E_GL_FWSTS); 1514 if (val & I40E_GL_FWSTS_FWS1B_MASK) { 1515 PMD_INIT_LOG(ERR, "\nERROR: " 1516 "Firmware recovery mode detected. Limiting functionality.\n" 1517 "Refer to the Intel(R) Ethernet Adapters and Devices " 1518 "User Guide for details on firmware recovery mode."); 1519 return -EIO; 1520 } 1521 1522 i40e_parse_vf_msg_config(dev, &pf->vf_msg_cfg); 1523 /* Check if need to support multi-driver */ 1524 i40e_support_multi_driver(dev); 1525 /* Check if users want the latest supported vec path */ 1526 i40e_use_latest_vec(dev); 1527 1528 /* Make sure all is clean before doing PF reset */ 1529 i40e_clear_hw(hw); 1530 1531 /* Reset here to make sure all is clean for each PF */ 1532 ret = i40e_pf_reset(hw); 1533 if (ret) { 1534 PMD_INIT_LOG(ERR, "Failed to reset pf: %d", ret); 1535 return ret; 1536 } 1537 1538 /* Initialize the shared code (base driver) */ 1539 ret = i40e_init_shared_code(hw); 1540 if (ret) { 1541 PMD_INIT_LOG(ERR, "Failed to init shared code (base driver): %d", ret); 1542 return ret; 1543 } 1544 1545 /* Initialize the parameters for adminq */ 1546 i40e_init_adminq_parameter(hw); 1547 ret = i40e_init_adminq(hw); 1548 if (ret != I40E_SUCCESS) { 1549 PMD_INIT_LOG(ERR, "Failed to init adminq: %d", ret); 1550 return -EIO; 1551 } 1552 /* Firmware of SFP x722 does not support adminq option */ 1553 if (hw->device_id == I40E_DEV_ID_SFP_X722) 1554 hw->flags &= ~I40E_HW_FLAG_802_1AD_CAPABLE; 1555 1556 PMD_INIT_LOG(INFO, "FW %d.%d API %d.%d NVM %02d.%02d.%02d eetrack %04x", 1557 hw->aq.fw_maj_ver, hw->aq.fw_min_ver, 1558 hw->aq.api_maj_ver, hw->aq.api_min_ver, 1559 ((hw->nvm.version >> 12) & 0xf), 1560 ((hw->nvm.version >> 4) & 0xff), 1561 (hw->nvm.version & 0xf), hw->nvm.eetrack); 1562 1563 /* Initialize the hardware */ 1564 i40e_hw_init(dev); 1565 1566 i40e_config_automask(pf); 1567 1568 i40e_set_default_pctype_table(dev); 1569 1570 /* 1571 * To work around the NVM issue, initialize registers 1572 * for packet type of QinQ by software. 1573 * It should be removed once issues are fixed in NVM. 1574 */ 1575 if (!pf->support_multi_driver) 1576 i40e_GLQF_reg_init(hw); 1577 1578 /* Initialize the input set for filters (hash and fd) to default value */ 1579 i40e_filter_input_set_init(pf); 1580 1581 /* initialise the L3_MAP register */ 1582 if (!pf->support_multi_driver) { 1583 ret = i40e_aq_debug_write_global_register(hw, 1584 I40E_GLQF_L3_MAP(40), 1585 0x00000028, NULL); 1586 if (ret) 1587 PMD_INIT_LOG(ERR, "Failed to write L3 MAP register %d", 1588 ret); 1589 PMD_INIT_LOG(DEBUG, 1590 "Global register 0x%08x is changed with 0x28", 1591 I40E_GLQF_L3_MAP(40)); 1592 } 1593 1594 /* Need the special FW version to support floating VEB */ 1595 config_floating_veb(dev); 1596 /* Clear PXE mode */ 1597 i40e_clear_pxe_mode(hw); 1598 i40e_dev_sync_phy_type(hw); 1599 1600 /* 1601 * On X710, performance number is far from the expectation on recent 1602 * firmware versions. The fix for this issue may not be integrated in 1603 * the following firmware version. So the workaround in software driver 1604 * is needed. It needs to modify the initial values of 3 internal only 1605 * registers. Note that the workaround can be removed when it is fixed 1606 * in firmware in the future. 1607 */ 1608 i40e_configure_registers(hw); 1609 1610 /* Get hw capabilities */ 1611 ret = i40e_get_cap(hw); 1612 if (ret != I40E_SUCCESS) { 1613 PMD_INIT_LOG(ERR, "Failed to get capabilities: %d", ret); 1614 goto err_get_capabilities; 1615 } 1616 1617 /* Initialize parameters for PF */ 1618 ret = i40e_pf_parameter_init(dev); 1619 if (ret != 0) { 1620 PMD_INIT_LOG(ERR, "Failed to do parameter init: %d", ret); 1621 goto err_parameter_init; 1622 } 1623 1624 /* Initialize the queue management */ 1625 ret = i40e_res_pool_init(&pf->qp_pool, 0, hw->func_caps.num_tx_qp); 1626 if (ret < 0) { 1627 PMD_INIT_LOG(ERR, "Failed to init queue pool"); 1628 goto err_qp_pool_init; 1629 } 1630 ret = i40e_res_pool_init(&pf->msix_pool, 1, 1631 hw->func_caps.num_msix_vectors - 1); 1632 if (ret < 0) { 1633 PMD_INIT_LOG(ERR, "Failed to init MSIX pool"); 1634 goto err_msix_pool_init; 1635 } 1636 1637 /* Initialize lan hmc */ 1638 ret = i40e_init_lan_hmc(hw, hw->func_caps.num_tx_qp, 1639 hw->func_caps.num_rx_qp, 0, 0); 1640 if (ret != I40E_SUCCESS) { 1641 PMD_INIT_LOG(ERR, "Failed to init lan hmc: %d", ret); 1642 goto err_init_lan_hmc; 1643 } 1644 1645 /* Configure lan hmc */ 1646 ret = i40e_configure_lan_hmc(hw, I40E_HMC_MODEL_DIRECT_ONLY); 1647 if (ret != I40E_SUCCESS) { 1648 PMD_INIT_LOG(ERR, "Failed to configure lan hmc: %d", ret); 1649 goto err_configure_lan_hmc; 1650 } 1651 1652 /* Get and check the mac address */ 1653 i40e_get_mac_addr(hw, hw->mac.addr); 1654 if (i40e_validate_mac_addr(hw->mac.addr) != I40E_SUCCESS) { 1655 PMD_INIT_LOG(ERR, "mac address is not valid"); 1656 ret = -EIO; 1657 goto err_get_mac_addr; 1658 } 1659 /* Copy the permanent MAC address */ 1660 rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.addr, 1661 (struct rte_ether_addr *)hw->mac.perm_addr); 1662 1663 /* Disable flow control */ 1664 hw->fc.requested_mode = I40E_FC_NONE; 1665 i40e_set_fc(hw, &aq_fail, TRUE); 1666 1667 /* Set the global registers with default ether type value */ 1668 if (!pf->support_multi_driver) { 1669 ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, 1670 RTE_ETHER_TYPE_VLAN); 1671 if (ret != I40E_SUCCESS) { 1672 PMD_INIT_LOG(ERR, 1673 "Failed to set the default outer " 1674 "VLAN ether type"); 1675 goto err_setup_pf_switch; 1676 } 1677 } 1678 1679 /* PF setup, which includes VSI setup */ 1680 ret = i40e_pf_setup(pf); 1681 if (ret) { 1682 PMD_INIT_LOG(ERR, "Failed to setup pf switch: %d", ret); 1683 goto err_setup_pf_switch; 1684 } 1685 1686 vsi = pf->main_vsi; 1687 1688 /* Disable double vlan by default */ 1689 i40e_vsi_config_double_vlan(vsi, FALSE); 1690 1691 /* Disable S-TAG identification when floating_veb is disabled */ 1692 if (!pf->floating_veb) { 1693 ret = I40E_READ_REG(hw, I40E_PRT_L2TAGSEN); 1694 if (ret & I40E_L2_TAGS_S_TAG_MASK) { 1695 ret &= ~I40E_L2_TAGS_S_TAG_MASK; 1696 I40E_WRITE_REG(hw, I40E_PRT_L2TAGSEN, ret); 1697 } 1698 } 1699 1700 if (!vsi->max_macaddrs) 1701 len = RTE_ETHER_ADDR_LEN; 1702 else 1703 len = RTE_ETHER_ADDR_LEN * vsi->max_macaddrs; 1704 1705 /* Should be after VSI initialized */ 1706 dev->data->mac_addrs = rte_zmalloc("i40e", len, 0); 1707 if (!dev->data->mac_addrs) { 1708 PMD_INIT_LOG(ERR, 1709 "Failed to allocated memory for storing mac address"); 1710 goto err_mac_alloc; 1711 } 1712 rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.perm_addr, 1713 &dev->data->mac_addrs[0]); 1714 1715 /* Init dcb to sw mode by default */ 1716 ret = i40e_dcb_init_configure(dev, TRUE); 1717 if (ret != I40E_SUCCESS) { 1718 PMD_INIT_LOG(INFO, "Failed to init dcb."); 1719 pf->flags &= ~I40E_FLAG_DCB; 1720 } 1721 /* Update HW struct after DCB configuration */ 1722 i40e_get_cap(hw); 1723 1724 /* initialize pf host driver to setup SRIOV resource if applicable */ 1725 i40e_pf_host_init(dev); 1726 1727 /* register callback func to eal lib */ 1728 rte_intr_callback_register(intr_handle, 1729 i40e_dev_interrupt_handler, dev); 1730 1731 /* configure and enable device interrupt */ 1732 i40e_pf_config_irq0(hw, TRUE); 1733 i40e_pf_enable_irq0(hw); 1734 1735 /* enable uio intr after callback register */ 1736 rte_intr_enable(intr_handle); 1737 1738 /* By default disable flexible payload in global configuration */ 1739 if (!pf->support_multi_driver) 1740 i40e_flex_payload_reg_set_default(hw); 1741 1742 /* 1743 * Add an ethertype filter to drop all flow control frames transmitted 1744 * from VSIs. By doing so, we stop VF from sending out PAUSE or PFC 1745 * frames to wire. 1746 */ 1747 i40e_add_tx_flow_control_drop_filter(pf); 1748 1749 /* Set the max frame size to 0x2600 by default, 1750 * in case other drivers changed the default value. 1751 */ 1752 i40e_aq_set_mac_config(hw, I40E_FRAME_SIZE_MAX, TRUE, false, 0, NULL); 1753 1754 /* initialize mirror rule list */ 1755 TAILQ_INIT(&pf->mirror_list); 1756 1757 /* initialize RSS rule list */ 1758 TAILQ_INIT(&pf->rss_config_list); 1759 1760 /* initialize Traffic Manager configuration */ 1761 i40e_tm_conf_init(dev); 1762 1763 /* Initialize customized information */ 1764 i40e_init_customized_info(pf); 1765 1766 /* Initialize the filter invalidation configuration */ 1767 i40e_init_filter_invalidation(pf); 1768 1769 ret = i40e_init_ethtype_filter_list(dev); 1770 if (ret < 0) 1771 goto err_init_ethtype_filter_list; 1772 ret = i40e_init_tunnel_filter_list(dev); 1773 if (ret < 0) 1774 goto err_init_tunnel_filter_list; 1775 ret = i40e_init_fdir_filter_list(dev); 1776 if (ret < 0) 1777 goto err_init_fdir_filter_list; 1778 1779 /* initialize queue region configuration */ 1780 i40e_init_queue_region_conf(dev); 1781 1782 /* initialize RSS configuration from rte_flow */ 1783 memset(&pf->rss_info, 0, 1784 sizeof(struct i40e_rte_flow_rss_conf)); 1785 1786 /* reset all stats of the device, including pf and main vsi */ 1787 i40e_dev_stats_reset(dev); 1788 1789 return 0; 1790 1791 err_init_fdir_filter_list: 1792 rte_free(pf->tunnel.hash_table); 1793 rte_free(pf->tunnel.hash_map); 1794 err_init_tunnel_filter_list: 1795 rte_free(pf->ethertype.hash_table); 1796 rte_free(pf->ethertype.hash_map); 1797 err_init_ethtype_filter_list: 1798 rte_free(dev->data->mac_addrs); 1799 dev->data->mac_addrs = NULL; 1800 err_mac_alloc: 1801 i40e_vsi_release(pf->main_vsi); 1802 err_setup_pf_switch: 1803 err_get_mac_addr: 1804 err_configure_lan_hmc: 1805 (void)i40e_shutdown_lan_hmc(hw); 1806 err_init_lan_hmc: 1807 i40e_res_pool_destroy(&pf->msix_pool); 1808 err_msix_pool_init: 1809 i40e_res_pool_destroy(&pf->qp_pool); 1810 err_qp_pool_init: 1811 err_parameter_init: 1812 err_get_capabilities: 1813 (void)i40e_shutdown_adminq(hw); 1814 1815 return ret; 1816 } 1817 1818 static void 1819 i40e_rm_ethtype_filter_list(struct i40e_pf *pf) 1820 { 1821 struct i40e_ethertype_filter *p_ethertype; 1822 struct i40e_ethertype_rule *ethertype_rule; 1823 1824 ethertype_rule = &pf->ethertype; 1825 /* Remove all ethertype filter rules and hash */ 1826 if (ethertype_rule->hash_map) 1827 rte_free(ethertype_rule->hash_map); 1828 if (ethertype_rule->hash_table) 1829 rte_hash_free(ethertype_rule->hash_table); 1830 1831 while ((p_ethertype = TAILQ_FIRST(ðertype_rule->ethertype_list))) { 1832 TAILQ_REMOVE(ðertype_rule->ethertype_list, 1833 p_ethertype, rules); 1834 rte_free(p_ethertype); 1835 } 1836 } 1837 1838 static void 1839 i40e_rm_tunnel_filter_list(struct i40e_pf *pf) 1840 { 1841 struct i40e_tunnel_filter *p_tunnel; 1842 struct i40e_tunnel_rule *tunnel_rule; 1843 1844 tunnel_rule = &pf->tunnel; 1845 /* Remove all tunnel director rules and hash */ 1846 if (tunnel_rule->hash_map) 1847 rte_free(tunnel_rule->hash_map); 1848 if (tunnel_rule->hash_table) 1849 rte_hash_free(tunnel_rule->hash_table); 1850 1851 while ((p_tunnel = TAILQ_FIRST(&tunnel_rule->tunnel_list))) { 1852 TAILQ_REMOVE(&tunnel_rule->tunnel_list, p_tunnel, rules); 1853 rte_free(p_tunnel); 1854 } 1855 } 1856 1857 static void 1858 i40e_rm_fdir_filter_list(struct i40e_pf *pf) 1859 { 1860 struct i40e_fdir_filter *p_fdir; 1861 struct i40e_fdir_info *fdir_info; 1862 1863 fdir_info = &pf->fdir; 1864 1865 /* Remove all flow director rules */ 1866 while ((p_fdir = TAILQ_FIRST(&fdir_info->fdir_list))) 1867 TAILQ_REMOVE(&fdir_info->fdir_list, p_fdir, rules); 1868 } 1869 1870 static void 1871 i40e_fdir_memory_cleanup(struct i40e_pf *pf) 1872 { 1873 struct i40e_fdir_info *fdir_info; 1874 1875 fdir_info = &pf->fdir; 1876 1877 /* flow director memory cleanup */ 1878 if (fdir_info->hash_map) 1879 rte_free(fdir_info->hash_map); 1880 if (fdir_info->hash_table) 1881 rte_hash_free(fdir_info->hash_table); 1882 if (fdir_info->fdir_flow_pool.bitmap) 1883 rte_free(fdir_info->fdir_flow_pool.bitmap); 1884 if (fdir_info->fdir_flow_pool.pool) 1885 rte_free(fdir_info->fdir_flow_pool.pool); 1886 if (fdir_info->fdir_filter_array) 1887 rte_free(fdir_info->fdir_filter_array); 1888 } 1889 1890 void i40e_flex_payload_reg_set_default(struct i40e_hw *hw) 1891 { 1892 /* 1893 * Disable by default flexible payload 1894 * for corresponding L2/L3/L4 layers. 1895 */ 1896 I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(33), 0x00000000); 1897 I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(34), 0x00000000); 1898 I40E_WRITE_GLB_REG(hw, I40E_GLQF_ORT(35), 0x00000000); 1899 } 1900 1901 static int 1902 eth_i40e_dev_uninit(struct rte_eth_dev *dev) 1903 { 1904 struct i40e_hw *hw; 1905 1906 PMD_INIT_FUNC_TRACE(); 1907 1908 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 1909 return 0; 1910 1911 hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 1912 1913 if (hw->adapter_closed == 0) 1914 i40e_dev_close(dev); 1915 1916 return 0; 1917 } 1918 1919 static int 1920 i40e_dev_configure(struct rte_eth_dev *dev) 1921 { 1922 struct i40e_adapter *ad = 1923 I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); 1924 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 1925 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 1926 enum rte_eth_rx_mq_mode mq_mode = dev->data->dev_conf.rxmode.mq_mode; 1927 int i, ret; 1928 1929 ret = i40e_dev_sync_phy_type(hw); 1930 if (ret) 1931 return ret; 1932 1933 /* Initialize to TRUE. If any of Rx queues doesn't meet the 1934 * bulk allocation or vector Rx preconditions we will reset it. 1935 */ 1936 ad->rx_bulk_alloc_allowed = true; 1937 ad->rx_vec_allowed = true; 1938 ad->tx_simple_allowed = true; 1939 ad->tx_vec_allowed = true; 1940 1941 if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) 1942 dev->data->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_RSS_HASH; 1943 1944 /* Only legacy filter API needs the following fdir config. So when the 1945 * legacy filter API is deprecated, the following codes should also be 1946 * removed. 1947 */ 1948 if (dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_PERFECT) { 1949 ret = i40e_fdir_setup(pf); 1950 if (ret != I40E_SUCCESS) { 1951 PMD_DRV_LOG(ERR, "Failed to setup flow director."); 1952 return -ENOTSUP; 1953 } 1954 ret = i40e_fdir_configure(dev); 1955 if (ret < 0) { 1956 PMD_DRV_LOG(ERR, "failed to configure fdir."); 1957 goto err; 1958 } 1959 } else 1960 i40e_fdir_teardown(pf); 1961 1962 ret = i40e_dev_init_vlan(dev); 1963 if (ret < 0) 1964 goto err; 1965 1966 /* VMDQ setup. 1967 * General PMD driver call sequence are NIC init, configure, 1968 * rx/tx_queue_setup and dev_start. In rx/tx_queue_setup() function, it 1969 * will try to lookup the VSI that specific queue belongs to if VMDQ 1970 * applicable. So, VMDQ setting has to be done before 1971 * rx/tx_queue_setup(). This function is good to place vmdq_setup. 1972 * For RSS setting, it will try to calculate actual configured RX queue 1973 * number, which will be available after rx_queue_setup(). dev_start() 1974 * function is good to place RSS setup. 1975 */ 1976 if (mq_mode & ETH_MQ_RX_VMDQ_FLAG) { 1977 ret = i40e_vmdq_setup(dev); 1978 if (ret) 1979 goto err; 1980 } 1981 1982 if (mq_mode & ETH_MQ_RX_DCB_FLAG) { 1983 ret = i40e_dcb_setup(dev); 1984 if (ret) { 1985 PMD_DRV_LOG(ERR, "failed to configure DCB."); 1986 goto err_dcb; 1987 } 1988 } 1989 1990 TAILQ_INIT(&pf->flow_list); 1991 1992 return 0; 1993 1994 err_dcb: 1995 /* need to release vmdq resource if exists */ 1996 for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) { 1997 i40e_vsi_release(pf->vmdq[i].vsi); 1998 pf->vmdq[i].vsi = NULL; 1999 } 2000 rte_free(pf->vmdq); 2001 pf->vmdq = NULL; 2002 err: 2003 /* Need to release fdir resource if exists. 2004 * Only legacy filter API needs the following fdir config. So when the 2005 * legacy filter API is deprecated, the following code should also be 2006 * removed. 2007 */ 2008 i40e_fdir_teardown(pf); 2009 return ret; 2010 } 2011 2012 void 2013 i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi) 2014 { 2015 struct rte_eth_dev *dev = vsi->adapter->eth_dev; 2016 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 2017 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 2018 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 2019 uint16_t msix_vect = vsi->msix_intr; 2020 uint16_t i; 2021 2022 for (i = 0; i < vsi->nb_qps; i++) { 2023 I40E_WRITE_REG(hw, I40E_QINT_TQCTL(vsi->base_queue + i), 0); 2024 I40E_WRITE_REG(hw, I40E_QINT_RQCTL(vsi->base_queue + i), 0); 2025 rte_wmb(); 2026 } 2027 2028 if (vsi->type != I40E_VSI_SRIOV) { 2029 if (!rte_intr_allow_others(intr_handle)) { 2030 I40E_WRITE_REG(hw, I40E_PFINT_LNKLST0, 2031 I40E_PFINT_LNKLST0_FIRSTQ_INDX_MASK); 2032 I40E_WRITE_REG(hw, 2033 I40E_PFINT_ITR0(I40E_ITR_INDEX_DEFAULT), 2034 0); 2035 } else { 2036 I40E_WRITE_REG(hw, I40E_PFINT_LNKLSTN(msix_vect - 1), 2037 I40E_PFINT_LNKLSTN_FIRSTQ_INDX_MASK); 2038 I40E_WRITE_REG(hw, 2039 I40E_PFINT_ITRN(I40E_ITR_INDEX_DEFAULT, 2040 msix_vect - 1), 0); 2041 } 2042 } else { 2043 uint32_t reg; 2044 reg = (hw->func_caps.num_msix_vectors_vf - 1) * 2045 vsi->user_param + (msix_vect - 1); 2046 2047 I40E_WRITE_REG(hw, I40E_VPINT_LNKLSTN(reg), 2048 I40E_VPINT_LNKLSTN_FIRSTQ_INDX_MASK); 2049 } 2050 I40E_WRITE_FLUSH(hw); 2051 } 2052 2053 static void 2054 __vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t msix_vect, 2055 int base_queue, int nb_queue, 2056 uint16_t itr_idx) 2057 { 2058 int i; 2059 uint32_t val; 2060 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 2061 struct i40e_pf *pf = I40E_VSI_TO_PF(vsi); 2062 2063 /* Bind all RX queues to allocated MSIX interrupt */ 2064 for (i = 0; i < nb_queue; i++) { 2065 val = (msix_vect << I40E_QINT_RQCTL_MSIX_INDX_SHIFT) | 2066 itr_idx << I40E_QINT_RQCTL_ITR_INDX_SHIFT | 2067 ((base_queue + i + 1) << 2068 I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT) | 2069 (0 << I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT) | 2070 I40E_QINT_RQCTL_CAUSE_ENA_MASK; 2071 2072 if (i == nb_queue - 1) 2073 val |= I40E_QINT_RQCTL_NEXTQ_INDX_MASK; 2074 I40E_WRITE_REG(hw, I40E_QINT_RQCTL(base_queue + i), val); 2075 } 2076 2077 /* Write first RX queue to Link list register as the head element */ 2078 if (vsi->type != I40E_VSI_SRIOV) { 2079 uint16_t interval = 2080 i40e_calc_itr_interval(1, pf->support_multi_driver); 2081 2082 if (msix_vect == I40E_MISC_VEC_ID) { 2083 I40E_WRITE_REG(hw, I40E_PFINT_LNKLST0, 2084 (base_queue << 2085 I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT) | 2086 (0x0 << 2087 I40E_PFINT_LNKLST0_FIRSTQ_TYPE_SHIFT)); 2088 I40E_WRITE_REG(hw, 2089 I40E_PFINT_ITR0(I40E_ITR_INDEX_DEFAULT), 2090 interval); 2091 } else { 2092 I40E_WRITE_REG(hw, I40E_PFINT_LNKLSTN(msix_vect - 1), 2093 (base_queue << 2094 I40E_PFINT_LNKLSTN_FIRSTQ_INDX_SHIFT) | 2095 (0x0 << 2096 I40E_PFINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)); 2097 I40E_WRITE_REG(hw, 2098 I40E_PFINT_ITRN(I40E_ITR_INDEX_DEFAULT, 2099 msix_vect - 1), 2100 interval); 2101 } 2102 } else { 2103 uint32_t reg; 2104 2105 if (msix_vect == I40E_MISC_VEC_ID) { 2106 I40E_WRITE_REG(hw, 2107 I40E_VPINT_LNKLST0(vsi->user_param), 2108 (base_queue << 2109 I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT) | 2110 (0x0 << 2111 I40E_VPINT_LNKLST0_FIRSTQ_TYPE_SHIFT)); 2112 } else { 2113 /* num_msix_vectors_vf needs to minus irq0 */ 2114 reg = (hw->func_caps.num_msix_vectors_vf - 1) * 2115 vsi->user_param + (msix_vect - 1); 2116 2117 I40E_WRITE_REG(hw, I40E_VPINT_LNKLSTN(reg), 2118 (base_queue << 2119 I40E_VPINT_LNKLSTN_FIRSTQ_INDX_SHIFT) | 2120 (0x0 << 2121 I40E_VPINT_LNKLSTN_FIRSTQ_TYPE_SHIFT)); 2122 } 2123 } 2124 2125 I40E_WRITE_FLUSH(hw); 2126 } 2127 2128 int 2129 i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi, uint16_t itr_idx) 2130 { 2131 struct rte_eth_dev *dev = vsi->adapter->eth_dev; 2132 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 2133 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 2134 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 2135 uint16_t msix_vect = vsi->msix_intr; 2136 uint16_t nb_msix = RTE_MIN(vsi->nb_msix, intr_handle->nb_efd); 2137 uint16_t queue_idx = 0; 2138 int record = 0; 2139 int i; 2140 2141 for (i = 0; i < vsi->nb_qps; i++) { 2142 I40E_WRITE_REG(hw, I40E_QINT_TQCTL(vsi->base_queue + i), 0); 2143 I40E_WRITE_REG(hw, I40E_QINT_RQCTL(vsi->base_queue + i), 0); 2144 } 2145 2146 /* VF bind interrupt */ 2147 if (vsi->type == I40E_VSI_SRIOV) { 2148 if (vsi->nb_msix == 0) { 2149 PMD_DRV_LOG(ERR, "No msix resource"); 2150 return -EINVAL; 2151 } 2152 __vsi_queues_bind_intr(vsi, msix_vect, 2153 vsi->base_queue, vsi->nb_qps, 2154 itr_idx); 2155 return 0; 2156 } 2157 2158 /* PF & VMDq bind interrupt */ 2159 if (rte_intr_dp_is_en(intr_handle)) { 2160 if (vsi->type == I40E_VSI_MAIN) { 2161 queue_idx = 0; 2162 record = 1; 2163 } else if (vsi->type == I40E_VSI_VMDQ2) { 2164 struct i40e_vsi *main_vsi = 2165 I40E_DEV_PRIVATE_TO_MAIN_VSI(vsi->adapter); 2166 queue_idx = vsi->base_queue - main_vsi->nb_qps; 2167 record = 1; 2168 } 2169 } 2170 2171 for (i = 0; i < vsi->nb_used_qps; i++) { 2172 if (vsi->nb_msix == 0) { 2173 PMD_DRV_LOG(ERR, "No msix resource"); 2174 return -EINVAL; 2175 } else if (nb_msix <= 1) { 2176 if (!rte_intr_allow_others(intr_handle)) 2177 /* allow to share MISC_VEC_ID */ 2178 msix_vect = I40E_MISC_VEC_ID; 2179 2180 /* no enough msix_vect, map all to one */ 2181 __vsi_queues_bind_intr(vsi, msix_vect, 2182 vsi->base_queue + i, 2183 vsi->nb_used_qps - i, 2184 itr_idx); 2185 for (; !!record && i < vsi->nb_used_qps; i++) 2186 intr_handle->intr_vec[queue_idx + i] = 2187 msix_vect; 2188 break; 2189 } 2190 /* 1:1 queue/msix_vect mapping */ 2191 __vsi_queues_bind_intr(vsi, msix_vect, 2192 vsi->base_queue + i, 1, 2193 itr_idx); 2194 if (!!record) 2195 intr_handle->intr_vec[queue_idx + i] = msix_vect; 2196 2197 msix_vect++; 2198 nb_msix--; 2199 } 2200 2201 return 0; 2202 } 2203 2204 void 2205 i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi) 2206 { 2207 struct rte_eth_dev *dev = vsi->adapter->eth_dev; 2208 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 2209 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 2210 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 2211 struct i40e_pf *pf = I40E_VSI_TO_PF(vsi); 2212 uint16_t msix_intr, i; 2213 2214 if (rte_intr_allow_others(intr_handle) && !pf->support_multi_driver) 2215 for (i = 0; i < vsi->nb_msix; i++) { 2216 msix_intr = vsi->msix_intr + i; 2217 I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTLN(msix_intr - 1), 2218 I40E_PFINT_DYN_CTLN_INTENA_MASK | 2219 I40E_PFINT_DYN_CTLN_CLEARPBA_MASK | 2220 I40E_PFINT_DYN_CTLN_ITR_INDX_MASK); 2221 } 2222 else 2223 I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 2224 I40E_PFINT_DYN_CTL0_INTENA_MASK | 2225 I40E_PFINT_DYN_CTL0_CLEARPBA_MASK | 2226 I40E_PFINT_DYN_CTL0_ITR_INDX_MASK); 2227 2228 I40E_WRITE_FLUSH(hw); 2229 } 2230 2231 void 2232 i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi) 2233 { 2234 struct rte_eth_dev *dev = vsi->adapter->eth_dev; 2235 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 2236 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 2237 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 2238 struct i40e_pf *pf = I40E_VSI_TO_PF(vsi); 2239 uint16_t msix_intr, i; 2240 2241 if (rte_intr_allow_others(intr_handle) && !pf->support_multi_driver) 2242 for (i = 0; i < vsi->nb_msix; i++) { 2243 msix_intr = vsi->msix_intr + i; 2244 I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTLN(msix_intr - 1), 2245 I40E_PFINT_DYN_CTLN_ITR_INDX_MASK); 2246 } 2247 else 2248 I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 2249 I40E_PFINT_DYN_CTL0_ITR_INDX_MASK); 2250 2251 I40E_WRITE_FLUSH(hw); 2252 } 2253 2254 static inline uint8_t 2255 i40e_parse_link_speeds(uint16_t link_speeds) 2256 { 2257 uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN; 2258 2259 if (link_speeds & ETH_LINK_SPEED_40G) 2260 link_speed |= I40E_LINK_SPEED_40GB; 2261 if (link_speeds & ETH_LINK_SPEED_25G) 2262 link_speed |= I40E_LINK_SPEED_25GB; 2263 if (link_speeds & ETH_LINK_SPEED_20G) 2264 link_speed |= I40E_LINK_SPEED_20GB; 2265 if (link_speeds & ETH_LINK_SPEED_10G) 2266 link_speed |= I40E_LINK_SPEED_10GB; 2267 if (link_speeds & ETH_LINK_SPEED_1G) 2268 link_speed |= I40E_LINK_SPEED_1GB; 2269 if (link_speeds & ETH_LINK_SPEED_100M) 2270 link_speed |= I40E_LINK_SPEED_100MB; 2271 2272 return link_speed; 2273 } 2274 2275 static int 2276 i40e_phy_conf_link(struct i40e_hw *hw, 2277 uint8_t abilities, 2278 uint8_t force_speed, 2279 bool is_up) 2280 { 2281 enum i40e_status_code status; 2282 struct i40e_aq_get_phy_abilities_resp phy_ab; 2283 struct i40e_aq_set_phy_config phy_conf; 2284 enum i40e_aq_phy_type cnt; 2285 uint8_t avail_speed; 2286 uint32_t phy_type_mask = 0; 2287 2288 const uint8_t mask = I40E_AQ_PHY_FLAG_PAUSE_TX | 2289 I40E_AQ_PHY_FLAG_PAUSE_RX | 2290 I40E_AQ_PHY_FLAG_PAUSE_RX | 2291 I40E_AQ_PHY_FLAG_LOW_POWER; 2292 int ret = -ENOTSUP; 2293 2294 /* To get phy capabilities of available speeds. */ 2295 status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_ab, 2296 NULL); 2297 if (status) { 2298 PMD_DRV_LOG(ERR, "Failed to get PHY capabilities: %d\n", 2299 status); 2300 return ret; 2301 } 2302 avail_speed = phy_ab.link_speed; 2303 2304 /* To get the current phy config. */ 2305 status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_ab, 2306 NULL); 2307 if (status) { 2308 PMD_DRV_LOG(ERR, "Failed to get the current PHY config: %d\n", 2309 status); 2310 return ret; 2311 } 2312 2313 /* If link needs to go up and it is in autoneg mode the speed is OK, 2314 * no need to set up again. 2315 */ 2316 if (is_up && phy_ab.phy_type != 0 && 2317 abilities & I40E_AQ_PHY_AN_ENABLED && 2318 phy_ab.link_speed != 0) 2319 return I40E_SUCCESS; 2320 2321 memset(&phy_conf, 0, sizeof(phy_conf)); 2322 2323 /* bits 0-2 use the values from get_phy_abilities_resp */ 2324 abilities &= ~mask; 2325 abilities |= phy_ab.abilities & mask; 2326 2327 phy_conf.abilities = abilities; 2328 2329 /* If link needs to go up, but the force speed is not supported, 2330 * Warn users and config the default available speeds. 2331 */ 2332 if (is_up && !(force_speed & avail_speed)) { 2333 PMD_DRV_LOG(WARNING, "Invalid speed setting, set to default!\n"); 2334 phy_conf.link_speed = avail_speed; 2335 } else { 2336 phy_conf.link_speed = is_up ? force_speed : avail_speed; 2337 } 2338 2339 /* PHY type mask needs to include each type except PHY type extension */ 2340 for (cnt = I40E_PHY_TYPE_SGMII; cnt < I40E_PHY_TYPE_25GBASE_KR; cnt++) 2341 phy_type_mask |= 1 << cnt; 2342 2343 /* use get_phy_abilities_resp value for the rest */ 2344 phy_conf.phy_type = is_up ? cpu_to_le32(phy_type_mask) : 0; 2345 phy_conf.phy_type_ext = is_up ? (I40E_AQ_PHY_TYPE_EXT_25G_KR | 2346 I40E_AQ_PHY_TYPE_EXT_25G_CR | I40E_AQ_PHY_TYPE_EXT_25G_SR | 2347 I40E_AQ_PHY_TYPE_EXT_25G_LR) : 0; 2348 phy_conf.fec_config = phy_ab.fec_cfg_curr_mod_ext_info; 2349 phy_conf.eee_capability = phy_ab.eee_capability; 2350 phy_conf.eeer = phy_ab.eeer_val; 2351 phy_conf.low_power_ctrl = phy_ab.d3_lpan; 2352 2353 PMD_DRV_LOG(DEBUG, "\tCurrent: abilities %x, link_speed %x", 2354 phy_ab.abilities, phy_ab.link_speed); 2355 PMD_DRV_LOG(DEBUG, "\tConfig: abilities %x, link_speed %x", 2356 phy_conf.abilities, phy_conf.link_speed); 2357 2358 status = i40e_aq_set_phy_config(hw, &phy_conf, NULL); 2359 if (status) 2360 return ret; 2361 2362 return I40E_SUCCESS; 2363 } 2364 2365 static int 2366 i40e_apply_link_speed(struct rte_eth_dev *dev) 2367 { 2368 uint8_t speed; 2369 uint8_t abilities = 0; 2370 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 2371 struct rte_eth_conf *conf = &dev->data->dev_conf; 2372 2373 abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK | 2374 I40E_AQ_PHY_LINK_ENABLED; 2375 2376 if (conf->link_speeds == ETH_LINK_SPEED_AUTONEG) { 2377 conf->link_speeds = ETH_LINK_SPEED_40G | 2378 ETH_LINK_SPEED_25G | 2379 ETH_LINK_SPEED_20G | 2380 ETH_LINK_SPEED_10G | 2381 ETH_LINK_SPEED_1G | 2382 ETH_LINK_SPEED_100M; 2383 2384 abilities |= I40E_AQ_PHY_AN_ENABLED; 2385 } else { 2386 abilities &= ~I40E_AQ_PHY_AN_ENABLED; 2387 } 2388 speed = i40e_parse_link_speeds(conf->link_speeds); 2389 2390 return i40e_phy_conf_link(hw, abilities, speed, true); 2391 } 2392 2393 static int 2394 i40e_dev_start(struct rte_eth_dev *dev) 2395 { 2396 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 2397 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 2398 struct i40e_vsi *main_vsi = pf->main_vsi; 2399 int ret, i; 2400 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 2401 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 2402 uint32_t intr_vector = 0; 2403 struct i40e_vsi *vsi; 2404 uint16_t nb_rxq, nb_txq; 2405 2406 hw->adapter_stopped = 0; 2407 2408 rte_intr_disable(intr_handle); 2409 2410 if ((rte_intr_cap_multiple(intr_handle) || 2411 !RTE_ETH_DEV_SRIOV(dev).active) && 2412 dev->data->dev_conf.intr_conf.rxq != 0) { 2413 intr_vector = dev->data->nb_rx_queues; 2414 ret = rte_intr_efd_enable(intr_handle, intr_vector); 2415 if (ret) 2416 return ret; 2417 } 2418 2419 if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) { 2420 intr_handle->intr_vec = 2421 rte_zmalloc("intr_vec", 2422 dev->data->nb_rx_queues * sizeof(int), 2423 0); 2424 if (!intr_handle->intr_vec) { 2425 PMD_INIT_LOG(ERR, 2426 "Failed to allocate %d rx_queues intr_vec", 2427 dev->data->nb_rx_queues); 2428 return -ENOMEM; 2429 } 2430 } 2431 2432 /* Initialize VSI */ 2433 ret = i40e_dev_rxtx_init(pf); 2434 if (ret != I40E_SUCCESS) { 2435 PMD_DRV_LOG(ERR, "Failed to init rx/tx queues"); 2436 return ret; 2437 } 2438 2439 /* Map queues with MSIX interrupt */ 2440 main_vsi->nb_used_qps = dev->data->nb_rx_queues - 2441 pf->nb_cfg_vmdq_vsi * RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM; 2442 ret = i40e_vsi_queues_bind_intr(main_vsi, I40E_ITR_INDEX_DEFAULT); 2443 if (ret < 0) 2444 return ret; 2445 i40e_vsi_enable_queues_intr(main_vsi); 2446 2447 /* Map VMDQ VSI queues with MSIX interrupt */ 2448 for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) { 2449 pf->vmdq[i].vsi->nb_used_qps = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM; 2450 ret = i40e_vsi_queues_bind_intr(pf->vmdq[i].vsi, 2451 I40E_ITR_INDEX_DEFAULT); 2452 if (ret < 0) 2453 return ret; 2454 i40e_vsi_enable_queues_intr(pf->vmdq[i].vsi); 2455 } 2456 2457 /* Enable all queues which have been configured */ 2458 for (nb_rxq = 0; nb_rxq < dev->data->nb_rx_queues; nb_rxq++) { 2459 ret = i40e_dev_rx_queue_start(dev, nb_rxq); 2460 if (ret) 2461 goto rx_err; 2462 } 2463 2464 for (nb_txq = 0; nb_txq < dev->data->nb_tx_queues; nb_txq++) { 2465 ret = i40e_dev_tx_queue_start(dev, nb_txq); 2466 if (ret) 2467 goto tx_err; 2468 } 2469 2470 /* Enable receiving broadcast packets */ 2471 ret = i40e_aq_set_vsi_broadcast(hw, main_vsi->seid, true, NULL); 2472 if (ret != I40E_SUCCESS) 2473 PMD_DRV_LOG(INFO, "fail to set vsi broadcast"); 2474 2475 for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) { 2476 ret = i40e_aq_set_vsi_broadcast(hw, pf->vmdq[i].vsi->seid, 2477 true, NULL); 2478 if (ret != I40E_SUCCESS) 2479 PMD_DRV_LOG(INFO, "fail to set vsi broadcast"); 2480 } 2481 2482 /* Enable the VLAN promiscuous mode. */ 2483 if (pf->vfs) { 2484 for (i = 0; i < pf->vf_num; i++) { 2485 vsi = pf->vfs[i].vsi; 2486 i40e_aq_set_vsi_vlan_promisc(hw, vsi->seid, 2487 true, NULL); 2488 } 2489 } 2490 2491 /* Enable mac loopback mode */ 2492 if (dev->data->dev_conf.lpbk_mode == I40E_AQ_LB_MODE_NONE || 2493 dev->data->dev_conf.lpbk_mode == I40E_AQ_LB_PHY_LOCAL) { 2494 ret = i40e_aq_set_lb_modes(hw, dev->data->dev_conf.lpbk_mode, NULL); 2495 if (ret != I40E_SUCCESS) { 2496 PMD_DRV_LOG(ERR, "fail to set loopback link"); 2497 goto tx_err; 2498 } 2499 } 2500 2501 /* Apply link configure */ 2502 ret = i40e_apply_link_speed(dev); 2503 if (I40E_SUCCESS != ret) { 2504 PMD_DRV_LOG(ERR, "Fail to apply link setting"); 2505 goto tx_err; 2506 } 2507 2508 if (!rte_intr_allow_others(intr_handle)) { 2509 rte_intr_callback_unregister(intr_handle, 2510 i40e_dev_interrupt_handler, 2511 (void *)dev); 2512 /* configure and enable device interrupt */ 2513 i40e_pf_config_irq0(hw, FALSE); 2514 i40e_pf_enable_irq0(hw); 2515 2516 if (dev->data->dev_conf.intr_conf.lsc != 0) 2517 PMD_INIT_LOG(INFO, 2518 "lsc won't enable because of no intr multiplex"); 2519 } else { 2520 ret = i40e_aq_set_phy_int_mask(hw, 2521 ~(I40E_AQ_EVENT_LINK_UPDOWN | 2522 I40E_AQ_EVENT_MODULE_QUAL_FAIL | 2523 I40E_AQ_EVENT_MEDIA_NA), NULL); 2524 if (ret != I40E_SUCCESS) 2525 PMD_DRV_LOG(WARNING, "Fail to set phy mask"); 2526 2527 /* Call get_link_info aq commond to enable/disable LSE */ 2528 i40e_dev_link_update(dev, 0); 2529 } 2530 2531 if (dev->data->dev_conf.intr_conf.rxq == 0) { 2532 rte_eal_alarm_set(I40E_ALARM_INTERVAL, 2533 i40e_dev_alarm_handler, dev); 2534 } else { 2535 /* enable uio intr after callback register */ 2536 rte_intr_enable(intr_handle); 2537 } 2538 2539 i40e_filter_restore(pf); 2540 2541 if (pf->tm_conf.root && !pf->tm_conf.committed) 2542 PMD_DRV_LOG(WARNING, 2543 "please call hierarchy_commit() " 2544 "before starting the port"); 2545 2546 return I40E_SUCCESS; 2547 2548 tx_err: 2549 for (i = 0; i < nb_txq; i++) 2550 i40e_dev_tx_queue_stop(dev, i); 2551 rx_err: 2552 for (i = 0; i < nb_rxq; i++) 2553 i40e_dev_rx_queue_stop(dev, i); 2554 2555 return ret; 2556 } 2557 2558 static int 2559 i40e_dev_stop(struct rte_eth_dev *dev) 2560 { 2561 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 2562 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 2563 struct i40e_vsi *main_vsi = pf->main_vsi; 2564 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 2565 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 2566 int i; 2567 2568 if (hw->adapter_stopped == 1) 2569 return 0; 2570 2571 if (dev->data->dev_conf.intr_conf.rxq == 0) { 2572 rte_eal_alarm_cancel(i40e_dev_alarm_handler, dev); 2573 rte_intr_enable(intr_handle); 2574 } 2575 2576 /* Disable all queues */ 2577 for (i = 0; i < dev->data->nb_tx_queues; i++) 2578 i40e_dev_tx_queue_stop(dev, i); 2579 2580 for (i = 0; i < dev->data->nb_rx_queues; i++) 2581 i40e_dev_rx_queue_stop(dev, i); 2582 2583 /* un-map queues with interrupt registers */ 2584 i40e_vsi_disable_queues_intr(main_vsi); 2585 i40e_vsi_queues_unbind_intr(main_vsi); 2586 2587 for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) { 2588 i40e_vsi_disable_queues_intr(pf->vmdq[i].vsi); 2589 i40e_vsi_queues_unbind_intr(pf->vmdq[i].vsi); 2590 } 2591 2592 /* Clear all queues and release memory */ 2593 i40e_dev_clear_queues(dev); 2594 2595 /* Set link down */ 2596 i40e_dev_set_link_down(dev); 2597 2598 if (!rte_intr_allow_others(intr_handle)) 2599 /* resume to the default handler */ 2600 rte_intr_callback_register(intr_handle, 2601 i40e_dev_interrupt_handler, 2602 (void *)dev); 2603 2604 /* Clean datapath event and queue/vec mapping */ 2605 rte_intr_efd_disable(intr_handle); 2606 if (intr_handle->intr_vec) { 2607 rte_free(intr_handle->intr_vec); 2608 intr_handle->intr_vec = NULL; 2609 } 2610 2611 /* reset hierarchy commit */ 2612 pf->tm_conf.committed = false; 2613 2614 hw->adapter_stopped = 1; 2615 dev->data->dev_started = 0; 2616 2617 pf->adapter->rss_reta_updated = 0; 2618 2619 return 0; 2620 } 2621 2622 static int 2623 i40e_dev_close(struct rte_eth_dev *dev) 2624 { 2625 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 2626 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 2627 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 2628 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 2629 struct i40e_mirror_rule *p_mirror; 2630 struct i40e_filter_control_settings settings; 2631 struct rte_flow *p_flow; 2632 uint32_t reg; 2633 int i; 2634 int ret; 2635 uint8_t aq_fail = 0; 2636 int retries = 0; 2637 2638 PMD_INIT_FUNC_TRACE(); 2639 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 2640 return 0; 2641 2642 ret = rte_eth_switch_domain_free(pf->switch_domain_id); 2643 if (ret) 2644 PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret); 2645 2646 2647 ret = i40e_dev_stop(dev); 2648 2649 /* Remove all mirror rules */ 2650 while ((p_mirror = TAILQ_FIRST(&pf->mirror_list))) { 2651 ret = i40e_aq_del_mirror_rule(hw, 2652 pf->main_vsi->veb->seid, 2653 p_mirror->rule_type, 2654 p_mirror->entries, 2655 p_mirror->num_entries, 2656 p_mirror->id); 2657 if (ret < 0) 2658 PMD_DRV_LOG(ERR, "failed to remove mirror rule: " 2659 "status = %d, aq_err = %d.", ret, 2660 hw->aq.asq_last_status); 2661 2662 /* remove mirror software resource anyway */ 2663 TAILQ_REMOVE(&pf->mirror_list, p_mirror, rules); 2664 rte_free(p_mirror); 2665 pf->nb_mirror_rule--; 2666 } 2667 2668 i40e_dev_free_queues(dev); 2669 2670 /* Disable interrupt */ 2671 i40e_pf_disable_irq0(hw); 2672 rte_intr_disable(intr_handle); 2673 2674 /* 2675 * Only legacy filter API needs the following fdir config. So when the 2676 * legacy filter API is deprecated, the following code should also be 2677 * removed. 2678 */ 2679 i40e_fdir_teardown(pf); 2680 2681 /* shutdown and destroy the HMC */ 2682 i40e_shutdown_lan_hmc(hw); 2683 2684 for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) { 2685 i40e_vsi_release(pf->vmdq[i].vsi); 2686 pf->vmdq[i].vsi = NULL; 2687 } 2688 rte_free(pf->vmdq); 2689 pf->vmdq = NULL; 2690 2691 /* release all the existing VSIs and VEBs */ 2692 i40e_vsi_release(pf->main_vsi); 2693 2694 /* shutdown the adminq */ 2695 i40e_aq_queue_shutdown(hw, true); 2696 i40e_shutdown_adminq(hw); 2697 2698 i40e_res_pool_destroy(&pf->qp_pool); 2699 i40e_res_pool_destroy(&pf->msix_pool); 2700 2701 /* Disable flexible payload in global configuration */ 2702 if (!pf->support_multi_driver) 2703 i40e_flex_payload_reg_set_default(hw); 2704 2705 /* force a PF reset to clean anything leftover */ 2706 reg = I40E_READ_REG(hw, I40E_PFGEN_CTRL); 2707 I40E_WRITE_REG(hw, I40E_PFGEN_CTRL, 2708 (reg | I40E_PFGEN_CTRL_PFSWR_MASK)); 2709 I40E_WRITE_FLUSH(hw); 2710 2711 /* Clear PXE mode */ 2712 i40e_clear_pxe_mode(hw); 2713 2714 /* Unconfigure filter control */ 2715 memset(&settings, 0, sizeof(settings)); 2716 ret = i40e_set_filter_control(hw, &settings); 2717 if (ret) 2718 PMD_INIT_LOG(WARNING, "setup_pf_filter_control failed: %d", 2719 ret); 2720 2721 /* Disable flow control */ 2722 hw->fc.requested_mode = I40E_FC_NONE; 2723 i40e_set_fc(hw, &aq_fail, TRUE); 2724 2725 /* uninitialize pf host driver */ 2726 i40e_pf_host_uninit(dev); 2727 2728 do { 2729 ret = rte_intr_callback_unregister(intr_handle, 2730 i40e_dev_interrupt_handler, dev); 2731 if (ret >= 0 || ret == -ENOENT) { 2732 break; 2733 } else if (ret != -EAGAIN) { 2734 PMD_INIT_LOG(ERR, 2735 "intr callback unregister failed: %d", 2736 ret); 2737 } 2738 i40e_msec_delay(500); 2739 } while (retries++ < 5); 2740 2741 i40e_rm_ethtype_filter_list(pf); 2742 i40e_rm_tunnel_filter_list(pf); 2743 i40e_rm_fdir_filter_list(pf); 2744 2745 /* Remove all flows */ 2746 while ((p_flow = TAILQ_FIRST(&pf->flow_list))) { 2747 TAILQ_REMOVE(&pf->flow_list, p_flow, node); 2748 /* Do not free FDIR flows since they are static allocated */ 2749 if (p_flow->filter_type != RTE_ETH_FILTER_FDIR) 2750 rte_free(p_flow); 2751 } 2752 2753 /* release the fdir static allocated memory */ 2754 i40e_fdir_memory_cleanup(pf); 2755 2756 /* Remove all Traffic Manager configuration */ 2757 i40e_tm_conf_uninit(dev); 2758 2759 i40e_clear_automask(pf); 2760 2761 hw->adapter_closed = 1; 2762 return ret; 2763 } 2764 2765 /* 2766 * Reset PF device only to re-initialize resources in PMD layer 2767 */ 2768 static int 2769 i40e_dev_reset(struct rte_eth_dev *dev) 2770 { 2771 int ret; 2772 2773 /* When a DPDK PMD PF begin to reset PF port, it should notify all 2774 * its VF to make them align with it. The detailed notification 2775 * mechanism is PMD specific. As to i40e PF, it is rather complex. 2776 * To avoid unexpected behavior in VF, currently reset of PF with 2777 * SR-IOV activation is not supported. It might be supported later. 2778 */ 2779 if (dev->data->sriov.active) 2780 return -ENOTSUP; 2781 2782 ret = eth_i40e_dev_uninit(dev); 2783 if (ret) 2784 return ret; 2785 2786 ret = eth_i40e_dev_init(dev, NULL); 2787 2788 return ret; 2789 } 2790 2791 static int 2792 i40e_dev_promiscuous_enable(struct rte_eth_dev *dev) 2793 { 2794 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 2795 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 2796 struct i40e_vsi *vsi = pf->main_vsi; 2797 int status; 2798 2799 status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid, 2800 true, NULL, true); 2801 if (status != I40E_SUCCESS) { 2802 PMD_DRV_LOG(ERR, "Failed to enable unicast promiscuous"); 2803 return -EAGAIN; 2804 } 2805 2806 status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, 2807 TRUE, NULL); 2808 if (status != I40E_SUCCESS) { 2809 PMD_DRV_LOG(ERR, "Failed to enable multicast promiscuous"); 2810 /* Rollback unicast promiscuous mode */ 2811 i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid, 2812 false, NULL, true); 2813 return -EAGAIN; 2814 } 2815 2816 return 0; 2817 } 2818 2819 static int 2820 i40e_dev_promiscuous_disable(struct rte_eth_dev *dev) 2821 { 2822 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 2823 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 2824 struct i40e_vsi *vsi = pf->main_vsi; 2825 int status; 2826 2827 status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid, 2828 false, NULL, true); 2829 if (status != I40E_SUCCESS) { 2830 PMD_DRV_LOG(ERR, "Failed to disable unicast promiscuous"); 2831 return -EAGAIN; 2832 } 2833 2834 /* must remain in all_multicast mode */ 2835 if (dev->data->all_multicast == 1) 2836 return 0; 2837 2838 status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, 2839 false, NULL); 2840 if (status != I40E_SUCCESS) { 2841 PMD_DRV_LOG(ERR, "Failed to disable multicast promiscuous"); 2842 /* Rollback unicast promiscuous mode */ 2843 i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid, 2844 true, NULL, true); 2845 return -EAGAIN; 2846 } 2847 2848 return 0; 2849 } 2850 2851 static int 2852 i40e_dev_allmulticast_enable(struct rte_eth_dev *dev) 2853 { 2854 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 2855 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 2856 struct i40e_vsi *vsi = pf->main_vsi; 2857 int ret; 2858 2859 ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, TRUE, NULL); 2860 if (ret != I40E_SUCCESS) { 2861 PMD_DRV_LOG(ERR, "Failed to enable multicast promiscuous"); 2862 return -EAGAIN; 2863 } 2864 2865 return 0; 2866 } 2867 2868 static int 2869 i40e_dev_allmulticast_disable(struct rte_eth_dev *dev) 2870 { 2871 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 2872 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 2873 struct i40e_vsi *vsi = pf->main_vsi; 2874 int ret; 2875 2876 if (dev->data->promiscuous == 1) 2877 return 0; /* must remain in all_multicast mode */ 2878 2879 ret = i40e_aq_set_vsi_multicast_promiscuous(hw, 2880 vsi->seid, FALSE, NULL); 2881 if (ret != I40E_SUCCESS) { 2882 PMD_DRV_LOG(ERR, "Failed to disable multicast promiscuous"); 2883 return -EAGAIN; 2884 } 2885 2886 return 0; 2887 } 2888 2889 /* 2890 * Set device link up. 2891 */ 2892 static int 2893 i40e_dev_set_link_up(struct rte_eth_dev *dev) 2894 { 2895 /* re-apply link speed setting */ 2896 return i40e_apply_link_speed(dev); 2897 } 2898 2899 /* 2900 * Set device link down. 2901 */ 2902 static int 2903 i40e_dev_set_link_down(struct rte_eth_dev *dev) 2904 { 2905 uint8_t speed = I40E_LINK_SPEED_UNKNOWN; 2906 uint8_t abilities = 0; 2907 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 2908 2909 abilities = I40E_AQ_PHY_ENABLE_ATOMIC_LINK; 2910 return i40e_phy_conf_link(hw, abilities, speed, false); 2911 } 2912 2913 static __rte_always_inline void 2914 update_link_reg(struct i40e_hw *hw, struct rte_eth_link *link) 2915 { 2916 /* Link status registers and values*/ 2917 #define I40E_PRTMAC_LINKSTA 0x001E2420 2918 #define I40E_REG_LINK_UP 0x40000080 2919 #define I40E_PRTMAC_MACC 0x001E24E0 2920 #define I40E_REG_MACC_25GB 0x00020000 2921 #define I40E_REG_SPEED_MASK 0x38000000 2922 #define I40E_REG_SPEED_0 0x00000000 2923 #define I40E_REG_SPEED_1 0x08000000 2924 #define I40E_REG_SPEED_2 0x10000000 2925 #define I40E_REG_SPEED_3 0x18000000 2926 #define I40E_REG_SPEED_4 0x20000000 2927 uint32_t link_speed; 2928 uint32_t reg_val; 2929 2930 reg_val = I40E_READ_REG(hw, I40E_PRTMAC_LINKSTA); 2931 link_speed = reg_val & I40E_REG_SPEED_MASK; 2932 reg_val &= I40E_REG_LINK_UP; 2933 link->link_status = (reg_val == I40E_REG_LINK_UP) ? 1 : 0; 2934 2935 if (unlikely(link->link_status == 0)) 2936 return; 2937 2938 /* Parse the link status */ 2939 switch (link_speed) { 2940 case I40E_REG_SPEED_0: 2941 link->link_speed = ETH_SPEED_NUM_100M; 2942 break; 2943 case I40E_REG_SPEED_1: 2944 link->link_speed = ETH_SPEED_NUM_1G; 2945 break; 2946 case I40E_REG_SPEED_2: 2947 if (hw->mac.type == I40E_MAC_X722) 2948 link->link_speed = ETH_SPEED_NUM_2_5G; 2949 else 2950 link->link_speed = ETH_SPEED_NUM_10G; 2951 break; 2952 case I40E_REG_SPEED_3: 2953 if (hw->mac.type == I40E_MAC_X722) { 2954 link->link_speed = ETH_SPEED_NUM_5G; 2955 } else { 2956 reg_val = I40E_READ_REG(hw, I40E_PRTMAC_MACC); 2957 2958 if (reg_val & I40E_REG_MACC_25GB) 2959 link->link_speed = ETH_SPEED_NUM_25G; 2960 else 2961 link->link_speed = ETH_SPEED_NUM_40G; 2962 } 2963 break; 2964 case I40E_REG_SPEED_4: 2965 if (hw->mac.type == I40E_MAC_X722) 2966 link->link_speed = ETH_SPEED_NUM_10G; 2967 else 2968 link->link_speed = ETH_SPEED_NUM_20G; 2969 break; 2970 default: 2971 PMD_DRV_LOG(ERR, "Unknown link speed info %u", link_speed); 2972 break; 2973 } 2974 } 2975 2976 static __rte_always_inline void 2977 update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link, 2978 bool enable_lse, int wait_to_complete) 2979 { 2980 #define CHECK_INTERVAL 100 /* 100ms */ 2981 #define MAX_REPEAT_TIME 10 /* 1s (10 * 100ms) in total */ 2982 uint32_t rep_cnt = MAX_REPEAT_TIME; 2983 struct i40e_link_status link_status; 2984 int status; 2985 2986 memset(&link_status, 0, sizeof(link_status)); 2987 2988 do { 2989 memset(&link_status, 0, sizeof(link_status)); 2990 2991 /* Get link status information from hardware */ 2992 status = i40e_aq_get_link_info(hw, enable_lse, 2993 &link_status, NULL); 2994 if (unlikely(status != I40E_SUCCESS)) { 2995 link->link_speed = ETH_SPEED_NUM_NONE; 2996 link->link_duplex = ETH_LINK_FULL_DUPLEX; 2997 PMD_DRV_LOG(ERR, "Failed to get link info"); 2998 return; 2999 } 3000 3001 link->link_status = link_status.link_info & I40E_AQ_LINK_UP; 3002 if (!wait_to_complete || link->link_status) 3003 break; 3004 3005 rte_delay_ms(CHECK_INTERVAL); 3006 } while (--rep_cnt); 3007 3008 /* Parse the link status */ 3009 switch (link_status.link_speed) { 3010 case I40E_LINK_SPEED_100MB: 3011 link->link_speed = ETH_SPEED_NUM_100M; 3012 break; 3013 case I40E_LINK_SPEED_1GB: 3014 link->link_speed = ETH_SPEED_NUM_1G; 3015 break; 3016 case I40E_LINK_SPEED_10GB: 3017 link->link_speed = ETH_SPEED_NUM_10G; 3018 break; 3019 case I40E_LINK_SPEED_20GB: 3020 link->link_speed = ETH_SPEED_NUM_20G; 3021 break; 3022 case I40E_LINK_SPEED_25GB: 3023 link->link_speed = ETH_SPEED_NUM_25G; 3024 break; 3025 case I40E_LINK_SPEED_40GB: 3026 link->link_speed = ETH_SPEED_NUM_40G; 3027 break; 3028 default: 3029 if (link->link_status) 3030 link->link_speed = ETH_SPEED_NUM_UNKNOWN; 3031 else 3032 link->link_speed = ETH_SPEED_NUM_NONE; 3033 break; 3034 } 3035 } 3036 3037 int 3038 i40e_dev_link_update(struct rte_eth_dev *dev, 3039 int wait_to_complete) 3040 { 3041 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3042 struct rte_eth_link link; 3043 bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false; 3044 int ret; 3045 3046 memset(&link, 0, sizeof(link)); 3047 3048 /* i40e uses full duplex only */ 3049 link.link_duplex = ETH_LINK_FULL_DUPLEX; 3050 link.link_autoneg = !(dev->data->dev_conf.link_speeds & 3051 ETH_LINK_SPEED_FIXED); 3052 3053 if (!wait_to_complete && !enable_lse) 3054 update_link_reg(hw, &link); 3055 else 3056 update_link_aq(hw, &link, enable_lse, wait_to_complete); 3057 3058 if (hw->switch_dev) 3059 rte_eth_linkstatus_get(hw->switch_dev, &link); 3060 3061 ret = rte_eth_linkstatus_set(dev, &link); 3062 i40e_notify_all_vfs_link_status(dev); 3063 3064 return ret; 3065 } 3066 3067 static void 3068 i40e_stat_update_48_in_64(struct i40e_hw *hw, uint32_t hireg, 3069 uint32_t loreg, bool offset_loaded, uint64_t *offset, 3070 uint64_t *stat, uint64_t *prev_stat) 3071 { 3072 i40e_stat_update_48(hw, hireg, loreg, offset_loaded, offset, stat); 3073 /* enlarge the limitation when statistics counters overflowed */ 3074 if (offset_loaded) { 3075 if (I40E_RXTX_BYTES_L_48_BIT(*prev_stat) > *stat) 3076 *stat += (uint64_t)1 << I40E_48_BIT_WIDTH; 3077 *stat += I40E_RXTX_BYTES_H_16_BIT(*prev_stat); 3078 } 3079 *prev_stat = *stat; 3080 } 3081 3082 /* Get all the statistics of a VSI */ 3083 void 3084 i40e_update_vsi_stats(struct i40e_vsi *vsi) 3085 { 3086 struct i40e_eth_stats *oes = &vsi->eth_stats_offset; 3087 struct i40e_eth_stats *nes = &vsi->eth_stats; 3088 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 3089 int idx = rte_le_to_cpu_16(vsi->info.stat_counter_idx); 3090 3091 i40e_stat_update_48_in_64(hw, I40E_GLV_GORCH(idx), I40E_GLV_GORCL(idx), 3092 vsi->offset_loaded, &oes->rx_bytes, 3093 &nes->rx_bytes, &vsi->prev_rx_bytes); 3094 i40e_stat_update_48(hw, I40E_GLV_UPRCH(idx), I40E_GLV_UPRCL(idx), 3095 vsi->offset_loaded, &oes->rx_unicast, 3096 &nes->rx_unicast); 3097 i40e_stat_update_48(hw, I40E_GLV_MPRCH(idx), I40E_GLV_MPRCL(idx), 3098 vsi->offset_loaded, &oes->rx_multicast, 3099 &nes->rx_multicast); 3100 i40e_stat_update_48(hw, I40E_GLV_BPRCH(idx), I40E_GLV_BPRCL(idx), 3101 vsi->offset_loaded, &oes->rx_broadcast, 3102 &nes->rx_broadcast); 3103 /* exclude CRC bytes */ 3104 nes->rx_bytes -= (nes->rx_unicast + nes->rx_multicast + 3105 nes->rx_broadcast) * RTE_ETHER_CRC_LEN; 3106 3107 i40e_stat_update_32(hw, I40E_GLV_RDPC(idx), vsi->offset_loaded, 3108 &oes->rx_discards, &nes->rx_discards); 3109 /* GLV_REPC not supported */ 3110 /* GLV_RMPC not supported */ 3111 i40e_stat_update_32(hw, I40E_GLV_RUPP(idx), vsi->offset_loaded, 3112 &oes->rx_unknown_protocol, 3113 &nes->rx_unknown_protocol); 3114 i40e_stat_update_48_in_64(hw, I40E_GLV_GOTCH(idx), I40E_GLV_GOTCL(idx), 3115 vsi->offset_loaded, &oes->tx_bytes, 3116 &nes->tx_bytes, &vsi->prev_tx_bytes); 3117 i40e_stat_update_48(hw, I40E_GLV_UPTCH(idx), I40E_GLV_UPTCL(idx), 3118 vsi->offset_loaded, &oes->tx_unicast, 3119 &nes->tx_unicast); 3120 i40e_stat_update_48(hw, I40E_GLV_MPTCH(idx), I40E_GLV_MPTCL(idx), 3121 vsi->offset_loaded, &oes->tx_multicast, 3122 &nes->tx_multicast); 3123 i40e_stat_update_48(hw, I40E_GLV_BPTCH(idx), I40E_GLV_BPTCL(idx), 3124 vsi->offset_loaded, &oes->tx_broadcast, 3125 &nes->tx_broadcast); 3126 /* GLV_TDPC not supported */ 3127 i40e_stat_update_32(hw, I40E_GLV_TEPC(idx), vsi->offset_loaded, 3128 &oes->tx_errors, &nes->tx_errors); 3129 vsi->offset_loaded = true; 3130 3131 PMD_DRV_LOG(DEBUG, "***************** VSI[%u] stats start *******************", 3132 vsi->vsi_id); 3133 PMD_DRV_LOG(DEBUG, "rx_bytes: %"PRIu64"", nes->rx_bytes); 3134 PMD_DRV_LOG(DEBUG, "rx_unicast: %"PRIu64"", nes->rx_unicast); 3135 PMD_DRV_LOG(DEBUG, "rx_multicast: %"PRIu64"", nes->rx_multicast); 3136 PMD_DRV_LOG(DEBUG, "rx_broadcast: %"PRIu64"", nes->rx_broadcast); 3137 PMD_DRV_LOG(DEBUG, "rx_discards: %"PRIu64"", nes->rx_discards); 3138 PMD_DRV_LOG(DEBUG, "rx_unknown_protocol: %"PRIu64"", 3139 nes->rx_unknown_protocol); 3140 PMD_DRV_LOG(DEBUG, "tx_bytes: %"PRIu64"", nes->tx_bytes); 3141 PMD_DRV_LOG(DEBUG, "tx_unicast: %"PRIu64"", nes->tx_unicast); 3142 PMD_DRV_LOG(DEBUG, "tx_multicast: %"PRIu64"", nes->tx_multicast); 3143 PMD_DRV_LOG(DEBUG, "tx_broadcast: %"PRIu64"", nes->tx_broadcast); 3144 PMD_DRV_LOG(DEBUG, "tx_discards: %"PRIu64"", nes->tx_discards); 3145 PMD_DRV_LOG(DEBUG, "tx_errors: %"PRIu64"", nes->tx_errors); 3146 PMD_DRV_LOG(DEBUG, "***************** VSI[%u] stats end *******************", 3147 vsi->vsi_id); 3148 } 3149 3150 static void 3151 i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw) 3152 { 3153 unsigned int i; 3154 struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */ 3155 struct i40e_hw_port_stats *os = &pf->stats_offset; /* old stats */ 3156 3157 /* Get rx/tx bytes of internal transfer packets */ 3158 i40e_stat_update_48_in_64(hw, I40E_GLV_GORCH(hw->port), 3159 I40E_GLV_GORCL(hw->port), 3160 pf->offset_loaded, 3161 &pf->internal_stats_offset.rx_bytes, 3162 &pf->internal_stats.rx_bytes, 3163 &pf->internal_prev_rx_bytes); 3164 i40e_stat_update_48_in_64(hw, I40E_GLV_GOTCH(hw->port), 3165 I40E_GLV_GOTCL(hw->port), 3166 pf->offset_loaded, 3167 &pf->internal_stats_offset.tx_bytes, 3168 &pf->internal_stats.tx_bytes, 3169 &pf->internal_prev_tx_bytes); 3170 /* Get total internal rx packet count */ 3171 i40e_stat_update_48(hw, I40E_GLV_UPRCH(hw->port), 3172 I40E_GLV_UPRCL(hw->port), 3173 pf->offset_loaded, 3174 &pf->internal_stats_offset.rx_unicast, 3175 &pf->internal_stats.rx_unicast); 3176 i40e_stat_update_48(hw, I40E_GLV_MPRCH(hw->port), 3177 I40E_GLV_MPRCL(hw->port), 3178 pf->offset_loaded, 3179 &pf->internal_stats_offset.rx_multicast, 3180 &pf->internal_stats.rx_multicast); 3181 i40e_stat_update_48(hw, I40E_GLV_BPRCH(hw->port), 3182 I40E_GLV_BPRCL(hw->port), 3183 pf->offset_loaded, 3184 &pf->internal_stats_offset.rx_broadcast, 3185 &pf->internal_stats.rx_broadcast); 3186 /* Get total internal tx packet count */ 3187 i40e_stat_update_48(hw, I40E_GLV_UPTCH(hw->port), 3188 I40E_GLV_UPTCL(hw->port), 3189 pf->offset_loaded, 3190 &pf->internal_stats_offset.tx_unicast, 3191 &pf->internal_stats.tx_unicast); 3192 i40e_stat_update_48(hw, I40E_GLV_MPTCH(hw->port), 3193 I40E_GLV_MPTCL(hw->port), 3194 pf->offset_loaded, 3195 &pf->internal_stats_offset.tx_multicast, 3196 &pf->internal_stats.tx_multicast); 3197 i40e_stat_update_48(hw, I40E_GLV_BPTCH(hw->port), 3198 I40E_GLV_BPTCL(hw->port), 3199 pf->offset_loaded, 3200 &pf->internal_stats_offset.tx_broadcast, 3201 &pf->internal_stats.tx_broadcast); 3202 3203 /* exclude CRC size */ 3204 pf->internal_stats.rx_bytes -= (pf->internal_stats.rx_unicast + 3205 pf->internal_stats.rx_multicast + 3206 pf->internal_stats.rx_broadcast) * RTE_ETHER_CRC_LEN; 3207 3208 /* Get statistics of struct i40e_eth_stats */ 3209 i40e_stat_update_48_in_64(hw, I40E_GLPRT_GORCH(hw->port), 3210 I40E_GLPRT_GORCL(hw->port), 3211 pf->offset_loaded, &os->eth.rx_bytes, 3212 &ns->eth.rx_bytes, &pf->prev_rx_bytes); 3213 i40e_stat_update_48(hw, I40E_GLPRT_UPRCH(hw->port), 3214 I40E_GLPRT_UPRCL(hw->port), 3215 pf->offset_loaded, &os->eth.rx_unicast, 3216 &ns->eth.rx_unicast); 3217 i40e_stat_update_48(hw, I40E_GLPRT_MPRCH(hw->port), 3218 I40E_GLPRT_MPRCL(hw->port), 3219 pf->offset_loaded, &os->eth.rx_multicast, 3220 &ns->eth.rx_multicast); 3221 i40e_stat_update_48(hw, I40E_GLPRT_BPRCH(hw->port), 3222 I40E_GLPRT_BPRCL(hw->port), 3223 pf->offset_loaded, &os->eth.rx_broadcast, 3224 &ns->eth.rx_broadcast); 3225 /* Workaround: CRC size should not be included in byte statistics, 3226 * so subtract RTE_ETHER_CRC_LEN from the byte counter for each rx 3227 * packet. 3228 */ 3229 ns->eth.rx_bytes -= (ns->eth.rx_unicast + ns->eth.rx_multicast + 3230 ns->eth.rx_broadcast) * RTE_ETHER_CRC_LEN; 3231 3232 /* exclude internal rx bytes 3233 * Workaround: it is possible I40E_GLV_GORCH[H/L] is updated before 3234 * I40E_GLPRT_GORCH[H/L], so there is a small window that cause negative 3235 * value. 3236 * same to I40E_GLV_UPRC[H/L], I40E_GLV_MPRC[H/L], I40E_GLV_BPRC[H/L]. 3237 */ 3238 if (ns->eth.rx_bytes < pf->internal_stats.rx_bytes) 3239 ns->eth.rx_bytes = 0; 3240 else 3241 ns->eth.rx_bytes -= pf->internal_stats.rx_bytes; 3242 3243 if (ns->eth.rx_unicast < pf->internal_stats.rx_unicast) 3244 ns->eth.rx_unicast = 0; 3245 else 3246 ns->eth.rx_unicast -= pf->internal_stats.rx_unicast; 3247 3248 if (ns->eth.rx_multicast < pf->internal_stats.rx_multicast) 3249 ns->eth.rx_multicast = 0; 3250 else 3251 ns->eth.rx_multicast -= pf->internal_stats.rx_multicast; 3252 3253 if (ns->eth.rx_broadcast < pf->internal_stats.rx_broadcast) 3254 ns->eth.rx_broadcast = 0; 3255 else 3256 ns->eth.rx_broadcast -= pf->internal_stats.rx_broadcast; 3257 3258 i40e_stat_update_32(hw, I40E_GLPRT_RDPC(hw->port), 3259 pf->offset_loaded, &os->eth.rx_discards, 3260 &ns->eth.rx_discards); 3261 /* GLPRT_REPC not supported */ 3262 /* GLPRT_RMPC not supported */ 3263 i40e_stat_update_32(hw, I40E_GLPRT_RUPP(hw->port), 3264 pf->offset_loaded, 3265 &os->eth.rx_unknown_protocol, 3266 &ns->eth.rx_unknown_protocol); 3267 i40e_stat_update_48_in_64(hw, I40E_GLPRT_GOTCH(hw->port), 3268 I40E_GLPRT_GOTCL(hw->port), 3269 pf->offset_loaded, &os->eth.tx_bytes, 3270 &ns->eth.tx_bytes, &pf->prev_tx_bytes); 3271 i40e_stat_update_48(hw, I40E_GLPRT_UPTCH(hw->port), 3272 I40E_GLPRT_UPTCL(hw->port), 3273 pf->offset_loaded, &os->eth.tx_unicast, 3274 &ns->eth.tx_unicast); 3275 i40e_stat_update_48(hw, I40E_GLPRT_MPTCH(hw->port), 3276 I40E_GLPRT_MPTCL(hw->port), 3277 pf->offset_loaded, &os->eth.tx_multicast, 3278 &ns->eth.tx_multicast); 3279 i40e_stat_update_48(hw, I40E_GLPRT_BPTCH(hw->port), 3280 I40E_GLPRT_BPTCL(hw->port), 3281 pf->offset_loaded, &os->eth.tx_broadcast, 3282 &ns->eth.tx_broadcast); 3283 ns->eth.tx_bytes -= (ns->eth.tx_unicast + ns->eth.tx_multicast + 3284 ns->eth.tx_broadcast) * RTE_ETHER_CRC_LEN; 3285 3286 /* exclude internal tx bytes 3287 * Workaround: it is possible I40E_GLV_GOTCH[H/L] is updated before 3288 * I40E_GLPRT_GOTCH[H/L], so there is a small window that cause negative 3289 * value. 3290 * same to I40E_GLV_UPTC[H/L], I40E_GLV_MPTC[H/L], I40E_GLV_BPTC[H/L]. 3291 */ 3292 if (ns->eth.tx_bytes < pf->internal_stats.tx_bytes) 3293 ns->eth.tx_bytes = 0; 3294 else 3295 ns->eth.tx_bytes -= pf->internal_stats.tx_bytes; 3296 3297 if (ns->eth.tx_unicast < pf->internal_stats.tx_unicast) 3298 ns->eth.tx_unicast = 0; 3299 else 3300 ns->eth.tx_unicast -= pf->internal_stats.tx_unicast; 3301 3302 if (ns->eth.tx_multicast < pf->internal_stats.tx_multicast) 3303 ns->eth.tx_multicast = 0; 3304 else 3305 ns->eth.tx_multicast -= pf->internal_stats.tx_multicast; 3306 3307 if (ns->eth.tx_broadcast < pf->internal_stats.tx_broadcast) 3308 ns->eth.tx_broadcast = 0; 3309 else 3310 ns->eth.tx_broadcast -= pf->internal_stats.tx_broadcast; 3311 3312 /* GLPRT_TEPC not supported */ 3313 3314 /* additional port specific stats */ 3315 i40e_stat_update_32(hw, I40E_GLPRT_TDOLD(hw->port), 3316 pf->offset_loaded, &os->tx_dropped_link_down, 3317 &ns->tx_dropped_link_down); 3318 i40e_stat_update_32(hw, I40E_GLPRT_CRCERRS(hw->port), 3319 pf->offset_loaded, &os->crc_errors, 3320 &ns->crc_errors); 3321 i40e_stat_update_32(hw, I40E_GLPRT_ILLERRC(hw->port), 3322 pf->offset_loaded, &os->illegal_bytes, 3323 &ns->illegal_bytes); 3324 /* GLPRT_ERRBC not supported */ 3325 i40e_stat_update_32(hw, I40E_GLPRT_MLFC(hw->port), 3326 pf->offset_loaded, &os->mac_local_faults, 3327 &ns->mac_local_faults); 3328 i40e_stat_update_32(hw, I40E_GLPRT_MRFC(hw->port), 3329 pf->offset_loaded, &os->mac_remote_faults, 3330 &ns->mac_remote_faults); 3331 i40e_stat_update_32(hw, I40E_GLPRT_RLEC(hw->port), 3332 pf->offset_loaded, &os->rx_length_errors, 3333 &ns->rx_length_errors); 3334 i40e_stat_update_32(hw, I40E_GLPRT_LXONRXC(hw->port), 3335 pf->offset_loaded, &os->link_xon_rx, 3336 &ns->link_xon_rx); 3337 i40e_stat_update_32(hw, I40E_GLPRT_LXOFFRXC(hw->port), 3338 pf->offset_loaded, &os->link_xoff_rx, 3339 &ns->link_xoff_rx); 3340 for (i = 0; i < 8; i++) { 3341 i40e_stat_update_32(hw, I40E_GLPRT_PXONRXC(hw->port, i), 3342 pf->offset_loaded, 3343 &os->priority_xon_rx[i], 3344 &ns->priority_xon_rx[i]); 3345 i40e_stat_update_32(hw, I40E_GLPRT_PXOFFRXC(hw->port, i), 3346 pf->offset_loaded, 3347 &os->priority_xoff_rx[i], 3348 &ns->priority_xoff_rx[i]); 3349 } 3350 i40e_stat_update_32(hw, I40E_GLPRT_LXONTXC(hw->port), 3351 pf->offset_loaded, &os->link_xon_tx, 3352 &ns->link_xon_tx); 3353 i40e_stat_update_32(hw, I40E_GLPRT_LXOFFTXC(hw->port), 3354 pf->offset_loaded, &os->link_xoff_tx, 3355 &ns->link_xoff_tx); 3356 for (i = 0; i < 8; i++) { 3357 i40e_stat_update_32(hw, I40E_GLPRT_PXONTXC(hw->port, i), 3358 pf->offset_loaded, 3359 &os->priority_xon_tx[i], 3360 &ns->priority_xon_tx[i]); 3361 i40e_stat_update_32(hw, I40E_GLPRT_PXOFFTXC(hw->port, i), 3362 pf->offset_loaded, 3363 &os->priority_xoff_tx[i], 3364 &ns->priority_xoff_tx[i]); 3365 i40e_stat_update_32(hw, I40E_GLPRT_RXON2OFFCNT(hw->port, i), 3366 pf->offset_loaded, 3367 &os->priority_xon_2_xoff[i], 3368 &ns->priority_xon_2_xoff[i]); 3369 } 3370 i40e_stat_update_48(hw, I40E_GLPRT_PRC64H(hw->port), 3371 I40E_GLPRT_PRC64L(hw->port), 3372 pf->offset_loaded, &os->rx_size_64, 3373 &ns->rx_size_64); 3374 i40e_stat_update_48(hw, I40E_GLPRT_PRC127H(hw->port), 3375 I40E_GLPRT_PRC127L(hw->port), 3376 pf->offset_loaded, &os->rx_size_127, 3377 &ns->rx_size_127); 3378 i40e_stat_update_48(hw, I40E_GLPRT_PRC255H(hw->port), 3379 I40E_GLPRT_PRC255L(hw->port), 3380 pf->offset_loaded, &os->rx_size_255, 3381 &ns->rx_size_255); 3382 i40e_stat_update_48(hw, I40E_GLPRT_PRC511H(hw->port), 3383 I40E_GLPRT_PRC511L(hw->port), 3384 pf->offset_loaded, &os->rx_size_511, 3385 &ns->rx_size_511); 3386 i40e_stat_update_48(hw, I40E_GLPRT_PRC1023H(hw->port), 3387 I40E_GLPRT_PRC1023L(hw->port), 3388 pf->offset_loaded, &os->rx_size_1023, 3389 &ns->rx_size_1023); 3390 i40e_stat_update_48(hw, I40E_GLPRT_PRC1522H(hw->port), 3391 I40E_GLPRT_PRC1522L(hw->port), 3392 pf->offset_loaded, &os->rx_size_1522, 3393 &ns->rx_size_1522); 3394 i40e_stat_update_48(hw, I40E_GLPRT_PRC9522H(hw->port), 3395 I40E_GLPRT_PRC9522L(hw->port), 3396 pf->offset_loaded, &os->rx_size_big, 3397 &ns->rx_size_big); 3398 i40e_stat_update_32(hw, I40E_GLPRT_RUC(hw->port), 3399 pf->offset_loaded, &os->rx_undersize, 3400 &ns->rx_undersize); 3401 i40e_stat_update_32(hw, I40E_GLPRT_RFC(hw->port), 3402 pf->offset_loaded, &os->rx_fragments, 3403 &ns->rx_fragments); 3404 i40e_stat_update_32(hw, I40E_GLPRT_ROC(hw->port), 3405 pf->offset_loaded, &os->rx_oversize, 3406 &ns->rx_oversize); 3407 i40e_stat_update_32(hw, I40E_GLPRT_RJC(hw->port), 3408 pf->offset_loaded, &os->rx_jabber, 3409 &ns->rx_jabber); 3410 i40e_stat_update_48(hw, I40E_GLPRT_PTC64H(hw->port), 3411 I40E_GLPRT_PTC64L(hw->port), 3412 pf->offset_loaded, &os->tx_size_64, 3413 &ns->tx_size_64); 3414 i40e_stat_update_48(hw, I40E_GLPRT_PTC127H(hw->port), 3415 I40E_GLPRT_PTC127L(hw->port), 3416 pf->offset_loaded, &os->tx_size_127, 3417 &ns->tx_size_127); 3418 i40e_stat_update_48(hw, I40E_GLPRT_PTC255H(hw->port), 3419 I40E_GLPRT_PTC255L(hw->port), 3420 pf->offset_loaded, &os->tx_size_255, 3421 &ns->tx_size_255); 3422 i40e_stat_update_48(hw, I40E_GLPRT_PTC511H(hw->port), 3423 I40E_GLPRT_PTC511L(hw->port), 3424 pf->offset_loaded, &os->tx_size_511, 3425 &ns->tx_size_511); 3426 i40e_stat_update_48(hw, I40E_GLPRT_PTC1023H(hw->port), 3427 I40E_GLPRT_PTC1023L(hw->port), 3428 pf->offset_loaded, &os->tx_size_1023, 3429 &ns->tx_size_1023); 3430 i40e_stat_update_48(hw, I40E_GLPRT_PTC1522H(hw->port), 3431 I40E_GLPRT_PTC1522L(hw->port), 3432 pf->offset_loaded, &os->tx_size_1522, 3433 &ns->tx_size_1522); 3434 i40e_stat_update_48(hw, I40E_GLPRT_PTC9522H(hw->port), 3435 I40E_GLPRT_PTC9522L(hw->port), 3436 pf->offset_loaded, &os->tx_size_big, 3437 &ns->tx_size_big); 3438 i40e_stat_update_32(hw, I40E_GLQF_PCNT(pf->fdir.match_counter_index), 3439 pf->offset_loaded, 3440 &os->fd_sb_match, &ns->fd_sb_match); 3441 /* GLPRT_MSPDC not supported */ 3442 /* GLPRT_XEC not supported */ 3443 3444 pf->offset_loaded = true; 3445 3446 if (pf->main_vsi) 3447 i40e_update_vsi_stats(pf->main_vsi); 3448 } 3449 3450 /* Get all statistics of a port */ 3451 static int 3452 i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) 3453 { 3454 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3455 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3456 struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */ 3457 struct i40e_vsi *vsi; 3458 unsigned i; 3459 3460 /* call read registers - updates values, now write them to struct */ 3461 i40e_read_stats_registers(pf, hw); 3462 3463 stats->ipackets = pf->main_vsi->eth_stats.rx_unicast + 3464 pf->main_vsi->eth_stats.rx_multicast + 3465 pf->main_vsi->eth_stats.rx_broadcast - 3466 pf->main_vsi->eth_stats.rx_discards; 3467 stats->opackets = ns->eth.tx_unicast + 3468 ns->eth.tx_multicast + 3469 ns->eth.tx_broadcast; 3470 stats->ibytes = pf->main_vsi->eth_stats.rx_bytes; 3471 stats->obytes = ns->eth.tx_bytes; 3472 stats->oerrors = ns->eth.tx_errors + 3473 pf->main_vsi->eth_stats.tx_errors; 3474 3475 /* Rx Errors */ 3476 stats->imissed = ns->eth.rx_discards + 3477 pf->main_vsi->eth_stats.rx_discards; 3478 stats->ierrors = ns->crc_errors + 3479 ns->rx_length_errors + ns->rx_undersize + 3480 ns->rx_oversize + ns->rx_fragments + ns->rx_jabber; 3481 3482 if (pf->vfs) { 3483 for (i = 0; i < pf->vf_num; i++) { 3484 vsi = pf->vfs[i].vsi; 3485 i40e_update_vsi_stats(vsi); 3486 3487 stats->ipackets += (vsi->eth_stats.rx_unicast + 3488 vsi->eth_stats.rx_multicast + 3489 vsi->eth_stats.rx_broadcast - 3490 vsi->eth_stats.rx_discards); 3491 stats->ibytes += vsi->eth_stats.rx_bytes; 3492 stats->oerrors += vsi->eth_stats.tx_errors; 3493 stats->imissed += vsi->eth_stats.rx_discards; 3494 } 3495 } 3496 3497 PMD_DRV_LOG(DEBUG, "***************** PF stats start *******************"); 3498 PMD_DRV_LOG(DEBUG, "rx_bytes: %"PRIu64"", ns->eth.rx_bytes); 3499 PMD_DRV_LOG(DEBUG, "rx_unicast: %"PRIu64"", ns->eth.rx_unicast); 3500 PMD_DRV_LOG(DEBUG, "rx_multicast: %"PRIu64"", ns->eth.rx_multicast); 3501 PMD_DRV_LOG(DEBUG, "rx_broadcast: %"PRIu64"", ns->eth.rx_broadcast); 3502 PMD_DRV_LOG(DEBUG, "rx_discards: %"PRIu64"", ns->eth.rx_discards); 3503 PMD_DRV_LOG(DEBUG, "rx_unknown_protocol: %"PRIu64"", 3504 ns->eth.rx_unknown_protocol); 3505 PMD_DRV_LOG(DEBUG, "tx_bytes: %"PRIu64"", ns->eth.tx_bytes); 3506 PMD_DRV_LOG(DEBUG, "tx_unicast: %"PRIu64"", ns->eth.tx_unicast); 3507 PMD_DRV_LOG(DEBUG, "tx_multicast: %"PRIu64"", ns->eth.tx_multicast); 3508 PMD_DRV_LOG(DEBUG, "tx_broadcast: %"PRIu64"", ns->eth.tx_broadcast); 3509 PMD_DRV_LOG(DEBUG, "tx_discards: %"PRIu64"", ns->eth.tx_discards); 3510 PMD_DRV_LOG(DEBUG, "tx_errors: %"PRIu64"", ns->eth.tx_errors); 3511 3512 PMD_DRV_LOG(DEBUG, "tx_dropped_link_down: %"PRIu64"", 3513 ns->tx_dropped_link_down); 3514 PMD_DRV_LOG(DEBUG, "crc_errors: %"PRIu64"", ns->crc_errors); 3515 PMD_DRV_LOG(DEBUG, "illegal_bytes: %"PRIu64"", 3516 ns->illegal_bytes); 3517 PMD_DRV_LOG(DEBUG, "error_bytes: %"PRIu64"", ns->error_bytes); 3518 PMD_DRV_LOG(DEBUG, "mac_local_faults: %"PRIu64"", 3519 ns->mac_local_faults); 3520 PMD_DRV_LOG(DEBUG, "mac_remote_faults: %"PRIu64"", 3521 ns->mac_remote_faults); 3522 PMD_DRV_LOG(DEBUG, "rx_length_errors: %"PRIu64"", 3523 ns->rx_length_errors); 3524 PMD_DRV_LOG(DEBUG, "link_xon_rx: %"PRIu64"", ns->link_xon_rx); 3525 PMD_DRV_LOG(DEBUG, "link_xoff_rx: %"PRIu64"", ns->link_xoff_rx); 3526 for (i = 0; i < 8; i++) { 3527 PMD_DRV_LOG(DEBUG, "priority_xon_rx[%d]: %"PRIu64"", 3528 i, ns->priority_xon_rx[i]); 3529 PMD_DRV_LOG(DEBUG, "priority_xoff_rx[%d]: %"PRIu64"", 3530 i, ns->priority_xoff_rx[i]); 3531 } 3532 PMD_DRV_LOG(DEBUG, "link_xon_tx: %"PRIu64"", ns->link_xon_tx); 3533 PMD_DRV_LOG(DEBUG, "link_xoff_tx: %"PRIu64"", ns->link_xoff_tx); 3534 for (i = 0; i < 8; i++) { 3535 PMD_DRV_LOG(DEBUG, "priority_xon_tx[%d]: %"PRIu64"", 3536 i, ns->priority_xon_tx[i]); 3537 PMD_DRV_LOG(DEBUG, "priority_xoff_tx[%d]: %"PRIu64"", 3538 i, ns->priority_xoff_tx[i]); 3539 PMD_DRV_LOG(DEBUG, "priority_xon_2_xoff[%d]: %"PRIu64"", 3540 i, ns->priority_xon_2_xoff[i]); 3541 } 3542 PMD_DRV_LOG(DEBUG, "rx_size_64: %"PRIu64"", ns->rx_size_64); 3543 PMD_DRV_LOG(DEBUG, "rx_size_127: %"PRIu64"", ns->rx_size_127); 3544 PMD_DRV_LOG(DEBUG, "rx_size_255: %"PRIu64"", ns->rx_size_255); 3545 PMD_DRV_LOG(DEBUG, "rx_size_511: %"PRIu64"", ns->rx_size_511); 3546 PMD_DRV_LOG(DEBUG, "rx_size_1023: %"PRIu64"", ns->rx_size_1023); 3547 PMD_DRV_LOG(DEBUG, "rx_size_1522: %"PRIu64"", ns->rx_size_1522); 3548 PMD_DRV_LOG(DEBUG, "rx_size_big: %"PRIu64"", ns->rx_size_big); 3549 PMD_DRV_LOG(DEBUG, "rx_undersize: %"PRIu64"", ns->rx_undersize); 3550 PMD_DRV_LOG(DEBUG, "rx_fragments: %"PRIu64"", ns->rx_fragments); 3551 PMD_DRV_LOG(DEBUG, "rx_oversize: %"PRIu64"", ns->rx_oversize); 3552 PMD_DRV_LOG(DEBUG, "rx_jabber: %"PRIu64"", ns->rx_jabber); 3553 PMD_DRV_LOG(DEBUG, "tx_size_64: %"PRIu64"", ns->tx_size_64); 3554 PMD_DRV_LOG(DEBUG, "tx_size_127: %"PRIu64"", ns->tx_size_127); 3555 PMD_DRV_LOG(DEBUG, "tx_size_255: %"PRIu64"", ns->tx_size_255); 3556 PMD_DRV_LOG(DEBUG, "tx_size_511: %"PRIu64"", ns->tx_size_511); 3557 PMD_DRV_LOG(DEBUG, "tx_size_1023: %"PRIu64"", ns->tx_size_1023); 3558 PMD_DRV_LOG(DEBUG, "tx_size_1522: %"PRIu64"", ns->tx_size_1522); 3559 PMD_DRV_LOG(DEBUG, "tx_size_big: %"PRIu64"", ns->tx_size_big); 3560 PMD_DRV_LOG(DEBUG, "mac_short_packet_dropped: %"PRIu64"", 3561 ns->mac_short_packet_dropped); 3562 PMD_DRV_LOG(DEBUG, "checksum_error: %"PRIu64"", 3563 ns->checksum_error); 3564 PMD_DRV_LOG(DEBUG, "fdir_match: %"PRIu64"", ns->fd_sb_match); 3565 PMD_DRV_LOG(DEBUG, "***************** PF stats end ********************"); 3566 return 0; 3567 } 3568 3569 /* Reset the statistics */ 3570 static int 3571 i40e_dev_stats_reset(struct rte_eth_dev *dev) 3572 { 3573 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3574 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3575 3576 /* Mark PF and VSI stats to update the offset, aka "reset" */ 3577 pf->offset_loaded = false; 3578 if (pf->main_vsi) 3579 pf->main_vsi->offset_loaded = false; 3580 3581 /* read the stats, reading current register values into offset */ 3582 i40e_read_stats_registers(pf, hw); 3583 3584 return 0; 3585 } 3586 3587 static uint32_t 3588 i40e_xstats_calc_num(void) 3589 { 3590 return I40E_NB_ETH_XSTATS + I40E_NB_HW_PORT_XSTATS + 3591 (I40E_NB_RXQ_PRIO_XSTATS * 8) + 3592 (I40E_NB_TXQ_PRIO_XSTATS * 8); 3593 } 3594 3595 static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, 3596 struct rte_eth_xstat_name *xstats_names, 3597 __rte_unused unsigned limit) 3598 { 3599 unsigned count = 0; 3600 unsigned i, prio; 3601 3602 if (xstats_names == NULL) 3603 return i40e_xstats_calc_num(); 3604 3605 /* Note: limit checked in rte_eth_xstats_names() */ 3606 3607 /* Get stats from i40e_eth_stats struct */ 3608 for (i = 0; i < I40E_NB_ETH_XSTATS; i++) { 3609 strlcpy(xstats_names[count].name, 3610 rte_i40e_stats_strings[i].name, 3611 sizeof(xstats_names[count].name)); 3612 count++; 3613 } 3614 3615 /* Get individiual stats from i40e_hw_port struct */ 3616 for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { 3617 strlcpy(xstats_names[count].name, 3618 rte_i40e_hw_port_strings[i].name, 3619 sizeof(xstats_names[count].name)); 3620 count++; 3621 } 3622 3623 for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { 3624 for (prio = 0; prio < 8; prio++) { 3625 snprintf(xstats_names[count].name, 3626 sizeof(xstats_names[count].name), 3627 "rx_priority%u_%s", prio, 3628 rte_i40e_rxq_prio_strings[i].name); 3629 count++; 3630 } 3631 } 3632 3633 for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { 3634 for (prio = 0; prio < 8; prio++) { 3635 snprintf(xstats_names[count].name, 3636 sizeof(xstats_names[count].name), 3637 "tx_priority%u_%s", prio, 3638 rte_i40e_txq_prio_strings[i].name); 3639 count++; 3640 } 3641 } 3642 return count; 3643 } 3644 3645 static int 3646 i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, 3647 unsigned n) 3648 { 3649 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3650 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3651 unsigned i, count, prio; 3652 struct i40e_hw_port_stats *hw_stats = &pf->stats; 3653 3654 count = i40e_xstats_calc_num(); 3655 if (n < count) 3656 return count; 3657 3658 i40e_read_stats_registers(pf, hw); 3659 3660 if (xstats == NULL) 3661 return 0; 3662 3663 count = 0; 3664 3665 /* Get stats from i40e_eth_stats struct */ 3666 for (i = 0; i < I40E_NB_ETH_XSTATS; i++) { 3667 xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) + 3668 rte_i40e_stats_strings[i].offset); 3669 xstats[count].id = count; 3670 count++; 3671 } 3672 3673 /* Get individiual stats from i40e_hw_port struct */ 3674 for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { 3675 xstats[count].value = *(uint64_t *)(((char *)hw_stats) + 3676 rte_i40e_hw_port_strings[i].offset); 3677 xstats[count].id = count; 3678 count++; 3679 } 3680 3681 for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { 3682 for (prio = 0; prio < 8; prio++) { 3683 xstats[count].value = 3684 *(uint64_t *)(((char *)hw_stats) + 3685 rte_i40e_rxq_prio_strings[i].offset + 3686 (sizeof(uint64_t) * prio)); 3687 xstats[count].id = count; 3688 count++; 3689 } 3690 } 3691 3692 for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { 3693 for (prio = 0; prio < 8; prio++) { 3694 xstats[count].value = 3695 *(uint64_t *)(((char *)hw_stats) + 3696 rte_i40e_txq_prio_strings[i].offset + 3697 (sizeof(uint64_t) * prio)); 3698 xstats[count].id = count; 3699 count++; 3700 } 3701 } 3702 3703 return count; 3704 } 3705 3706 static int 3707 i40e_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) 3708 { 3709 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3710 u32 full_ver; 3711 u8 ver, patch; 3712 u16 build; 3713 int ret; 3714 3715 full_ver = hw->nvm.oem_ver; 3716 ver = (u8)(full_ver >> 24); 3717 build = (u16)((full_ver >> 8) & 0xffff); 3718 patch = (u8)(full_ver & 0xff); 3719 3720 ret = snprintf(fw_version, fw_size, 3721 "%d.%d%d 0x%08x %d.%d.%d", 3722 ((hw->nvm.version >> 12) & 0xf), 3723 ((hw->nvm.version >> 4) & 0xff), 3724 (hw->nvm.version & 0xf), hw->nvm.eetrack, 3725 ver, build, patch); 3726 3727 ret += 1; /* add the size of '\0' */ 3728 if (fw_size < (u32)ret) 3729 return ret; 3730 else 3731 return 0; 3732 } 3733 3734 /* 3735 * When using NVM 6.01(for X710 XL710 XXV710)/3.33(for X722) or later, 3736 * the Rx data path does not hang if the FW LLDP is stopped. 3737 * return true if lldp need to stop 3738 * return false if we cannot disable the LLDP to avoid Rx data path blocking. 3739 */ 3740 static bool 3741 i40e_need_stop_lldp(struct rte_eth_dev *dev) 3742 { 3743 double nvm_ver; 3744 char ver_str[64] = {0}; 3745 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3746 3747 i40e_fw_version_get(dev, ver_str, 64); 3748 nvm_ver = atof(ver_str); 3749 if ((hw->mac.type == I40E_MAC_X722 || 3750 hw->mac.type == I40E_MAC_X722_VF) && 3751 ((uint32_t)(nvm_ver * 1000) >= (uint32_t)(3.33 * 1000))) 3752 return true; 3753 else if ((uint32_t)(nvm_ver * 1000) >= (uint32_t)(6.01 * 1000)) 3754 return true; 3755 3756 return false; 3757 } 3758 3759 static int 3760 i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) 3761 { 3762 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3763 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3764 struct i40e_vsi *vsi = pf->main_vsi; 3765 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 3766 3767 dev_info->max_rx_queues = vsi->nb_qps; 3768 dev_info->max_tx_queues = vsi->nb_qps; 3769 dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN; 3770 dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX; 3771 dev_info->max_mac_addrs = vsi->max_macaddrs; 3772 dev_info->max_vfs = pci_dev->max_vfs; 3773 dev_info->max_mtu = dev_info->max_rx_pktlen - I40E_ETH_OVERHEAD; 3774 dev_info->min_mtu = RTE_ETHER_MIN_MTU; 3775 dev_info->rx_queue_offload_capa = 0; 3776 dev_info->rx_offload_capa = 3777 DEV_RX_OFFLOAD_VLAN_STRIP | 3778 DEV_RX_OFFLOAD_QINQ_STRIP | 3779 DEV_RX_OFFLOAD_IPV4_CKSUM | 3780 DEV_RX_OFFLOAD_UDP_CKSUM | 3781 DEV_RX_OFFLOAD_TCP_CKSUM | 3782 DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | 3783 DEV_RX_OFFLOAD_KEEP_CRC | 3784 DEV_RX_OFFLOAD_SCATTER | 3785 DEV_RX_OFFLOAD_VLAN_EXTEND | 3786 DEV_RX_OFFLOAD_VLAN_FILTER | 3787 DEV_RX_OFFLOAD_JUMBO_FRAME | 3788 DEV_RX_OFFLOAD_RSS_HASH; 3789 3790 dev_info->tx_queue_offload_capa = DEV_TX_OFFLOAD_MBUF_FAST_FREE; 3791 dev_info->tx_offload_capa = 3792 DEV_TX_OFFLOAD_VLAN_INSERT | 3793 DEV_TX_OFFLOAD_QINQ_INSERT | 3794 DEV_TX_OFFLOAD_IPV4_CKSUM | 3795 DEV_TX_OFFLOAD_UDP_CKSUM | 3796 DEV_TX_OFFLOAD_TCP_CKSUM | 3797 DEV_TX_OFFLOAD_SCTP_CKSUM | 3798 DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | 3799 DEV_TX_OFFLOAD_TCP_TSO | 3800 DEV_TX_OFFLOAD_VXLAN_TNL_TSO | 3801 DEV_TX_OFFLOAD_GRE_TNL_TSO | 3802 DEV_TX_OFFLOAD_IPIP_TNL_TSO | 3803 DEV_TX_OFFLOAD_GENEVE_TNL_TSO | 3804 DEV_TX_OFFLOAD_MULTI_SEGS | 3805 dev_info->tx_queue_offload_capa; 3806 dev_info->dev_capa = 3807 RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | 3808 RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; 3809 3810 dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) * 3811 sizeof(uint32_t); 3812 dev_info->reta_size = pf->hash_lut_size; 3813 dev_info->flow_type_rss_offloads = pf->adapter->flow_types_mask; 3814 3815 dev_info->default_rxconf = (struct rte_eth_rxconf) { 3816 .rx_thresh = { 3817 .pthresh = I40E_DEFAULT_RX_PTHRESH, 3818 .hthresh = I40E_DEFAULT_RX_HTHRESH, 3819 .wthresh = I40E_DEFAULT_RX_WTHRESH, 3820 }, 3821 .rx_free_thresh = I40E_DEFAULT_RX_FREE_THRESH, 3822 .rx_drop_en = 0, 3823 .offloads = 0, 3824 }; 3825 3826 dev_info->default_txconf = (struct rte_eth_txconf) { 3827 .tx_thresh = { 3828 .pthresh = I40E_DEFAULT_TX_PTHRESH, 3829 .hthresh = I40E_DEFAULT_TX_HTHRESH, 3830 .wthresh = I40E_DEFAULT_TX_WTHRESH, 3831 }, 3832 .tx_free_thresh = I40E_DEFAULT_TX_FREE_THRESH, 3833 .tx_rs_thresh = I40E_DEFAULT_TX_RSBIT_THRESH, 3834 .offloads = 0, 3835 }; 3836 3837 dev_info->rx_desc_lim = (struct rte_eth_desc_lim) { 3838 .nb_max = I40E_MAX_RING_DESC, 3839 .nb_min = I40E_MIN_RING_DESC, 3840 .nb_align = I40E_ALIGN_RING_DESC, 3841 }; 3842 3843 dev_info->tx_desc_lim = (struct rte_eth_desc_lim) { 3844 .nb_max = I40E_MAX_RING_DESC, 3845 .nb_min = I40E_MIN_RING_DESC, 3846 .nb_align = I40E_ALIGN_RING_DESC, 3847 .nb_seg_max = I40E_TX_MAX_SEG, 3848 .nb_mtu_seg_max = I40E_TX_MAX_MTU_SEG, 3849 }; 3850 3851 if (pf->flags & I40E_FLAG_VMDQ) { 3852 dev_info->max_vmdq_pools = pf->max_nb_vmdq_vsi; 3853 dev_info->vmdq_queue_base = dev_info->max_rx_queues; 3854 dev_info->vmdq_queue_num = pf->vmdq_nb_qps * 3855 pf->max_nb_vmdq_vsi; 3856 dev_info->vmdq_pool_base = I40E_VMDQ_POOL_BASE; 3857 dev_info->max_rx_queues += dev_info->vmdq_queue_num; 3858 dev_info->max_tx_queues += dev_info->vmdq_queue_num; 3859 } 3860 3861 if (I40E_PHY_TYPE_SUPPORT_40G(hw->phy.phy_types)) { 3862 /* For XL710 */ 3863 dev_info->speed_capa = ETH_LINK_SPEED_40G; 3864 dev_info->default_rxportconf.nb_queues = 2; 3865 dev_info->default_txportconf.nb_queues = 2; 3866 if (dev->data->nb_rx_queues == 1) 3867 dev_info->default_rxportconf.ring_size = 2048; 3868 else 3869 dev_info->default_rxportconf.ring_size = 1024; 3870 if (dev->data->nb_tx_queues == 1) 3871 dev_info->default_txportconf.ring_size = 1024; 3872 else 3873 dev_info->default_txportconf.ring_size = 512; 3874 3875 } else if (I40E_PHY_TYPE_SUPPORT_25G(hw->phy.phy_types)) { 3876 /* For XXV710 */ 3877 dev_info->speed_capa = ETH_LINK_SPEED_25G; 3878 dev_info->default_rxportconf.nb_queues = 1; 3879 dev_info->default_txportconf.nb_queues = 1; 3880 dev_info->default_rxportconf.ring_size = 256; 3881 dev_info->default_txportconf.ring_size = 256; 3882 } else { 3883 /* For X710 */ 3884 dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G; 3885 dev_info->default_rxportconf.nb_queues = 1; 3886 dev_info->default_txportconf.nb_queues = 1; 3887 if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_10G) { 3888 dev_info->default_rxportconf.ring_size = 512; 3889 dev_info->default_txportconf.ring_size = 256; 3890 } else { 3891 dev_info->default_rxportconf.ring_size = 256; 3892 dev_info->default_txportconf.ring_size = 256; 3893 } 3894 } 3895 dev_info->default_rxportconf.burst_size = 32; 3896 dev_info->default_txportconf.burst_size = 32; 3897 3898 return 0; 3899 } 3900 3901 static int 3902 i40e_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) 3903 { 3904 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3905 struct i40e_vsi *vsi = pf->main_vsi; 3906 PMD_INIT_FUNC_TRACE(); 3907 3908 if (on) 3909 return i40e_vsi_add_vlan(vsi, vlan_id); 3910 else 3911 return i40e_vsi_delete_vlan(vsi, vlan_id); 3912 } 3913 3914 static int 3915 i40e_vlan_tpid_set_by_registers(struct rte_eth_dev *dev, 3916 enum rte_vlan_type vlan_type, 3917 uint16_t tpid, int qinq) 3918 { 3919 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3920 uint64_t reg_r = 0; 3921 uint64_t reg_w = 0; 3922 uint16_t reg_id = 3; 3923 int ret; 3924 3925 if (qinq) { 3926 if (vlan_type == ETH_VLAN_TYPE_OUTER) 3927 reg_id = 2; 3928 } 3929 3930 ret = i40e_aq_debug_read_register(hw, I40E_GL_SWT_L2TAGCTRL(reg_id), 3931 ®_r, NULL); 3932 if (ret != I40E_SUCCESS) { 3933 PMD_DRV_LOG(ERR, 3934 "Fail to debug read from I40E_GL_SWT_L2TAGCTRL[%d]", 3935 reg_id); 3936 return -EIO; 3937 } 3938 PMD_DRV_LOG(DEBUG, 3939 "Debug read from I40E_GL_SWT_L2TAGCTRL[%d]: 0x%08"PRIx64, 3940 reg_id, reg_r); 3941 3942 reg_w = reg_r & (~(I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_MASK)); 3943 reg_w |= ((uint64_t)tpid << I40E_GL_SWT_L2TAGCTRL_ETHERTYPE_SHIFT); 3944 if (reg_r == reg_w) { 3945 PMD_DRV_LOG(DEBUG, "No need to write"); 3946 return 0; 3947 } 3948 3949 ret = i40e_aq_debug_write_global_register(hw, 3950 I40E_GL_SWT_L2TAGCTRL(reg_id), 3951 reg_w, NULL); 3952 if (ret != I40E_SUCCESS) { 3953 PMD_DRV_LOG(ERR, 3954 "Fail to debug write to I40E_GL_SWT_L2TAGCTRL[%d]", 3955 reg_id); 3956 return -EIO; 3957 } 3958 PMD_DRV_LOG(DEBUG, 3959 "Global register 0x%08x is changed with value 0x%08x", 3960 I40E_GL_SWT_L2TAGCTRL(reg_id), (uint32_t)reg_w); 3961 3962 return 0; 3963 } 3964 3965 static int 3966 i40e_vlan_tpid_set(struct rte_eth_dev *dev, 3967 enum rte_vlan_type vlan_type, 3968 uint16_t tpid) 3969 { 3970 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 3971 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 3972 int qinq = dev->data->dev_conf.rxmode.offloads & 3973 DEV_RX_OFFLOAD_VLAN_EXTEND; 3974 int ret = 0; 3975 3976 if ((vlan_type != ETH_VLAN_TYPE_INNER && 3977 vlan_type != ETH_VLAN_TYPE_OUTER) || 3978 (!qinq && vlan_type == ETH_VLAN_TYPE_INNER)) { 3979 PMD_DRV_LOG(ERR, 3980 "Unsupported vlan type."); 3981 return -EINVAL; 3982 } 3983 3984 if (pf->support_multi_driver) { 3985 PMD_DRV_LOG(ERR, "Setting TPID is not supported."); 3986 return -ENOTSUP; 3987 } 3988 3989 /* 802.1ad frames ability is added in NVM API 1.7*/ 3990 if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) { 3991 if (qinq) { 3992 if (vlan_type == ETH_VLAN_TYPE_OUTER) 3993 hw->first_tag = rte_cpu_to_le_16(tpid); 3994 else if (vlan_type == ETH_VLAN_TYPE_INNER) 3995 hw->second_tag = rte_cpu_to_le_16(tpid); 3996 } else { 3997 if (vlan_type == ETH_VLAN_TYPE_OUTER) 3998 hw->second_tag = rte_cpu_to_le_16(tpid); 3999 } 4000 ret = i40e_aq_set_switch_config(hw, 0, 0, 0, NULL); 4001 if (ret != I40E_SUCCESS) { 4002 PMD_DRV_LOG(ERR, 4003 "Set switch config failed aq_err: %d", 4004 hw->aq.asq_last_status); 4005 ret = -EIO; 4006 } 4007 } else 4008 /* If NVM API < 1.7, keep the register setting */ 4009 ret = i40e_vlan_tpid_set_by_registers(dev, vlan_type, 4010 tpid, qinq); 4011 4012 return ret; 4013 } 4014 4015 /* Configure outer vlan stripping on or off in QinQ mode */ 4016 static int 4017 i40e_vsi_config_outer_vlan_stripping(struct i40e_vsi *vsi, bool on) 4018 { 4019 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 4020 int ret = I40E_SUCCESS; 4021 uint32_t reg; 4022 4023 if (vsi->vsi_id >= I40E_MAX_NUM_VSIS) { 4024 PMD_DRV_LOG(ERR, "VSI ID exceeds the maximum"); 4025 return -EINVAL; 4026 } 4027 4028 /* Configure for outer VLAN RX stripping */ 4029 reg = I40E_READ_REG(hw, I40E_VSI_TSR(vsi->vsi_id)); 4030 4031 if (on) 4032 reg |= I40E_VSI_TSR_QINQ_STRIP; 4033 else 4034 reg &= ~I40E_VSI_TSR_QINQ_STRIP; 4035 4036 ret = i40e_aq_debug_write_register(hw, 4037 I40E_VSI_TSR(vsi->vsi_id), 4038 reg, NULL); 4039 if (ret < 0) { 4040 PMD_DRV_LOG(ERR, "Failed to update VSI_TSR[%d]", 4041 vsi->vsi_id); 4042 return I40E_ERR_CONFIG; 4043 } 4044 4045 return ret; 4046 } 4047 4048 static int 4049 i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) 4050 { 4051 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4052 struct i40e_vsi *vsi = pf->main_vsi; 4053 struct rte_eth_rxmode *rxmode; 4054 4055 rxmode = &dev->data->dev_conf.rxmode; 4056 if (mask & ETH_VLAN_FILTER_MASK) { 4057 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) 4058 i40e_vsi_config_vlan_filter(vsi, TRUE); 4059 else 4060 i40e_vsi_config_vlan_filter(vsi, FALSE); 4061 } 4062 4063 if (mask & ETH_VLAN_STRIP_MASK) { 4064 /* Enable or disable VLAN stripping */ 4065 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) 4066 i40e_vsi_config_vlan_stripping(vsi, TRUE); 4067 else 4068 i40e_vsi_config_vlan_stripping(vsi, FALSE); 4069 } 4070 4071 if (mask & ETH_VLAN_EXTEND_MASK) { 4072 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) { 4073 i40e_vsi_config_double_vlan(vsi, TRUE); 4074 /* Set global registers with default ethertype. */ 4075 i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, 4076 RTE_ETHER_TYPE_VLAN); 4077 i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER, 4078 RTE_ETHER_TYPE_VLAN); 4079 } 4080 else 4081 i40e_vsi_config_double_vlan(vsi, FALSE); 4082 } 4083 4084 if (mask & ETH_QINQ_STRIP_MASK) { 4085 /* Enable or disable outer VLAN stripping */ 4086 if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) 4087 i40e_vsi_config_outer_vlan_stripping(vsi, TRUE); 4088 else 4089 i40e_vsi_config_outer_vlan_stripping(vsi, FALSE); 4090 } 4091 4092 return 0; 4093 } 4094 4095 static void 4096 i40e_vlan_strip_queue_set(__rte_unused struct rte_eth_dev *dev, 4097 __rte_unused uint16_t queue, 4098 __rte_unused int on) 4099 { 4100 PMD_INIT_FUNC_TRACE(); 4101 } 4102 4103 static int 4104 i40e_vlan_pvid_set(struct rte_eth_dev *dev, uint16_t pvid, int on) 4105 { 4106 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4107 struct i40e_vsi *vsi = pf->main_vsi; 4108 struct rte_eth_dev_data *data = I40E_VSI_TO_DEV_DATA(vsi); 4109 struct i40e_vsi_vlan_pvid_info info; 4110 4111 memset(&info, 0, sizeof(info)); 4112 info.on = on; 4113 if (info.on) 4114 info.config.pvid = pvid; 4115 else { 4116 info.config.reject.tagged = 4117 data->dev_conf.txmode.hw_vlan_reject_tagged; 4118 info.config.reject.untagged = 4119 data->dev_conf.txmode.hw_vlan_reject_untagged; 4120 } 4121 4122 return i40e_vsi_vlan_pvid_set(vsi, &info); 4123 } 4124 4125 static int 4126 i40e_dev_led_on(struct rte_eth_dev *dev) 4127 { 4128 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 4129 uint32_t mode = i40e_led_get(hw); 4130 4131 if (mode == 0) 4132 i40e_led_set(hw, 0xf, true); /* 0xf means led always true */ 4133 4134 return 0; 4135 } 4136 4137 static int 4138 i40e_dev_led_off(struct rte_eth_dev *dev) 4139 { 4140 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 4141 uint32_t mode = i40e_led_get(hw); 4142 4143 if (mode != 0) 4144 i40e_led_set(hw, 0, false); 4145 4146 return 0; 4147 } 4148 4149 static int 4150 i40e_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 4151 { 4152 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 4153 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4154 4155 fc_conf->pause_time = pf->fc_conf.pause_time; 4156 4157 /* read out from register, in case they are modified by other port */ 4158 pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] = 4159 I40E_READ_REG(hw, I40E_GLRPB_GHW) >> I40E_KILOSHIFT; 4160 pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] = 4161 I40E_READ_REG(hw, I40E_GLRPB_GLW) >> I40E_KILOSHIFT; 4162 4163 fc_conf->high_water = pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]; 4164 fc_conf->low_water = pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]; 4165 4166 /* Return current mode according to actual setting*/ 4167 switch (hw->fc.current_mode) { 4168 case I40E_FC_FULL: 4169 fc_conf->mode = RTE_FC_FULL; 4170 break; 4171 case I40E_FC_TX_PAUSE: 4172 fc_conf->mode = RTE_FC_TX_PAUSE; 4173 break; 4174 case I40E_FC_RX_PAUSE: 4175 fc_conf->mode = RTE_FC_RX_PAUSE; 4176 break; 4177 case I40E_FC_NONE: 4178 default: 4179 fc_conf->mode = RTE_FC_NONE; 4180 }; 4181 4182 return 0; 4183 } 4184 4185 static int 4186 i40e_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 4187 { 4188 uint32_t mflcn_reg, fctrl_reg, reg; 4189 uint32_t max_high_water; 4190 uint8_t i, aq_failure; 4191 int err; 4192 struct i40e_hw *hw; 4193 struct i40e_pf *pf; 4194 enum i40e_fc_mode rte_fcmode_2_i40e_fcmode[] = { 4195 [RTE_FC_NONE] = I40E_FC_NONE, 4196 [RTE_FC_RX_PAUSE] = I40E_FC_RX_PAUSE, 4197 [RTE_FC_TX_PAUSE] = I40E_FC_TX_PAUSE, 4198 [RTE_FC_FULL] = I40E_FC_FULL 4199 }; 4200 4201 /* high_water field in the rte_eth_fc_conf using the kilobytes unit */ 4202 4203 max_high_water = I40E_RXPBSIZE >> I40E_KILOSHIFT; 4204 if ((fc_conf->high_water > max_high_water) || 4205 (fc_conf->high_water < fc_conf->low_water)) { 4206 PMD_INIT_LOG(ERR, 4207 "Invalid high/low water setup value in KB, High_water must be <= %d.", 4208 max_high_water); 4209 return -EINVAL; 4210 } 4211 4212 hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 4213 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4214 hw->fc.requested_mode = rte_fcmode_2_i40e_fcmode[fc_conf->mode]; 4215 4216 pf->fc_conf.pause_time = fc_conf->pause_time; 4217 pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] = fc_conf->high_water; 4218 pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] = fc_conf->low_water; 4219 4220 PMD_INIT_FUNC_TRACE(); 4221 4222 /* All the link flow control related enable/disable register 4223 * configuration is handle by the F/W 4224 */ 4225 err = i40e_set_fc(hw, &aq_failure, true); 4226 if (err < 0) 4227 return -ENOSYS; 4228 4229 if (I40E_PHY_TYPE_SUPPORT_40G(hw->phy.phy_types)) { 4230 /* Configure flow control refresh threshold, 4231 * the value for stat_tx_pause_refresh_timer[8] 4232 * is used for global pause operation. 4233 */ 4234 4235 I40E_WRITE_REG(hw, 4236 I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(8), 4237 pf->fc_conf.pause_time); 4238 4239 /* configure the timer value included in transmitted pause 4240 * frame, 4241 * the value for stat_tx_pause_quanta[8] is used for global 4242 * pause operation 4243 */ 4244 I40E_WRITE_REG(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(8), 4245 pf->fc_conf.pause_time); 4246 4247 fctrl_reg = I40E_READ_REG(hw, 4248 I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL); 4249 4250 if (fc_conf->mac_ctrl_frame_fwd != 0) 4251 fctrl_reg |= I40E_PRTMAC_FWD_CTRL; 4252 else 4253 fctrl_reg &= ~I40E_PRTMAC_FWD_CTRL; 4254 4255 I40E_WRITE_REG(hw, I40E_PRTMAC_HSEC_CTL_RX_FORWARD_CONTROL, 4256 fctrl_reg); 4257 } else { 4258 /* Configure pause time (2 TCs per register) */ 4259 reg = (uint32_t)pf->fc_conf.pause_time * (uint32_t)0x00010001; 4260 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS / 2; i++) 4261 I40E_WRITE_REG(hw, I40E_PRTDCB_FCTTVN(i), reg); 4262 4263 /* Configure flow control refresh threshold value */ 4264 I40E_WRITE_REG(hw, I40E_PRTDCB_FCRTV, 4265 pf->fc_conf.pause_time / 2); 4266 4267 mflcn_reg = I40E_READ_REG(hw, I40E_PRTDCB_MFLCN); 4268 4269 /* set or clear MFLCN.PMCF & MFLCN.DPF bits 4270 *depending on configuration 4271 */ 4272 if (fc_conf->mac_ctrl_frame_fwd != 0) { 4273 mflcn_reg |= I40E_PRTDCB_MFLCN_PMCF_MASK; 4274 mflcn_reg &= ~I40E_PRTDCB_MFLCN_DPF_MASK; 4275 } else { 4276 mflcn_reg &= ~I40E_PRTDCB_MFLCN_PMCF_MASK; 4277 mflcn_reg |= I40E_PRTDCB_MFLCN_DPF_MASK; 4278 } 4279 4280 I40E_WRITE_REG(hw, I40E_PRTDCB_MFLCN, mflcn_reg); 4281 } 4282 4283 if (!pf->support_multi_driver) { 4284 /* config water marker both based on the packets and bytes */ 4285 I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PHW, 4286 (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] 4287 << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE); 4288 I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PLW, 4289 (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] 4290 << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE); 4291 I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GHW, 4292 pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS] 4293 << I40E_KILOSHIFT); 4294 I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GLW, 4295 pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS] 4296 << I40E_KILOSHIFT); 4297 } else { 4298 PMD_DRV_LOG(ERR, 4299 "Water marker configuration is not supported."); 4300 } 4301 4302 I40E_WRITE_FLUSH(hw); 4303 4304 return 0; 4305 } 4306 4307 static int 4308 i40e_priority_flow_ctrl_set(__rte_unused struct rte_eth_dev *dev, 4309 __rte_unused struct rte_eth_pfc_conf *pfc_conf) 4310 { 4311 PMD_INIT_FUNC_TRACE(); 4312 4313 return -ENOSYS; 4314 } 4315 4316 /* Add a MAC address, and update filters */ 4317 static int 4318 i40e_macaddr_add(struct rte_eth_dev *dev, 4319 struct rte_ether_addr *mac_addr, 4320 __rte_unused uint32_t index, 4321 uint32_t pool) 4322 { 4323 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4324 struct i40e_mac_filter_info mac_filter; 4325 struct i40e_vsi *vsi; 4326 struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; 4327 int ret; 4328 4329 /* If VMDQ not enabled or configured, return */ 4330 if (pool != 0 && (!(pf->flags & I40E_FLAG_VMDQ) || 4331 !pf->nb_cfg_vmdq_vsi)) { 4332 PMD_DRV_LOG(ERR, "VMDQ not %s, can't set mac to pool %u", 4333 pf->flags & I40E_FLAG_VMDQ ? "configured" : "enabled", 4334 pool); 4335 return -ENOTSUP; 4336 } 4337 4338 if (pool > pf->nb_cfg_vmdq_vsi) { 4339 PMD_DRV_LOG(ERR, "Pool number %u invalid. Max pool is %u", 4340 pool, pf->nb_cfg_vmdq_vsi); 4341 return -EINVAL; 4342 } 4343 4344 rte_memcpy(&mac_filter.mac_addr, mac_addr, RTE_ETHER_ADDR_LEN); 4345 if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) 4346 mac_filter.filter_type = I40E_MACVLAN_PERFECT_MATCH; 4347 else 4348 mac_filter.filter_type = I40E_MAC_PERFECT_MATCH; 4349 4350 if (pool == 0) 4351 vsi = pf->main_vsi; 4352 else 4353 vsi = pf->vmdq[pool - 1].vsi; 4354 4355 ret = i40e_vsi_add_mac(vsi, &mac_filter); 4356 if (ret != I40E_SUCCESS) { 4357 PMD_DRV_LOG(ERR, "Failed to add MACVLAN filter"); 4358 return -ENODEV; 4359 } 4360 return 0; 4361 } 4362 4363 /* Remove a MAC address, and update filters */ 4364 static void 4365 i40e_macaddr_remove(struct rte_eth_dev *dev, uint32_t index) 4366 { 4367 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 4368 struct i40e_vsi *vsi; 4369 struct rte_eth_dev_data *data = dev->data; 4370 struct rte_ether_addr *macaddr; 4371 int ret; 4372 uint32_t i; 4373 uint64_t pool_sel; 4374 4375 macaddr = &(data->mac_addrs[index]); 4376 4377 pool_sel = dev->data->mac_pool_sel[index]; 4378 4379 for (i = 0; i < sizeof(pool_sel) * CHAR_BIT; i++) { 4380 if (pool_sel & (1ULL << i)) { 4381 if (i == 0) 4382 vsi = pf->main_vsi; 4383 else { 4384 /* No VMDQ pool enabled or configured */ 4385 if (!(pf->flags & I40E_FLAG_VMDQ) || 4386 (i > pf->nb_cfg_vmdq_vsi)) { 4387 PMD_DRV_LOG(ERR, 4388 "No VMDQ pool enabled/configured"); 4389 return; 4390 } 4391 vsi = pf->vmdq[i - 1].vsi; 4392 } 4393 ret = i40e_vsi_delete_mac(vsi, macaddr); 4394 4395 if (ret) { 4396 PMD_DRV_LOG(ERR, "Failed to remove MACVLAN filter"); 4397 return; 4398 } 4399 } 4400 } 4401 } 4402 4403 static int 4404 i40e_get_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size) 4405 { 4406 struct i40e_pf *pf = I40E_VSI_TO_PF(vsi); 4407 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 4408 uint32_t reg; 4409 int ret; 4410 4411 if (!lut) 4412 return -EINVAL; 4413 4414 if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) { 4415 ret = i40e_aq_get_rss_lut(hw, vsi->vsi_id, 4416 vsi->type != I40E_VSI_SRIOV, 4417 lut, lut_size); 4418 if (ret) { 4419 PMD_DRV_LOG(ERR, "Failed to get RSS lookup table"); 4420 return ret; 4421 } 4422 } else { 4423 uint32_t *lut_dw = (uint32_t *)lut; 4424 uint16_t i, lut_size_dw = lut_size / 4; 4425 4426 if (vsi->type == I40E_VSI_SRIOV) { 4427 for (i = 0; i <= lut_size_dw; i++) { 4428 reg = I40E_VFQF_HLUT1(i, vsi->user_param); 4429 lut_dw[i] = i40e_read_rx_ctl(hw, reg); 4430 } 4431 } else { 4432 for (i = 0; i < lut_size_dw; i++) 4433 lut_dw[i] = I40E_READ_REG(hw, 4434 I40E_PFQF_HLUT(i)); 4435 } 4436 } 4437 4438 return 0; 4439 } 4440 4441 int 4442 i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size) 4443 { 4444 struct i40e_pf *pf; 4445 struct i40e_hw *hw; 4446 int ret; 4447 4448 if (!vsi || !lut) 4449 return -EINVAL; 4450 4451 pf = I40E_VSI_TO_PF(vsi); 4452 hw = I40E_VSI_TO_HW(vsi); 4453 4454 if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) { 4455 ret = i40e_aq_set_rss_lut(hw, vsi->vsi_id, 4456 vsi->type != I40E_VSI_SRIOV, 4457 lut, lut_size); 4458 if (ret) { 4459 PMD_DRV_LOG(ERR, "Failed to set RSS lookup table"); 4460 return ret; 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 static 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 int ret = 0; 7616 7617 if (!key || key_len == 0) { 7618 PMD_DRV_LOG(DEBUG, "No key to be configured"); 7619 return 0; 7620 } else if (key_len != (key_idx + 1) * 7621 sizeof(uint32_t)) { 7622 PMD_DRV_LOG(ERR, "Invalid key length %u", key_len); 7623 return -EINVAL; 7624 } 7625 7626 if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) { 7627 struct i40e_aqc_get_set_rss_key_data *key_dw = 7628 (struct i40e_aqc_get_set_rss_key_data *)key; 7629 7630 ret = i40e_aq_set_rss_key(hw, vsi->vsi_id, key_dw); 7631 if (ret) 7632 PMD_INIT_LOG(ERR, "Failed to configure RSS key via AQ"); 7633 } else { 7634 uint32_t *hash_key = (uint32_t *)key; 7635 uint16_t i; 7636 7637 if (vsi->type == I40E_VSI_SRIOV) { 7638 for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) 7639 I40E_WRITE_REG( 7640 hw, 7641 I40E_VFQF_HKEY1(i, vsi->user_param), 7642 hash_key[i]); 7643 7644 } else { 7645 for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) 7646 I40E_WRITE_REG(hw, I40E_PFQF_HKEY(i), 7647 hash_key[i]); 7648 } 7649 I40E_WRITE_FLUSH(hw); 7650 } 7651 7652 return ret; 7653 } 7654 7655 static int 7656 i40e_get_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t *key_len) 7657 { 7658 struct i40e_pf *pf = I40E_VSI_TO_PF(vsi); 7659 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 7660 uint32_t reg; 7661 int ret; 7662 7663 if (!key || !key_len) 7664 return 0; 7665 7666 if (pf->flags & I40E_FLAG_RSS_AQ_CAPABLE) { 7667 ret = i40e_aq_get_rss_key(hw, vsi->vsi_id, 7668 (struct i40e_aqc_get_set_rss_key_data *)key); 7669 if (ret) { 7670 PMD_INIT_LOG(ERR, "Failed to get RSS key via AQ"); 7671 return ret; 7672 } 7673 } else { 7674 uint32_t *key_dw = (uint32_t *)key; 7675 uint16_t i; 7676 7677 if (vsi->type == I40E_VSI_SRIOV) { 7678 for (i = 0; i <= I40E_VFQF_HKEY_MAX_INDEX; i++) { 7679 reg = I40E_VFQF_HKEY1(i, vsi->user_param); 7680 key_dw[i] = i40e_read_rx_ctl(hw, reg); 7681 } 7682 *key_len = (I40E_VFQF_HKEY_MAX_INDEX + 1) * 7683 sizeof(uint32_t); 7684 } else { 7685 for (i = 0; i <= I40E_PFQF_HKEY_MAX_INDEX; i++) { 7686 reg = I40E_PFQF_HKEY(i); 7687 key_dw[i] = i40e_read_rx_ctl(hw, reg); 7688 } 7689 *key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) * 7690 sizeof(uint32_t); 7691 } 7692 } 7693 return 0; 7694 } 7695 7696 static int 7697 i40e_hw_rss_hash_set(struct i40e_pf *pf, struct rte_eth_rss_conf *rss_conf) 7698 { 7699 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 7700 uint64_t hena; 7701 int ret; 7702 7703 ret = i40e_set_rss_key(pf->main_vsi, rss_conf->rss_key, 7704 rss_conf->rss_key_len); 7705 if (ret) 7706 return ret; 7707 7708 hena = i40e_config_hena(pf->adapter, rss_conf->rss_hf); 7709 i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena); 7710 i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32)); 7711 I40E_WRITE_FLUSH(hw); 7712 7713 return 0; 7714 } 7715 7716 static int 7717 i40e_dev_rss_hash_update(struct rte_eth_dev *dev, 7718 struct rte_eth_rss_conf *rss_conf) 7719 { 7720 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 7721 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 7722 uint64_t rss_hf = rss_conf->rss_hf & pf->adapter->flow_types_mask; 7723 uint64_t hena; 7724 7725 hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)); 7726 hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32; 7727 7728 if (!(hena & pf->adapter->pctypes_mask)) { /* RSS disabled */ 7729 if (rss_hf != 0) /* Enable RSS */ 7730 return -EINVAL; 7731 return 0; /* Nothing to do */ 7732 } 7733 /* RSS enabled */ 7734 if (rss_hf == 0) /* Disable RSS */ 7735 return -EINVAL; 7736 7737 return i40e_hw_rss_hash_set(pf, rss_conf); 7738 } 7739 7740 static int 7741 i40e_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 7742 struct rte_eth_rss_conf *rss_conf) 7743 { 7744 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 7745 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 7746 uint64_t hena; 7747 int ret; 7748 7749 if (!rss_conf) 7750 return -EINVAL; 7751 7752 ret = i40e_get_rss_key(pf->main_vsi, rss_conf->rss_key, 7753 &rss_conf->rss_key_len); 7754 if (ret) 7755 return ret; 7756 7757 hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)); 7758 hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32; 7759 rss_conf->rss_hf = i40e_parse_hena(pf->adapter, hena); 7760 7761 return 0; 7762 } 7763 7764 static int 7765 i40e_dev_get_filter_type(uint16_t filter_type, uint16_t *flag) 7766 { 7767 switch (filter_type) { 7768 case RTE_TUNNEL_FILTER_IMAC_IVLAN: 7769 *flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN; 7770 break; 7771 case RTE_TUNNEL_FILTER_IMAC_IVLAN_TENID: 7772 *flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID; 7773 break; 7774 case RTE_TUNNEL_FILTER_IMAC_TENID: 7775 *flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID; 7776 break; 7777 case RTE_TUNNEL_FILTER_OMAC_TENID_IMAC: 7778 *flag = I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC; 7779 break; 7780 case ETH_TUNNEL_FILTER_IMAC: 7781 *flag = I40E_AQC_ADD_CLOUD_FILTER_IMAC; 7782 break; 7783 case ETH_TUNNEL_FILTER_OIP: 7784 *flag = I40E_AQC_ADD_CLOUD_FILTER_OIP; 7785 break; 7786 case ETH_TUNNEL_FILTER_IIP: 7787 *flag = I40E_AQC_ADD_CLOUD_FILTER_IIP; 7788 break; 7789 default: 7790 PMD_DRV_LOG(ERR, "invalid tunnel filter type"); 7791 return -EINVAL; 7792 } 7793 7794 return 0; 7795 } 7796 7797 /* Convert tunnel filter structure */ 7798 static int 7799 i40e_tunnel_filter_convert( 7800 struct i40e_aqc_cloud_filters_element_bb *cld_filter, 7801 struct i40e_tunnel_filter *tunnel_filter) 7802 { 7803 rte_ether_addr_copy((struct rte_ether_addr *) 7804 &cld_filter->element.outer_mac, 7805 (struct rte_ether_addr *)&tunnel_filter->input.outer_mac); 7806 rte_ether_addr_copy((struct rte_ether_addr *) 7807 &cld_filter->element.inner_mac, 7808 (struct rte_ether_addr *)&tunnel_filter->input.inner_mac); 7809 tunnel_filter->input.inner_vlan = cld_filter->element.inner_vlan; 7810 if ((rte_le_to_cpu_16(cld_filter->element.flags) & 7811 I40E_AQC_ADD_CLOUD_FLAGS_IPV6) == 7812 I40E_AQC_ADD_CLOUD_FLAGS_IPV6) 7813 tunnel_filter->input.ip_type = I40E_TUNNEL_IPTYPE_IPV6; 7814 else 7815 tunnel_filter->input.ip_type = I40E_TUNNEL_IPTYPE_IPV4; 7816 tunnel_filter->input.flags = cld_filter->element.flags; 7817 tunnel_filter->input.tenant_id = cld_filter->element.tenant_id; 7818 tunnel_filter->queue = cld_filter->element.queue_number; 7819 rte_memcpy(tunnel_filter->input.general_fields, 7820 cld_filter->general_fields, 7821 sizeof(cld_filter->general_fields)); 7822 7823 return 0; 7824 } 7825 7826 /* Check if there exists the tunnel filter */ 7827 struct i40e_tunnel_filter * 7828 i40e_sw_tunnel_filter_lookup(struct i40e_tunnel_rule *tunnel_rule, 7829 const struct i40e_tunnel_filter_input *input) 7830 { 7831 int ret; 7832 7833 ret = rte_hash_lookup(tunnel_rule->hash_table, (const void *)input); 7834 if (ret < 0) 7835 return NULL; 7836 7837 return tunnel_rule->hash_map[ret]; 7838 } 7839 7840 /* Add a tunnel filter into the SW list */ 7841 static int 7842 i40e_sw_tunnel_filter_insert(struct i40e_pf *pf, 7843 struct i40e_tunnel_filter *tunnel_filter) 7844 { 7845 struct i40e_tunnel_rule *rule = &pf->tunnel; 7846 int ret; 7847 7848 ret = rte_hash_add_key(rule->hash_table, &tunnel_filter->input); 7849 if (ret < 0) { 7850 PMD_DRV_LOG(ERR, 7851 "Failed to insert tunnel filter to hash table %d!", 7852 ret); 7853 return ret; 7854 } 7855 rule->hash_map[ret] = tunnel_filter; 7856 7857 TAILQ_INSERT_TAIL(&rule->tunnel_list, tunnel_filter, rules); 7858 7859 return 0; 7860 } 7861 7862 /* Delete a tunnel filter from the SW list */ 7863 int 7864 i40e_sw_tunnel_filter_del(struct i40e_pf *pf, 7865 struct i40e_tunnel_filter_input *input) 7866 { 7867 struct i40e_tunnel_rule *rule = &pf->tunnel; 7868 struct i40e_tunnel_filter *tunnel_filter; 7869 int ret; 7870 7871 ret = rte_hash_del_key(rule->hash_table, input); 7872 if (ret < 0) { 7873 PMD_DRV_LOG(ERR, 7874 "Failed to delete tunnel filter to hash table %d!", 7875 ret); 7876 return ret; 7877 } 7878 tunnel_filter = rule->hash_map[ret]; 7879 rule->hash_map[ret] = NULL; 7880 7881 TAILQ_REMOVE(&rule->tunnel_list, tunnel_filter, rules); 7882 rte_free(tunnel_filter); 7883 7884 return 0; 7885 } 7886 7887 #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_TR_WORD0 0x48 7888 #define I40E_TR_VXLAN_GRE_KEY_MASK 0x4 7889 #define I40E_TR_GENEVE_KEY_MASK 0x8 7890 #define I40E_TR_GENERIC_UDP_TUNNEL_MASK 0x40 7891 #define I40E_TR_GRE_KEY_MASK 0x400 7892 #define I40E_TR_GRE_KEY_WITH_XSUM_MASK 0x800 7893 #define I40E_TR_GRE_NO_KEY_MASK 0x8000 7894 #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_PORT_TR_WORD0 0x49 7895 #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_DIRECTION_WORD0 0x41 7896 #define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_INGRESS_WORD0 0x80 7897 #define I40E_DIRECTION_INGRESS_KEY 0x8000 7898 #define I40E_TR_L4_TYPE_TCP 0x2 7899 #define I40E_TR_L4_TYPE_UDP 0x4 7900 #define I40E_TR_L4_TYPE_SCTP 0x8 7901 7902 static enum 7903 i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf) 7904 { 7905 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 7906 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 7907 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 7908 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 7909 enum i40e_status_code status = I40E_SUCCESS; 7910 7911 if (pf->support_multi_driver) { 7912 PMD_DRV_LOG(ERR, "Replace l1 filter is not supported."); 7913 return I40E_NOT_SUPPORTED; 7914 } 7915 7916 memset(&filter_replace, 0, 7917 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 7918 memset(&filter_replace_buf, 0, 7919 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 7920 7921 /* create L1 filter */ 7922 filter_replace.old_filter_type = 7923 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC; 7924 filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X11; 7925 filter_replace.tr_bit = 0; 7926 7927 /* Prepare the buffer, 3 entries */ 7928 filter_replace_buf.data[0] = 7929 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0; 7930 filter_replace_buf.data[0] |= 7931 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7932 filter_replace_buf.data[2] = 0xFF; 7933 filter_replace_buf.data[3] = 0xFF; 7934 filter_replace_buf.data[4] = 7935 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1; 7936 filter_replace_buf.data[4] |= 7937 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7938 filter_replace_buf.data[7] = 0xF0; 7939 filter_replace_buf.data[8] 7940 = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_TR_WORD0; 7941 filter_replace_buf.data[8] |= 7942 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7943 filter_replace_buf.data[10] = I40E_TR_VXLAN_GRE_KEY_MASK | 7944 I40E_TR_GENEVE_KEY_MASK | 7945 I40E_TR_GENERIC_UDP_TUNNEL_MASK; 7946 filter_replace_buf.data[11] = (I40E_TR_GRE_KEY_MASK | 7947 I40E_TR_GRE_KEY_WITH_XSUM_MASK | 7948 I40E_TR_GRE_NO_KEY_MASK) >> 8; 7949 7950 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 7951 &filter_replace_buf); 7952 if (!status && (filter_replace.old_filter_type != 7953 filter_replace.new_filter_type)) 7954 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type." 7955 " original: 0x%x, new: 0x%x", 7956 dev->device->name, 7957 filter_replace.old_filter_type, 7958 filter_replace.new_filter_type); 7959 7960 return status; 7961 } 7962 7963 static enum 7964 i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf) 7965 { 7966 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 7967 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 7968 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 7969 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 7970 enum i40e_status_code status = I40E_SUCCESS; 7971 7972 if (pf->support_multi_driver) { 7973 PMD_DRV_LOG(ERR, "Replace cloud filter is not supported."); 7974 return I40E_NOT_SUPPORTED; 7975 } 7976 7977 /* For MPLSoUDP */ 7978 memset(&filter_replace, 0, 7979 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 7980 memset(&filter_replace_buf, 0, 7981 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 7982 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER | 7983 I40E_AQC_MIRROR_CLOUD_FILTER; 7984 filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IIP; 7985 filter_replace.new_filter_type = 7986 I40E_AQC_ADD_CLOUD_FILTER_0X11; 7987 /* Prepare the buffer, 2 entries */ 7988 filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 7989 filter_replace_buf.data[0] |= 7990 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7991 filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_0X11; 7992 filter_replace_buf.data[4] |= 7993 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 7994 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 7995 &filter_replace_buf); 7996 if (status < 0) 7997 return status; 7998 if (filter_replace.old_filter_type != 7999 filter_replace.new_filter_type) 8000 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 8001 " original: 0x%x, new: 0x%x", 8002 dev->device->name, 8003 filter_replace.old_filter_type, 8004 filter_replace.new_filter_type); 8005 8006 /* For MPLSoGRE */ 8007 memset(&filter_replace, 0, 8008 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 8009 memset(&filter_replace_buf, 0, 8010 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 8011 8012 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER | 8013 I40E_AQC_MIRROR_CLOUD_FILTER; 8014 filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IMAC; 8015 filter_replace.new_filter_type = 8016 I40E_AQC_ADD_CLOUD_FILTER_0X12; 8017 /* Prepare the buffer, 2 entries */ 8018 filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 8019 filter_replace_buf.data[0] |= 8020 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8021 filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_0X11; 8022 filter_replace_buf.data[4] |= 8023 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8024 8025 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 8026 &filter_replace_buf); 8027 if (!status && (filter_replace.old_filter_type != 8028 filter_replace.new_filter_type)) 8029 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 8030 " original: 0x%x, new: 0x%x", 8031 dev->device->name, 8032 filter_replace.old_filter_type, 8033 filter_replace.new_filter_type); 8034 8035 return status; 8036 } 8037 8038 static enum i40e_status_code 8039 i40e_replace_gtp_l1_filter(struct i40e_pf *pf) 8040 { 8041 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 8042 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 8043 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8044 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 8045 enum i40e_status_code status = I40E_SUCCESS; 8046 8047 if (pf->support_multi_driver) { 8048 PMD_DRV_LOG(ERR, "Replace l1 filter is not supported."); 8049 return I40E_NOT_SUPPORTED; 8050 } 8051 8052 /* For GTP-C */ 8053 memset(&filter_replace, 0, 8054 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 8055 memset(&filter_replace_buf, 0, 8056 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 8057 /* create L1 filter */ 8058 filter_replace.old_filter_type = 8059 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC; 8060 filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X12; 8061 filter_replace.tr_bit = I40E_AQC_NEW_TR_22 | 8062 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8063 /* Prepare the buffer, 2 entries */ 8064 filter_replace_buf.data[0] = 8065 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0; 8066 filter_replace_buf.data[0] |= 8067 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8068 filter_replace_buf.data[2] = 0xFF; 8069 filter_replace_buf.data[3] = 0xFF; 8070 filter_replace_buf.data[4] = 8071 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1; 8072 filter_replace_buf.data[4] |= 8073 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8074 filter_replace_buf.data[6] = 0xFF; 8075 filter_replace_buf.data[7] = 0xFF; 8076 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 8077 &filter_replace_buf); 8078 if (status < 0) 8079 return status; 8080 if (filter_replace.old_filter_type != 8081 filter_replace.new_filter_type) 8082 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type." 8083 " original: 0x%x, new: 0x%x", 8084 dev->device->name, 8085 filter_replace.old_filter_type, 8086 filter_replace.new_filter_type); 8087 8088 /* for GTP-U */ 8089 memset(&filter_replace, 0, 8090 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 8091 memset(&filter_replace_buf, 0, 8092 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 8093 /* create L1 filter */ 8094 filter_replace.old_filter_type = 8095 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TUNNLE_KEY; 8096 filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X13; 8097 filter_replace.tr_bit = I40E_AQC_NEW_TR_21 | 8098 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8099 /* Prepare the buffer, 2 entries */ 8100 filter_replace_buf.data[0] = 8101 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0; 8102 filter_replace_buf.data[0] |= 8103 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8104 filter_replace_buf.data[2] = 0xFF; 8105 filter_replace_buf.data[3] = 0xFF; 8106 filter_replace_buf.data[4] = 8107 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1; 8108 filter_replace_buf.data[4] |= 8109 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8110 filter_replace_buf.data[6] = 0xFF; 8111 filter_replace_buf.data[7] = 0xFF; 8112 8113 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 8114 &filter_replace_buf); 8115 if (!status && (filter_replace.old_filter_type != 8116 filter_replace.new_filter_type)) 8117 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type." 8118 " original: 0x%x, new: 0x%x", 8119 dev->device->name, 8120 filter_replace.old_filter_type, 8121 filter_replace.new_filter_type); 8122 8123 return status; 8124 } 8125 8126 static enum 8127 i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf) 8128 { 8129 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 8130 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 8131 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8132 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 8133 enum i40e_status_code status = I40E_SUCCESS; 8134 8135 if (pf->support_multi_driver) { 8136 PMD_DRV_LOG(ERR, "Replace cloud filter is not supported."); 8137 return I40E_NOT_SUPPORTED; 8138 } 8139 8140 /* for GTP-C */ 8141 memset(&filter_replace, 0, 8142 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 8143 memset(&filter_replace_buf, 0, 8144 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 8145 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER; 8146 filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN; 8147 filter_replace.new_filter_type = 8148 I40E_AQC_ADD_CLOUD_FILTER_0X11; 8149 /* Prepare the buffer, 2 entries */ 8150 filter_replace_buf.data[0] = I40E_AQC_ADD_L1_FILTER_0X12; 8151 filter_replace_buf.data[0] |= 8152 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8153 filter_replace_buf.data[4] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 8154 filter_replace_buf.data[4] |= 8155 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8156 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 8157 &filter_replace_buf); 8158 if (status < 0) 8159 return status; 8160 if (filter_replace.old_filter_type != 8161 filter_replace.new_filter_type) 8162 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 8163 " original: 0x%x, new: 0x%x", 8164 dev->device->name, 8165 filter_replace.old_filter_type, 8166 filter_replace.new_filter_type); 8167 8168 /* for GTP-U */ 8169 memset(&filter_replace, 0, 8170 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 8171 memset(&filter_replace_buf, 0, 8172 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 8173 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER; 8174 filter_replace.old_filter_type = 8175 I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID; 8176 filter_replace.new_filter_type = 8177 I40E_AQC_ADD_CLOUD_FILTER_0X12; 8178 /* Prepare the buffer, 2 entries */ 8179 filter_replace_buf.data[0] = I40E_AQC_ADD_L1_FILTER_0X13; 8180 filter_replace_buf.data[0] |= 8181 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8182 filter_replace_buf.data[4] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 8183 filter_replace_buf.data[4] |= 8184 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8185 8186 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 8187 &filter_replace_buf); 8188 if (!status && (filter_replace.old_filter_type != 8189 filter_replace.new_filter_type)) 8190 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 8191 " original: 0x%x, new: 0x%x", 8192 dev->device->name, 8193 filter_replace.old_filter_type, 8194 filter_replace.new_filter_type); 8195 8196 return status; 8197 } 8198 8199 static enum i40e_status_code 8200 i40e_replace_port_l1_filter(struct i40e_pf *pf, 8201 enum i40e_l4_port_type l4_port_type) 8202 { 8203 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 8204 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 8205 enum i40e_status_code status = I40E_SUCCESS; 8206 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8207 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 8208 8209 if (pf->support_multi_driver) { 8210 PMD_DRV_LOG(ERR, "Replace l1 filter is not supported."); 8211 return I40E_NOT_SUPPORTED; 8212 } 8213 8214 memset(&filter_replace, 0, 8215 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 8216 memset(&filter_replace_buf, 0, 8217 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 8218 8219 /* create L1 filter */ 8220 if (l4_port_type == I40E_L4_PORT_TYPE_SRC) { 8221 filter_replace.old_filter_type = 8222 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TUNNLE_KEY; 8223 filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X11; 8224 filter_replace_buf.data[8] = 8225 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_SRC_PORT; 8226 } else { 8227 filter_replace.old_filter_type = 8228 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_IVLAN; 8229 filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_0X10; 8230 filter_replace_buf.data[8] = 8231 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_DST_PORT; 8232 } 8233 8234 filter_replace.tr_bit = 0; 8235 /* Prepare the buffer, 3 entries */ 8236 filter_replace_buf.data[0] = 8237 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_DIRECTION_WORD0; 8238 filter_replace_buf.data[0] |= 8239 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8240 filter_replace_buf.data[2] = 0x00; 8241 filter_replace_buf.data[3] = 8242 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_INGRESS_WORD0; 8243 filter_replace_buf.data[4] = 8244 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_PORT_TR_WORD0; 8245 filter_replace_buf.data[4] |= 8246 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8247 filter_replace_buf.data[5] = 0x00; 8248 filter_replace_buf.data[6] = I40E_TR_L4_TYPE_UDP | 8249 I40E_TR_L4_TYPE_TCP | 8250 I40E_TR_L4_TYPE_SCTP; 8251 filter_replace_buf.data[7] = 0x00; 8252 filter_replace_buf.data[8] |= 8253 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8254 filter_replace_buf.data[9] = 0x00; 8255 filter_replace_buf.data[10] = 0xFF; 8256 filter_replace_buf.data[11] = 0xFF; 8257 8258 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 8259 &filter_replace_buf); 8260 if (!status && filter_replace.old_filter_type != 8261 filter_replace.new_filter_type) 8262 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type." 8263 " original: 0x%x, new: 0x%x", 8264 dev->device->name, 8265 filter_replace.old_filter_type, 8266 filter_replace.new_filter_type); 8267 8268 return status; 8269 } 8270 8271 static enum i40e_status_code 8272 i40e_replace_port_cloud_filter(struct i40e_pf *pf, 8273 enum i40e_l4_port_type l4_port_type) 8274 { 8275 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 8276 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 8277 enum i40e_status_code status = I40E_SUCCESS; 8278 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8279 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 8280 8281 if (pf->support_multi_driver) { 8282 PMD_DRV_LOG(ERR, "Replace cloud filter is not supported."); 8283 return I40E_NOT_SUPPORTED; 8284 } 8285 8286 memset(&filter_replace, 0, 8287 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 8288 memset(&filter_replace_buf, 0, 8289 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 8290 8291 if (l4_port_type == I40E_L4_PORT_TYPE_SRC) { 8292 filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IIP; 8293 filter_replace.new_filter_type = 8294 I40E_AQC_ADD_CLOUD_FILTER_0X11; 8295 filter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_0X11; 8296 } else { 8297 filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_OIP; 8298 filter_replace.new_filter_type = 8299 I40E_AQC_ADD_CLOUD_FILTER_0X10; 8300 filter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_0X10; 8301 } 8302 8303 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER; 8304 filter_replace.tr_bit = 0; 8305 /* Prepare the buffer, 2 entries */ 8306 filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 8307 filter_replace_buf.data[0] |= 8308 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8309 filter_replace_buf.data[4] |= 8310 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 8311 status = i40e_aq_replace_cloud_filters(hw, &filter_replace, 8312 &filter_replace_buf); 8313 8314 if (!status && filter_replace.old_filter_type != 8315 filter_replace.new_filter_type) 8316 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 8317 " original: 0x%x, new: 0x%x", 8318 dev->device->name, 8319 filter_replace.old_filter_type, 8320 filter_replace.new_filter_type); 8321 8322 return status; 8323 } 8324 8325 int 8326 i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf, 8327 struct i40e_tunnel_filter_conf *tunnel_filter, 8328 uint8_t add) 8329 { 8330 uint16_t ip_type; 8331 uint32_t ipv4_addr, ipv4_addr_le; 8332 uint8_t i, tun_type = 0; 8333 /* internal variable to convert ipv6 byte order */ 8334 uint32_t convert_ipv6[4]; 8335 int val, ret = 0; 8336 struct i40e_pf_vf *vf = NULL; 8337 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8338 struct i40e_vsi *vsi; 8339 struct i40e_aqc_cloud_filters_element_bb *cld_filter; 8340 struct i40e_aqc_cloud_filters_element_bb *pfilter; 8341 struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel; 8342 struct i40e_tunnel_filter *tunnel, *node; 8343 struct i40e_tunnel_filter check_filter; /* Check if filter exists */ 8344 uint32_t teid_le; 8345 bool big_buffer = 0; 8346 8347 cld_filter = rte_zmalloc("tunnel_filter", 8348 sizeof(struct i40e_aqc_add_rm_cloud_filt_elem_ext), 8349 0); 8350 8351 if (cld_filter == NULL) { 8352 PMD_DRV_LOG(ERR, "Failed to alloc memory."); 8353 return -ENOMEM; 8354 } 8355 pfilter = cld_filter; 8356 8357 rte_ether_addr_copy(&tunnel_filter->outer_mac, 8358 (struct rte_ether_addr *)&pfilter->element.outer_mac); 8359 rte_ether_addr_copy(&tunnel_filter->inner_mac, 8360 (struct rte_ether_addr *)&pfilter->element.inner_mac); 8361 8362 pfilter->element.inner_vlan = 8363 rte_cpu_to_le_16(tunnel_filter->inner_vlan); 8364 if (tunnel_filter->ip_type == I40E_TUNNEL_IPTYPE_IPV4) { 8365 ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV4; 8366 ipv4_addr = rte_be_to_cpu_32(tunnel_filter->ip_addr.ipv4_addr); 8367 ipv4_addr_le = rte_cpu_to_le_32(ipv4_addr); 8368 rte_memcpy(&pfilter->element.ipaddr.v4.data, 8369 &ipv4_addr_le, 8370 sizeof(pfilter->element.ipaddr.v4.data)); 8371 } else { 8372 ip_type = I40E_AQC_ADD_CLOUD_FLAGS_IPV6; 8373 for (i = 0; i < 4; i++) { 8374 convert_ipv6[i] = 8375 rte_cpu_to_le_32(rte_be_to_cpu_32( 8376 tunnel_filter->ip_addr.ipv6_addr[i])); 8377 } 8378 rte_memcpy(&pfilter->element.ipaddr.v6.data, 8379 &convert_ipv6, 8380 sizeof(pfilter->element.ipaddr.v6.data)); 8381 } 8382 8383 /* check tunneled type */ 8384 switch (tunnel_filter->tunnel_type) { 8385 case I40E_TUNNEL_TYPE_VXLAN: 8386 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_VXLAN; 8387 break; 8388 case I40E_TUNNEL_TYPE_NVGRE: 8389 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC; 8390 break; 8391 case I40E_TUNNEL_TYPE_IP_IN_GRE: 8392 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_IP; 8393 break; 8394 case I40E_TUNNEL_TYPE_MPLSoUDP: 8395 if (!pf->mpls_replace_flag) { 8396 i40e_replace_mpls_l1_filter(pf); 8397 i40e_replace_mpls_cloud_filter(pf); 8398 pf->mpls_replace_flag = 1; 8399 } 8400 teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8401 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0] = 8402 teid_le >> 4; 8403 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] = 8404 (teid_le & 0xF) << 12; 8405 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] = 8406 0x40; 8407 big_buffer = 1; 8408 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSOUDP; 8409 break; 8410 case I40E_TUNNEL_TYPE_MPLSoGRE: 8411 if (!pf->mpls_replace_flag) { 8412 i40e_replace_mpls_l1_filter(pf); 8413 i40e_replace_mpls_cloud_filter(pf); 8414 pf->mpls_replace_flag = 1; 8415 } 8416 teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8417 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0] = 8418 teid_le >> 4; 8419 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] = 8420 (teid_le & 0xF) << 12; 8421 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] = 8422 0x0; 8423 big_buffer = 1; 8424 tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSOGRE; 8425 break; 8426 case I40E_TUNNEL_TYPE_GTPC: 8427 if (!pf->gtp_replace_flag) { 8428 i40e_replace_gtp_l1_filter(pf); 8429 i40e_replace_gtp_cloud_filter(pf); 8430 pf->gtp_replace_flag = 1; 8431 } 8432 teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8433 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD0] = 8434 (teid_le >> 16) & 0xFFFF; 8435 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD1] = 8436 teid_le & 0xFFFF; 8437 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X12_WORD2] = 8438 0x0; 8439 big_buffer = 1; 8440 break; 8441 case I40E_TUNNEL_TYPE_GTPU: 8442 if (!pf->gtp_replace_flag) { 8443 i40e_replace_gtp_l1_filter(pf); 8444 i40e_replace_gtp_cloud_filter(pf); 8445 pf->gtp_replace_flag = 1; 8446 } 8447 teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8448 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD0] = 8449 (teid_le >> 16) & 0xFFFF; 8450 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD1] = 8451 teid_le & 0xFFFF; 8452 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X13_WORD2] = 8453 0x0; 8454 big_buffer = 1; 8455 break; 8456 case I40E_TUNNEL_TYPE_QINQ: 8457 if (!pf->qinq_replace_flag) { 8458 ret = i40e_cloud_filter_qinq_create(pf); 8459 if (ret < 0) 8460 PMD_DRV_LOG(DEBUG, 8461 "QinQ tunnel filter already created."); 8462 pf->qinq_replace_flag = 1; 8463 } 8464 /* Add in the General fields the values of 8465 * the Outer and Inner VLAN 8466 * Big Buffer should be set, see changes in 8467 * i40e_aq_add_cloud_filters 8468 */ 8469 pfilter->general_fields[0] = tunnel_filter->inner_vlan; 8470 pfilter->general_fields[1] = tunnel_filter->outer_vlan; 8471 big_buffer = 1; 8472 break; 8473 case I40E_CLOUD_TYPE_UDP: 8474 case I40E_CLOUD_TYPE_TCP: 8475 case I40E_CLOUD_TYPE_SCTP: 8476 if (tunnel_filter->l4_port_type == I40E_L4_PORT_TYPE_SRC) { 8477 if (!pf->sport_replace_flag) { 8478 i40e_replace_port_l1_filter(pf, 8479 tunnel_filter->l4_port_type); 8480 i40e_replace_port_cloud_filter(pf, 8481 tunnel_filter->l4_port_type); 8482 pf->sport_replace_flag = 1; 8483 } 8484 teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8485 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0] = 8486 I40E_DIRECTION_INGRESS_KEY; 8487 8488 if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_UDP) 8489 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] = 8490 I40E_TR_L4_TYPE_UDP; 8491 else if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_TCP) 8492 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] = 8493 I40E_TR_L4_TYPE_TCP; 8494 else 8495 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] = 8496 I40E_TR_L4_TYPE_SCTP; 8497 8498 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] = 8499 (teid_le >> 16) & 0xFFFF; 8500 big_buffer = 1; 8501 } else { 8502 if (!pf->dport_replace_flag) { 8503 i40e_replace_port_l1_filter(pf, 8504 tunnel_filter->l4_port_type); 8505 i40e_replace_port_cloud_filter(pf, 8506 tunnel_filter->l4_port_type); 8507 pf->dport_replace_flag = 1; 8508 } 8509 teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8510 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD0] = 8511 I40E_DIRECTION_INGRESS_KEY; 8512 8513 if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_UDP) 8514 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1] = 8515 I40E_TR_L4_TYPE_UDP; 8516 else if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_TCP) 8517 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1] = 8518 I40E_TR_L4_TYPE_TCP; 8519 else 8520 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1] = 8521 I40E_TR_L4_TYPE_SCTP; 8522 8523 pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X10_WORD2] = 8524 (teid_le >> 16) & 0xFFFF; 8525 big_buffer = 1; 8526 } 8527 8528 break; 8529 default: 8530 /* Other tunnel types is not supported. */ 8531 PMD_DRV_LOG(ERR, "tunnel type is not supported."); 8532 rte_free(cld_filter); 8533 return -EINVAL; 8534 } 8535 8536 if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_MPLSoUDP) 8537 pfilter->element.flags = 8538 I40E_AQC_ADD_CLOUD_FILTER_0X11; 8539 else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_MPLSoGRE) 8540 pfilter->element.flags = 8541 I40E_AQC_ADD_CLOUD_FILTER_0X12; 8542 else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_GTPC) 8543 pfilter->element.flags = 8544 I40E_AQC_ADD_CLOUD_FILTER_0X11; 8545 else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_GTPU) 8546 pfilter->element.flags = 8547 I40E_AQC_ADD_CLOUD_FILTER_0X12; 8548 else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_QINQ) 8549 pfilter->element.flags |= 8550 I40E_AQC_ADD_CLOUD_FILTER_0X10; 8551 else if (tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_UDP || 8552 tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_TCP || 8553 tunnel_filter->tunnel_type == I40E_CLOUD_TYPE_SCTP) { 8554 if (tunnel_filter->l4_port_type == I40E_L4_PORT_TYPE_SRC) 8555 pfilter->element.flags |= 8556 I40E_AQC_ADD_CLOUD_FILTER_0X11; 8557 else 8558 pfilter->element.flags |= 8559 I40E_AQC_ADD_CLOUD_FILTER_0X10; 8560 } else { 8561 val = i40e_dev_get_filter_type(tunnel_filter->filter_type, 8562 &pfilter->element.flags); 8563 if (val < 0) { 8564 rte_free(cld_filter); 8565 return -EINVAL; 8566 } 8567 } 8568 8569 pfilter->element.flags |= rte_cpu_to_le_16( 8570 I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE | 8571 ip_type | (tun_type << I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT)); 8572 pfilter->element.tenant_id = rte_cpu_to_le_32(tunnel_filter->tenant_id); 8573 pfilter->element.queue_number = 8574 rte_cpu_to_le_16(tunnel_filter->queue_id); 8575 8576 if (!tunnel_filter->is_to_vf) 8577 vsi = pf->main_vsi; 8578 else { 8579 if (tunnel_filter->vf_id >= pf->vf_num) { 8580 PMD_DRV_LOG(ERR, "Invalid argument."); 8581 rte_free(cld_filter); 8582 return -EINVAL; 8583 } 8584 vf = &pf->vfs[tunnel_filter->vf_id]; 8585 vsi = vf->vsi; 8586 } 8587 8588 /* Check if there is the filter in SW list */ 8589 memset(&check_filter, 0, sizeof(check_filter)); 8590 i40e_tunnel_filter_convert(cld_filter, &check_filter); 8591 check_filter.is_to_vf = tunnel_filter->is_to_vf; 8592 check_filter.vf_id = tunnel_filter->vf_id; 8593 node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &check_filter.input); 8594 if (add && node) { 8595 PMD_DRV_LOG(ERR, "Conflict with existing tunnel rules!"); 8596 rte_free(cld_filter); 8597 return -EINVAL; 8598 } 8599 8600 if (!add && !node) { 8601 PMD_DRV_LOG(ERR, "There's no corresponding tunnel filter!"); 8602 rte_free(cld_filter); 8603 return -EINVAL; 8604 } 8605 8606 if (add) { 8607 if (big_buffer) 8608 ret = i40e_aq_add_cloud_filters_bb(hw, 8609 vsi->seid, cld_filter, 1); 8610 else 8611 ret = i40e_aq_add_cloud_filters(hw, 8612 vsi->seid, &cld_filter->element, 1); 8613 if (ret < 0) { 8614 PMD_DRV_LOG(ERR, "Failed to add a tunnel filter."); 8615 rte_free(cld_filter); 8616 return -ENOTSUP; 8617 } 8618 tunnel = rte_zmalloc("tunnel_filter", sizeof(*tunnel), 0); 8619 if (tunnel == NULL) { 8620 PMD_DRV_LOG(ERR, "Failed to alloc memory."); 8621 rte_free(cld_filter); 8622 return -ENOMEM; 8623 } 8624 8625 rte_memcpy(tunnel, &check_filter, sizeof(check_filter)); 8626 ret = i40e_sw_tunnel_filter_insert(pf, tunnel); 8627 if (ret < 0) 8628 rte_free(tunnel); 8629 } else { 8630 if (big_buffer) 8631 ret = i40e_aq_rem_cloud_filters_bb( 8632 hw, vsi->seid, cld_filter, 1); 8633 else 8634 ret = i40e_aq_rem_cloud_filters(hw, vsi->seid, 8635 &cld_filter->element, 1); 8636 if (ret < 0) { 8637 PMD_DRV_LOG(ERR, "Failed to delete a tunnel filter."); 8638 rte_free(cld_filter); 8639 return -ENOTSUP; 8640 } 8641 ret = i40e_sw_tunnel_filter_del(pf, &node->input); 8642 } 8643 8644 rte_free(cld_filter); 8645 return ret; 8646 } 8647 8648 static int 8649 i40e_get_vxlan_port_idx(struct i40e_pf *pf, uint16_t port) 8650 { 8651 uint8_t i; 8652 8653 for (i = 0; i < I40E_MAX_PF_UDP_OFFLOAD_PORTS; i++) { 8654 if (pf->vxlan_ports[i] == port) 8655 return i; 8656 } 8657 8658 return -1; 8659 } 8660 8661 static int 8662 i40e_add_vxlan_port(struct i40e_pf *pf, uint16_t port, int udp_type) 8663 { 8664 int idx, ret; 8665 uint8_t filter_idx = 0; 8666 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8667 8668 idx = i40e_get_vxlan_port_idx(pf, port); 8669 8670 /* Check if port already exists */ 8671 if (idx >= 0) { 8672 PMD_DRV_LOG(ERR, "Port %d already offloaded", port); 8673 return -EINVAL; 8674 } 8675 8676 /* Now check if there is space to add the new port */ 8677 idx = i40e_get_vxlan_port_idx(pf, 0); 8678 if (idx < 0) { 8679 PMD_DRV_LOG(ERR, 8680 "Maximum number of UDP ports reached, not adding port %d", 8681 port); 8682 return -ENOSPC; 8683 } 8684 8685 ret = i40e_aq_add_udp_tunnel(hw, port, udp_type, 8686 &filter_idx, NULL); 8687 if (ret < 0) { 8688 PMD_DRV_LOG(ERR, "Failed to add VXLAN UDP port %d", port); 8689 return -1; 8690 } 8691 8692 PMD_DRV_LOG(INFO, "Added port %d with AQ command with index %d", 8693 port, filter_idx); 8694 8695 /* New port: add it and mark its index in the bitmap */ 8696 pf->vxlan_ports[idx] = port; 8697 pf->vxlan_bitmap |= (1 << idx); 8698 8699 if (!(pf->flags & I40E_FLAG_VXLAN)) 8700 pf->flags |= I40E_FLAG_VXLAN; 8701 8702 return 0; 8703 } 8704 8705 static int 8706 i40e_del_vxlan_port(struct i40e_pf *pf, uint16_t port) 8707 { 8708 int idx; 8709 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8710 8711 if (!(pf->flags & I40E_FLAG_VXLAN)) { 8712 PMD_DRV_LOG(ERR, "VXLAN UDP port was not configured."); 8713 return -EINVAL; 8714 } 8715 8716 idx = i40e_get_vxlan_port_idx(pf, port); 8717 8718 if (idx < 0) { 8719 PMD_DRV_LOG(ERR, "Port %d doesn't exist", port); 8720 return -EINVAL; 8721 } 8722 8723 if (i40e_aq_del_udp_tunnel(hw, idx, NULL) < 0) { 8724 PMD_DRV_LOG(ERR, "Failed to delete VXLAN UDP port %d", port); 8725 return -1; 8726 } 8727 8728 PMD_DRV_LOG(INFO, "Deleted port %d with AQ command with index %d", 8729 port, idx); 8730 8731 pf->vxlan_ports[idx] = 0; 8732 pf->vxlan_bitmap &= ~(1 << idx); 8733 8734 if (!pf->vxlan_bitmap) 8735 pf->flags &= ~I40E_FLAG_VXLAN; 8736 8737 return 0; 8738 } 8739 8740 /* Add UDP tunneling port */ 8741 static int 8742 i40e_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, 8743 struct rte_eth_udp_tunnel *udp_tunnel) 8744 { 8745 int ret = 0; 8746 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 8747 8748 if (udp_tunnel == NULL) 8749 return -EINVAL; 8750 8751 switch (udp_tunnel->prot_type) { 8752 case RTE_TUNNEL_TYPE_VXLAN: 8753 ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port, 8754 I40E_AQC_TUNNEL_TYPE_VXLAN); 8755 break; 8756 case RTE_TUNNEL_TYPE_VXLAN_GPE: 8757 ret = i40e_add_vxlan_port(pf, udp_tunnel->udp_port, 8758 I40E_AQC_TUNNEL_TYPE_VXLAN_GPE); 8759 break; 8760 case RTE_TUNNEL_TYPE_GENEVE: 8761 case RTE_TUNNEL_TYPE_TEREDO: 8762 PMD_DRV_LOG(ERR, "Tunnel type is not supported now."); 8763 ret = -1; 8764 break; 8765 8766 default: 8767 PMD_DRV_LOG(ERR, "Invalid tunnel type"); 8768 ret = -1; 8769 break; 8770 } 8771 8772 return ret; 8773 } 8774 8775 /* Remove UDP tunneling port */ 8776 static int 8777 i40e_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, 8778 struct rte_eth_udp_tunnel *udp_tunnel) 8779 { 8780 int ret = 0; 8781 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 8782 8783 if (udp_tunnel == NULL) 8784 return -EINVAL; 8785 8786 switch (udp_tunnel->prot_type) { 8787 case RTE_TUNNEL_TYPE_VXLAN: 8788 case RTE_TUNNEL_TYPE_VXLAN_GPE: 8789 ret = i40e_del_vxlan_port(pf, udp_tunnel->udp_port); 8790 break; 8791 case RTE_TUNNEL_TYPE_GENEVE: 8792 case RTE_TUNNEL_TYPE_TEREDO: 8793 PMD_DRV_LOG(ERR, "Tunnel type is not supported now."); 8794 ret = -1; 8795 break; 8796 default: 8797 PMD_DRV_LOG(ERR, "Invalid tunnel type"); 8798 ret = -1; 8799 break; 8800 } 8801 8802 return ret; 8803 } 8804 8805 /* Calculate the maximum number of contiguous PF queues that are configured */ 8806 static int 8807 i40e_pf_calc_configured_queues_num(struct i40e_pf *pf) 8808 { 8809 struct rte_eth_dev_data *data = pf->dev_data; 8810 int i, num; 8811 struct i40e_rx_queue *rxq; 8812 8813 num = 0; 8814 for (i = 0; i < pf->lan_nb_qps; i++) { 8815 rxq = data->rx_queues[i]; 8816 if (rxq && rxq->q_set) 8817 num++; 8818 else 8819 break; 8820 } 8821 8822 return num; 8823 } 8824 8825 /* Configure RSS */ 8826 static int 8827 i40e_pf_config_rss(struct i40e_pf *pf) 8828 { 8829 enum rte_eth_rx_mq_mode mq_mode = pf->dev_data->dev_conf.rxmode.mq_mode; 8830 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 8831 struct rte_eth_rss_conf rss_conf; 8832 uint32_t i, lut = 0; 8833 uint16_t j, num; 8834 8835 /* 8836 * If both VMDQ and RSS enabled, not all of PF queues are configured. 8837 * It's necessary to calculate the actual PF queues that are configured. 8838 */ 8839 if (pf->dev_data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_VMDQ_FLAG) 8840 num = i40e_pf_calc_configured_queues_num(pf); 8841 else 8842 num = pf->dev_data->nb_rx_queues; 8843 8844 num = RTE_MIN(num, I40E_MAX_Q_PER_TC); 8845 PMD_INIT_LOG(INFO, "Max of contiguous %u PF queues are configured", 8846 num); 8847 8848 if (num == 0) { 8849 PMD_INIT_LOG(ERR, 8850 "No PF queues are configured to enable RSS for port %u", 8851 pf->dev_data->port_id); 8852 return -ENOTSUP; 8853 } 8854 8855 if (pf->adapter->rss_reta_updated == 0) { 8856 for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) { 8857 if (j == num) 8858 j = 0; 8859 lut = (lut << 8) | (j & ((0x1 << 8860 hw->func_caps.rss_table_entry_width) - 1)); 8861 if ((i & 3) == 3) 8862 I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), 8863 rte_bswap32(lut)); 8864 } 8865 } 8866 8867 rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf; 8868 if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0 || 8869 !(mq_mode & ETH_MQ_RX_RSS_FLAG)) { 8870 i40e_pf_disable_rss(pf); 8871 return 0; 8872 } 8873 if (rss_conf.rss_key == NULL || rss_conf.rss_key_len < 8874 (I40E_PFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t)) { 8875 /* Random default keys */ 8876 static uint32_t rss_key_default[] = {0x6b793944, 8877 0x23504cb5, 0x5bea75b6, 0x309f4f12, 0x3dc0a2b8, 8878 0x024ddcdf, 0x339b8ca0, 0x4c4af64a, 0x34fac605, 8879 0x55d85839, 0x3a58997d, 0x2ec938e1, 0x66031581}; 8880 8881 rss_conf.rss_key = (uint8_t *)rss_key_default; 8882 rss_conf.rss_key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) * 8883 sizeof(uint32_t); 8884 } 8885 8886 return i40e_hw_rss_hash_set(pf, &rss_conf); 8887 } 8888 8889 #define I40E_GL_PRS_FVBM_MSK_ENA 0x80000000 8890 #define I40E_GL_PRS_FVBM(_i) (0x00269760 + ((_i) * 4)) 8891 int 8892 i40e_dev_set_gre_key_len(struct i40e_hw *hw, uint8_t len) 8893 { 8894 struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf; 8895 uint32_t val, reg; 8896 int ret = -EINVAL; 8897 8898 if (pf->support_multi_driver) { 8899 PMD_DRV_LOG(ERR, "GRE key length configuration is unsupported"); 8900 return -ENOTSUP; 8901 } 8902 8903 val = I40E_READ_REG(hw, I40E_GL_PRS_FVBM(2)); 8904 PMD_DRV_LOG(DEBUG, "Read original GL_PRS_FVBM with 0x%08x", val); 8905 8906 if (len == 3) { 8907 reg = val | I40E_GL_PRS_FVBM_MSK_ENA; 8908 } else if (len == 4) { 8909 reg = val & ~I40E_GL_PRS_FVBM_MSK_ENA; 8910 } else { 8911 PMD_DRV_LOG(ERR, "Unsupported GRE key length of %u", len); 8912 return ret; 8913 } 8914 8915 if (reg != val) { 8916 ret = i40e_aq_debug_write_global_register(hw, 8917 I40E_GL_PRS_FVBM(2), 8918 reg, NULL); 8919 if (ret != 0) 8920 return ret; 8921 PMD_DRV_LOG(DEBUG, "Global register 0x%08x is changed " 8922 "with value 0x%08x", 8923 I40E_GL_PRS_FVBM(2), reg); 8924 } else { 8925 ret = 0; 8926 } 8927 PMD_DRV_LOG(DEBUG, "Read modified GL_PRS_FVBM with 0x%08x", 8928 I40E_READ_REG(hw, I40E_GL_PRS_FVBM(2))); 8929 8930 return ret; 8931 } 8932 8933 /* Set the symmetric hash enable configurations per port */ 8934 static void 8935 i40e_set_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t enable) 8936 { 8937 uint32_t reg = i40e_read_rx_ctl(hw, I40E_PRTQF_CTL_0); 8938 8939 if (enable > 0) { 8940 if (reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK) { 8941 PMD_DRV_LOG(INFO, 8942 "Symmetric hash has already been enabled"); 8943 return; 8944 } 8945 reg |= I40E_PRTQF_CTL_0_HSYM_ENA_MASK; 8946 } else { 8947 if (!(reg & I40E_PRTQF_CTL_0_HSYM_ENA_MASK)) { 8948 PMD_DRV_LOG(INFO, 8949 "Symmetric hash has already been disabled"); 8950 return; 8951 } 8952 reg &= ~I40E_PRTQF_CTL_0_HSYM_ENA_MASK; 8953 } 8954 i40e_write_rx_ctl(hw, I40E_PRTQF_CTL_0, reg); 8955 I40E_WRITE_FLUSH(hw); 8956 } 8957 8958 /** 8959 * Valid input sets for hash and flow director filters per PCTYPE 8960 */ 8961 static uint64_t 8962 i40e_get_valid_input_set(enum i40e_filter_pctype pctype, 8963 enum rte_filter_type filter) 8964 { 8965 uint64_t valid; 8966 8967 static const uint64_t valid_hash_inset_table[] = { 8968 [I40E_FILTER_PCTYPE_FRAG_IPV4] = 8969 I40E_INSET_DMAC | I40E_INSET_SMAC | 8970 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 8971 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_SRC | 8972 I40E_INSET_IPV4_DST | I40E_INSET_IPV4_TOS | 8973 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 8974 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 8975 I40E_INSET_FLEX_PAYLOAD, 8976 [I40E_FILTER_PCTYPE_NONF_IPV4_UDP] = 8977 I40E_INSET_DMAC | I40E_INSET_SMAC | 8978 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 8979 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 8980 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 8981 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 8982 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 8983 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 8984 I40E_INSET_FLEX_PAYLOAD, 8985 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] = 8986 I40E_INSET_DMAC | I40E_INSET_SMAC | 8987 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 8988 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 8989 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 8990 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 8991 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 8992 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 8993 I40E_INSET_FLEX_PAYLOAD, 8994 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] = 8995 I40E_INSET_DMAC | I40E_INSET_SMAC | 8996 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 8997 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 8998 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 8999 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 9000 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9001 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9002 I40E_INSET_FLEX_PAYLOAD, 9003 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP] = 9004 I40E_INSET_DMAC | I40E_INSET_SMAC | 9005 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9006 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 9007 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 9008 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 9009 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9010 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9011 I40E_INSET_TCP_FLAGS | I40E_INSET_FLEX_PAYLOAD, 9012 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] = 9013 I40E_INSET_DMAC | I40E_INSET_SMAC | 9014 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9015 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 9016 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 9017 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 9018 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9019 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9020 I40E_INSET_TCP_FLAGS | I40E_INSET_FLEX_PAYLOAD, 9021 [I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] = 9022 I40E_INSET_DMAC | I40E_INSET_SMAC | 9023 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9024 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 9025 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 9026 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 9027 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9028 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9029 I40E_INSET_SCTP_VT | I40E_INSET_FLEX_PAYLOAD, 9030 [I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] = 9031 I40E_INSET_DMAC | I40E_INSET_SMAC | 9032 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9033 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV4_TOS | 9034 I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL | 9035 I40E_INSET_TUNNEL_DMAC | I40E_INSET_TUNNEL_ID | 9036 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9037 I40E_INSET_FLEX_PAYLOAD, 9038 [I40E_FILTER_PCTYPE_FRAG_IPV6] = 9039 I40E_INSET_DMAC | I40E_INSET_SMAC | 9040 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9041 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9042 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9043 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_TUNNEL_DMAC | 9044 I40E_INSET_TUNNEL_ID | I40E_INSET_IPV6_SRC | 9045 I40E_INSET_IPV6_DST | I40E_INSET_FLEX_PAYLOAD, 9046 [I40E_FILTER_PCTYPE_NONF_IPV6_UDP] = 9047 I40E_INSET_DMAC | I40E_INSET_SMAC | 9048 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9049 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9050 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9051 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9052 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9053 I40E_INSET_DST_PORT | I40E_INSET_FLEX_PAYLOAD, 9054 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] = 9055 I40E_INSET_DMAC | I40E_INSET_SMAC | 9056 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9057 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9058 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9059 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9060 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9061 I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS | 9062 I40E_INSET_FLEX_PAYLOAD, 9063 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] = 9064 I40E_INSET_DMAC | I40E_INSET_SMAC | 9065 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9066 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9067 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9068 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9069 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9070 I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS | 9071 I40E_INSET_FLEX_PAYLOAD, 9072 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP] = 9073 I40E_INSET_DMAC | I40E_INSET_SMAC | 9074 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9075 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9076 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9077 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9078 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9079 I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS | 9080 I40E_INSET_FLEX_PAYLOAD, 9081 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] = 9082 I40E_INSET_DMAC | I40E_INSET_SMAC | 9083 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9084 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9085 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9086 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9087 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9088 I40E_INSET_DST_PORT | I40E_INSET_TCP_FLAGS | 9089 I40E_INSET_FLEX_PAYLOAD, 9090 [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] = 9091 I40E_INSET_DMAC | I40E_INSET_SMAC | 9092 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9093 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9094 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9095 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9096 I40E_INSET_IPV6_DST | I40E_INSET_SRC_PORT | 9097 I40E_INSET_DST_PORT | I40E_INSET_SCTP_VT | 9098 I40E_INSET_FLEX_PAYLOAD, 9099 [I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] = 9100 I40E_INSET_DMAC | I40E_INSET_SMAC | 9101 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9102 I40E_INSET_VLAN_TUNNEL | I40E_INSET_IPV6_TC | 9103 I40E_INSET_IPV6_FLOW | I40E_INSET_IPV6_NEXT_HDR | 9104 I40E_INSET_IPV6_HOP_LIMIT | I40E_INSET_IPV6_SRC | 9105 I40E_INSET_IPV6_DST | I40E_INSET_TUNNEL_ID | 9106 I40E_INSET_FLEX_PAYLOAD, 9107 [I40E_FILTER_PCTYPE_L2_PAYLOAD] = 9108 I40E_INSET_DMAC | I40E_INSET_SMAC | 9109 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9110 I40E_INSET_VLAN_TUNNEL | I40E_INSET_LAST_ETHER_TYPE | 9111 I40E_INSET_FLEX_PAYLOAD, 9112 }; 9113 9114 /** 9115 * Flow director supports only fields defined in 9116 * union rte_eth_fdir_flow. 9117 */ 9118 static const uint64_t valid_fdir_inset_table[] = { 9119 [I40E_FILTER_PCTYPE_FRAG_IPV4] = 9120 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9121 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9122 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | 9123 I40E_INSET_IPV4_TTL, 9124 [I40E_FILTER_PCTYPE_NONF_IPV4_UDP] = 9125 I40E_INSET_DMAC | I40E_INSET_SMAC | 9126 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9127 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9128 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9129 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9130 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] = 9131 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9132 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9133 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9134 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9135 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] = 9136 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9137 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9138 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9139 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9140 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP] = 9141 I40E_INSET_DMAC | I40E_INSET_SMAC | 9142 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9143 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9144 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9145 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9146 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] = 9147 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9148 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9149 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9150 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9151 [I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] = 9152 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9153 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9154 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL | 9155 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9156 I40E_INSET_SCTP_VT, 9157 [I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] = 9158 I40E_INSET_DMAC | I40E_INSET_SMAC | 9159 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9160 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9161 I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO | 9162 I40E_INSET_IPV4_TTL, 9163 [I40E_FILTER_PCTYPE_FRAG_IPV6] = 9164 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9165 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9166 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR | 9167 I40E_INSET_IPV6_HOP_LIMIT, 9168 [I40E_FILTER_PCTYPE_NONF_IPV6_UDP] = 9169 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9170 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9171 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9172 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9173 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] = 9174 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9175 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9176 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9177 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9178 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] = 9179 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9180 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9181 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9182 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9183 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP] = 9184 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9185 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9186 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9187 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9188 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] = 9189 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9190 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9191 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9192 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9193 [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] = 9194 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9195 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9196 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT | 9197 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9198 I40E_INSET_SCTP_VT, 9199 [I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] = 9200 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9201 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9202 I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR | 9203 I40E_INSET_IPV6_HOP_LIMIT, 9204 [I40E_FILTER_PCTYPE_L2_PAYLOAD] = 9205 I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER | 9206 I40E_INSET_LAST_ETHER_TYPE, 9207 }; 9208 9209 if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) 9210 return 0; 9211 if (filter == RTE_ETH_FILTER_HASH) 9212 valid = valid_hash_inset_table[pctype]; 9213 else 9214 valid = valid_fdir_inset_table[pctype]; 9215 9216 return valid; 9217 } 9218 9219 /** 9220 * Validate if the input set is allowed for a specific PCTYPE 9221 */ 9222 int 9223 i40e_validate_input_set(enum i40e_filter_pctype pctype, 9224 enum rte_filter_type filter, uint64_t inset) 9225 { 9226 uint64_t valid; 9227 9228 valid = i40e_get_valid_input_set(pctype, filter); 9229 if (inset & (~valid)) 9230 return -EINVAL; 9231 9232 return 0; 9233 } 9234 9235 /* default input set fields combination per pctype */ 9236 uint64_t 9237 i40e_get_default_input_set(uint16_t pctype) 9238 { 9239 static const uint64_t default_inset_table[] = { 9240 [I40E_FILTER_PCTYPE_FRAG_IPV4] = 9241 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST, 9242 [I40E_FILTER_PCTYPE_NONF_IPV4_UDP] = 9243 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9244 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9245 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP] = 9246 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9247 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9248 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP] = 9249 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9250 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9251 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP] = 9252 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9253 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9254 [I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK] = 9255 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9256 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9257 [I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] = 9258 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST | 9259 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9260 I40E_INSET_SCTP_VT, 9261 [I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] = 9262 I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST, 9263 [I40E_FILTER_PCTYPE_FRAG_IPV6] = 9264 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST, 9265 [I40E_FILTER_PCTYPE_NONF_IPV6_UDP] = 9266 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9267 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9268 [I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP] = 9269 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9270 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9271 [I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP] = 9272 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9273 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9274 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP] = 9275 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9276 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9277 [I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK] = 9278 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9279 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT, 9280 [I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] = 9281 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST | 9282 I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT | 9283 I40E_INSET_SCTP_VT, 9284 [I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] = 9285 I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST, 9286 [I40E_FILTER_PCTYPE_L2_PAYLOAD] = 9287 I40E_INSET_LAST_ETHER_TYPE, 9288 }; 9289 9290 if (pctype > I40E_FILTER_PCTYPE_L2_PAYLOAD) 9291 return 0; 9292 9293 return default_inset_table[pctype]; 9294 } 9295 9296 /** 9297 * Parse the input set from index to logical bit masks 9298 */ 9299 static int 9300 i40e_parse_input_set(uint64_t *inset, 9301 enum i40e_filter_pctype pctype, 9302 enum rte_eth_input_set_field *field, 9303 uint16_t size) 9304 { 9305 uint16_t i, j; 9306 int ret = -EINVAL; 9307 9308 static const struct { 9309 enum rte_eth_input_set_field field; 9310 uint64_t inset; 9311 } inset_convert_table[] = { 9312 {RTE_ETH_INPUT_SET_NONE, I40E_INSET_NONE}, 9313 {RTE_ETH_INPUT_SET_L2_SRC_MAC, I40E_INSET_SMAC}, 9314 {RTE_ETH_INPUT_SET_L2_DST_MAC, I40E_INSET_DMAC}, 9315 {RTE_ETH_INPUT_SET_L2_OUTER_VLAN, I40E_INSET_VLAN_OUTER}, 9316 {RTE_ETH_INPUT_SET_L2_INNER_VLAN, I40E_INSET_VLAN_INNER}, 9317 {RTE_ETH_INPUT_SET_L2_ETHERTYPE, I40E_INSET_LAST_ETHER_TYPE}, 9318 {RTE_ETH_INPUT_SET_L3_SRC_IP4, I40E_INSET_IPV4_SRC}, 9319 {RTE_ETH_INPUT_SET_L3_DST_IP4, I40E_INSET_IPV4_DST}, 9320 {RTE_ETH_INPUT_SET_L3_IP4_TOS, I40E_INSET_IPV4_TOS}, 9321 {RTE_ETH_INPUT_SET_L3_IP4_PROTO, I40E_INSET_IPV4_PROTO}, 9322 {RTE_ETH_INPUT_SET_L3_IP4_TTL, I40E_INSET_IPV4_TTL}, 9323 {RTE_ETH_INPUT_SET_L3_SRC_IP6, I40E_INSET_IPV6_SRC}, 9324 {RTE_ETH_INPUT_SET_L3_DST_IP6, I40E_INSET_IPV6_DST}, 9325 {RTE_ETH_INPUT_SET_L3_IP6_TC, I40E_INSET_IPV6_TC}, 9326 {RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER, 9327 I40E_INSET_IPV6_NEXT_HDR}, 9328 {RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS, 9329 I40E_INSET_IPV6_HOP_LIMIT}, 9330 {RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT, I40E_INSET_SRC_PORT}, 9331 {RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT, I40E_INSET_SRC_PORT}, 9332 {RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT, I40E_INSET_SRC_PORT}, 9333 {RTE_ETH_INPUT_SET_L4_UDP_DST_PORT, I40E_INSET_DST_PORT}, 9334 {RTE_ETH_INPUT_SET_L4_TCP_DST_PORT, I40E_INSET_DST_PORT}, 9335 {RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT, I40E_INSET_DST_PORT}, 9336 {RTE_ETH_INPUT_SET_L4_SCTP_VERIFICATION_TAG, 9337 I40E_INSET_SCTP_VT}, 9338 {RTE_ETH_INPUT_SET_TUNNEL_L2_INNER_DST_MAC, 9339 I40E_INSET_TUNNEL_DMAC}, 9340 {RTE_ETH_INPUT_SET_TUNNEL_L2_INNER_VLAN, 9341 I40E_INSET_VLAN_TUNNEL}, 9342 {RTE_ETH_INPUT_SET_TUNNEL_L4_UDP_KEY, 9343 I40E_INSET_TUNNEL_ID}, 9344 {RTE_ETH_INPUT_SET_TUNNEL_GRE_KEY, I40E_INSET_TUNNEL_ID}, 9345 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_1ST_WORD, 9346 I40E_INSET_FLEX_PAYLOAD_W1}, 9347 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_2ND_WORD, 9348 I40E_INSET_FLEX_PAYLOAD_W2}, 9349 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_3RD_WORD, 9350 I40E_INSET_FLEX_PAYLOAD_W3}, 9351 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_4TH_WORD, 9352 I40E_INSET_FLEX_PAYLOAD_W4}, 9353 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_5TH_WORD, 9354 I40E_INSET_FLEX_PAYLOAD_W5}, 9355 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_6TH_WORD, 9356 I40E_INSET_FLEX_PAYLOAD_W6}, 9357 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_7TH_WORD, 9358 I40E_INSET_FLEX_PAYLOAD_W7}, 9359 {RTE_ETH_INPUT_SET_FLEX_PAYLOAD_8TH_WORD, 9360 I40E_INSET_FLEX_PAYLOAD_W8}, 9361 }; 9362 9363 if (!inset || !field || size > RTE_ETH_INSET_SIZE_MAX) 9364 return ret; 9365 9366 /* Only one item allowed for default or all */ 9367 if (size == 1) { 9368 if (field[0] == RTE_ETH_INPUT_SET_DEFAULT) { 9369 *inset = i40e_get_default_input_set(pctype); 9370 return 0; 9371 } else if (field[0] == RTE_ETH_INPUT_SET_NONE) { 9372 *inset = I40E_INSET_NONE; 9373 return 0; 9374 } 9375 } 9376 9377 for (i = 0, *inset = 0; i < size; i++) { 9378 for (j = 0; j < RTE_DIM(inset_convert_table); j++) { 9379 if (field[i] == inset_convert_table[j].field) { 9380 *inset |= inset_convert_table[j].inset; 9381 break; 9382 } 9383 } 9384 9385 /* It contains unsupported input set, return immediately */ 9386 if (j == RTE_DIM(inset_convert_table)) 9387 return ret; 9388 } 9389 9390 return 0; 9391 } 9392 9393 /** 9394 * Translate the input set from bit masks to register aware bit masks 9395 * and vice versa 9396 */ 9397 uint64_t 9398 i40e_translate_input_set_reg(enum i40e_mac_type type, uint64_t input) 9399 { 9400 uint64_t val = 0; 9401 uint16_t i; 9402 9403 struct inset_map { 9404 uint64_t inset; 9405 uint64_t inset_reg; 9406 }; 9407 9408 static const struct inset_map inset_map_common[] = { 9409 {I40E_INSET_DMAC, I40E_REG_INSET_L2_DMAC}, 9410 {I40E_INSET_SMAC, I40E_REG_INSET_L2_SMAC}, 9411 {I40E_INSET_VLAN_OUTER, I40E_REG_INSET_L2_OUTER_VLAN}, 9412 {I40E_INSET_VLAN_INNER, I40E_REG_INSET_L2_INNER_VLAN}, 9413 {I40E_INSET_LAST_ETHER_TYPE, I40E_REG_INSET_LAST_ETHER_TYPE}, 9414 {I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS}, 9415 {I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6}, 9416 {I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6}, 9417 {I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC}, 9418 {I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR}, 9419 {I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT}, 9420 {I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT}, 9421 {I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT}, 9422 {I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG}, 9423 {I40E_INSET_TUNNEL_ID, I40E_REG_INSET_TUNNEL_ID}, 9424 {I40E_INSET_TUNNEL_DMAC, 9425 I40E_REG_INSET_TUNNEL_L2_INNER_DST_MAC}, 9426 {I40E_INSET_TUNNEL_IPV4_DST, I40E_REG_INSET_TUNNEL_L3_DST_IP4}, 9427 {I40E_INSET_TUNNEL_IPV6_DST, I40E_REG_INSET_TUNNEL_L3_DST_IP6}, 9428 {I40E_INSET_TUNNEL_SRC_PORT, 9429 I40E_REG_INSET_TUNNEL_L4_UDP_SRC_PORT}, 9430 {I40E_INSET_TUNNEL_DST_PORT, 9431 I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT}, 9432 {I40E_INSET_VLAN_TUNNEL, I40E_REG_INSET_TUNNEL_VLAN}, 9433 {I40E_INSET_FLEX_PAYLOAD_W1, I40E_REG_INSET_FLEX_PAYLOAD_WORD1}, 9434 {I40E_INSET_FLEX_PAYLOAD_W2, I40E_REG_INSET_FLEX_PAYLOAD_WORD2}, 9435 {I40E_INSET_FLEX_PAYLOAD_W3, I40E_REG_INSET_FLEX_PAYLOAD_WORD3}, 9436 {I40E_INSET_FLEX_PAYLOAD_W4, I40E_REG_INSET_FLEX_PAYLOAD_WORD4}, 9437 {I40E_INSET_FLEX_PAYLOAD_W5, I40E_REG_INSET_FLEX_PAYLOAD_WORD5}, 9438 {I40E_INSET_FLEX_PAYLOAD_W6, I40E_REG_INSET_FLEX_PAYLOAD_WORD6}, 9439 {I40E_INSET_FLEX_PAYLOAD_W7, I40E_REG_INSET_FLEX_PAYLOAD_WORD7}, 9440 {I40E_INSET_FLEX_PAYLOAD_W8, I40E_REG_INSET_FLEX_PAYLOAD_WORD8}, 9441 }; 9442 9443 /* some different registers map in x722*/ 9444 static const struct inset_map inset_map_diff_x722[] = { 9445 {I40E_INSET_IPV4_SRC, I40E_X722_REG_INSET_L3_SRC_IP4}, 9446 {I40E_INSET_IPV4_DST, I40E_X722_REG_INSET_L3_DST_IP4}, 9447 {I40E_INSET_IPV4_PROTO, I40E_X722_REG_INSET_L3_IP4_PROTO}, 9448 {I40E_INSET_IPV4_TTL, I40E_X722_REG_INSET_L3_IP4_TTL}, 9449 }; 9450 9451 static const struct inset_map inset_map_diff_not_x722[] = { 9452 {I40E_INSET_IPV4_SRC, I40E_REG_INSET_L3_SRC_IP4}, 9453 {I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4}, 9454 {I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO}, 9455 {I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL}, 9456 }; 9457 9458 if (input == 0) 9459 return val; 9460 9461 /* Translate input set to register aware inset */ 9462 if (type == I40E_MAC_X722) { 9463 for (i = 0; i < RTE_DIM(inset_map_diff_x722); i++) { 9464 if (input & inset_map_diff_x722[i].inset) 9465 val |= inset_map_diff_x722[i].inset_reg; 9466 } 9467 } else { 9468 for (i = 0; i < RTE_DIM(inset_map_diff_not_x722); i++) { 9469 if (input & inset_map_diff_not_x722[i].inset) 9470 val |= inset_map_diff_not_x722[i].inset_reg; 9471 } 9472 } 9473 9474 for (i = 0; i < RTE_DIM(inset_map_common); i++) { 9475 if (input & inset_map_common[i].inset) 9476 val |= inset_map_common[i].inset_reg; 9477 } 9478 9479 return val; 9480 } 9481 9482 int 9483 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem) 9484 { 9485 uint8_t i, idx = 0; 9486 uint64_t inset_need_mask = inset; 9487 9488 static const struct { 9489 uint64_t inset; 9490 uint32_t mask; 9491 } inset_mask_map[] = { 9492 {I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK}, 9493 {I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0}, 9494 {I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK}, 9495 {I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK}, 9496 {I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK}, 9497 {I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0}, 9498 {I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK}, 9499 {I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK}, 9500 }; 9501 9502 if (!inset || !mask || !nb_elem) 9503 return 0; 9504 9505 for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) { 9506 /* Clear the inset bit, if no MASK is required, 9507 * for example proto + ttl 9508 */ 9509 if ((inset & inset_mask_map[i].inset) == 9510 inset_mask_map[i].inset && inset_mask_map[i].mask == 0) 9511 inset_need_mask &= ~inset_mask_map[i].inset; 9512 if (!inset_need_mask) 9513 return 0; 9514 } 9515 for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) { 9516 if ((inset_need_mask & inset_mask_map[i].inset) == 9517 inset_mask_map[i].inset) { 9518 if (idx >= nb_elem) { 9519 PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks"); 9520 return -EINVAL; 9521 } 9522 mask[idx] = inset_mask_map[i].mask; 9523 idx++; 9524 } 9525 } 9526 9527 return idx; 9528 } 9529 9530 void 9531 i40e_check_write_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val) 9532 { 9533 uint32_t reg = i40e_read_rx_ctl(hw, addr); 9534 9535 PMD_DRV_LOG(DEBUG, "[0x%08x] original: 0x%08x", addr, reg); 9536 if (reg != val) 9537 i40e_write_rx_ctl(hw, addr, val); 9538 PMD_DRV_LOG(DEBUG, "[0x%08x] after: 0x%08x", addr, 9539 (uint32_t)i40e_read_rx_ctl(hw, addr)); 9540 } 9541 9542 void 9543 i40e_check_write_global_reg(struct i40e_hw *hw, uint32_t addr, uint32_t val) 9544 { 9545 uint32_t reg = i40e_read_rx_ctl(hw, addr); 9546 struct rte_eth_dev *dev; 9547 9548 dev = ((struct i40e_adapter *)hw->back)->eth_dev; 9549 if (reg != val) { 9550 i40e_write_rx_ctl(hw, addr, val); 9551 PMD_DRV_LOG(WARNING, 9552 "i40e device %s changed global register [0x%08x]." 9553 " original: 0x%08x, new: 0x%08x", 9554 dev->device->name, addr, reg, 9555 (uint32_t)i40e_read_rx_ctl(hw, addr)); 9556 } 9557 } 9558 9559 static void 9560 i40e_filter_input_set_init(struct i40e_pf *pf) 9561 { 9562 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 9563 enum i40e_filter_pctype pctype; 9564 uint64_t input_set, inset_reg; 9565 uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0}; 9566 int num, i; 9567 uint16_t flow_type; 9568 9569 for (pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP; 9570 pctype <= I40E_FILTER_PCTYPE_L2_PAYLOAD; pctype++) { 9571 flow_type = i40e_pctype_to_flowtype(pf->adapter, pctype); 9572 9573 if (flow_type == RTE_ETH_FLOW_UNKNOWN) 9574 continue; 9575 9576 input_set = i40e_get_default_input_set(pctype); 9577 9578 num = i40e_generate_inset_mask_reg(input_set, mask_reg, 9579 I40E_INSET_MASK_NUM_REG); 9580 if (num < 0) 9581 return; 9582 if (pf->support_multi_driver && num > 0) { 9583 PMD_DRV_LOG(ERR, "Input set setting is not supported."); 9584 return; 9585 } 9586 inset_reg = i40e_translate_input_set_reg(hw->mac.type, 9587 input_set); 9588 9589 i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0), 9590 (uint32_t)(inset_reg & UINT32_MAX)); 9591 i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1), 9592 (uint32_t)((inset_reg >> 9593 I40E_32_BIT_WIDTH) & UINT32_MAX)); 9594 if (!pf->support_multi_driver) { 9595 i40e_check_write_global_reg(hw, 9596 I40E_GLQF_HASH_INSET(0, pctype), 9597 (uint32_t)(inset_reg & UINT32_MAX)); 9598 i40e_check_write_global_reg(hw, 9599 I40E_GLQF_HASH_INSET(1, pctype), 9600 (uint32_t)((inset_reg >> 9601 I40E_32_BIT_WIDTH) & UINT32_MAX)); 9602 9603 for (i = 0; i < num; i++) { 9604 i40e_check_write_global_reg(hw, 9605 I40E_GLQF_FD_MSK(i, pctype), 9606 mask_reg[i]); 9607 i40e_check_write_global_reg(hw, 9608 I40E_GLQF_HASH_MSK(i, pctype), 9609 mask_reg[i]); 9610 } 9611 /*clear unused mask registers of the pctype */ 9612 for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) { 9613 i40e_check_write_global_reg(hw, 9614 I40E_GLQF_FD_MSK(i, pctype), 9615 0); 9616 i40e_check_write_global_reg(hw, 9617 I40E_GLQF_HASH_MSK(i, pctype), 9618 0); 9619 } 9620 } else { 9621 PMD_DRV_LOG(ERR, "Input set setting is not supported."); 9622 } 9623 I40E_WRITE_FLUSH(hw); 9624 9625 /* store the default input set */ 9626 if (!pf->support_multi_driver) 9627 pf->hash_input_set[pctype] = input_set; 9628 pf->fdir.input_set[pctype] = input_set; 9629 } 9630 } 9631 9632 int 9633 i40e_hash_filter_inset_select(struct i40e_hw *hw, 9634 struct rte_eth_input_set_conf *conf) 9635 { 9636 struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf; 9637 enum i40e_filter_pctype pctype; 9638 uint64_t input_set, inset_reg = 0; 9639 uint32_t mask_reg[I40E_INSET_MASK_NUM_REG] = {0}; 9640 int ret, i, num; 9641 9642 if (!conf) { 9643 PMD_DRV_LOG(ERR, "Invalid pointer"); 9644 return -EFAULT; 9645 } 9646 if (conf->op != RTE_ETH_INPUT_SET_SELECT && 9647 conf->op != RTE_ETH_INPUT_SET_ADD) { 9648 PMD_DRV_LOG(ERR, "Unsupported input set operation"); 9649 return -EINVAL; 9650 } 9651 9652 if (pf->support_multi_driver) { 9653 PMD_DRV_LOG(ERR, "Hash input set setting is not supported."); 9654 return -ENOTSUP; 9655 } 9656 9657 pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type); 9658 if (pctype == I40E_FILTER_PCTYPE_INVALID) { 9659 PMD_DRV_LOG(ERR, "invalid flow_type input."); 9660 return -EINVAL; 9661 } 9662 9663 if (hw->mac.type == I40E_MAC_X722) { 9664 /* get translated pctype value in fd pctype register */ 9665 pctype = (enum i40e_filter_pctype)i40e_read_rx_ctl(hw, 9666 I40E_GLQF_FD_PCTYPES((int)pctype)); 9667 } 9668 9669 ret = i40e_parse_input_set(&input_set, pctype, conf->field, 9670 conf->inset_size); 9671 if (ret) { 9672 PMD_DRV_LOG(ERR, "Failed to parse input set"); 9673 return -EINVAL; 9674 } 9675 9676 if (conf->op == RTE_ETH_INPUT_SET_ADD) { 9677 /* get inset value in register */ 9678 inset_reg = i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype)); 9679 inset_reg <<= I40E_32_BIT_WIDTH; 9680 inset_reg |= i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype)); 9681 input_set |= pf->hash_input_set[pctype]; 9682 } 9683 num = i40e_generate_inset_mask_reg(input_set, mask_reg, 9684 I40E_INSET_MASK_NUM_REG); 9685 if (num < 0) 9686 return -EINVAL; 9687 9688 inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set); 9689 9690 i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(0, pctype), 9691 (uint32_t)(inset_reg & UINT32_MAX)); 9692 i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(1, pctype), 9693 (uint32_t)((inset_reg >> 9694 I40E_32_BIT_WIDTH) & UINT32_MAX)); 9695 9696 for (i = 0; i < num; i++) 9697 i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype), 9698 mask_reg[i]); 9699 /*clear unused mask registers of the pctype */ 9700 for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) 9701 i40e_check_write_global_reg(hw, I40E_GLQF_HASH_MSK(i, pctype), 9702 0); 9703 I40E_WRITE_FLUSH(hw); 9704 9705 pf->hash_input_set[pctype] = input_set; 9706 return 0; 9707 } 9708 9709 /* Convert ethertype filter structure */ 9710 static int 9711 i40e_ethertype_filter_convert(const struct rte_eth_ethertype_filter *input, 9712 struct i40e_ethertype_filter *filter) 9713 { 9714 rte_memcpy(&filter->input.mac_addr, &input->mac_addr, 9715 RTE_ETHER_ADDR_LEN); 9716 filter->input.ether_type = input->ether_type; 9717 filter->flags = input->flags; 9718 filter->queue = input->queue; 9719 9720 return 0; 9721 } 9722 9723 /* Check if there exists the ehtertype filter */ 9724 struct i40e_ethertype_filter * 9725 i40e_sw_ethertype_filter_lookup(struct i40e_ethertype_rule *ethertype_rule, 9726 const struct i40e_ethertype_filter_input *input) 9727 { 9728 int ret; 9729 9730 ret = rte_hash_lookup(ethertype_rule->hash_table, (const void *)input); 9731 if (ret < 0) 9732 return NULL; 9733 9734 return ethertype_rule->hash_map[ret]; 9735 } 9736 9737 /* Add ethertype filter in SW list */ 9738 static int 9739 i40e_sw_ethertype_filter_insert(struct i40e_pf *pf, 9740 struct i40e_ethertype_filter *filter) 9741 { 9742 struct i40e_ethertype_rule *rule = &pf->ethertype; 9743 int ret; 9744 9745 ret = rte_hash_add_key(rule->hash_table, &filter->input); 9746 if (ret < 0) { 9747 PMD_DRV_LOG(ERR, 9748 "Failed to insert ethertype filter" 9749 " to hash table %d!", 9750 ret); 9751 return ret; 9752 } 9753 rule->hash_map[ret] = filter; 9754 9755 TAILQ_INSERT_TAIL(&rule->ethertype_list, filter, rules); 9756 9757 return 0; 9758 } 9759 9760 /* Delete ethertype filter in SW list */ 9761 int 9762 i40e_sw_ethertype_filter_del(struct i40e_pf *pf, 9763 struct i40e_ethertype_filter_input *input) 9764 { 9765 struct i40e_ethertype_rule *rule = &pf->ethertype; 9766 struct i40e_ethertype_filter *filter; 9767 int ret; 9768 9769 ret = rte_hash_del_key(rule->hash_table, input); 9770 if (ret < 0) { 9771 PMD_DRV_LOG(ERR, 9772 "Failed to delete ethertype filter" 9773 " to hash table %d!", 9774 ret); 9775 return ret; 9776 } 9777 filter = rule->hash_map[ret]; 9778 rule->hash_map[ret] = NULL; 9779 9780 TAILQ_REMOVE(&rule->ethertype_list, filter, rules); 9781 rte_free(filter); 9782 9783 return 0; 9784 } 9785 9786 /* 9787 * Configure ethertype filter, which can director packet by filtering 9788 * with mac address and ether_type or only ether_type 9789 */ 9790 int 9791 i40e_ethertype_filter_set(struct i40e_pf *pf, 9792 struct rte_eth_ethertype_filter *filter, 9793 bool add) 9794 { 9795 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 9796 struct i40e_ethertype_rule *ethertype_rule = &pf->ethertype; 9797 struct i40e_ethertype_filter *ethertype_filter, *node; 9798 struct i40e_ethertype_filter check_filter; 9799 struct i40e_control_filter_stats stats; 9800 uint16_t flags = 0; 9801 int ret; 9802 9803 if (filter->queue >= pf->dev_data->nb_rx_queues) { 9804 PMD_DRV_LOG(ERR, "Invalid queue ID"); 9805 return -EINVAL; 9806 } 9807 if (filter->ether_type == RTE_ETHER_TYPE_IPV4 || 9808 filter->ether_type == RTE_ETHER_TYPE_IPV6) { 9809 PMD_DRV_LOG(ERR, 9810 "unsupported ether_type(0x%04x) in control packet filter.", 9811 filter->ether_type); 9812 return -EINVAL; 9813 } 9814 if (filter->ether_type == RTE_ETHER_TYPE_VLAN) 9815 PMD_DRV_LOG(WARNING, 9816 "filter vlan ether_type in first tag is not supported."); 9817 9818 /* Check if there is the filter in SW list */ 9819 memset(&check_filter, 0, sizeof(check_filter)); 9820 i40e_ethertype_filter_convert(filter, &check_filter); 9821 node = i40e_sw_ethertype_filter_lookup(ethertype_rule, 9822 &check_filter.input); 9823 if (add && node) { 9824 PMD_DRV_LOG(ERR, "Conflict with existing ethertype rules!"); 9825 return -EINVAL; 9826 } 9827 9828 if (!add && !node) { 9829 PMD_DRV_LOG(ERR, "There's no corresponding ethertype filter!"); 9830 return -EINVAL; 9831 } 9832 9833 if (!(filter->flags & RTE_ETHTYPE_FLAGS_MAC)) 9834 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC; 9835 if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) 9836 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP; 9837 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE; 9838 9839 memset(&stats, 0, sizeof(stats)); 9840 ret = i40e_aq_add_rem_control_packet_filter(hw, 9841 filter->mac_addr.addr_bytes, 9842 filter->ether_type, flags, 9843 pf->main_vsi->seid, 9844 filter->queue, add, &stats, NULL); 9845 9846 PMD_DRV_LOG(INFO, 9847 "add/rem control packet filter, return %d, mac_etype_used = %u, etype_used = %u, mac_etype_free = %u, etype_free = %u", 9848 ret, stats.mac_etype_used, stats.etype_used, 9849 stats.mac_etype_free, stats.etype_free); 9850 if (ret < 0) 9851 return -ENOSYS; 9852 9853 /* Add or delete a filter in SW list */ 9854 if (add) { 9855 ethertype_filter = rte_zmalloc("ethertype_filter", 9856 sizeof(*ethertype_filter), 0); 9857 if (ethertype_filter == NULL) { 9858 PMD_DRV_LOG(ERR, "Failed to alloc memory."); 9859 return -ENOMEM; 9860 } 9861 9862 rte_memcpy(ethertype_filter, &check_filter, 9863 sizeof(check_filter)); 9864 ret = i40e_sw_ethertype_filter_insert(pf, ethertype_filter); 9865 if (ret < 0) 9866 rte_free(ethertype_filter); 9867 } else { 9868 ret = i40e_sw_ethertype_filter_del(pf, &node->input); 9869 } 9870 9871 return ret; 9872 } 9873 9874 static int 9875 i40e_dev_filter_ctrl(struct rte_eth_dev *dev, 9876 enum rte_filter_type filter_type, 9877 enum rte_filter_op filter_op, 9878 void *arg) 9879 { 9880 int ret = 0; 9881 9882 if (dev == NULL) 9883 return -EINVAL; 9884 9885 switch (filter_type) { 9886 case RTE_ETH_FILTER_GENERIC: 9887 if (filter_op != RTE_ETH_FILTER_GET) 9888 return -EINVAL; 9889 *(const void **)arg = &i40e_flow_ops; 9890 break; 9891 default: 9892 PMD_DRV_LOG(WARNING, "Filter type (%d) not supported", 9893 filter_type); 9894 ret = -EINVAL; 9895 break; 9896 } 9897 9898 return ret; 9899 } 9900 9901 /* 9902 * Check and enable Extended Tag. 9903 * Enabling Extended Tag is important for 40G performance. 9904 */ 9905 static void 9906 i40e_enable_extended_tag(struct rte_eth_dev *dev) 9907 { 9908 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 9909 uint32_t buf = 0; 9910 int ret; 9911 9912 ret = rte_pci_read_config(pci_dev, &buf, sizeof(buf), 9913 PCI_DEV_CAP_REG); 9914 if (ret < 0) { 9915 PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x", 9916 PCI_DEV_CAP_REG); 9917 return; 9918 } 9919 if (!(buf & PCI_DEV_CAP_EXT_TAG_MASK)) { 9920 PMD_DRV_LOG(ERR, "Does not support Extended Tag"); 9921 return; 9922 } 9923 9924 buf = 0; 9925 ret = rte_pci_read_config(pci_dev, &buf, sizeof(buf), 9926 PCI_DEV_CTRL_REG); 9927 if (ret < 0) { 9928 PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x", 9929 PCI_DEV_CTRL_REG); 9930 return; 9931 } 9932 if (buf & PCI_DEV_CTRL_EXT_TAG_MASK) { 9933 PMD_DRV_LOG(DEBUG, "Extended Tag has already been enabled"); 9934 return; 9935 } 9936 buf |= PCI_DEV_CTRL_EXT_TAG_MASK; 9937 ret = rte_pci_write_config(pci_dev, &buf, sizeof(buf), 9938 PCI_DEV_CTRL_REG); 9939 if (ret < 0) { 9940 PMD_DRV_LOG(ERR, "Failed to write PCI offset 0x%x", 9941 PCI_DEV_CTRL_REG); 9942 return; 9943 } 9944 } 9945 9946 /* 9947 * As some registers wouldn't be reset unless a global hardware reset, 9948 * hardware initialization is needed to put those registers into an 9949 * expected initial state. 9950 */ 9951 static void 9952 i40e_hw_init(struct rte_eth_dev *dev) 9953 { 9954 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 9955 9956 i40e_enable_extended_tag(dev); 9957 9958 /* clear the PF Queue Filter control register */ 9959 i40e_write_rx_ctl(hw, I40E_PFQF_CTL_0, 0); 9960 9961 /* Disable symmetric hash per port */ 9962 i40e_set_symmetric_hash_enable_per_port(hw, 0); 9963 } 9964 9965 /* 9966 * For X722 it is possible to have multiple pctypes mapped to the same flowtype 9967 * however this function will return only one highest pctype index, 9968 * which is not quite correct. This is known problem of i40e driver 9969 * and needs to be fixed later. 9970 */ 9971 enum i40e_filter_pctype 9972 i40e_flowtype_to_pctype(const struct i40e_adapter *adapter, uint16_t flow_type) 9973 { 9974 int i; 9975 uint64_t pctype_mask; 9976 9977 if (flow_type < I40E_FLOW_TYPE_MAX) { 9978 pctype_mask = adapter->pctypes_tbl[flow_type]; 9979 for (i = I40E_FILTER_PCTYPE_MAX - 1; i > 0; i--) { 9980 if (pctype_mask & (1ULL << i)) 9981 return (enum i40e_filter_pctype)i; 9982 } 9983 } 9984 return I40E_FILTER_PCTYPE_INVALID; 9985 } 9986 9987 uint16_t 9988 i40e_pctype_to_flowtype(const struct i40e_adapter *adapter, 9989 enum i40e_filter_pctype pctype) 9990 { 9991 uint16_t flowtype; 9992 uint64_t pctype_mask = 1ULL << pctype; 9993 9994 for (flowtype = RTE_ETH_FLOW_UNKNOWN + 1; flowtype < I40E_FLOW_TYPE_MAX; 9995 flowtype++) { 9996 if (adapter->pctypes_tbl[flowtype] & pctype_mask) 9997 return flowtype; 9998 } 9999 10000 return RTE_ETH_FLOW_UNKNOWN; 10001 } 10002 10003 /* 10004 * On X710, performance number is far from the expectation on recent firmware 10005 * versions; on XL710, performance number is also far from the expectation on 10006 * recent firmware versions, if promiscuous mode is disabled, or promiscuous 10007 * mode is enabled and port MAC address is equal to the packet destination MAC 10008 * address. The fix for this issue may not be integrated in the following 10009 * firmware version. So the workaround in software driver is needed. It needs 10010 * to modify the initial values of 3 internal only registers for both X710 and 10011 * XL710. Note that the values for X710 or XL710 could be different, and the 10012 * workaround can be removed when it is fixed in firmware in the future. 10013 */ 10014 10015 /* For both X710 and XL710 */ 10016 #define I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_1 0x10000200 10017 #define I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_2 0x203F0200 10018 #define I40E_GL_SWR_PRI_JOIN_MAP_0 0x26CE00 10019 10020 #define I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE 0x011f0200 10021 #define I40E_GL_SWR_PRI_JOIN_MAP_2 0x26CE08 10022 10023 /* For X722 */ 10024 #define I40E_X722_GL_SWR_PRI_JOIN_MAP_0_VALUE 0x20000200 10025 #define I40E_X722_GL_SWR_PRI_JOIN_MAP_2_VALUE 0x013F0200 10026 10027 /* For X710 */ 10028 #define I40E_GL_SWR_PM_UP_THR_EF_VALUE 0x03030303 10029 /* For XL710 */ 10030 #define I40E_GL_SWR_PM_UP_THR_SF_VALUE 0x06060606 10031 #define I40E_GL_SWR_PM_UP_THR 0x269FBC 10032 10033 /* 10034 * GL_SWR_PM_UP_THR: 10035 * The value is not impacted from the link speed, its value is set according 10036 * to the total number of ports for a better pipe-monitor configuration. 10037 */ 10038 static bool 10039 i40e_get_swr_pm_cfg(struct i40e_hw *hw, uint32_t *value) 10040 { 10041 #define I40E_GL_SWR_PM_EF_DEVICE(dev) \ 10042 .device_id = (dev), \ 10043 .val = I40E_GL_SWR_PM_UP_THR_EF_VALUE 10044 10045 #define I40E_GL_SWR_PM_SF_DEVICE(dev) \ 10046 .device_id = (dev), \ 10047 .val = I40E_GL_SWR_PM_UP_THR_SF_VALUE 10048 10049 static const struct { 10050 uint16_t device_id; 10051 uint32_t val; 10052 } swr_pm_table[] = { 10053 { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_SFP_XL710) }, 10054 { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_KX_C) }, 10055 { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T) }, 10056 { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_10G_BASE_T4) }, 10057 { I40E_GL_SWR_PM_EF_DEVICE(I40E_DEV_ID_SFP_X722) }, 10058 10059 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_KX_B) }, 10060 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_A) }, 10061 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_QSFP_B) }, 10062 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_20G_KR2) }, 10063 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_20G_KR2_A) }, 10064 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_25G_B) }, 10065 { I40E_GL_SWR_PM_SF_DEVICE(I40E_DEV_ID_25G_SFP28) }, 10066 }; 10067 uint32_t i; 10068 10069 if (value == NULL) { 10070 PMD_DRV_LOG(ERR, "value is NULL"); 10071 return false; 10072 } 10073 10074 for (i = 0; i < RTE_DIM(swr_pm_table); i++) { 10075 if (hw->device_id == swr_pm_table[i].device_id) { 10076 *value = swr_pm_table[i].val; 10077 10078 PMD_DRV_LOG(DEBUG, "Device 0x%x with GL_SWR_PM_UP_THR " 10079 "value - 0x%08x", 10080 hw->device_id, *value); 10081 return true; 10082 } 10083 } 10084 10085 return false; 10086 } 10087 10088 static int 10089 i40e_dev_sync_phy_type(struct i40e_hw *hw) 10090 { 10091 enum i40e_status_code status; 10092 struct i40e_aq_get_phy_abilities_resp phy_ab; 10093 int ret = -ENOTSUP; 10094 int retries = 0; 10095 10096 status = i40e_aq_get_phy_capabilities(hw, false, true, &phy_ab, 10097 NULL); 10098 10099 while (status) { 10100 PMD_INIT_LOG(WARNING, "Failed to sync phy type: status=%d", 10101 status); 10102 retries++; 10103 rte_delay_us(100000); 10104 if (retries < 5) 10105 status = i40e_aq_get_phy_capabilities(hw, false, 10106 true, &phy_ab, NULL); 10107 else 10108 return ret; 10109 } 10110 return 0; 10111 } 10112 10113 static void 10114 i40e_configure_registers(struct i40e_hw *hw) 10115 { 10116 static struct { 10117 uint32_t addr; 10118 uint64_t val; 10119 } reg_table[] = { 10120 {I40E_GL_SWR_PRI_JOIN_MAP_0, 0}, 10121 {I40E_GL_SWR_PRI_JOIN_MAP_2, 0}, 10122 {I40E_GL_SWR_PM_UP_THR, 0}, /* Compute value dynamically */ 10123 }; 10124 uint64_t reg; 10125 uint32_t i; 10126 int ret; 10127 10128 for (i = 0; i < RTE_DIM(reg_table); i++) { 10129 if (reg_table[i].addr == I40E_GL_SWR_PRI_JOIN_MAP_0) { 10130 if (hw->mac.type == I40E_MAC_X722) /* For X722 */ 10131 reg_table[i].val = 10132 I40E_X722_GL_SWR_PRI_JOIN_MAP_0_VALUE; 10133 else /* For X710/XL710/XXV710 */ 10134 if (hw->aq.fw_maj_ver < 6) 10135 reg_table[i].val = 10136 I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_1; 10137 else 10138 reg_table[i].val = 10139 I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE_2; 10140 } 10141 10142 if (reg_table[i].addr == I40E_GL_SWR_PRI_JOIN_MAP_2) { 10143 if (hw->mac.type == I40E_MAC_X722) /* For X722 */ 10144 reg_table[i].val = 10145 I40E_X722_GL_SWR_PRI_JOIN_MAP_2_VALUE; 10146 else /* For X710/XL710/XXV710 */ 10147 reg_table[i].val = 10148 I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE; 10149 } 10150 10151 if (reg_table[i].addr == I40E_GL_SWR_PM_UP_THR) { 10152 uint32_t cfg_val; 10153 10154 if (!i40e_get_swr_pm_cfg(hw, &cfg_val)) { 10155 PMD_DRV_LOG(DEBUG, "Device 0x%x skips " 10156 "GL_SWR_PM_UP_THR value fixup", 10157 hw->device_id); 10158 continue; 10159 } 10160 10161 reg_table[i].val = cfg_val; 10162 } 10163 10164 ret = i40e_aq_debug_read_register(hw, reg_table[i].addr, 10165 ®, NULL); 10166 if (ret < 0) { 10167 PMD_DRV_LOG(ERR, "Failed to read from 0x%"PRIx32, 10168 reg_table[i].addr); 10169 break; 10170 } 10171 PMD_DRV_LOG(DEBUG, "Read from 0x%"PRIx32": 0x%"PRIx64, 10172 reg_table[i].addr, reg); 10173 if (reg == reg_table[i].val) 10174 continue; 10175 10176 ret = i40e_aq_debug_write_register(hw, reg_table[i].addr, 10177 reg_table[i].val, NULL); 10178 if (ret < 0) { 10179 PMD_DRV_LOG(ERR, 10180 "Failed to write 0x%"PRIx64" to the address of 0x%"PRIx32, 10181 reg_table[i].val, reg_table[i].addr); 10182 break; 10183 } 10184 PMD_DRV_LOG(DEBUG, "Write 0x%"PRIx64" to the address of " 10185 "0x%"PRIx32, reg_table[i].val, reg_table[i].addr); 10186 } 10187 } 10188 10189 #define I40E_VSI_TSR_QINQ_CONFIG 0xc030 10190 #define I40E_VSI_L2TAGSTXVALID(_i) (0x00042800 + ((_i) * 4)) 10191 #define I40E_VSI_L2TAGSTXVALID_QINQ 0xab 10192 static int 10193 i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi) 10194 { 10195 uint32_t reg; 10196 int ret; 10197 10198 if (vsi->vsi_id >= I40E_MAX_NUM_VSIS) { 10199 PMD_DRV_LOG(ERR, "VSI ID exceeds the maximum"); 10200 return -EINVAL; 10201 } 10202 10203 /* Configure for double VLAN RX stripping */ 10204 reg = I40E_READ_REG(hw, I40E_VSI_TSR(vsi->vsi_id)); 10205 if ((reg & I40E_VSI_TSR_QINQ_CONFIG) != I40E_VSI_TSR_QINQ_CONFIG) { 10206 reg |= I40E_VSI_TSR_QINQ_CONFIG; 10207 ret = i40e_aq_debug_write_register(hw, 10208 I40E_VSI_TSR(vsi->vsi_id), 10209 reg, NULL); 10210 if (ret < 0) { 10211 PMD_DRV_LOG(ERR, "Failed to update VSI_TSR[%d]", 10212 vsi->vsi_id); 10213 return I40E_ERR_CONFIG; 10214 } 10215 } 10216 10217 /* Configure for double VLAN TX insertion */ 10218 reg = I40E_READ_REG(hw, I40E_VSI_L2TAGSTXVALID(vsi->vsi_id)); 10219 if ((reg & 0xff) != I40E_VSI_L2TAGSTXVALID_QINQ) { 10220 reg = I40E_VSI_L2TAGSTXVALID_QINQ; 10221 ret = i40e_aq_debug_write_register(hw, 10222 I40E_VSI_L2TAGSTXVALID( 10223 vsi->vsi_id), reg, NULL); 10224 if (ret < 0) { 10225 PMD_DRV_LOG(ERR, 10226 "Failed to update VSI_L2TAGSTXVALID[%d]", 10227 vsi->vsi_id); 10228 return I40E_ERR_CONFIG; 10229 } 10230 } 10231 10232 return 0; 10233 } 10234 10235 /** 10236 * i40e_aq_add_mirror_rule 10237 * @hw: pointer to the hardware structure 10238 * @seid: VEB seid to add mirror rule to 10239 * @dst_id: destination vsi seid 10240 * @entries: Buffer which contains the entities to be mirrored 10241 * @count: number of entities contained in the buffer 10242 * @rule_id:the rule_id of the rule to be added 10243 * 10244 * Add a mirror rule for a given veb. 10245 * 10246 **/ 10247 static enum i40e_status_code 10248 i40e_aq_add_mirror_rule(struct i40e_hw *hw, 10249 uint16_t seid, uint16_t dst_id, 10250 uint16_t rule_type, uint16_t *entries, 10251 uint16_t count, uint16_t *rule_id) 10252 { 10253 struct i40e_aq_desc desc; 10254 struct i40e_aqc_add_delete_mirror_rule cmd; 10255 struct i40e_aqc_add_delete_mirror_rule_completion *resp = 10256 (struct i40e_aqc_add_delete_mirror_rule_completion *) 10257 &desc.params.raw; 10258 uint16_t buff_len; 10259 enum i40e_status_code status; 10260 10261 i40e_fill_default_direct_cmd_desc(&desc, 10262 i40e_aqc_opc_add_mirror_rule); 10263 memset(&cmd, 0, sizeof(cmd)); 10264 10265 buff_len = sizeof(uint16_t) * count; 10266 desc.datalen = rte_cpu_to_le_16(buff_len); 10267 if (buff_len > 0) 10268 desc.flags |= rte_cpu_to_le_16( 10269 (uint16_t)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); 10270 cmd.rule_type = rte_cpu_to_le_16(rule_type << 10271 I40E_AQC_MIRROR_RULE_TYPE_SHIFT); 10272 cmd.num_entries = rte_cpu_to_le_16(count); 10273 cmd.seid = rte_cpu_to_le_16(seid); 10274 cmd.destination = rte_cpu_to_le_16(dst_id); 10275 10276 rte_memcpy(&desc.params.raw, &cmd, sizeof(cmd)); 10277 status = i40e_asq_send_command(hw, &desc, entries, buff_len, NULL); 10278 PMD_DRV_LOG(INFO, 10279 "i40e_aq_add_mirror_rule, aq_status %d, rule_id = %u mirror_rules_used = %u, mirror_rules_free = %u,", 10280 hw->aq.asq_last_status, resp->rule_id, 10281 resp->mirror_rules_used, resp->mirror_rules_free); 10282 *rule_id = rte_le_to_cpu_16(resp->rule_id); 10283 10284 return status; 10285 } 10286 10287 /** 10288 * i40e_aq_del_mirror_rule 10289 * @hw: pointer to the hardware structure 10290 * @seid: VEB seid to add mirror rule to 10291 * @entries: Buffer which contains the entities to be mirrored 10292 * @count: number of entities contained in the buffer 10293 * @rule_id:the rule_id of the rule to be delete 10294 * 10295 * Delete a mirror rule for a given veb. 10296 * 10297 **/ 10298 static enum i40e_status_code 10299 i40e_aq_del_mirror_rule(struct i40e_hw *hw, 10300 uint16_t seid, uint16_t rule_type, uint16_t *entries, 10301 uint16_t count, uint16_t rule_id) 10302 { 10303 struct i40e_aq_desc desc; 10304 struct i40e_aqc_add_delete_mirror_rule cmd; 10305 uint16_t buff_len = 0; 10306 enum i40e_status_code status; 10307 void *buff = NULL; 10308 10309 i40e_fill_default_direct_cmd_desc(&desc, 10310 i40e_aqc_opc_delete_mirror_rule); 10311 memset(&cmd, 0, sizeof(cmd)); 10312 if (rule_type == I40E_AQC_MIRROR_RULE_TYPE_VLAN) { 10313 desc.flags |= rte_cpu_to_le_16((uint16_t)(I40E_AQ_FLAG_BUF | 10314 I40E_AQ_FLAG_RD)); 10315 cmd.num_entries = count; 10316 buff_len = sizeof(uint16_t) * count; 10317 desc.datalen = rte_cpu_to_le_16(buff_len); 10318 buff = (void *)entries; 10319 } else 10320 /* rule id is filled in destination field for deleting mirror rule */ 10321 cmd.destination = rte_cpu_to_le_16(rule_id); 10322 10323 cmd.rule_type = rte_cpu_to_le_16(rule_type << 10324 I40E_AQC_MIRROR_RULE_TYPE_SHIFT); 10325 cmd.seid = rte_cpu_to_le_16(seid); 10326 10327 rte_memcpy(&desc.params.raw, &cmd, sizeof(cmd)); 10328 status = i40e_asq_send_command(hw, &desc, buff, buff_len, NULL); 10329 10330 return status; 10331 } 10332 10333 /** 10334 * i40e_mirror_rule_set 10335 * @dev: pointer to the hardware structure 10336 * @mirror_conf: mirror rule info 10337 * @sw_id: mirror rule's sw_id 10338 * @on: enable/disable 10339 * 10340 * set a mirror rule. 10341 * 10342 **/ 10343 static int 10344 i40e_mirror_rule_set(struct rte_eth_dev *dev, 10345 struct rte_eth_mirror_conf *mirror_conf, 10346 uint8_t sw_id, uint8_t on) 10347 { 10348 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 10349 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10350 struct i40e_mirror_rule *it, *mirr_rule = NULL; 10351 struct i40e_mirror_rule *parent = NULL; 10352 uint16_t seid, dst_seid, rule_id; 10353 uint16_t i, j = 0; 10354 int ret; 10355 10356 PMD_DRV_LOG(DEBUG, "i40e_mirror_rule_set: sw_id = %d.", sw_id); 10357 10358 if (pf->main_vsi->veb == NULL || pf->vfs == NULL) { 10359 PMD_DRV_LOG(ERR, 10360 "mirror rule can not be configured without veb or vfs."); 10361 return -ENOSYS; 10362 } 10363 if (pf->nb_mirror_rule > I40E_MAX_MIRROR_RULES) { 10364 PMD_DRV_LOG(ERR, "mirror table is full."); 10365 return -ENOSPC; 10366 } 10367 if (mirror_conf->dst_pool > pf->vf_num) { 10368 PMD_DRV_LOG(ERR, "invalid destination pool %u.", 10369 mirror_conf->dst_pool); 10370 return -EINVAL; 10371 } 10372 10373 seid = pf->main_vsi->veb->seid; 10374 10375 TAILQ_FOREACH(it, &pf->mirror_list, rules) { 10376 if (sw_id <= it->index) { 10377 mirr_rule = it; 10378 break; 10379 } 10380 parent = it; 10381 } 10382 if (mirr_rule && sw_id == mirr_rule->index) { 10383 if (on) { 10384 PMD_DRV_LOG(ERR, "mirror rule exists."); 10385 return -EEXIST; 10386 } else { 10387 ret = i40e_aq_del_mirror_rule(hw, seid, 10388 mirr_rule->rule_type, 10389 mirr_rule->entries, 10390 mirr_rule->num_entries, mirr_rule->id); 10391 if (ret < 0) { 10392 PMD_DRV_LOG(ERR, 10393 "failed to remove mirror rule: ret = %d, aq_err = %d.", 10394 ret, hw->aq.asq_last_status); 10395 return -ENOSYS; 10396 } 10397 TAILQ_REMOVE(&pf->mirror_list, mirr_rule, rules); 10398 rte_free(mirr_rule); 10399 pf->nb_mirror_rule--; 10400 return 0; 10401 } 10402 } else if (!on) { 10403 PMD_DRV_LOG(ERR, "mirror rule doesn't exist."); 10404 return -ENOENT; 10405 } 10406 10407 mirr_rule = rte_zmalloc("i40e_mirror_rule", 10408 sizeof(struct i40e_mirror_rule) , 0); 10409 if (!mirr_rule) { 10410 PMD_DRV_LOG(ERR, "failed to allocate memory"); 10411 return I40E_ERR_NO_MEMORY; 10412 } 10413 switch (mirror_conf->rule_type) { 10414 case ETH_MIRROR_VLAN: 10415 for (i = 0, j = 0; i < ETH_MIRROR_MAX_VLANS; i++) { 10416 if (mirror_conf->vlan.vlan_mask & (1ULL << i)) { 10417 mirr_rule->entries[j] = 10418 mirror_conf->vlan.vlan_id[i]; 10419 j++; 10420 } 10421 } 10422 if (j == 0) { 10423 PMD_DRV_LOG(ERR, "vlan is not specified."); 10424 rte_free(mirr_rule); 10425 return -EINVAL; 10426 } 10427 mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_VLAN; 10428 break; 10429 case ETH_MIRROR_VIRTUAL_POOL_UP: 10430 case ETH_MIRROR_VIRTUAL_POOL_DOWN: 10431 /* check if the specified pool bit is out of range */ 10432 if (mirror_conf->pool_mask > (uint64_t)(1ULL << (pf->vf_num + 1))) { 10433 PMD_DRV_LOG(ERR, "pool mask is out of range."); 10434 rte_free(mirr_rule); 10435 return -EINVAL; 10436 } 10437 for (i = 0, j = 0; i < pf->vf_num; i++) { 10438 if (mirror_conf->pool_mask & (1ULL << i)) { 10439 mirr_rule->entries[j] = pf->vfs[i].vsi->seid; 10440 j++; 10441 } 10442 } 10443 if (mirror_conf->pool_mask & (1ULL << pf->vf_num)) { 10444 /* add pf vsi to entries */ 10445 mirr_rule->entries[j] = pf->main_vsi_seid; 10446 j++; 10447 } 10448 if (j == 0) { 10449 PMD_DRV_LOG(ERR, "pool is not specified."); 10450 rte_free(mirr_rule); 10451 return -EINVAL; 10452 } 10453 /* egress and ingress in aq commands means from switch but not port */ 10454 mirr_rule->rule_type = 10455 (mirror_conf->rule_type == ETH_MIRROR_VIRTUAL_POOL_UP) ? 10456 I40E_AQC_MIRROR_RULE_TYPE_VPORT_EGRESS : 10457 I40E_AQC_MIRROR_RULE_TYPE_VPORT_INGRESS; 10458 break; 10459 case ETH_MIRROR_UPLINK_PORT: 10460 /* egress and ingress in aq commands means from switch but not port*/ 10461 mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_ALL_EGRESS; 10462 break; 10463 case ETH_MIRROR_DOWNLINK_PORT: 10464 mirr_rule->rule_type = I40E_AQC_MIRROR_RULE_TYPE_ALL_INGRESS; 10465 break; 10466 default: 10467 PMD_DRV_LOG(ERR, "unsupported mirror type %d.", 10468 mirror_conf->rule_type); 10469 rte_free(mirr_rule); 10470 return -EINVAL; 10471 } 10472 10473 /* If the dst_pool is equal to vf_num, consider it as PF */ 10474 if (mirror_conf->dst_pool == pf->vf_num) 10475 dst_seid = pf->main_vsi_seid; 10476 else 10477 dst_seid = pf->vfs[mirror_conf->dst_pool].vsi->seid; 10478 10479 ret = i40e_aq_add_mirror_rule(hw, seid, dst_seid, 10480 mirr_rule->rule_type, mirr_rule->entries, 10481 j, &rule_id); 10482 if (ret < 0) { 10483 PMD_DRV_LOG(ERR, 10484 "failed to add mirror rule: ret = %d, aq_err = %d.", 10485 ret, hw->aq.asq_last_status); 10486 rte_free(mirr_rule); 10487 return -ENOSYS; 10488 } 10489 10490 mirr_rule->index = sw_id; 10491 mirr_rule->num_entries = j; 10492 mirr_rule->id = rule_id; 10493 mirr_rule->dst_vsi_seid = dst_seid; 10494 10495 if (parent) 10496 TAILQ_INSERT_AFTER(&pf->mirror_list, parent, mirr_rule, rules); 10497 else 10498 TAILQ_INSERT_HEAD(&pf->mirror_list, mirr_rule, rules); 10499 10500 pf->nb_mirror_rule++; 10501 return 0; 10502 } 10503 10504 /** 10505 * i40e_mirror_rule_reset 10506 * @dev: pointer to the device 10507 * @sw_id: mirror rule's sw_id 10508 * 10509 * reset a mirror rule. 10510 * 10511 **/ 10512 static int 10513 i40e_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t sw_id) 10514 { 10515 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 10516 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10517 struct i40e_mirror_rule *it, *mirr_rule = NULL; 10518 uint16_t seid; 10519 int ret; 10520 10521 PMD_DRV_LOG(DEBUG, "i40e_mirror_rule_reset: sw_id = %d.", sw_id); 10522 10523 seid = pf->main_vsi->veb->seid; 10524 10525 TAILQ_FOREACH(it, &pf->mirror_list, rules) { 10526 if (sw_id == it->index) { 10527 mirr_rule = it; 10528 break; 10529 } 10530 } 10531 if (mirr_rule) { 10532 ret = i40e_aq_del_mirror_rule(hw, seid, 10533 mirr_rule->rule_type, 10534 mirr_rule->entries, 10535 mirr_rule->num_entries, mirr_rule->id); 10536 if (ret < 0) { 10537 PMD_DRV_LOG(ERR, 10538 "failed to remove mirror rule: status = %d, aq_err = %d.", 10539 ret, hw->aq.asq_last_status); 10540 return -ENOSYS; 10541 } 10542 TAILQ_REMOVE(&pf->mirror_list, mirr_rule, rules); 10543 rte_free(mirr_rule); 10544 pf->nb_mirror_rule--; 10545 } else { 10546 PMD_DRV_LOG(ERR, "mirror rule doesn't exist."); 10547 return -ENOENT; 10548 } 10549 return 0; 10550 } 10551 10552 static uint64_t 10553 i40e_read_systime_cyclecounter(struct rte_eth_dev *dev) 10554 { 10555 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10556 uint64_t systim_cycles; 10557 10558 systim_cycles = (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TIME_L); 10559 systim_cycles |= (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TIME_H) 10560 << 32; 10561 10562 return systim_cycles; 10563 } 10564 10565 static uint64_t 10566 i40e_read_rx_tstamp_cyclecounter(struct rte_eth_dev *dev, uint8_t index) 10567 { 10568 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10569 uint64_t rx_tstamp; 10570 10571 rx_tstamp = (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_L(index)); 10572 rx_tstamp |= (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(index)) 10573 << 32; 10574 10575 return rx_tstamp; 10576 } 10577 10578 static uint64_t 10579 i40e_read_tx_tstamp_cyclecounter(struct rte_eth_dev *dev) 10580 { 10581 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10582 uint64_t tx_tstamp; 10583 10584 tx_tstamp = (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TXTIME_L); 10585 tx_tstamp |= (uint64_t)I40E_READ_REG(hw, I40E_PRTTSYN_TXTIME_H) 10586 << 32; 10587 10588 return tx_tstamp; 10589 } 10590 10591 static void 10592 i40e_start_timecounters(struct rte_eth_dev *dev) 10593 { 10594 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10595 struct i40e_adapter *adapter = dev->data->dev_private; 10596 struct rte_eth_link link; 10597 uint32_t tsync_inc_l; 10598 uint32_t tsync_inc_h; 10599 10600 /* Get current link speed. */ 10601 i40e_dev_link_update(dev, 1); 10602 rte_eth_linkstatus_get(dev, &link); 10603 10604 switch (link.link_speed) { 10605 case ETH_SPEED_NUM_40G: 10606 case ETH_SPEED_NUM_25G: 10607 tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF; 10608 tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32; 10609 break; 10610 case ETH_SPEED_NUM_10G: 10611 tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF; 10612 tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32; 10613 break; 10614 case ETH_SPEED_NUM_1G: 10615 tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF; 10616 tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32; 10617 break; 10618 default: 10619 tsync_inc_l = 0x0; 10620 tsync_inc_h = 0x0; 10621 } 10622 10623 /* Set the timesync increment value. */ 10624 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_L, tsync_inc_l); 10625 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_H, tsync_inc_h); 10626 10627 memset(&adapter->systime_tc, 0, sizeof(struct rte_timecounter)); 10628 memset(&adapter->rx_tstamp_tc, 0, sizeof(struct rte_timecounter)); 10629 memset(&adapter->tx_tstamp_tc, 0, sizeof(struct rte_timecounter)); 10630 10631 adapter->systime_tc.cc_mask = I40E_CYCLECOUNTER_MASK; 10632 adapter->systime_tc.cc_shift = 0; 10633 adapter->systime_tc.nsec_mask = 0; 10634 10635 adapter->rx_tstamp_tc.cc_mask = I40E_CYCLECOUNTER_MASK; 10636 adapter->rx_tstamp_tc.cc_shift = 0; 10637 adapter->rx_tstamp_tc.nsec_mask = 0; 10638 10639 adapter->tx_tstamp_tc.cc_mask = I40E_CYCLECOUNTER_MASK; 10640 adapter->tx_tstamp_tc.cc_shift = 0; 10641 adapter->tx_tstamp_tc.nsec_mask = 0; 10642 } 10643 10644 static int 10645 i40e_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta) 10646 { 10647 struct i40e_adapter *adapter = dev->data->dev_private; 10648 10649 adapter->systime_tc.nsec += delta; 10650 adapter->rx_tstamp_tc.nsec += delta; 10651 adapter->tx_tstamp_tc.nsec += delta; 10652 10653 return 0; 10654 } 10655 10656 static int 10657 i40e_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts) 10658 { 10659 uint64_t ns; 10660 struct i40e_adapter *adapter = dev->data->dev_private; 10661 10662 ns = rte_timespec_to_ns(ts); 10663 10664 /* Set the timecounters to a new value. */ 10665 adapter->systime_tc.nsec = ns; 10666 adapter->rx_tstamp_tc.nsec = ns; 10667 adapter->tx_tstamp_tc.nsec = ns; 10668 10669 return 0; 10670 } 10671 10672 static int 10673 i40e_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts) 10674 { 10675 uint64_t ns, systime_cycles; 10676 struct i40e_adapter *adapter = dev->data->dev_private; 10677 10678 systime_cycles = i40e_read_systime_cyclecounter(dev); 10679 ns = rte_timecounter_update(&adapter->systime_tc, systime_cycles); 10680 *ts = rte_ns_to_timespec(ns); 10681 10682 return 0; 10683 } 10684 10685 static int 10686 i40e_timesync_enable(struct rte_eth_dev *dev) 10687 { 10688 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10689 uint32_t tsync_ctl_l; 10690 uint32_t tsync_ctl_h; 10691 10692 /* Stop the timesync system time. */ 10693 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_L, 0x0); 10694 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_H, 0x0); 10695 /* Reset the timesync system time value. */ 10696 I40E_WRITE_REG(hw, I40E_PRTTSYN_TIME_L, 0x0); 10697 I40E_WRITE_REG(hw, I40E_PRTTSYN_TIME_H, 0x0); 10698 10699 i40e_start_timecounters(dev); 10700 10701 /* Clear timesync registers. */ 10702 I40E_READ_REG(hw, I40E_PRTTSYN_STAT_0); 10703 I40E_READ_REG(hw, I40E_PRTTSYN_TXTIME_H); 10704 I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(0)); 10705 I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(1)); 10706 I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(2)); 10707 I40E_READ_REG(hw, I40E_PRTTSYN_RXTIME_H(3)); 10708 10709 /* Enable timestamping of PTP packets. */ 10710 tsync_ctl_l = I40E_READ_REG(hw, I40E_PRTTSYN_CTL0); 10711 tsync_ctl_l |= I40E_PRTTSYN_TSYNENA; 10712 10713 tsync_ctl_h = I40E_READ_REG(hw, I40E_PRTTSYN_CTL1); 10714 tsync_ctl_h |= I40E_PRTTSYN_TSYNENA; 10715 tsync_ctl_h |= I40E_PRTTSYN_TSYNTYPE; 10716 10717 I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL0, tsync_ctl_l); 10718 I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL1, tsync_ctl_h); 10719 10720 return 0; 10721 } 10722 10723 static int 10724 i40e_timesync_disable(struct rte_eth_dev *dev) 10725 { 10726 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10727 uint32_t tsync_ctl_l; 10728 uint32_t tsync_ctl_h; 10729 10730 /* Disable timestamping of transmitted PTP packets. */ 10731 tsync_ctl_l = I40E_READ_REG(hw, I40E_PRTTSYN_CTL0); 10732 tsync_ctl_l &= ~I40E_PRTTSYN_TSYNENA; 10733 10734 tsync_ctl_h = I40E_READ_REG(hw, I40E_PRTTSYN_CTL1); 10735 tsync_ctl_h &= ~I40E_PRTTSYN_TSYNENA; 10736 10737 I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL0, tsync_ctl_l); 10738 I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL1, tsync_ctl_h); 10739 10740 /* Reset the timesync increment value. */ 10741 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_L, 0x0); 10742 I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_H, 0x0); 10743 10744 return 0; 10745 } 10746 10747 static int 10748 i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev, 10749 struct timespec *timestamp, uint32_t flags) 10750 { 10751 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10752 struct i40e_adapter *adapter = dev->data->dev_private; 10753 uint32_t sync_status; 10754 uint32_t index = flags & 0x03; 10755 uint64_t rx_tstamp_cycles; 10756 uint64_t ns; 10757 10758 sync_status = I40E_READ_REG(hw, I40E_PRTTSYN_STAT_1); 10759 if ((sync_status & (1 << index)) == 0) 10760 return -EINVAL; 10761 10762 rx_tstamp_cycles = i40e_read_rx_tstamp_cyclecounter(dev, index); 10763 ns = rte_timecounter_update(&adapter->rx_tstamp_tc, rx_tstamp_cycles); 10764 *timestamp = rte_ns_to_timespec(ns); 10765 10766 return 0; 10767 } 10768 10769 static int 10770 i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev, 10771 struct timespec *timestamp) 10772 { 10773 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 10774 struct i40e_adapter *adapter = dev->data->dev_private; 10775 uint32_t sync_status; 10776 uint64_t tx_tstamp_cycles; 10777 uint64_t ns; 10778 10779 sync_status = I40E_READ_REG(hw, I40E_PRTTSYN_STAT_0); 10780 if ((sync_status & I40E_PRTTSYN_STAT_0_TXTIME_MASK) == 0) 10781 return -EINVAL; 10782 10783 tx_tstamp_cycles = i40e_read_tx_tstamp_cyclecounter(dev); 10784 ns = rte_timecounter_update(&adapter->tx_tstamp_tc, tx_tstamp_cycles); 10785 *timestamp = rte_ns_to_timespec(ns); 10786 10787 return 0; 10788 } 10789 10790 /* 10791 * i40e_parse_dcb_configure - parse dcb configure from user 10792 * @dev: the device being configured 10793 * @dcb_cfg: pointer of the result of parse 10794 * @*tc_map: bit map of enabled traffic classes 10795 * 10796 * Returns 0 on success, negative value on failure 10797 */ 10798 static int 10799 i40e_parse_dcb_configure(struct rte_eth_dev *dev, 10800 struct i40e_dcbx_config *dcb_cfg, 10801 uint8_t *tc_map) 10802 { 10803 struct rte_eth_dcb_rx_conf *dcb_rx_conf; 10804 uint8_t i, tc_bw, bw_lf; 10805 10806 memset(dcb_cfg, 0, sizeof(struct i40e_dcbx_config)); 10807 10808 dcb_rx_conf = &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf; 10809 if (dcb_rx_conf->nb_tcs > I40E_MAX_TRAFFIC_CLASS) { 10810 PMD_INIT_LOG(ERR, "number of tc exceeds max."); 10811 return -EINVAL; 10812 } 10813 10814 /* assume each tc has the same bw */ 10815 tc_bw = I40E_MAX_PERCENT / dcb_rx_conf->nb_tcs; 10816 for (i = 0; i < dcb_rx_conf->nb_tcs; i++) 10817 dcb_cfg->etscfg.tcbwtable[i] = tc_bw; 10818 /* to ensure the sum of tcbw is equal to 100 */ 10819 bw_lf = I40E_MAX_PERCENT % dcb_rx_conf->nb_tcs; 10820 for (i = 0; i < bw_lf; i++) 10821 dcb_cfg->etscfg.tcbwtable[i]++; 10822 10823 /* assume each tc has the same Transmission Selection Algorithm */ 10824 for (i = 0; i < dcb_rx_conf->nb_tcs; i++) 10825 dcb_cfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS; 10826 10827 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) 10828 dcb_cfg->etscfg.prioritytable[i] = 10829 dcb_rx_conf->dcb_tc[i]; 10830 10831 /* FW needs one App to configure HW */ 10832 dcb_cfg->numapps = I40E_DEFAULT_DCB_APP_NUM; 10833 dcb_cfg->app[0].selector = I40E_APP_SEL_ETHTYPE; 10834 dcb_cfg->app[0].priority = I40E_DEFAULT_DCB_APP_PRIO; 10835 dcb_cfg->app[0].protocolid = I40E_APP_PROTOID_FCOE; 10836 10837 if (dcb_rx_conf->nb_tcs == 0) 10838 *tc_map = 1; /* tc0 only */ 10839 else 10840 *tc_map = RTE_LEN2MASK(dcb_rx_conf->nb_tcs, uint8_t); 10841 10842 if (dev->data->dev_conf.dcb_capability_en & ETH_DCB_PFC_SUPPORT) { 10843 dcb_cfg->pfc.willing = 0; 10844 dcb_cfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS; 10845 dcb_cfg->pfc.pfcenable = *tc_map; 10846 } 10847 return 0; 10848 } 10849 10850 10851 static enum i40e_status_code 10852 i40e_vsi_update_queue_mapping(struct i40e_vsi *vsi, 10853 struct i40e_aqc_vsi_properties_data *info, 10854 uint8_t enabled_tcmap) 10855 { 10856 enum i40e_status_code ret; 10857 int i, total_tc = 0; 10858 uint16_t qpnum_per_tc, bsf, qp_idx; 10859 struct rte_eth_dev_data *dev_data = I40E_VSI_TO_DEV_DATA(vsi); 10860 struct i40e_pf *pf = I40E_VSI_TO_PF(vsi); 10861 uint16_t used_queues; 10862 10863 ret = validate_tcmap_parameter(vsi, enabled_tcmap); 10864 if (ret != I40E_SUCCESS) 10865 return ret; 10866 10867 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 10868 if (enabled_tcmap & (1 << i)) 10869 total_tc++; 10870 } 10871 if (total_tc == 0) 10872 total_tc = 1; 10873 vsi->enabled_tc = enabled_tcmap; 10874 10875 /* different VSI has different queues assigned */ 10876 if (vsi->type == I40E_VSI_MAIN) 10877 used_queues = dev_data->nb_rx_queues - 10878 pf->nb_cfg_vmdq_vsi * RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM; 10879 else if (vsi->type == I40E_VSI_VMDQ2) 10880 used_queues = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM; 10881 else { 10882 PMD_INIT_LOG(ERR, "unsupported VSI type."); 10883 return I40E_ERR_NO_AVAILABLE_VSI; 10884 } 10885 10886 qpnum_per_tc = used_queues / total_tc; 10887 /* Number of queues per enabled TC */ 10888 if (qpnum_per_tc == 0) { 10889 PMD_INIT_LOG(ERR, " number of queues is less that tcs."); 10890 return I40E_ERR_INVALID_QP_ID; 10891 } 10892 qpnum_per_tc = RTE_MIN(i40e_align_floor(qpnum_per_tc), 10893 I40E_MAX_Q_PER_TC); 10894 bsf = rte_bsf32(qpnum_per_tc); 10895 10896 /** 10897 * Configure TC and queue mapping parameters, for enabled TC, 10898 * allocate qpnum_per_tc queues to this traffic. For disabled TC, 10899 * default queue will serve it. 10900 */ 10901 qp_idx = 0; 10902 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 10903 if (vsi->enabled_tc & (1 << i)) { 10904 info->tc_mapping[i] = rte_cpu_to_le_16((qp_idx << 10905 I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) | 10906 (bsf << I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT)); 10907 qp_idx += qpnum_per_tc; 10908 } else 10909 info->tc_mapping[i] = 0; 10910 } 10911 10912 /* Associate queue number with VSI, Keep vsi->nb_qps unchanged */ 10913 if (vsi->type == I40E_VSI_SRIOV) { 10914 info->mapping_flags |= 10915 rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_NONCONTIG); 10916 for (i = 0; i < vsi->nb_qps; i++) 10917 info->queue_mapping[i] = 10918 rte_cpu_to_le_16(vsi->base_queue + i); 10919 } else { 10920 info->mapping_flags |= 10921 rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_CONTIG); 10922 info->queue_mapping[0] = rte_cpu_to_le_16(vsi->base_queue); 10923 } 10924 info->valid_sections |= 10925 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_QUEUE_MAP_VALID); 10926 10927 return I40E_SUCCESS; 10928 } 10929 10930 /* 10931 * i40e_config_switch_comp_tc - Configure VEB tc setting for given TC map 10932 * @veb: VEB to be configured 10933 * @tc_map: enabled TC bitmap 10934 * 10935 * Returns 0 on success, negative value on failure 10936 */ 10937 static enum i40e_status_code 10938 i40e_config_switch_comp_tc(struct i40e_veb *veb, uint8_t tc_map) 10939 { 10940 struct i40e_aqc_configure_switching_comp_bw_config_data veb_bw; 10941 struct i40e_aqc_query_switching_comp_bw_config_resp bw_query; 10942 struct i40e_aqc_query_switching_comp_ets_config_resp ets_query; 10943 struct i40e_hw *hw = I40E_VSI_TO_HW(veb->associate_vsi); 10944 enum i40e_status_code ret = I40E_SUCCESS; 10945 int i; 10946 uint32_t bw_max; 10947 10948 /* Check if enabled_tc is same as existing or new TCs */ 10949 if (veb->enabled_tc == tc_map) 10950 return ret; 10951 10952 /* configure tc bandwidth */ 10953 memset(&veb_bw, 0, sizeof(veb_bw)); 10954 veb_bw.tc_valid_bits = tc_map; 10955 /* Enable ETS TCs with equal BW Share for now across all VSIs */ 10956 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 10957 if (tc_map & BIT_ULL(i)) 10958 veb_bw.tc_bw_share_credits[i] = 1; 10959 } 10960 ret = i40e_aq_config_switch_comp_bw_config(hw, veb->seid, 10961 &veb_bw, NULL); 10962 if (ret) { 10963 PMD_INIT_LOG(ERR, 10964 "AQ command Config switch_comp BW allocation per TC failed = %d", 10965 hw->aq.asq_last_status); 10966 return ret; 10967 } 10968 10969 memset(&ets_query, 0, sizeof(ets_query)); 10970 ret = i40e_aq_query_switch_comp_ets_config(hw, veb->seid, 10971 &ets_query, NULL); 10972 if (ret != I40E_SUCCESS) { 10973 PMD_DRV_LOG(ERR, 10974 "Failed to get switch_comp ETS configuration %u", 10975 hw->aq.asq_last_status); 10976 return ret; 10977 } 10978 memset(&bw_query, 0, sizeof(bw_query)); 10979 ret = i40e_aq_query_switch_comp_bw_config(hw, veb->seid, 10980 &bw_query, NULL); 10981 if (ret != I40E_SUCCESS) { 10982 PMD_DRV_LOG(ERR, 10983 "Failed to get switch_comp bandwidth configuration %u", 10984 hw->aq.asq_last_status); 10985 return ret; 10986 } 10987 10988 /* store and print out BW info */ 10989 veb->bw_info.bw_limit = rte_le_to_cpu_16(ets_query.port_bw_limit); 10990 veb->bw_info.bw_max = ets_query.tc_bw_max; 10991 PMD_DRV_LOG(DEBUG, "switch_comp bw limit:%u", veb->bw_info.bw_limit); 10992 PMD_DRV_LOG(DEBUG, "switch_comp max_bw:%u", veb->bw_info.bw_max); 10993 bw_max = rte_le_to_cpu_16(bw_query.tc_bw_max[0]) | 10994 (rte_le_to_cpu_16(bw_query.tc_bw_max[1]) << 10995 I40E_16_BIT_WIDTH); 10996 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 10997 veb->bw_info.bw_ets_share_credits[i] = 10998 bw_query.tc_bw_share_credits[i]; 10999 veb->bw_info.bw_ets_credits[i] = 11000 rte_le_to_cpu_16(bw_query.tc_bw_limits[i]); 11001 /* 4 bits per TC, 4th bit is reserved */ 11002 veb->bw_info.bw_ets_max[i] = 11003 (uint8_t)((bw_max >> (i * I40E_4_BIT_WIDTH)) & 11004 RTE_LEN2MASK(3, uint8_t)); 11005 PMD_DRV_LOG(DEBUG, "\tVEB TC%u:share credits %u", i, 11006 veb->bw_info.bw_ets_share_credits[i]); 11007 PMD_DRV_LOG(DEBUG, "\tVEB TC%u:credits %u", i, 11008 veb->bw_info.bw_ets_credits[i]); 11009 PMD_DRV_LOG(DEBUG, "\tVEB TC%u: max credits: %u", i, 11010 veb->bw_info.bw_ets_max[i]); 11011 } 11012 11013 veb->enabled_tc = tc_map; 11014 11015 return ret; 11016 } 11017 11018 11019 /* 11020 * i40e_vsi_config_tc - Configure VSI tc setting for given TC map 11021 * @vsi: VSI to be configured 11022 * @tc_map: enabled TC bitmap 11023 * 11024 * Returns 0 on success, negative value on failure 11025 */ 11026 static enum i40e_status_code 11027 i40e_vsi_config_tc(struct i40e_vsi *vsi, uint8_t tc_map) 11028 { 11029 struct i40e_aqc_configure_vsi_tc_bw_data bw_data; 11030 struct i40e_vsi_context ctxt; 11031 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); 11032 enum i40e_status_code ret = I40E_SUCCESS; 11033 int i; 11034 11035 /* Check if enabled_tc is same as existing or new TCs */ 11036 if (vsi->enabled_tc == tc_map) 11037 return ret; 11038 11039 /* configure tc bandwidth */ 11040 memset(&bw_data, 0, sizeof(bw_data)); 11041 bw_data.tc_valid_bits = tc_map; 11042 /* Enable ETS TCs with equal BW Share for now across all VSIs */ 11043 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 11044 if (tc_map & BIT_ULL(i)) 11045 bw_data.tc_bw_credits[i] = 1; 11046 } 11047 ret = i40e_aq_config_vsi_tc_bw(hw, vsi->seid, &bw_data, NULL); 11048 if (ret) { 11049 PMD_INIT_LOG(ERR, 11050 "AQ command Config VSI BW allocation per TC failed = %d", 11051 hw->aq.asq_last_status); 11052 goto out; 11053 } 11054 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) 11055 vsi->info.qs_handle[i] = bw_data.qs_handles[i]; 11056 11057 /* Update Queue Pairs Mapping for currently enabled UPs */ 11058 ctxt.seid = vsi->seid; 11059 ctxt.pf_num = hw->pf_id; 11060 ctxt.vf_num = 0; 11061 ctxt.uplink_seid = vsi->uplink_seid; 11062 ctxt.info = vsi->info; 11063 i40e_get_cap(hw); 11064 ret = i40e_vsi_update_queue_mapping(vsi, &ctxt.info, tc_map); 11065 if (ret) 11066 goto out; 11067 11068 /* Update the VSI after updating the VSI queue-mapping information */ 11069 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); 11070 if (ret) { 11071 PMD_INIT_LOG(ERR, "Failed to configure TC queue mapping = %d", 11072 hw->aq.asq_last_status); 11073 goto out; 11074 } 11075 /* update the local VSI info with updated queue map */ 11076 rte_memcpy(&vsi->info.tc_mapping, &ctxt.info.tc_mapping, 11077 sizeof(vsi->info.tc_mapping)); 11078 rte_memcpy(&vsi->info.queue_mapping, 11079 &ctxt.info.queue_mapping, 11080 sizeof(vsi->info.queue_mapping)); 11081 vsi->info.mapping_flags = ctxt.info.mapping_flags; 11082 vsi->info.valid_sections = 0; 11083 11084 /* query and update current VSI BW information */ 11085 ret = i40e_vsi_get_bw_config(vsi); 11086 if (ret) { 11087 PMD_INIT_LOG(ERR, 11088 "Failed updating vsi bw info, err %s aq_err %s", 11089 i40e_stat_str(hw, ret), 11090 i40e_aq_str(hw, hw->aq.asq_last_status)); 11091 goto out; 11092 } 11093 11094 vsi->enabled_tc = tc_map; 11095 11096 out: 11097 return ret; 11098 } 11099 11100 /* 11101 * i40e_dcb_hw_configure - program the dcb setting to hw 11102 * @pf: pf the configuration is taken on 11103 * @new_cfg: new configuration 11104 * @tc_map: enabled TC bitmap 11105 * 11106 * Returns 0 on success, negative value on failure 11107 */ 11108 static enum i40e_status_code 11109 i40e_dcb_hw_configure(struct i40e_pf *pf, 11110 struct i40e_dcbx_config *new_cfg, 11111 uint8_t tc_map) 11112 { 11113 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 11114 struct i40e_dcbx_config *old_cfg = &hw->local_dcbx_config; 11115 struct i40e_vsi *main_vsi = pf->main_vsi; 11116 struct i40e_vsi_list *vsi_list; 11117 enum i40e_status_code ret; 11118 int i; 11119 uint32_t val; 11120 11121 /* Use the FW API if FW > v4.4*/ 11122 if (!(((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver >= 4)) || 11123 (hw->aq.fw_maj_ver >= 5))) { 11124 PMD_INIT_LOG(ERR, 11125 "FW < v4.4, can not use FW LLDP API to configure DCB"); 11126 return I40E_ERR_FIRMWARE_API_VERSION; 11127 } 11128 11129 /* Check if need reconfiguration */ 11130 if (!memcmp(new_cfg, old_cfg, sizeof(struct i40e_dcbx_config))) { 11131 PMD_INIT_LOG(ERR, "No Change in DCB Config required."); 11132 return I40E_SUCCESS; 11133 } 11134 11135 /* Copy the new config to the current config */ 11136 *old_cfg = *new_cfg; 11137 old_cfg->etsrec = old_cfg->etscfg; 11138 ret = i40e_set_dcb_config(hw); 11139 if (ret) { 11140 PMD_INIT_LOG(ERR, "Set DCB Config failed, err %s aq_err %s", 11141 i40e_stat_str(hw, ret), 11142 i40e_aq_str(hw, hw->aq.asq_last_status)); 11143 return ret; 11144 } 11145 /* set receive Arbiter to RR mode and ETS scheme by default */ 11146 for (i = 0; i <= I40E_PRTDCB_RETSTCC_MAX_INDEX; i++) { 11147 val = I40E_READ_REG(hw, I40E_PRTDCB_RETSTCC(i)); 11148 val &= ~(I40E_PRTDCB_RETSTCC_BWSHARE_MASK | 11149 I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK | 11150 I40E_PRTDCB_RETSTCC_ETSTC_SHIFT); 11151 val |= ((uint32_t)old_cfg->etscfg.tcbwtable[i] << 11152 I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT) & 11153 I40E_PRTDCB_RETSTCC_BWSHARE_MASK; 11154 val |= ((uint32_t)1 << I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT) & 11155 I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK; 11156 val |= ((uint32_t)1 << I40E_PRTDCB_RETSTCC_ETSTC_SHIFT) & 11157 I40E_PRTDCB_RETSTCC_ETSTC_MASK; 11158 I40E_WRITE_REG(hw, I40E_PRTDCB_RETSTCC(i), val); 11159 } 11160 /* get local mib to check whether it is configured correctly */ 11161 /* IEEE mode */ 11162 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE; 11163 /* Get Local DCB Config */ 11164 i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0, 11165 &hw->local_dcbx_config); 11166 11167 /* if Veb is created, need to update TC of it at first */ 11168 if (main_vsi->veb) { 11169 ret = i40e_config_switch_comp_tc(main_vsi->veb, tc_map); 11170 if (ret) 11171 PMD_INIT_LOG(WARNING, 11172 "Failed configuring TC for VEB seid=%d", 11173 main_vsi->veb->seid); 11174 } 11175 /* Update each VSI */ 11176 i40e_vsi_config_tc(main_vsi, tc_map); 11177 if (main_vsi->veb) { 11178 TAILQ_FOREACH(vsi_list, &main_vsi->veb->head, list) { 11179 /* Beside main VSI and VMDQ VSIs, only enable default 11180 * TC for other VSIs 11181 */ 11182 if (vsi_list->vsi->type == I40E_VSI_VMDQ2) 11183 ret = i40e_vsi_config_tc(vsi_list->vsi, 11184 tc_map); 11185 else 11186 ret = i40e_vsi_config_tc(vsi_list->vsi, 11187 I40E_DEFAULT_TCMAP); 11188 if (ret) 11189 PMD_INIT_LOG(WARNING, 11190 "Failed configuring TC for VSI seid=%d", 11191 vsi_list->vsi->seid); 11192 /* continue */ 11193 } 11194 } 11195 return I40E_SUCCESS; 11196 } 11197 11198 /* 11199 * i40e_dcb_init_configure - initial dcb config 11200 * @dev: device being configured 11201 * @sw_dcb: indicate whether dcb is sw configured or hw offload 11202 * 11203 * Returns 0 on success, negative value on failure 11204 */ 11205 int 11206 i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb) 11207 { 11208 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11209 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11210 int i, ret = 0; 11211 11212 if ((pf->flags & I40E_FLAG_DCB) == 0) { 11213 PMD_INIT_LOG(ERR, "HW doesn't support DCB"); 11214 return -ENOTSUP; 11215 } 11216 11217 /* DCB initialization: 11218 * Update DCB configuration from the Firmware and configure 11219 * LLDP MIB change event. 11220 */ 11221 if (sw_dcb == TRUE) { 11222 /* Stopping lldp is necessary for DPDK, but it will cause 11223 * DCB init failed. For i40e_init_dcb(), the prerequisite 11224 * for successful initialization of DCB is that LLDP is 11225 * enabled. So it is needed to start lldp before DCB init 11226 * and stop it after initialization. 11227 */ 11228 ret = i40e_aq_start_lldp(hw, true, NULL); 11229 if (ret != I40E_SUCCESS) 11230 PMD_INIT_LOG(DEBUG, "Failed to start lldp"); 11231 11232 ret = i40e_init_dcb(hw, true); 11233 /* If lldp agent is stopped, the return value from 11234 * i40e_init_dcb we expect is failure with I40E_AQ_RC_EPERM 11235 * adminq status. Otherwise, it should return success. 11236 */ 11237 if ((ret == I40E_SUCCESS) || (ret != I40E_SUCCESS && 11238 hw->aq.asq_last_status == I40E_AQ_RC_EPERM)) { 11239 memset(&hw->local_dcbx_config, 0, 11240 sizeof(struct i40e_dcbx_config)); 11241 /* set dcb default configuration */ 11242 hw->local_dcbx_config.etscfg.willing = 0; 11243 hw->local_dcbx_config.etscfg.maxtcs = 0; 11244 hw->local_dcbx_config.etscfg.tcbwtable[0] = 100; 11245 hw->local_dcbx_config.etscfg.tsatable[0] = 11246 I40E_IEEE_TSA_ETS; 11247 /* all UPs mapping to TC0 */ 11248 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) 11249 hw->local_dcbx_config.etscfg.prioritytable[i] = 0; 11250 hw->local_dcbx_config.etsrec = 11251 hw->local_dcbx_config.etscfg; 11252 hw->local_dcbx_config.pfc.willing = 0; 11253 hw->local_dcbx_config.pfc.pfccap = 11254 I40E_MAX_TRAFFIC_CLASS; 11255 /* FW needs one App to configure HW */ 11256 hw->local_dcbx_config.numapps = 1; 11257 hw->local_dcbx_config.app[0].selector = 11258 I40E_APP_SEL_ETHTYPE; 11259 hw->local_dcbx_config.app[0].priority = 3; 11260 hw->local_dcbx_config.app[0].protocolid = 11261 I40E_APP_PROTOID_FCOE; 11262 ret = i40e_set_dcb_config(hw); 11263 if (ret) { 11264 PMD_INIT_LOG(ERR, 11265 "default dcb config fails. err = %d, aq_err = %d.", 11266 ret, hw->aq.asq_last_status); 11267 return -ENOSYS; 11268 } 11269 } else { 11270 PMD_INIT_LOG(ERR, 11271 "DCB initialization in FW fails, err = %d, aq_err = %d.", 11272 ret, hw->aq.asq_last_status); 11273 return -ENOTSUP; 11274 } 11275 11276 if (i40e_need_stop_lldp(dev)) { 11277 ret = i40e_aq_stop_lldp(hw, true, true, NULL); 11278 if (ret != I40E_SUCCESS) 11279 PMD_INIT_LOG(DEBUG, "Failed to stop lldp"); 11280 } 11281 } else { 11282 ret = i40e_aq_start_lldp(hw, true, NULL); 11283 if (ret != I40E_SUCCESS) 11284 PMD_INIT_LOG(DEBUG, "Failed to start lldp"); 11285 11286 ret = i40e_init_dcb(hw, true); 11287 if (!ret) { 11288 if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) { 11289 PMD_INIT_LOG(ERR, 11290 "HW doesn't support DCBX offload."); 11291 return -ENOTSUP; 11292 } 11293 } else { 11294 PMD_INIT_LOG(ERR, 11295 "DCBX configuration failed, err = %d, aq_err = %d.", 11296 ret, hw->aq.asq_last_status); 11297 return -ENOTSUP; 11298 } 11299 } 11300 return 0; 11301 } 11302 11303 /* 11304 * i40e_dcb_setup - setup dcb related config 11305 * @dev: device being configured 11306 * 11307 * Returns 0 on success, negative value on failure 11308 */ 11309 static int 11310 i40e_dcb_setup(struct rte_eth_dev *dev) 11311 { 11312 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11313 struct i40e_dcbx_config dcb_cfg; 11314 uint8_t tc_map = 0; 11315 int ret = 0; 11316 11317 if ((pf->flags & I40E_FLAG_DCB) == 0) { 11318 PMD_INIT_LOG(ERR, "HW doesn't support DCB"); 11319 return -ENOTSUP; 11320 } 11321 11322 if (pf->vf_num != 0) 11323 PMD_INIT_LOG(DEBUG, " DCB only works on pf and vmdq vsis."); 11324 11325 ret = i40e_parse_dcb_configure(dev, &dcb_cfg, &tc_map); 11326 if (ret) { 11327 PMD_INIT_LOG(ERR, "invalid dcb config"); 11328 return -EINVAL; 11329 } 11330 ret = i40e_dcb_hw_configure(pf, &dcb_cfg, tc_map); 11331 if (ret) { 11332 PMD_INIT_LOG(ERR, "dcb sw configure fails"); 11333 return -ENOSYS; 11334 } 11335 11336 return 0; 11337 } 11338 11339 static int 11340 i40e_dev_get_dcb_info(struct rte_eth_dev *dev, 11341 struct rte_eth_dcb_info *dcb_info) 11342 { 11343 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11344 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11345 struct i40e_vsi *vsi = pf->main_vsi; 11346 struct i40e_dcbx_config *dcb_cfg = &hw->local_dcbx_config; 11347 uint16_t bsf, tc_mapping; 11348 int i, j = 0; 11349 11350 if (dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_DCB_FLAG) 11351 dcb_info->nb_tcs = rte_bsf32(vsi->enabled_tc + 1); 11352 else 11353 dcb_info->nb_tcs = 1; 11354 for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) 11355 dcb_info->prio_tc[i] = dcb_cfg->etscfg.prioritytable[i]; 11356 for (i = 0; i < dcb_info->nb_tcs; i++) 11357 dcb_info->tc_bws[i] = dcb_cfg->etscfg.tcbwtable[i]; 11358 11359 /* get queue mapping if vmdq is disabled */ 11360 if (!pf->nb_cfg_vmdq_vsi) { 11361 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 11362 if (!(vsi->enabled_tc & (1 << i))) 11363 continue; 11364 tc_mapping = rte_le_to_cpu_16(vsi->info.tc_mapping[i]); 11365 dcb_info->tc_queue.tc_rxq[j][i].base = 11366 (tc_mapping & I40E_AQ_VSI_TC_QUE_OFFSET_MASK) >> 11367 I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT; 11368 dcb_info->tc_queue.tc_txq[j][i].base = 11369 dcb_info->tc_queue.tc_rxq[j][i].base; 11370 bsf = (tc_mapping & I40E_AQ_VSI_TC_QUE_NUMBER_MASK) >> 11371 I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT; 11372 dcb_info->tc_queue.tc_rxq[j][i].nb_queue = 1 << bsf; 11373 dcb_info->tc_queue.tc_txq[j][i].nb_queue = 11374 dcb_info->tc_queue.tc_rxq[j][i].nb_queue; 11375 } 11376 return 0; 11377 } 11378 11379 /* get queue mapping if vmdq is enabled */ 11380 do { 11381 vsi = pf->vmdq[j].vsi; 11382 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { 11383 if (!(vsi->enabled_tc & (1 << i))) 11384 continue; 11385 tc_mapping = rte_le_to_cpu_16(vsi->info.tc_mapping[i]); 11386 dcb_info->tc_queue.tc_rxq[j][i].base = 11387 (tc_mapping & I40E_AQ_VSI_TC_QUE_OFFSET_MASK) >> 11388 I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT; 11389 dcb_info->tc_queue.tc_txq[j][i].base = 11390 dcb_info->tc_queue.tc_rxq[j][i].base; 11391 bsf = (tc_mapping & I40E_AQ_VSI_TC_QUE_NUMBER_MASK) >> 11392 I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT; 11393 dcb_info->tc_queue.tc_rxq[j][i].nb_queue = 1 << bsf; 11394 dcb_info->tc_queue.tc_txq[j][i].nb_queue = 11395 dcb_info->tc_queue.tc_rxq[j][i].nb_queue; 11396 } 11397 j++; 11398 } while (j < RTE_MIN(pf->nb_cfg_vmdq_vsi, ETH_MAX_VMDQ_POOL)); 11399 return 0; 11400 } 11401 11402 static int 11403 i40e_dev_rx_queue_intr_enable(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_INTENA_MASK | 11414 I40E_PFINT_DYN_CTL0_CLEARPBA_MASK | 11415 I40E_PFINT_DYN_CTL0_ITR_INDX_MASK); 11416 else 11417 I40E_WRITE_REG(hw, 11418 I40E_PFINT_DYN_CTLN(msix_intr - 11419 I40E_RX_VEC_START), 11420 I40E_PFINT_DYN_CTLN_INTENA_MASK | 11421 I40E_PFINT_DYN_CTLN_CLEARPBA_MASK | 11422 I40E_PFINT_DYN_CTLN_ITR_INDX_MASK); 11423 11424 I40E_WRITE_FLUSH(hw); 11425 rte_intr_ack(&pci_dev->intr_handle); 11426 11427 return 0; 11428 } 11429 11430 static int 11431 i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id) 11432 { 11433 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); 11434 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; 11435 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11436 uint16_t msix_intr; 11437 11438 msix_intr = intr_handle->intr_vec[queue_id]; 11439 if (msix_intr == I40E_MISC_VEC_ID) 11440 I40E_WRITE_REG(hw, I40E_PFINT_DYN_CTL0, 11441 I40E_PFINT_DYN_CTL0_ITR_INDX_MASK); 11442 else 11443 I40E_WRITE_REG(hw, 11444 I40E_PFINT_DYN_CTLN(msix_intr - 11445 I40E_RX_VEC_START), 11446 I40E_PFINT_DYN_CTLN_ITR_INDX_MASK); 11447 I40E_WRITE_FLUSH(hw); 11448 11449 return 0; 11450 } 11451 11452 /** 11453 * This function is used to check if the register is valid. 11454 * Below is the valid registers list for X722 only: 11455 * 0x2b800--0x2bb00 11456 * 0x38700--0x38a00 11457 * 0x3d800--0x3db00 11458 * 0x208e00--0x209000 11459 * 0x20be00--0x20c000 11460 * 0x263c00--0x264000 11461 * 0x265c00--0x266000 11462 */ 11463 static inline int i40e_valid_regs(enum i40e_mac_type type, uint32_t reg_offset) 11464 { 11465 if ((type != I40E_MAC_X722) && 11466 ((reg_offset >= 0x2b800 && reg_offset <= 0x2bb00) || 11467 (reg_offset >= 0x38700 && reg_offset <= 0x38a00) || 11468 (reg_offset >= 0x3d800 && reg_offset <= 0x3db00) || 11469 (reg_offset >= 0x208e00 && reg_offset <= 0x209000) || 11470 (reg_offset >= 0x20be00 && reg_offset <= 0x20c000) || 11471 (reg_offset >= 0x263c00 && reg_offset <= 0x264000) || 11472 (reg_offset >= 0x265c00 && reg_offset <= 0x266000))) 11473 return 0; 11474 else 11475 return 1; 11476 } 11477 11478 static int i40e_get_regs(struct rte_eth_dev *dev, 11479 struct rte_dev_reg_info *regs) 11480 { 11481 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11482 uint32_t *ptr_data = regs->data; 11483 uint32_t reg_idx, arr_idx, arr_idx2, reg_offset; 11484 const struct i40e_reg_info *reg_info; 11485 11486 if (ptr_data == NULL) { 11487 regs->length = I40E_GLGEN_STAT_CLEAR + 4; 11488 regs->width = sizeof(uint32_t); 11489 return 0; 11490 } 11491 11492 /* The first few registers have to be read using AQ operations */ 11493 reg_idx = 0; 11494 while (i40e_regs_adminq[reg_idx].name) { 11495 reg_info = &i40e_regs_adminq[reg_idx++]; 11496 for (arr_idx = 0; arr_idx <= reg_info->count1; arr_idx++) 11497 for (arr_idx2 = 0; 11498 arr_idx2 <= reg_info->count2; 11499 arr_idx2++) { 11500 reg_offset = arr_idx * reg_info->stride1 + 11501 arr_idx2 * reg_info->stride2; 11502 reg_offset += reg_info->base_addr; 11503 ptr_data[reg_offset >> 2] = 11504 i40e_read_rx_ctl(hw, reg_offset); 11505 } 11506 } 11507 11508 /* The remaining registers can be read using primitives */ 11509 reg_idx = 0; 11510 while (i40e_regs_others[reg_idx].name) { 11511 reg_info = &i40e_regs_others[reg_idx++]; 11512 for (arr_idx = 0; arr_idx <= reg_info->count1; arr_idx++) 11513 for (arr_idx2 = 0; 11514 arr_idx2 <= reg_info->count2; 11515 arr_idx2++) { 11516 reg_offset = arr_idx * reg_info->stride1 + 11517 arr_idx2 * reg_info->stride2; 11518 reg_offset += reg_info->base_addr; 11519 if (!i40e_valid_regs(hw->mac.type, reg_offset)) 11520 ptr_data[reg_offset >> 2] = 0; 11521 else 11522 ptr_data[reg_offset >> 2] = 11523 I40E_READ_REG(hw, reg_offset); 11524 } 11525 } 11526 11527 return 0; 11528 } 11529 11530 static int i40e_get_eeprom_length(struct rte_eth_dev *dev) 11531 { 11532 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11533 11534 /* Convert word count to byte count */ 11535 return hw->nvm.sr_size << 1; 11536 } 11537 11538 static int i40e_get_eeprom(struct rte_eth_dev *dev, 11539 struct rte_dev_eeprom_info *eeprom) 11540 { 11541 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11542 uint16_t *data = eeprom->data; 11543 uint16_t offset, length, cnt_words; 11544 int ret_code; 11545 11546 offset = eeprom->offset >> 1; 11547 length = eeprom->length >> 1; 11548 cnt_words = length; 11549 11550 if (offset > hw->nvm.sr_size || 11551 offset + length > hw->nvm.sr_size) { 11552 PMD_DRV_LOG(ERR, "Requested EEPROM bytes out of range."); 11553 return -EINVAL; 11554 } 11555 11556 eeprom->magic = hw->vendor_id | (hw->device_id << 16); 11557 11558 ret_code = i40e_read_nvm_buffer(hw, offset, &cnt_words, data); 11559 if (ret_code != I40E_SUCCESS || cnt_words != length) { 11560 PMD_DRV_LOG(ERR, "EEPROM read failed."); 11561 return -EIO; 11562 } 11563 11564 return 0; 11565 } 11566 11567 static int i40e_get_module_info(struct rte_eth_dev *dev, 11568 struct rte_eth_dev_module_info *modinfo) 11569 { 11570 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11571 uint32_t sff8472_comp = 0; 11572 uint32_t sff8472_swap = 0; 11573 uint32_t sff8636_rev = 0; 11574 i40e_status status; 11575 uint32_t type = 0; 11576 11577 /* Check if firmware supports reading module EEPROM. */ 11578 if (!(hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE)) { 11579 PMD_DRV_LOG(ERR, 11580 "Module EEPROM memory read not supported. " 11581 "Please update the NVM image.\n"); 11582 return -EINVAL; 11583 } 11584 11585 status = i40e_update_link_info(hw); 11586 if (status) 11587 return -EIO; 11588 11589 if (hw->phy.link_info.phy_type == I40E_PHY_TYPE_EMPTY) { 11590 PMD_DRV_LOG(ERR, 11591 "Cannot read module EEPROM memory. " 11592 "No module connected.\n"); 11593 return -EINVAL; 11594 } 11595 11596 type = hw->phy.link_info.module_type[0]; 11597 11598 switch (type) { 11599 case I40E_MODULE_TYPE_SFP: 11600 status = i40e_aq_get_phy_register(hw, 11601 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, 11602 I40E_I2C_EEPROM_DEV_ADDR, 1, 11603 I40E_MODULE_SFF_8472_COMP, 11604 &sff8472_comp, NULL); 11605 if (status) 11606 return -EIO; 11607 11608 status = i40e_aq_get_phy_register(hw, 11609 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, 11610 I40E_I2C_EEPROM_DEV_ADDR, 1, 11611 I40E_MODULE_SFF_8472_SWAP, 11612 &sff8472_swap, NULL); 11613 if (status) 11614 return -EIO; 11615 11616 /* Check if the module requires address swap to access 11617 * the other EEPROM memory page. 11618 */ 11619 if (sff8472_swap & I40E_MODULE_SFF_ADDR_MODE) { 11620 PMD_DRV_LOG(WARNING, 11621 "Module address swap to access " 11622 "page 0xA2 is not supported.\n"); 11623 modinfo->type = RTE_ETH_MODULE_SFF_8079; 11624 modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN; 11625 } else if (sff8472_comp == 0x00) { 11626 /* Module is not SFF-8472 compliant */ 11627 modinfo->type = RTE_ETH_MODULE_SFF_8079; 11628 modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN; 11629 } else { 11630 modinfo->type = RTE_ETH_MODULE_SFF_8472; 11631 modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN; 11632 } 11633 break; 11634 case I40E_MODULE_TYPE_QSFP_PLUS: 11635 /* Read from memory page 0. */ 11636 status = i40e_aq_get_phy_register(hw, 11637 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, 11638 0, 1, 11639 I40E_MODULE_REVISION_ADDR, 11640 &sff8636_rev, NULL); 11641 if (status) 11642 return -EIO; 11643 /* Determine revision compliance byte */ 11644 if (sff8636_rev > 0x02) { 11645 /* Module is SFF-8636 compliant */ 11646 modinfo->type = RTE_ETH_MODULE_SFF_8636; 11647 modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN; 11648 } else { 11649 modinfo->type = RTE_ETH_MODULE_SFF_8436; 11650 modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN; 11651 } 11652 break; 11653 case I40E_MODULE_TYPE_QSFP28: 11654 modinfo->type = RTE_ETH_MODULE_SFF_8636; 11655 modinfo->eeprom_len = I40E_MODULE_QSFP_MAX_LEN; 11656 break; 11657 default: 11658 PMD_DRV_LOG(ERR, "Module type unrecognized\n"); 11659 return -EINVAL; 11660 } 11661 return 0; 11662 } 11663 11664 static int i40e_get_module_eeprom(struct rte_eth_dev *dev, 11665 struct rte_dev_eeprom_info *info) 11666 { 11667 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11668 bool is_sfp = false; 11669 i40e_status status; 11670 uint8_t *data; 11671 uint32_t value = 0; 11672 uint32_t i; 11673 11674 if (!info || !info->length || !info->data) 11675 return -EINVAL; 11676 11677 if (hw->phy.link_info.module_type[0] == I40E_MODULE_TYPE_SFP) 11678 is_sfp = true; 11679 11680 data = info->data; 11681 for (i = 0; i < info->length; i++) { 11682 u32 offset = i + info->offset; 11683 u32 addr = is_sfp ? I40E_I2C_EEPROM_DEV_ADDR : 0; 11684 11685 /* Check if we need to access the other memory page */ 11686 if (is_sfp) { 11687 if (offset >= RTE_ETH_MODULE_SFF_8079_LEN) { 11688 offset -= RTE_ETH_MODULE_SFF_8079_LEN; 11689 addr = I40E_I2C_EEPROM_DEV_ADDR2; 11690 } 11691 } else { 11692 while (offset >= RTE_ETH_MODULE_SFF_8436_LEN) { 11693 /* Compute memory page number and offset. */ 11694 offset -= RTE_ETH_MODULE_SFF_8436_LEN / 2; 11695 addr++; 11696 } 11697 } 11698 status = i40e_aq_get_phy_register(hw, 11699 I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, 11700 addr, 1, offset, &value, NULL); 11701 if (status) 11702 return -EIO; 11703 data[i] = (uint8_t)value; 11704 } 11705 return 0; 11706 } 11707 11708 static int i40e_set_default_mac_addr(struct rte_eth_dev *dev, 11709 struct rte_ether_addr *mac_addr) 11710 { 11711 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); 11712 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11713 struct i40e_vsi *vsi = pf->main_vsi; 11714 struct i40e_mac_filter_info mac_filter; 11715 struct i40e_mac_filter *f; 11716 int ret; 11717 11718 if (!rte_is_valid_assigned_ether_addr(mac_addr)) { 11719 PMD_DRV_LOG(ERR, "Tried to set invalid MAC address."); 11720 return -EINVAL; 11721 } 11722 11723 TAILQ_FOREACH(f, &vsi->mac_list, next) { 11724 if (rte_is_same_ether_addr(&pf->dev_addr, 11725 &f->mac_info.mac_addr)) 11726 break; 11727 } 11728 11729 if (f == NULL) { 11730 PMD_DRV_LOG(ERR, "Failed to find filter for default mac"); 11731 return -EIO; 11732 } 11733 11734 mac_filter = f->mac_info; 11735 ret = i40e_vsi_delete_mac(vsi, &mac_filter.mac_addr); 11736 if (ret != I40E_SUCCESS) { 11737 PMD_DRV_LOG(ERR, "Failed to delete mac filter"); 11738 return -EIO; 11739 } 11740 memcpy(&mac_filter.mac_addr, mac_addr, ETH_ADDR_LEN); 11741 ret = i40e_vsi_add_mac(vsi, &mac_filter); 11742 if (ret != I40E_SUCCESS) { 11743 PMD_DRV_LOG(ERR, "Failed to add mac filter"); 11744 return -EIO; 11745 } 11746 memcpy(&pf->dev_addr, mac_addr, ETH_ADDR_LEN); 11747 11748 ret = i40e_aq_mac_address_write(hw, I40E_AQC_WRITE_TYPE_LAA_WOL, 11749 mac_addr->addr_bytes, NULL); 11750 if (ret != I40E_SUCCESS) { 11751 PMD_DRV_LOG(ERR, "Failed to change mac"); 11752 return -EIO; 11753 } 11754 11755 return 0; 11756 } 11757 11758 static int 11759 i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 11760 { 11761 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11762 struct rte_eth_dev_data *dev_data = pf->dev_data; 11763 uint32_t frame_size = mtu + I40E_ETH_OVERHEAD; 11764 int ret = 0; 11765 11766 /* check if mtu is within the allowed range */ 11767 if (mtu < RTE_ETHER_MIN_MTU || frame_size > I40E_FRAME_SIZE_MAX) 11768 return -EINVAL; 11769 11770 /* mtu setting is forbidden if port is start */ 11771 if (dev_data->dev_started) { 11772 PMD_DRV_LOG(ERR, "port %d must be stopped before configuration", 11773 dev_data->port_id); 11774 return -EBUSY; 11775 } 11776 11777 if (frame_size > RTE_ETHER_MAX_LEN) 11778 dev_data->dev_conf.rxmode.offloads |= 11779 DEV_RX_OFFLOAD_JUMBO_FRAME; 11780 else 11781 dev_data->dev_conf.rxmode.offloads &= 11782 ~DEV_RX_OFFLOAD_JUMBO_FRAME; 11783 11784 dev_data->dev_conf.rxmode.max_rx_pkt_len = frame_size; 11785 11786 return ret; 11787 } 11788 11789 /* Restore ethertype filter */ 11790 static void 11791 i40e_ethertype_filter_restore(struct i40e_pf *pf) 11792 { 11793 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 11794 struct i40e_ethertype_filter_list 11795 *ethertype_list = &pf->ethertype.ethertype_list; 11796 struct i40e_ethertype_filter *f; 11797 struct i40e_control_filter_stats stats; 11798 uint16_t flags; 11799 11800 TAILQ_FOREACH(f, ethertype_list, rules) { 11801 flags = 0; 11802 if (!(f->flags & RTE_ETHTYPE_FLAGS_MAC)) 11803 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC; 11804 if (f->flags & RTE_ETHTYPE_FLAGS_DROP) 11805 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP; 11806 flags |= I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE; 11807 11808 memset(&stats, 0, sizeof(stats)); 11809 i40e_aq_add_rem_control_packet_filter(hw, 11810 f->input.mac_addr.addr_bytes, 11811 f->input.ether_type, 11812 flags, pf->main_vsi->seid, 11813 f->queue, 1, &stats, NULL); 11814 } 11815 PMD_DRV_LOG(INFO, "Ethertype filter:" 11816 " mac_etype_used = %u, etype_used = %u," 11817 " mac_etype_free = %u, etype_free = %u", 11818 stats.mac_etype_used, stats.etype_used, 11819 stats.mac_etype_free, stats.etype_free); 11820 } 11821 11822 /* Restore tunnel filter */ 11823 static void 11824 i40e_tunnel_filter_restore(struct i40e_pf *pf) 11825 { 11826 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 11827 struct i40e_vsi *vsi; 11828 struct i40e_pf_vf *vf; 11829 struct i40e_tunnel_filter_list 11830 *tunnel_list = &pf->tunnel.tunnel_list; 11831 struct i40e_tunnel_filter *f; 11832 struct i40e_aqc_cloud_filters_element_bb cld_filter; 11833 bool big_buffer = 0; 11834 11835 TAILQ_FOREACH(f, tunnel_list, rules) { 11836 if (!f->is_to_vf) 11837 vsi = pf->main_vsi; 11838 else { 11839 vf = &pf->vfs[f->vf_id]; 11840 vsi = vf->vsi; 11841 } 11842 memset(&cld_filter, 0, sizeof(cld_filter)); 11843 rte_ether_addr_copy((struct rte_ether_addr *) 11844 &f->input.outer_mac, 11845 (struct rte_ether_addr *)&cld_filter.element.outer_mac); 11846 rte_ether_addr_copy((struct rte_ether_addr *) 11847 &f->input.inner_mac, 11848 (struct rte_ether_addr *)&cld_filter.element.inner_mac); 11849 cld_filter.element.inner_vlan = f->input.inner_vlan; 11850 cld_filter.element.flags = f->input.flags; 11851 cld_filter.element.tenant_id = f->input.tenant_id; 11852 cld_filter.element.queue_number = f->queue; 11853 rte_memcpy(cld_filter.general_fields, 11854 f->input.general_fields, 11855 sizeof(f->input.general_fields)); 11856 11857 if (((f->input.flags & 11858 I40E_AQC_ADD_CLOUD_FILTER_0X11) == 11859 I40E_AQC_ADD_CLOUD_FILTER_0X11) || 11860 ((f->input.flags & 11861 I40E_AQC_ADD_CLOUD_FILTER_0X12) == 11862 I40E_AQC_ADD_CLOUD_FILTER_0X12) || 11863 ((f->input.flags & 11864 I40E_AQC_ADD_CLOUD_FILTER_0X10) == 11865 I40E_AQC_ADD_CLOUD_FILTER_0X10)) 11866 big_buffer = 1; 11867 11868 if (big_buffer) 11869 i40e_aq_add_cloud_filters_bb(hw, 11870 vsi->seid, &cld_filter, 1); 11871 else 11872 i40e_aq_add_cloud_filters(hw, vsi->seid, 11873 &cld_filter.element, 1); 11874 } 11875 } 11876 11877 /* Restore RSS filter */ 11878 static inline void 11879 i40e_rss_filter_restore(struct i40e_pf *pf) 11880 { 11881 struct i40e_rss_conf_list *list = &pf->rss_config_list; 11882 struct i40e_rss_filter *filter; 11883 11884 TAILQ_FOREACH(filter, list, next) { 11885 i40e_config_rss_filter(pf, &filter->rss_filter_info, TRUE); 11886 } 11887 } 11888 11889 static void 11890 i40e_filter_restore(struct i40e_pf *pf) 11891 { 11892 i40e_ethertype_filter_restore(pf); 11893 i40e_tunnel_filter_restore(pf); 11894 i40e_fdir_filter_restore(pf); 11895 i40e_rss_filter_restore(pf); 11896 } 11897 11898 bool 11899 is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv) 11900 { 11901 if (strcmp(dev->device->driver->name, drv->driver.name)) 11902 return false; 11903 11904 return true; 11905 } 11906 11907 bool 11908 is_i40e_supported(struct rte_eth_dev *dev) 11909 { 11910 return is_device_supported(dev, &rte_i40e_pmd); 11911 } 11912 11913 struct i40e_customized_pctype* 11914 i40e_find_customized_pctype(struct i40e_pf *pf, uint8_t index) 11915 { 11916 int i; 11917 11918 for (i = 0; i < I40E_CUSTOMIZED_MAX; i++) { 11919 if (pf->customized_pctype[i].index == index) 11920 return &pf->customized_pctype[i]; 11921 } 11922 return NULL; 11923 } 11924 11925 static int 11926 i40e_update_customized_pctype(struct rte_eth_dev *dev, uint8_t *pkg, 11927 uint32_t pkg_size, uint32_t proto_num, 11928 struct rte_pmd_i40e_proto_info *proto, 11929 enum rte_pmd_i40e_package_op op) 11930 { 11931 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 11932 uint32_t pctype_num; 11933 struct rte_pmd_i40e_ptype_info *pctype; 11934 uint32_t buff_size; 11935 struct i40e_customized_pctype *new_pctype = NULL; 11936 uint8_t proto_id; 11937 uint8_t pctype_value; 11938 char name[64]; 11939 uint32_t i, j, n; 11940 int ret; 11941 11942 if (op != RTE_PMD_I40E_PKG_OP_WR_ADD && 11943 op != RTE_PMD_I40E_PKG_OP_WR_DEL) { 11944 PMD_DRV_LOG(ERR, "Unsupported operation."); 11945 return -1; 11946 } 11947 11948 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 11949 (uint8_t *)&pctype_num, sizeof(pctype_num), 11950 RTE_PMD_I40E_PKG_INFO_PCTYPE_NUM); 11951 if (ret) { 11952 PMD_DRV_LOG(ERR, "Failed to get pctype number"); 11953 return -1; 11954 } 11955 if (!pctype_num) { 11956 PMD_DRV_LOG(INFO, "No new pctype added"); 11957 return -1; 11958 } 11959 11960 buff_size = pctype_num * sizeof(struct rte_pmd_i40e_proto_info); 11961 pctype = rte_zmalloc("new_pctype", buff_size, 0); 11962 if (!pctype) { 11963 PMD_DRV_LOG(ERR, "Failed to allocate memory"); 11964 return -1; 11965 } 11966 /* get information about new pctype list */ 11967 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 11968 (uint8_t *)pctype, buff_size, 11969 RTE_PMD_I40E_PKG_INFO_PCTYPE_LIST); 11970 if (ret) { 11971 PMD_DRV_LOG(ERR, "Failed to get pctype list"); 11972 rte_free(pctype); 11973 return -1; 11974 } 11975 11976 /* Update customized pctype. */ 11977 for (i = 0; i < pctype_num; i++) { 11978 pctype_value = pctype[i].ptype_id; 11979 memset(name, 0, sizeof(name)); 11980 for (j = 0; j < RTE_PMD_I40E_PROTO_NUM; j++) { 11981 proto_id = pctype[i].protocols[j]; 11982 if (proto_id == RTE_PMD_I40E_PROTO_UNUSED) 11983 continue; 11984 for (n = 0; n < proto_num; n++) { 11985 if (proto[n].proto_id != proto_id) 11986 continue; 11987 strlcat(name, proto[n].name, sizeof(name)); 11988 strlcat(name, "_", sizeof(name)); 11989 break; 11990 } 11991 } 11992 name[strlen(name) - 1] = '\0'; 11993 PMD_DRV_LOG(INFO, "name = %s\n", name); 11994 if (!strcmp(name, "GTPC")) 11995 new_pctype = 11996 i40e_find_customized_pctype(pf, 11997 I40E_CUSTOMIZED_GTPC); 11998 else if (!strcmp(name, "GTPU_IPV4")) 11999 new_pctype = 12000 i40e_find_customized_pctype(pf, 12001 I40E_CUSTOMIZED_GTPU_IPV4); 12002 else if (!strcmp(name, "GTPU_IPV6")) 12003 new_pctype = 12004 i40e_find_customized_pctype(pf, 12005 I40E_CUSTOMIZED_GTPU_IPV6); 12006 else if (!strcmp(name, "GTPU")) 12007 new_pctype = 12008 i40e_find_customized_pctype(pf, 12009 I40E_CUSTOMIZED_GTPU); 12010 else if (!strcmp(name, "IPV4_L2TPV3")) 12011 new_pctype = 12012 i40e_find_customized_pctype(pf, 12013 I40E_CUSTOMIZED_IPV4_L2TPV3); 12014 else if (!strcmp(name, "IPV6_L2TPV3")) 12015 new_pctype = 12016 i40e_find_customized_pctype(pf, 12017 I40E_CUSTOMIZED_IPV6_L2TPV3); 12018 else if (!strcmp(name, "IPV4_ESP")) 12019 new_pctype = 12020 i40e_find_customized_pctype(pf, 12021 I40E_CUSTOMIZED_ESP_IPV4); 12022 else if (!strcmp(name, "IPV6_ESP")) 12023 new_pctype = 12024 i40e_find_customized_pctype(pf, 12025 I40E_CUSTOMIZED_ESP_IPV6); 12026 else if (!strcmp(name, "IPV4_UDP_ESP")) 12027 new_pctype = 12028 i40e_find_customized_pctype(pf, 12029 I40E_CUSTOMIZED_ESP_IPV4_UDP); 12030 else if (!strcmp(name, "IPV6_UDP_ESP")) 12031 new_pctype = 12032 i40e_find_customized_pctype(pf, 12033 I40E_CUSTOMIZED_ESP_IPV6_UDP); 12034 else if (!strcmp(name, "IPV4_AH")) 12035 new_pctype = 12036 i40e_find_customized_pctype(pf, 12037 I40E_CUSTOMIZED_AH_IPV4); 12038 else if (!strcmp(name, "IPV6_AH")) 12039 new_pctype = 12040 i40e_find_customized_pctype(pf, 12041 I40E_CUSTOMIZED_AH_IPV6); 12042 if (new_pctype) { 12043 if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) { 12044 new_pctype->pctype = pctype_value; 12045 new_pctype->valid = true; 12046 } else { 12047 new_pctype->pctype = I40E_FILTER_PCTYPE_INVALID; 12048 new_pctype->valid = false; 12049 } 12050 } 12051 } 12052 12053 rte_free(pctype); 12054 return 0; 12055 } 12056 12057 static int 12058 i40e_update_customized_ptype(struct rte_eth_dev *dev, uint8_t *pkg, 12059 uint32_t pkg_size, uint32_t proto_num, 12060 struct rte_pmd_i40e_proto_info *proto, 12061 enum rte_pmd_i40e_package_op op) 12062 { 12063 struct rte_pmd_i40e_ptype_mapping *ptype_mapping; 12064 uint16_t port_id = dev->data->port_id; 12065 uint32_t ptype_num; 12066 struct rte_pmd_i40e_ptype_info *ptype; 12067 uint32_t buff_size; 12068 uint8_t proto_id; 12069 char name[RTE_PMD_I40E_DDP_NAME_SIZE]; 12070 uint32_t i, j, n; 12071 bool in_tunnel; 12072 int ret; 12073 12074 if (op != RTE_PMD_I40E_PKG_OP_WR_ADD && 12075 op != RTE_PMD_I40E_PKG_OP_WR_DEL) { 12076 PMD_DRV_LOG(ERR, "Unsupported operation."); 12077 return -1; 12078 } 12079 12080 if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) { 12081 rte_pmd_i40e_ptype_mapping_reset(port_id); 12082 return 0; 12083 } 12084 12085 /* get information about new ptype num */ 12086 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 12087 (uint8_t *)&ptype_num, sizeof(ptype_num), 12088 RTE_PMD_I40E_PKG_INFO_PTYPE_NUM); 12089 if (ret) { 12090 PMD_DRV_LOG(ERR, "Failed to get ptype number"); 12091 return ret; 12092 } 12093 if (!ptype_num) { 12094 PMD_DRV_LOG(INFO, "No new ptype added"); 12095 return -1; 12096 } 12097 12098 buff_size = ptype_num * sizeof(struct rte_pmd_i40e_ptype_info); 12099 ptype = rte_zmalloc("new_ptype", buff_size, 0); 12100 if (!ptype) { 12101 PMD_DRV_LOG(ERR, "Failed to allocate memory"); 12102 return -1; 12103 } 12104 12105 /* get information about new ptype list */ 12106 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 12107 (uint8_t *)ptype, buff_size, 12108 RTE_PMD_I40E_PKG_INFO_PTYPE_LIST); 12109 if (ret) { 12110 PMD_DRV_LOG(ERR, "Failed to get ptype list"); 12111 rte_free(ptype); 12112 return ret; 12113 } 12114 12115 buff_size = ptype_num * sizeof(struct rte_pmd_i40e_ptype_mapping); 12116 ptype_mapping = rte_zmalloc("ptype_mapping", buff_size, 0); 12117 if (!ptype_mapping) { 12118 PMD_DRV_LOG(ERR, "Failed to allocate memory"); 12119 rte_free(ptype); 12120 return -1; 12121 } 12122 12123 /* Update ptype mapping table. */ 12124 for (i = 0; i < ptype_num; i++) { 12125 ptype_mapping[i].hw_ptype = ptype[i].ptype_id; 12126 ptype_mapping[i].sw_ptype = 0; 12127 in_tunnel = false; 12128 for (j = 0; j < RTE_PMD_I40E_PROTO_NUM; j++) { 12129 proto_id = ptype[i].protocols[j]; 12130 if (proto_id == RTE_PMD_I40E_PROTO_UNUSED) 12131 continue; 12132 for (n = 0; n < proto_num; n++) { 12133 if (proto[n].proto_id != proto_id) 12134 continue; 12135 memset(name, 0, sizeof(name)); 12136 strcpy(name, proto[n].name); 12137 PMD_DRV_LOG(INFO, "name = %s\n", name); 12138 if (!strncasecmp(name, "PPPOE", 5)) 12139 ptype_mapping[i].sw_ptype |= 12140 RTE_PTYPE_L2_ETHER_PPPOE; 12141 else if (!strncasecmp(name, "IPV4FRAG", 8) && 12142 !in_tunnel) { 12143 ptype_mapping[i].sw_ptype |= 12144 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; 12145 ptype_mapping[i].sw_ptype |= 12146 RTE_PTYPE_L4_FRAG; 12147 } else if (!strncasecmp(name, "IPV4FRAG", 8) && 12148 in_tunnel) { 12149 ptype_mapping[i].sw_ptype |= 12150 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN; 12151 ptype_mapping[i].sw_ptype |= 12152 RTE_PTYPE_INNER_L4_FRAG; 12153 } else if (!strncasecmp(name, "OIPV4", 5)) { 12154 ptype_mapping[i].sw_ptype |= 12155 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; 12156 in_tunnel = true; 12157 } else if (!strncasecmp(name, "IPV4", 4) && 12158 !in_tunnel) 12159 ptype_mapping[i].sw_ptype |= 12160 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; 12161 else if (!strncasecmp(name, "IPV4", 4) && 12162 in_tunnel) 12163 ptype_mapping[i].sw_ptype |= 12164 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN; 12165 else if (!strncasecmp(name, "IPV6FRAG", 8) && 12166 !in_tunnel) { 12167 ptype_mapping[i].sw_ptype |= 12168 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; 12169 ptype_mapping[i].sw_ptype |= 12170 RTE_PTYPE_L4_FRAG; 12171 } else if (!strncasecmp(name, "IPV6FRAG", 8) && 12172 in_tunnel) { 12173 ptype_mapping[i].sw_ptype |= 12174 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN; 12175 ptype_mapping[i].sw_ptype |= 12176 RTE_PTYPE_INNER_L4_FRAG; 12177 } else if (!strncasecmp(name, "OIPV6", 5)) { 12178 ptype_mapping[i].sw_ptype |= 12179 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; 12180 in_tunnel = true; 12181 } else if (!strncasecmp(name, "IPV6", 4) && 12182 !in_tunnel) 12183 ptype_mapping[i].sw_ptype |= 12184 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; 12185 else if (!strncasecmp(name, "IPV6", 4) && 12186 in_tunnel) 12187 ptype_mapping[i].sw_ptype |= 12188 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN; 12189 else if (!strncasecmp(name, "UDP", 3) && 12190 !in_tunnel) 12191 ptype_mapping[i].sw_ptype |= 12192 RTE_PTYPE_L4_UDP; 12193 else if (!strncasecmp(name, "UDP", 3) && 12194 in_tunnel) 12195 ptype_mapping[i].sw_ptype |= 12196 RTE_PTYPE_INNER_L4_UDP; 12197 else if (!strncasecmp(name, "TCP", 3) && 12198 !in_tunnel) 12199 ptype_mapping[i].sw_ptype |= 12200 RTE_PTYPE_L4_TCP; 12201 else if (!strncasecmp(name, "TCP", 3) && 12202 in_tunnel) 12203 ptype_mapping[i].sw_ptype |= 12204 RTE_PTYPE_INNER_L4_TCP; 12205 else if (!strncasecmp(name, "SCTP", 4) && 12206 !in_tunnel) 12207 ptype_mapping[i].sw_ptype |= 12208 RTE_PTYPE_L4_SCTP; 12209 else if (!strncasecmp(name, "SCTP", 4) && 12210 in_tunnel) 12211 ptype_mapping[i].sw_ptype |= 12212 RTE_PTYPE_INNER_L4_SCTP; 12213 else if ((!strncasecmp(name, "ICMP", 4) || 12214 !strncasecmp(name, "ICMPV6", 6)) && 12215 !in_tunnel) 12216 ptype_mapping[i].sw_ptype |= 12217 RTE_PTYPE_L4_ICMP; 12218 else if ((!strncasecmp(name, "ICMP", 4) || 12219 !strncasecmp(name, "ICMPV6", 6)) && 12220 in_tunnel) 12221 ptype_mapping[i].sw_ptype |= 12222 RTE_PTYPE_INNER_L4_ICMP; 12223 else if (!strncasecmp(name, "GTPC", 4)) { 12224 ptype_mapping[i].sw_ptype |= 12225 RTE_PTYPE_TUNNEL_GTPC; 12226 in_tunnel = true; 12227 } else if (!strncasecmp(name, "GTPU", 4)) { 12228 ptype_mapping[i].sw_ptype |= 12229 RTE_PTYPE_TUNNEL_GTPU; 12230 in_tunnel = true; 12231 } else if (!strncasecmp(name, "ESP", 3)) { 12232 ptype_mapping[i].sw_ptype |= 12233 RTE_PTYPE_TUNNEL_ESP; 12234 in_tunnel = true; 12235 } else if (!strncasecmp(name, "GRENAT", 6)) { 12236 ptype_mapping[i].sw_ptype |= 12237 RTE_PTYPE_TUNNEL_GRENAT; 12238 in_tunnel = true; 12239 } else if (!strncasecmp(name, "L2TPV2CTL", 9) || 12240 !strncasecmp(name, "L2TPV2", 6) || 12241 !strncasecmp(name, "L2TPV3", 6)) { 12242 ptype_mapping[i].sw_ptype |= 12243 RTE_PTYPE_TUNNEL_L2TP; 12244 in_tunnel = true; 12245 } 12246 12247 break; 12248 } 12249 } 12250 } 12251 12252 ret = rte_pmd_i40e_ptype_mapping_update(port_id, ptype_mapping, 12253 ptype_num, 0); 12254 if (ret) 12255 PMD_DRV_LOG(ERR, "Failed to update ptype mapping table."); 12256 12257 rte_free(ptype_mapping); 12258 rte_free(ptype); 12259 return ret; 12260 } 12261 12262 void 12263 i40e_update_customized_info(struct rte_eth_dev *dev, uint8_t *pkg, 12264 uint32_t pkg_size, enum rte_pmd_i40e_package_op op) 12265 { 12266 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); 12267 uint32_t proto_num; 12268 struct rte_pmd_i40e_proto_info *proto; 12269 uint32_t buff_size; 12270 uint32_t i; 12271 int ret; 12272 12273 if (op != RTE_PMD_I40E_PKG_OP_WR_ADD && 12274 op != RTE_PMD_I40E_PKG_OP_WR_DEL) { 12275 PMD_DRV_LOG(ERR, "Unsupported operation."); 12276 return; 12277 } 12278 12279 /* get information about protocol number */ 12280 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 12281 (uint8_t *)&proto_num, sizeof(proto_num), 12282 RTE_PMD_I40E_PKG_INFO_PROTOCOL_NUM); 12283 if (ret) { 12284 PMD_DRV_LOG(ERR, "Failed to get protocol number"); 12285 return; 12286 } 12287 if (!proto_num) { 12288 PMD_DRV_LOG(INFO, "No new protocol added"); 12289 return; 12290 } 12291 12292 buff_size = proto_num * sizeof(struct rte_pmd_i40e_proto_info); 12293 proto = rte_zmalloc("new_proto", buff_size, 0); 12294 if (!proto) { 12295 PMD_DRV_LOG(ERR, "Failed to allocate memory"); 12296 return; 12297 } 12298 12299 /* get information about protocol list */ 12300 ret = rte_pmd_i40e_get_ddp_info(pkg, pkg_size, 12301 (uint8_t *)proto, buff_size, 12302 RTE_PMD_I40E_PKG_INFO_PROTOCOL_LIST); 12303 if (ret) { 12304 PMD_DRV_LOG(ERR, "Failed to get protocol list"); 12305 rte_free(proto); 12306 return; 12307 } 12308 12309 /* Check if GTP is supported. */ 12310 for (i = 0; i < proto_num; i++) { 12311 if (!strncmp(proto[i].name, "GTP", 3)) { 12312 if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) 12313 pf->gtp_support = true; 12314 else 12315 pf->gtp_support = false; 12316 break; 12317 } 12318 } 12319 12320 /* Check if ESP is supported. */ 12321 for (i = 0; i < proto_num; i++) { 12322 if (!strncmp(proto[i].name, "ESP", 3)) { 12323 if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) 12324 pf->esp_support = true; 12325 else 12326 pf->esp_support = false; 12327 break; 12328 } 12329 } 12330 12331 /* Update customized pctype info */ 12332 ret = i40e_update_customized_pctype(dev, pkg, pkg_size, 12333 proto_num, proto, op); 12334 if (ret) 12335 PMD_DRV_LOG(INFO, "No pctype is updated."); 12336 12337 /* Update customized ptype info */ 12338 ret = i40e_update_customized_ptype(dev, pkg, pkg_size, 12339 proto_num, proto, op); 12340 if (ret) 12341 PMD_DRV_LOG(INFO, "No ptype is updated."); 12342 12343 rte_free(proto); 12344 } 12345 12346 /* Create a QinQ cloud filter 12347 * 12348 * The Fortville NIC has limited resources for tunnel filters, 12349 * so we can only reuse existing filters. 12350 * 12351 * In step 1 we define which Field Vector fields can be used for 12352 * filter types. 12353 * As we do not have the inner tag defined as a field, 12354 * we have to define it first, by reusing one of L1 entries. 12355 * 12356 * In step 2 we are replacing one of existing filter types with 12357 * a new one for QinQ. 12358 * As we reusing L1 and replacing L2, some of the default filter 12359 * types will disappear,which depends on L1 and L2 entries we reuse. 12360 * 12361 * Step 1: Create L1 filter of outer vlan (12b) + inner vlan (12b) 12362 * 12363 * 1. Create L1 filter of outer vlan (12b) which will be in use 12364 * later when we define the cloud filter. 12365 * a. Valid_flags.replace_cloud = 0 12366 * b. Old_filter = 10 (Stag_Inner_Vlan) 12367 * c. New_filter = 0x10 12368 * d. TR bit = 0xff (optional, not used here) 12369 * e. Buffer – 2 entries: 12370 * i. Byte 0 = 8 (outer vlan FV index). 12371 * Byte 1 = 0 (rsv) 12372 * Byte 2-3 = 0x0fff 12373 * ii. Byte 0 = 37 (inner vlan FV index). 12374 * Byte 1 =0 (rsv) 12375 * Byte 2-3 = 0x0fff 12376 * 12377 * Step 2: 12378 * 2. Create cloud filter using two L1 filters entries: stag and 12379 * new filter(outer vlan+ inner vlan) 12380 * a. Valid_flags.replace_cloud = 1 12381 * b. Old_filter = 1 (instead of outer IP) 12382 * c. New_filter = 0x10 12383 * d. Buffer – 2 entries: 12384 * i. Byte 0 = 0x80 | 7 (valid | Stag). 12385 * Byte 1-3 = 0 (rsv) 12386 * ii. Byte 8 = 0x80 | 0x10 (valid | new l1 filter step1) 12387 * Byte 9-11 = 0 (rsv) 12388 */ 12389 static int 12390 i40e_cloud_filter_qinq_create(struct i40e_pf *pf) 12391 { 12392 int ret = -ENOTSUP; 12393 struct i40e_aqc_replace_cloud_filters_cmd filter_replace; 12394 struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf; 12395 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12396 struct rte_eth_dev *dev = ((struct i40e_adapter *)hw->back)->eth_dev; 12397 12398 if (pf->support_multi_driver) { 12399 PMD_DRV_LOG(ERR, "Replace cloud filter is not supported."); 12400 return ret; 12401 } 12402 12403 /* Init */ 12404 memset(&filter_replace, 0, 12405 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 12406 memset(&filter_replace_buf, 0, 12407 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 12408 12409 /* create L1 filter */ 12410 filter_replace.old_filter_type = 12411 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_IVLAN; 12412 filter_replace.new_filter_type = I40E_AQC_ADD_CLOUD_FILTER_0X10; 12413 filter_replace.tr_bit = 0; 12414 12415 /* Prepare the buffer, 2 entries */ 12416 filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_VLAN; 12417 filter_replace_buf.data[0] |= 12418 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 12419 /* Field Vector 12b mask */ 12420 filter_replace_buf.data[2] = 0xff; 12421 filter_replace_buf.data[3] = 0x0f; 12422 filter_replace_buf.data[4] = 12423 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_INNER_VLAN; 12424 filter_replace_buf.data[4] |= 12425 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 12426 /* Field Vector 12b mask */ 12427 filter_replace_buf.data[6] = 0xff; 12428 filter_replace_buf.data[7] = 0x0f; 12429 ret = i40e_aq_replace_cloud_filters(hw, &filter_replace, 12430 &filter_replace_buf); 12431 if (ret != I40E_SUCCESS) 12432 return ret; 12433 12434 if (filter_replace.old_filter_type != 12435 filter_replace.new_filter_type) 12436 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud l1 type." 12437 " original: 0x%x, new: 0x%x", 12438 dev->device->name, 12439 filter_replace.old_filter_type, 12440 filter_replace.new_filter_type); 12441 12442 /* Apply the second L2 cloud filter */ 12443 memset(&filter_replace, 0, 12444 sizeof(struct i40e_aqc_replace_cloud_filters_cmd)); 12445 memset(&filter_replace_buf, 0, 12446 sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf)); 12447 12448 /* create L2 filter, input for L2 filter will be L1 filter */ 12449 filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER; 12450 filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_OIP; 12451 filter_replace.new_filter_type = I40E_AQC_ADD_CLOUD_FILTER_0X10; 12452 12453 /* Prepare the buffer, 2 entries */ 12454 filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG; 12455 filter_replace_buf.data[0] |= 12456 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 12457 filter_replace_buf.data[4] = I40E_AQC_ADD_CLOUD_FILTER_0X10; 12458 filter_replace_buf.data[4] |= 12459 I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED; 12460 ret = i40e_aq_replace_cloud_filters(hw, &filter_replace, 12461 &filter_replace_buf); 12462 if (!ret && (filter_replace.old_filter_type != 12463 filter_replace.new_filter_type)) 12464 PMD_DRV_LOG(WARNING, "i40e device %s changed cloud filter type." 12465 " original: 0x%x, new: 0x%x", 12466 dev->device->name, 12467 filter_replace.old_filter_type, 12468 filter_replace.new_filter_type); 12469 12470 return ret; 12471 } 12472 12473 int 12474 i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out, 12475 const struct rte_flow_action_rss *in) 12476 { 12477 if (in->key_len > RTE_DIM(out->key) || 12478 in->queue_num > RTE_DIM(out->queue)) 12479 return -EINVAL; 12480 if (!in->key && in->key_len) 12481 return -EINVAL; 12482 out->conf = (struct rte_flow_action_rss){ 12483 .func = in->func, 12484 .level = in->level, 12485 .types = in->types, 12486 .key_len = in->key_len, 12487 .queue_num = in->queue_num, 12488 .queue = memcpy(out->queue, in->queue, 12489 sizeof(*in->queue) * in->queue_num), 12490 }; 12491 if (in->key) 12492 out->conf.key = memcpy(out->key, in->key, in->key_len); 12493 return 0; 12494 } 12495 12496 /* Write HENA register to enable hash */ 12497 static int 12498 i40e_rss_hash_set(struct i40e_pf *pf, struct i40e_rte_flow_rss_conf *rss_conf) 12499 { 12500 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12501 uint8_t *key = (void *)(uintptr_t)rss_conf->conf.key; 12502 uint64_t hena; 12503 int ret; 12504 12505 ret = i40e_set_rss_key(pf->main_vsi, key, 12506 rss_conf->conf.key_len); 12507 if (ret) 12508 return ret; 12509 12510 hena = i40e_config_hena(pf->adapter, rss_conf->conf.types); 12511 i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (uint32_t)hena); 12512 i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (uint32_t)(hena >> 32)); 12513 I40E_WRITE_FLUSH(hw); 12514 12515 return 0; 12516 } 12517 12518 /* Configure hash input set */ 12519 static int 12520 i40e_rss_conf_hash_inset(struct i40e_pf *pf, uint64_t types) 12521 { 12522 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12523 struct rte_eth_input_set_conf conf; 12524 uint64_t mask0; 12525 int ret = 0; 12526 uint32_t j; 12527 int i; 12528 static const struct { 12529 uint64_t type; 12530 enum rte_eth_input_set_field field; 12531 } inset_match_table[] = { 12532 {ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_SRC_ONLY, 12533 RTE_ETH_INPUT_SET_L3_SRC_IP4}, 12534 {ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_DST_ONLY, 12535 RTE_ETH_INPUT_SET_L3_DST_IP4}, 12536 {ETH_RSS_FRAG_IPV4 | ETH_RSS_L4_SRC_ONLY, 12537 RTE_ETH_INPUT_SET_UNKNOWN}, 12538 {ETH_RSS_FRAG_IPV4 | ETH_RSS_L4_DST_ONLY, 12539 RTE_ETH_INPUT_SET_UNKNOWN}, 12540 12541 {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY, 12542 RTE_ETH_INPUT_SET_L3_SRC_IP4}, 12543 {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY, 12544 RTE_ETH_INPUT_SET_L3_DST_IP4}, 12545 {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_SRC_ONLY, 12546 RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT}, 12547 {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_DST_ONLY, 12548 RTE_ETH_INPUT_SET_L4_TCP_DST_PORT}, 12549 12550 {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY, 12551 RTE_ETH_INPUT_SET_L3_SRC_IP4}, 12552 {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY, 12553 RTE_ETH_INPUT_SET_L3_DST_IP4}, 12554 {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_SRC_ONLY, 12555 RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT}, 12556 {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_DST_ONLY, 12557 RTE_ETH_INPUT_SET_L4_UDP_DST_PORT}, 12558 12559 {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY, 12560 RTE_ETH_INPUT_SET_L3_SRC_IP4}, 12561 {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY, 12562 RTE_ETH_INPUT_SET_L3_DST_IP4}, 12563 {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_SRC_ONLY, 12564 RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT}, 12565 {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_DST_ONLY, 12566 RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT}, 12567 12568 {ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L3_SRC_ONLY, 12569 RTE_ETH_INPUT_SET_L3_SRC_IP4}, 12570 {ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L3_DST_ONLY, 12571 RTE_ETH_INPUT_SET_L3_DST_IP4}, 12572 {ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L4_SRC_ONLY, 12573 RTE_ETH_INPUT_SET_UNKNOWN}, 12574 {ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L4_DST_ONLY, 12575 RTE_ETH_INPUT_SET_UNKNOWN}, 12576 12577 {ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_SRC_ONLY, 12578 RTE_ETH_INPUT_SET_L3_SRC_IP6}, 12579 {ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_DST_ONLY, 12580 RTE_ETH_INPUT_SET_L3_DST_IP6}, 12581 {ETH_RSS_FRAG_IPV6 | ETH_RSS_L4_SRC_ONLY, 12582 RTE_ETH_INPUT_SET_UNKNOWN}, 12583 {ETH_RSS_FRAG_IPV6 | ETH_RSS_L4_DST_ONLY, 12584 RTE_ETH_INPUT_SET_UNKNOWN}, 12585 12586 {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY, 12587 RTE_ETH_INPUT_SET_L3_SRC_IP6}, 12588 {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY, 12589 RTE_ETH_INPUT_SET_L3_DST_IP6}, 12590 {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_SRC_ONLY, 12591 RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT}, 12592 {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_DST_ONLY, 12593 RTE_ETH_INPUT_SET_L4_TCP_DST_PORT}, 12594 12595 {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY, 12596 RTE_ETH_INPUT_SET_L3_SRC_IP6}, 12597 {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY, 12598 RTE_ETH_INPUT_SET_L3_DST_IP6}, 12599 {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_SRC_ONLY, 12600 RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT}, 12601 {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_DST_ONLY, 12602 RTE_ETH_INPUT_SET_L4_UDP_DST_PORT}, 12603 12604 {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY, 12605 RTE_ETH_INPUT_SET_L3_SRC_IP6}, 12606 {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY, 12607 RTE_ETH_INPUT_SET_L3_DST_IP6}, 12608 {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_SRC_ONLY, 12609 RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT}, 12610 {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_DST_ONLY, 12611 RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT}, 12612 12613 {ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L3_SRC_ONLY, 12614 RTE_ETH_INPUT_SET_L3_SRC_IP6}, 12615 {ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L3_DST_ONLY, 12616 RTE_ETH_INPUT_SET_L3_DST_IP6}, 12617 {ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L4_SRC_ONLY, 12618 RTE_ETH_INPUT_SET_UNKNOWN}, 12619 {ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L4_DST_ONLY, 12620 RTE_ETH_INPUT_SET_UNKNOWN}, 12621 }; 12622 12623 mask0 = types & pf->adapter->flow_types_mask; 12624 conf.op = RTE_ETH_INPUT_SET_SELECT; 12625 conf.inset_size = 0; 12626 for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < RTE_ETH_FLOW_MAX; i++) { 12627 if (mask0 & (1ULL << i)) { 12628 conf.flow_type = i; 12629 break; 12630 } 12631 } 12632 12633 for (j = 0; j < RTE_DIM(inset_match_table); j++) { 12634 if ((types & inset_match_table[j].type) == 12635 inset_match_table[j].type) { 12636 if (inset_match_table[j].field == 12637 RTE_ETH_INPUT_SET_UNKNOWN) 12638 return -EINVAL; 12639 12640 conf.field[conf.inset_size] = 12641 inset_match_table[j].field; 12642 conf.inset_size++; 12643 } 12644 } 12645 12646 if (conf.inset_size) { 12647 ret = i40e_hash_filter_inset_select(hw, &conf); 12648 if (ret) 12649 return ret; 12650 } 12651 12652 return ret; 12653 } 12654 12655 /* Look up the conflicted rule then mark it as invalid */ 12656 static void 12657 i40e_rss_mark_invalid_rule(struct i40e_pf *pf, 12658 struct i40e_rte_flow_rss_conf *conf) 12659 { 12660 struct i40e_rss_filter *rss_item; 12661 uint64_t rss_inset; 12662 12663 /* Clear input set bits before comparing the pctype */ 12664 rss_inset = ~(ETH_RSS_L3_SRC_ONLY | ETH_RSS_L3_DST_ONLY | 12665 ETH_RSS_L4_SRC_ONLY | ETH_RSS_L4_DST_ONLY); 12666 12667 /* Look up the conflicted rule then mark it as invalid */ 12668 TAILQ_FOREACH(rss_item, &pf->rss_config_list, next) { 12669 if (!rss_item->rss_filter_info.valid) 12670 continue; 12671 12672 if (conf->conf.queue_num && 12673 rss_item->rss_filter_info.conf.queue_num) 12674 rss_item->rss_filter_info.valid = false; 12675 12676 if (conf->conf.types && 12677 (rss_item->rss_filter_info.conf.types & 12678 rss_inset) == 12679 (conf->conf.types & rss_inset)) 12680 rss_item->rss_filter_info.valid = false; 12681 12682 if (conf->conf.func == 12683 RTE_ETH_HASH_FUNCTION_SIMPLE_XOR && 12684 rss_item->rss_filter_info.conf.func == 12685 RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) 12686 rss_item->rss_filter_info.valid = false; 12687 } 12688 } 12689 12690 /* Configure RSS hash function */ 12691 static int 12692 i40e_rss_config_hash_function(struct i40e_pf *pf, 12693 struct i40e_rte_flow_rss_conf *conf) 12694 { 12695 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12696 uint32_t reg, i; 12697 uint64_t mask0; 12698 uint16_t j; 12699 12700 if (conf->conf.func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) { 12701 reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL); 12702 if (!(reg & I40E_GLQF_CTL_HTOEP_MASK)) { 12703 PMD_DRV_LOG(DEBUG, "Hash function already set to Simple XOR"); 12704 I40E_WRITE_FLUSH(hw); 12705 i40e_rss_mark_invalid_rule(pf, conf); 12706 12707 return 0; 12708 } 12709 reg &= ~I40E_GLQF_CTL_HTOEP_MASK; 12710 12711 i40e_write_global_rx_ctl(hw, I40E_GLQF_CTL, reg); 12712 I40E_WRITE_FLUSH(hw); 12713 i40e_rss_mark_invalid_rule(pf, conf); 12714 } else if (conf->conf.func == 12715 RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) { 12716 mask0 = conf->conf.types & pf->adapter->flow_types_mask; 12717 12718 i40e_set_symmetric_hash_enable_per_port(hw, 1); 12719 for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT64_BIT; i++) { 12720 if (mask0 & (1UL << i)) 12721 break; 12722 } 12723 12724 if (i == UINT64_BIT) 12725 return -EINVAL; 12726 12727 for (j = I40E_FILTER_PCTYPE_INVALID + 1; 12728 j < I40E_FILTER_PCTYPE_MAX; j++) { 12729 if (pf->adapter->pctypes_tbl[i] & (1ULL << j)) 12730 i40e_write_global_rx_ctl(hw, 12731 I40E_GLQF_HSYM(j), 12732 I40E_GLQF_HSYM_SYMH_ENA_MASK); 12733 } 12734 } 12735 12736 return 0; 12737 } 12738 12739 /* Enable RSS according to the configuration */ 12740 static int 12741 i40e_rss_enable_hash(struct i40e_pf *pf, 12742 struct i40e_rte_flow_rss_conf *conf) 12743 { 12744 struct i40e_rte_flow_rss_conf *rss_info = &pf->rss_info; 12745 struct i40e_rte_flow_rss_conf rss_conf; 12746 12747 if (!(conf->conf.types & pf->adapter->flow_types_mask)) 12748 return -ENOTSUP; 12749 12750 memset(&rss_conf, 0, sizeof(rss_conf)); 12751 rte_memcpy(&rss_conf, conf, sizeof(rss_conf)); 12752 12753 /* Configure hash input set */ 12754 if (i40e_rss_conf_hash_inset(pf, conf->conf.types)) 12755 return -EINVAL; 12756 12757 if (rss_conf.conf.key == NULL || rss_conf.conf.key_len < 12758 (I40E_PFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t)) { 12759 /* Random default keys */ 12760 static uint32_t rss_key_default[] = {0x6b793944, 12761 0x23504cb5, 0x5bea75b6, 0x309f4f12, 0x3dc0a2b8, 12762 0x024ddcdf, 0x339b8ca0, 0x4c4af64a, 0x34fac605, 12763 0x55d85839, 0x3a58997d, 0x2ec938e1, 0x66031581}; 12764 12765 rss_conf.conf.key = (uint8_t *)rss_key_default; 12766 rss_conf.conf.key_len = (I40E_PFQF_HKEY_MAX_INDEX + 1) * 12767 sizeof(uint32_t); 12768 PMD_DRV_LOG(INFO, 12769 "No valid RSS key config for i40e, using default\n"); 12770 } 12771 12772 rss_conf.conf.types |= rss_info->conf.types; 12773 i40e_rss_hash_set(pf, &rss_conf); 12774 12775 if (conf->conf.func == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) 12776 i40e_rss_config_hash_function(pf, conf); 12777 12778 i40e_rss_mark_invalid_rule(pf, conf); 12779 12780 return 0; 12781 } 12782 12783 /* Configure RSS queue region */ 12784 static int 12785 i40e_rss_config_queue_region(struct i40e_pf *pf, 12786 struct i40e_rte_flow_rss_conf *conf) 12787 { 12788 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12789 uint32_t lut = 0; 12790 uint16_t j, num; 12791 uint32_t i; 12792 12793 /* If both VMDQ and RSS enabled, not all of PF queues are configured. 12794 * It's necessary to calculate the actual PF queues that are configured. 12795 */ 12796 if (pf->dev_data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_VMDQ_FLAG) 12797 num = i40e_pf_calc_configured_queues_num(pf); 12798 else 12799 num = pf->dev_data->nb_rx_queues; 12800 12801 num = RTE_MIN(num, conf->conf.queue_num); 12802 PMD_DRV_LOG(INFO, "Max of contiguous %u PF queues are configured", 12803 num); 12804 12805 if (num == 0) { 12806 PMD_DRV_LOG(ERR, 12807 "No PF queues are configured to enable RSS for port %u", 12808 pf->dev_data->port_id); 12809 return -ENOTSUP; 12810 } 12811 12812 /* Fill in redirection table */ 12813 for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) { 12814 if (j == num) 12815 j = 0; 12816 lut = (lut << 8) | (conf->conf.queue[j] & ((0x1 << 12817 hw->func_caps.rss_table_entry_width) - 1)); 12818 if ((i & 3) == 3) 12819 I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut); 12820 } 12821 12822 i40e_rss_mark_invalid_rule(pf, conf); 12823 12824 return 0; 12825 } 12826 12827 /* Configure RSS hash function to default */ 12828 static int 12829 i40e_rss_clear_hash_function(struct i40e_pf *pf, 12830 struct i40e_rte_flow_rss_conf *conf) 12831 { 12832 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12833 uint32_t i, reg; 12834 uint64_t mask0; 12835 uint16_t j; 12836 12837 if (conf->conf.func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) { 12838 reg = i40e_read_rx_ctl(hw, I40E_GLQF_CTL); 12839 if (reg & I40E_GLQF_CTL_HTOEP_MASK) { 12840 PMD_DRV_LOG(DEBUG, 12841 "Hash function already set to Toeplitz"); 12842 I40E_WRITE_FLUSH(hw); 12843 12844 return 0; 12845 } 12846 reg |= I40E_GLQF_CTL_HTOEP_MASK; 12847 12848 i40e_write_global_rx_ctl(hw, I40E_GLQF_CTL, reg); 12849 I40E_WRITE_FLUSH(hw); 12850 } else if (conf->conf.func == 12851 RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) { 12852 mask0 = conf->conf.types & pf->adapter->flow_types_mask; 12853 12854 for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT64_BIT; i++) { 12855 if (mask0 & (1UL << i)) 12856 break; 12857 } 12858 12859 if (i == UINT64_BIT) 12860 return -EINVAL; 12861 12862 for (j = I40E_FILTER_PCTYPE_INVALID + 1; 12863 j < I40E_FILTER_PCTYPE_MAX; j++) { 12864 if (pf->adapter->pctypes_tbl[i] & (1ULL << j)) 12865 i40e_write_global_rx_ctl(hw, 12866 I40E_GLQF_HSYM(j), 12867 0); 12868 } 12869 } 12870 12871 return 0; 12872 } 12873 12874 /* Disable RSS hash and configure default input set */ 12875 static int 12876 i40e_rss_disable_hash(struct i40e_pf *pf, 12877 struct i40e_rte_flow_rss_conf *conf) 12878 { 12879 struct i40e_rte_flow_rss_conf *rss_info = &pf->rss_info; 12880 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12881 struct i40e_rte_flow_rss_conf rss_conf; 12882 uint32_t i; 12883 12884 memset(&rss_conf, 0, sizeof(rss_conf)); 12885 rte_memcpy(&rss_conf, conf, sizeof(rss_conf)); 12886 12887 /* Disable RSS hash */ 12888 rss_conf.conf.types = rss_info->conf.types & ~(conf->conf.types); 12889 i40e_rss_hash_set(pf, &rss_conf); 12890 12891 for (i = RTE_ETH_FLOW_IPV4; i <= RTE_ETH_FLOW_L2_PAYLOAD; i++) { 12892 if (!(pf->adapter->flow_types_mask & (1ULL << i)) || 12893 !(conf->conf.types & (1ULL << i))) 12894 continue; 12895 12896 /* Configure default input set */ 12897 struct rte_eth_input_set_conf input_conf = { 12898 .op = RTE_ETH_INPUT_SET_SELECT, 12899 .flow_type = i, 12900 .inset_size = 1, 12901 }; 12902 input_conf.field[0] = RTE_ETH_INPUT_SET_DEFAULT; 12903 i40e_hash_filter_inset_select(hw, &input_conf); 12904 } 12905 12906 rss_info->conf.types = rss_conf.conf.types; 12907 12908 i40e_rss_clear_hash_function(pf, conf); 12909 12910 return 0; 12911 } 12912 12913 /* Configure RSS queue region to default */ 12914 static int 12915 i40e_rss_clear_queue_region(struct i40e_pf *pf) 12916 { 12917 struct i40e_hw *hw = I40E_PF_TO_HW(pf); 12918 struct i40e_rte_flow_rss_conf *rss_info = &pf->rss_info; 12919 uint16_t queue[I40E_MAX_Q_PER_TC]; 12920 uint32_t num_rxq, i; 12921 uint32_t lut = 0; 12922 uint16_t j, num; 12923 12924 num_rxq = RTE_MIN(pf->dev_data->nb_rx_queues, I40E_MAX_Q_PER_TC); 12925 12926 for (j = 0; j < num_rxq; j++) 12927 queue[j] = j; 12928 12929 /* If both VMDQ and RSS enabled, not all of PF queues are configured. 12930 * It's necessary to calculate the actual PF queues that are configured. 12931 */ 12932 if (pf->dev_data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_VMDQ_FLAG) 12933 num = i40e_pf_calc_configured_queues_num(pf); 12934 else 12935 num = pf->dev_data->nb_rx_queues; 12936 12937 num = RTE_MIN(num, num_rxq); 12938 PMD_DRV_LOG(INFO, "Max of contiguous %u PF queues are configured", 12939 num); 12940 12941 if (num == 0) { 12942 PMD_DRV_LOG(ERR, 12943 "No PF queues are configured to enable RSS for port %u", 12944 pf->dev_data->port_id); 12945 return -ENOTSUP; 12946 } 12947 12948 /* Fill in redirection table */ 12949 for (i = 0, j = 0; i < hw->func_caps.rss_table_size; i++, j++) { 12950 if (j == num) 12951 j = 0; 12952 lut = (lut << 8) | (queue[j] & ((0x1 << 12953 hw->func_caps.rss_table_entry_width) - 1)); 12954 if ((i & 3) == 3) 12955 I40E_WRITE_REG(hw, I40E_PFQF_HLUT(i >> 2), lut); 12956 } 12957 12958 rss_info->conf.queue_num = 0; 12959 memset(&rss_info->conf.queue, 0, sizeof(uint16_t)); 12960 12961 return 0; 12962 } 12963 12964 int 12965 i40e_config_rss_filter(struct i40e_pf *pf, 12966 struct i40e_rte_flow_rss_conf *conf, bool add) 12967 { 12968 struct i40e_rte_flow_rss_conf *rss_info = &pf->rss_info; 12969 struct rte_flow_action_rss update_conf = rss_info->conf; 12970 int ret = 0; 12971 12972 if (add) { 12973 if (conf->conf.queue_num) { 12974 /* Configure RSS queue region */ 12975 ret = i40e_rss_config_queue_region(pf, conf); 12976 if (ret) 12977 return ret; 12978 12979 update_conf.queue_num = conf->conf.queue_num; 12980 update_conf.queue = conf->conf.queue; 12981 } else if (conf->conf.func == 12982 RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) { 12983 /* Configure hash function */ 12984 ret = i40e_rss_config_hash_function(pf, conf); 12985 if (ret) 12986 return ret; 12987 12988 update_conf.func = conf->conf.func; 12989 } else { 12990 /* Configure hash enable and input set */ 12991 ret = i40e_rss_enable_hash(pf, conf); 12992 if (ret) 12993 return ret; 12994 12995 update_conf.types |= conf->conf.types; 12996 update_conf.key = conf->conf.key; 12997 update_conf.key_len = conf->conf.key_len; 12998 } 12999 13000 /* Update RSS info in pf */ 13001 if (i40e_rss_conf_init(rss_info, &update_conf)) 13002 return -EINVAL; 13003 } else { 13004 if (!conf->valid) 13005 return 0; 13006 13007 if (conf->conf.queue_num) 13008 i40e_rss_clear_queue_region(pf); 13009 else if (conf->conf.func == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) 13010 i40e_rss_clear_hash_function(pf, conf); 13011 else 13012 i40e_rss_disable_hash(pf, conf); 13013 } 13014 13015 return 0; 13016 } 13017 13018 RTE_LOG_REGISTER(i40e_logtype_init, pmd.net.i40e.init, NOTICE); 13019 RTE_LOG_REGISTER(i40e_logtype_driver, pmd.net.i40e.driver, NOTICE); 13020 #ifdef RTE_LIBRTE_I40E_DEBUG_RX 13021 RTE_LOG_REGISTER(i40e_logtype_rx, pmd.net.i40e.rx, DEBUG); 13022 #endif 13023 #ifdef RTE_LIBRTE_I40E_DEBUG_TX 13024 RTE_LOG_REGISTER(i40e_logtype_tx, pmd.net.i40e.tx, DEBUG); 13025 #endif 13026 #ifdef RTE_LIBRTE_I40E_DEBUG_TX_FREE 13027 RTE_LOG_REGISTER(i40e_logtype_tx_free, pmd.net.i40e.tx_free, DEBUG); 13028 #endif 13029 13030 RTE_PMD_REGISTER_PARAM_STRING(net_i40e, 13031 ETH_I40E_FLOATING_VEB_ARG "=1" 13032 ETH_I40E_FLOATING_VEB_LIST_ARG "=<string>" 13033 ETH_I40E_QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16" 13034 ETH_I40E_SUPPORT_MULTI_DRIVER "=1" 13035 ETH_I40E_USE_LATEST_VEC "=0|1"); 13036