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