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