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