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