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