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