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