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