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