X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fixgbe%2Fixgbe_ethdev.c;h=30c0379d4145b93eed2ee86a27104f1ac91d8f9b;hb=1ca05831b9be946001ebabba2b3fdb0456684d9a;hp=68b1e4f730fdbe404185ec4e2efea924f9dc4f92;hpb=6bee9d5f456a61a427384c815f6827aad83e3c06;p=dpdk.git diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index 68b1e4f730..30c0379d41 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -149,10 +149,10 @@ static int ixgbe_dev_set_link_up(struct rte_eth_dev *dev); static int ixgbe_dev_set_link_down(struct rte_eth_dev *dev); static void ixgbe_dev_close(struct rte_eth_dev *dev); static int ixgbe_dev_reset(struct rte_eth_dev *dev); -static void ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev); -static void ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev); -static void ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev); -static void ixgbe_dev_allmulticast_disable(struct rte_eth_dev *dev); +static int ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev); +static int ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev); +static int ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev); +static int ixgbe_dev_allmulticast_disable(struct rte_eth_dev *dev); static int ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete); static int ixgbe_dev_stats_get(struct rte_eth_dev *dev, @@ -164,8 +164,8 @@ static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, static int ixgbe_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, uint64_t *values, unsigned int n); -static void ixgbe_dev_stats_reset(struct rte_eth_dev *dev); -static void ixgbe_dev_xstats_reset(struct rte_eth_dev *dev); +static int ixgbe_dev_stats_reset(struct rte_eth_dev *dev); +static int ixgbe_dev_xstats_reset(struct rte_eth_dev *dev); static int ixgbe_dev_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned int size); @@ -182,11 +182,11 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev, uint8_t is_rx); static int ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size); -static void ixgbe_dev_info_get(struct rte_eth_dev *dev, - struct rte_eth_dev_info *dev_info); +static int ixgbe_dev_info_get(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info); static const uint32_t *ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev); -static void ixgbevf_dev_info_get(struct rte_eth_dev *dev, - struct rte_eth_dev_info *dev_info); +static int ixgbevf_dev_info_get(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info); static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); static int ixgbe_vlan_filter_set(struct rte_eth_dev *dev, @@ -255,7 +255,7 @@ static void ixgbevf_intr_disable(struct rte_eth_dev *dev); static void ixgbevf_intr_enable(struct rte_eth_dev *dev); static int ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats); -static void ixgbevf_dev_stats_reset(struct rte_eth_dev *dev); +static int ixgbevf_dev_stats_reset(struct rte_eth_dev *dev); static int ixgbevf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on); static void ixgbevf_vlan_strip_queue_set(struct rte_eth_dev *dev, @@ -270,10 +270,10 @@ static int ixgbevf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, static void ixgbevf_set_ivar_map(struct ixgbe_hw *hw, int8_t direction, uint8_t queue, uint8_t msix_vector); static void ixgbevf_configure_msix(struct rte_eth_dev *dev); -static void ixgbevf_dev_promiscuous_enable(struct rte_eth_dev *dev); -static void ixgbevf_dev_promiscuous_disable(struct rte_eth_dev *dev); -static void ixgbevf_dev_allmulticast_enable(struct rte_eth_dev *dev); -static void ixgbevf_dev_allmulticast_disable(struct rte_eth_dev *dev); +static int ixgbevf_dev_promiscuous_enable(struct rte_eth_dev *dev); +static int ixgbevf_dev_promiscuous_disable(struct rte_eth_dev *dev); +static int ixgbevf_dev_allmulticast_enable(struct rte_eth_dev *dev); +static int ixgbevf_dev_allmulticast_disable(struct rte_eth_dev *dev); /* For Eth VMDQ APIs support */ static int ixgbe_uc_hash_table_set(struct rte_eth_dev *dev, struct @@ -419,6 +419,16 @@ static void ixgbe_l2_tunnel_conf(struct rte_eth_dev *dev); int ixgbe_logtype_init; int ixgbe_logtype_driver; +#ifdef RTE_LIBRTE_IXGBE_DEBUG_RX +int ixgbe_logtype_rx; +#endif +#ifdef RTE_LIBRTE_IXGBE_DEBUG_TX +int ixgbe_logtype_tx; +#endif +#ifdef RTE_LIBRTE_IXGBE_DEBUG_TX_FREE +int ixgbe_logtype_tx_free; +#endif + /* * The set of PCI devices this driver supports */ @@ -1245,6 +1255,11 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) return -ENOMEM; } + /* Pass the information to the rte_eth_dev_close() that it should also + * release the private port resources. + */ + eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE; + /* initialize the vfta */ memset(shadow_vfta, 0, sizeof(*shadow_vfta)); @@ -1311,73 +1326,12 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) static int eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev) { - struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); - struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; - struct ixgbe_hw *hw; - int retries = 0; - int ret; - PMD_INIT_FUNC_TRACE(); if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; - hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); - - if (hw->adapter_stopped == 0) - ixgbe_dev_close(eth_dev); - - eth_dev->dev_ops = NULL; - eth_dev->rx_pkt_burst = NULL; - eth_dev->tx_pkt_burst = NULL; - - /* Unlock any pending hardware semaphore */ - ixgbe_swfw_lock_reset(hw); - - /* disable uio intr before callback unregister */ - rte_intr_disable(intr_handle); - - do { - ret = rte_intr_callback_unregister(intr_handle, - ixgbe_dev_interrupt_handler, eth_dev); - if (ret >= 0) { - break; - } else if (ret != -EAGAIN) { - PMD_INIT_LOG(ERR, - "intr callback unregister failed: %d", - ret); - return ret; - } - rte_delay_ms(100); - } while (retries++ < (10 + IXGBE_LINK_UP_TIME)); - - /* cancel the delay handler before remove dev */ - rte_eal_alarm_cancel(ixgbe_dev_interrupt_delayed_handler, eth_dev); - - /* cancel the link handler before remove dev */ - rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, eth_dev); - - /* uninitialize PF if max_vfs not zero */ - ixgbe_pf_host_uninit(eth_dev); - - /* remove all the fdir filters & hash */ - ixgbe_fdir_filter_uninit(eth_dev); - - /* remove all the L2 tunnel filters & hash */ - ixgbe_l2_tn_filter_uninit(eth_dev); - - /* Remove all ntuple filters of the device */ - ixgbe_ntuple_filter_uninit(eth_dev); - - /* clear all the filters list */ - ixgbe_filterlist_flush(); - - /* Remove all Traffic Manager configuration */ - ixgbe_tm_conf_uninit(eth_dev); - -#ifdef RTE_LIBRTE_SECURITY - rte_free(eth_dev->security_ctx); -#endif + ixgbe_dev_close(eth_dev); return 0; } @@ -1711,6 +1665,11 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev) return -ENOMEM; } + /* Pass the information to the rte_eth_dev_close() that it should also + * release the private port resources. + */ + eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE; + /* Generate a random MAC address, if none was assigned by PF. */ if (rte_is_zero_ether_addr(perm_addr)) { generate_random_mac_addr(perm_addr); @@ -1762,30 +1721,12 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev) static int eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev) { - struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); - struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; - struct ixgbe_hw *hw; - PMD_INIT_FUNC_TRACE(); if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; - hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); - - if (hw->adapter_stopped == 0) - ixgbevf_dev_close(eth_dev); - - eth_dev->dev_ops = NULL; - eth_dev->rx_pkt_burst = NULL; - eth_dev->tx_pkt_burst = NULL; - - /* Disable the interrupts for VF */ - ixgbevf_intr_disable(eth_dev); - - rte_intr_disable(intr_handle); - rte_intr_callback_unregister(intr_handle, - ixgbevf_dev_interrupt_handler, eth_dev); + ixgbevf_dev_close(eth_dev); return 0; } @@ -2514,9 +2455,12 @@ ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf, uint32_t queue_end; uint16_t total_rate = 0; struct rte_pci_device *pci_dev; + int ret; pci_dev = RTE_ETH_DEV_TO_PCI(dev); - rte_eth_link_get_nowait(dev->data->port_id, &link); + ret = rte_eth_link_get_nowait(dev->data->port_id, &link); + if (ret < 0) + return ret; if (vf >= pci_dev->max_vfs) return -EINVAL; @@ -2598,6 +2542,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev) uint32_t *link_speeds; struct ixgbe_tm_conf *tm_conf = IXGBE_DEV_PRIVATE_TO_TM_CONF(dev->data->dev_private); + struct ixgbe_macsec_setting *macsec_ctrl = + IXGBE_DEV_PRIVATE_TO_MACSEC_SETTING(dev->data->dev_private); PMD_INIT_FUNC_TRACE(); @@ -2850,6 +2796,9 @@ skip_link_setup: */ ixgbe_dev_link_update(dev, 0); + /* setup the macsec ctrl register */ + ixgbe_dev_macsec_register_enable(dev, macsec_ctrl); + return 0; error: @@ -2876,8 +2825,14 @@ ixgbe_dev_stop(struct rte_eth_dev *dev) struct ixgbe_tm_conf *tm_conf = IXGBE_DEV_PRIVATE_TO_TM_CONF(dev->data->dev_private); + if (hw->adapter_stopped) + return; + PMD_INIT_FUNC_TRACE(); + /* disable mecsec register */ + ixgbe_dev_macsec_register_disable(dev); + rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev); /* disable interrupts */ @@ -2928,6 +2883,8 @@ ixgbe_dev_stop(struct rte_eth_dev *dev) tm_conf->committed = false; adapter->rss_reta_updated = 0; + + hw->adapter_stopped = true; } /* @@ -2955,6 +2912,7 @@ ixgbe_dev_set_link_up(struct rte_eth_dev *dev) } else { /* Turn on the laser */ ixgbe_enable_tx_laser(hw); + ixgbe_dev_link_update(dev, 0); } return 0; @@ -2985,6 +2943,7 @@ ixgbe_dev_set_link_down(struct rte_eth_dev *dev) } else { /* Turn off the laser */ ixgbe_disable_tx_laser(hw); + ixgbe_dev_link_update(dev, 0); } return 0; @@ -2998,13 +2957,16 @@ ixgbe_dev_close(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + int retries = 0; + int ret; PMD_INIT_FUNC_TRACE(); ixgbe_pf_reset_hw(hw); ixgbe_dev_stop(dev); - hw->adapter_stopped = 1; ixgbe_dev_free_queues(dev); @@ -3012,6 +2974,55 @@ ixgbe_dev_close(struct rte_eth_dev *dev) /* reprogram the RAR[0] in case user changed it. */ ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); + + dev->dev_ops = NULL; + dev->rx_pkt_burst = NULL; + dev->tx_pkt_burst = NULL; + + /* Unlock any pending hardware semaphore */ + ixgbe_swfw_lock_reset(hw); + + /* disable uio intr before callback unregister */ + rte_intr_disable(intr_handle); + + do { + ret = rte_intr_callback_unregister(intr_handle, + ixgbe_dev_interrupt_handler, dev); + if (ret >= 0 || ret == -ENOENT) { + break; + } else if (ret != -EAGAIN) { + PMD_INIT_LOG(ERR, + "intr callback unregister failed: %d", + ret); + } + rte_delay_ms(100); + } while (retries++ < (10 + IXGBE_LINK_UP_TIME)); + + /* cancel the delay handler before remove dev */ + rte_eal_alarm_cancel(ixgbe_dev_interrupt_delayed_handler, dev); + + /* uninitialize PF if max_vfs not zero */ + ixgbe_pf_host_uninit(dev); + + /* remove all the fdir filters & hash */ + ixgbe_fdir_filter_uninit(dev); + + /* remove all the L2 tunnel filters & hash */ + ixgbe_l2_tn_filter_uninit(dev); + + /* Remove all ntuple filters of the device */ + ixgbe_ntuple_filter_uninit(dev); + + /* clear all the filters list */ + ixgbe_filterlist_flush(); + + /* Remove all Traffic Manager configuration */ + ixgbe_tm_conf_uninit(dev); + +#ifdef RTE_LIBRTE_SECURITY + rte_free(dev->security_ctx); +#endif + } /* @@ -3317,7 +3328,7 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) return 0; } -static void +static int ixgbe_dev_stats_reset(struct rte_eth_dev *dev) { struct ixgbe_hw_stats *stats = @@ -3328,6 +3339,8 @@ ixgbe_dev_stats_reset(struct rte_eth_dev *dev) /* Reset software totals */ memset(stats, 0, sizeof(*stats)); + + return 0; } /* This function calculates the number of xstats based on the current config */ @@ -3649,7 +3662,7 @@ ixgbe_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, return n; } -static void +static int ixgbe_dev_xstats_reset(struct rte_eth_dev *dev) { struct ixgbe_hw_stats *stats = @@ -3666,6 +3679,8 @@ ixgbe_dev_xstats_reset(struct rte_eth_dev *dev) /* Reset software totals */ memset(stats, 0, sizeof(*stats)); memset(macsec_stats, 0, sizeof(*macsec_stats)); + + return 0; } static void @@ -3740,7 +3755,7 @@ ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) return 0; } -static void +static int ixgbevf_dev_stats_reset(struct rte_eth_dev *dev) { struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *) @@ -3754,6 +3769,8 @@ ixgbevf_dev_stats_reset(struct rte_eth_dev *dev) hw_stats->vfgorc = 0; hw_stats->vfgptc = 0; hw_stats->vfgotc = 0; + + return 0; } static int @@ -3777,7 +3794,7 @@ ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) return 0; } -static void +static int ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); @@ -3843,6 +3860,11 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL; dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G; + if (hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T || + hw->device_id == IXGBE_DEV_ID_X550EM_A_1G_T_L) + dev_info->speed_capa = ETH_LINK_SPEED_10M | + ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G; + if (hw->mac.type == ixgbe_mac_X540 || hw->mac.type == ixgbe_mac_X540_vf || hw->mac.type == ixgbe_mac_X550 || @@ -3861,6 +3883,8 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->default_txportconf.nb_queues = 1; dev_info->default_rxportconf.ring_size = 256; dev_info->default_txportconf.ring_size = 256; + + return 0; } static const uint32_t * @@ -3894,7 +3918,7 @@ ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev) dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc) return ptypes; -#if defined(RTE_ARCH_X86) +#if defined(RTE_ARCH_X86) || defined(RTE_MACHINE_CPUFLAG_NEON) if (dev->rx_pkt_burst == ixgbe_recv_pkts_vec || dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec) return ptypes; @@ -3902,7 +3926,7 @@ ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev) return NULL; } -static void +static int ixgbevf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { @@ -3926,6 +3950,9 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev, dev_info->rx_queue_offload_capa); dev_info->tx_queue_offload_capa = ixgbe_get_tx_queue_offloads(dev); dev_info->tx_offload_capa = ixgbe_get_tx_port_offloads(dev); + dev_info->hash_key_size = IXGBE_HKEY_MAX_INDEX * sizeof(uint32_t); + dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type); + dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL; dev_info->default_rxconf = (struct rte_eth_rxconf) { .rx_thresh = { @@ -3951,6 +3978,8 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev, dev_info->rx_desc_lim = rx_desc_lim; dev_info->tx_desc_lim = tx_desc_lim; + + return 0; } static int @@ -4089,6 +4118,7 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, int link_up; int diag; int wait = 1; + u32 esdp_reg; memset(&link, 0, sizeof(link)); link.link_status = ETH_LINK_DOWN; @@ -4116,6 +4146,10 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, return rte_eth_linkstatus_set(dev, &link); } + esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); + if ((esdp_reg & IXGBE_ESDP_SDP3)) + link_up = 0; + if (link_up == 0) { if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) { intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG; @@ -4136,7 +4170,6 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, link.link_speed = ETH_SPEED_NUM_10M; else link.link_speed = ETH_SPEED_NUM_100M; - link.link_duplex = ETH_LINK_FULL_DUPLEX; break; case IXGBE_LINK_SPEED_100_FULL: @@ -4175,7 +4208,7 @@ ixgbevf_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete) return ixgbe_dev_link_update_share(dev, wait_to_complete, 1); } -static void +static int ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); @@ -4184,9 +4217,11 @@ ixgbe_dev_promiscuous_enable(struct rte_eth_dev *dev) fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + + return 0; } -static void +static int ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); @@ -4199,9 +4234,11 @@ ixgbe_dev_promiscuous_disable(struct rte_eth_dev *dev) else fctrl &= (~IXGBE_FCTRL_MPE); IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + + return 0; } -static void +static int ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); @@ -4210,20 +4247,24 @@ ixgbe_dev_allmulticast_enable(struct rte_eth_dev *dev) fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); fctrl |= IXGBE_FCTRL_MPE; IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + + return 0; } -static void +static int ixgbe_dev_allmulticast_disable(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); uint32_t fctrl; if (dev->data->promiscuous == 1) - return; /* must remain in all_multicast mode */ + return 0; /* must remain in all_multicast mode */ fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); fctrl &= (~IXGBE_FCTRL_MPE); IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + + return 0; } /** @@ -5016,8 +5057,11 @@ ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) struct rte_eth_dev_info dev_info; uint32_t frame_size = mtu + IXGBE_ETH_OVERHEAD; struct rte_eth_dev_data *dev_data = dev->data; + int ret; - ixgbe_dev_info_get(dev, &dev_info); + ret = ixgbe_dev_info_get(dev, &dev_info); + if (ret != 0) + return ret; /* check that mtu is within the allowed range */ if (mtu < RTE_ETHER_MIN_MTU || frame_size > dev_info.max_rx_pktlen) @@ -5231,6 +5275,8 @@ ixgbevf_dev_start(struct rte_eth_dev *dev) */ ixgbevf_dev_link_update(dev, 0); + hw->adapter_stopped = false; + return 0; } @@ -5242,6 +5288,9 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev) struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + if (hw->adapter_stopped) + return; + PMD_INIT_FUNC_TRACE(); rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev); @@ -5276,6 +5325,8 @@ static void ixgbevf_dev_close(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); + struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; PMD_INIT_FUNC_TRACE(); @@ -5291,6 +5342,14 @@ ixgbevf_dev_close(struct rte_eth_dev *dev) * after stop, close and detach of the VF **/ ixgbevf_remove_mac_addr(dev, 0); + + dev->dev_ops = NULL; + dev->rx_pkt_burst = NULL; + dev->tx_pkt_burst = NULL; + + rte_intr_disable(intr_handle); + rte_intr_callback_unregister(intr_handle, + ixgbevf_dev_interrupt_handler, dev); } /* @@ -5894,7 +5953,8 @@ ixgbe_set_ivar_map(struct ixgbe_hw *hw, int8_t direction, IXGBE_WRITE_REG(hw, IXGBE_IVAR(idx), tmp); } else if ((hw->mac.type == ixgbe_mac_82599EB) || (hw->mac.type == ixgbe_mac_X540) || - (hw->mac.type == ixgbe_mac_X550)) { + (hw->mac.type == ixgbe_mac_X550) || + (hw->mac.type == ixgbe_mac_X550EM_x)) { if (direction == -1) { /* other causes */ idx = ((queue & 1) * 8); @@ -6024,6 +6084,7 @@ ixgbe_configure_msix(struct rte_eth_dev *dev) case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: ixgbe_set_ivar_map(hw, -1, 1, IXGBE_MISC_VEC_ID); break; default: @@ -7437,6 +7498,9 @@ ixgbe_reta_size_get(enum ixgbe_mac_type mac_type) { case ixgbe_mac_X550EM_x_vf: case ixgbe_mac_X550EM_a_vf: return ETH_RSS_RETA_SIZE_64; + case ixgbe_mac_X540_vf: + case ixgbe_mac_82599_vf: + return 0; default: return ETH_RSS_RETA_SIZE_128; } @@ -8388,36 +8452,89 @@ ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, return ret; } -static void +static int ixgbevf_dev_promiscuous_enable(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret; + + switch (hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_PROMISC)) { + case IXGBE_SUCCESS: + ret = 0; + break; + case IXGBE_ERR_FEATURE_NOT_SUPPORTED: + ret = -ENOTSUP; + break; + default: + ret = -EAGAIN; + break; + } - hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_PROMISC); + return ret; } -static void +static int ixgbevf_dev_promiscuous_disable(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret; - hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_NONE); + switch (hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_NONE)) { + case IXGBE_SUCCESS: + ret = 0; + break; + case IXGBE_ERR_FEATURE_NOT_SUPPORTED: + ret = -ENOTSUP; + break; + default: + ret = -EAGAIN; + break; + } + + return ret; } -static void +static int ixgbevf_dev_allmulticast_enable(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret; + int mode = IXGBEVF_XCAST_MODE_ALLMULTI; + + switch (hw->mac.ops.update_xcast_mode(hw, mode)) { + case IXGBE_SUCCESS: + ret = 0; + break; + case IXGBE_ERR_FEATURE_NOT_SUPPORTED: + ret = -ENOTSUP; + break; + default: + ret = -EAGAIN; + break; + } - hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_ALLMULTI); + return ret; } -static void +static int ixgbevf_dev_allmulticast_disable(struct rte_eth_dev *dev) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret; + + switch (hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_MULTI)) { + case IXGBE_SUCCESS: + ret = 0; + break; + case IXGBE_ERR_FEATURE_NOT_SUPPORTED: + ret = -ENOTSUP; + break; + default: + ret = -EAGAIN; + break; + } - hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_MULTI); + return ret; } static void ixgbevf_mbx_process(struct rte_eth_dev *dev) @@ -8714,6 +8831,147 @@ ixgbe_clear_all_l2_tn_filter(struct rte_eth_dev *dev) return 0; } +void +ixgbe_dev_macsec_setting_save(struct rte_eth_dev *dev, + struct ixgbe_macsec_setting *macsec_setting) +{ + struct ixgbe_macsec_setting *macsec = + IXGBE_DEV_PRIVATE_TO_MACSEC_SETTING(dev->data->dev_private); + + macsec->encrypt_en = macsec_setting->encrypt_en; + macsec->replayprotect_en = macsec_setting->replayprotect_en; +} + +void +ixgbe_dev_macsec_setting_reset(struct rte_eth_dev *dev) +{ + struct ixgbe_macsec_setting *macsec = + IXGBE_DEV_PRIVATE_TO_MACSEC_SETTING(dev->data->dev_private); + + macsec->encrypt_en = 0; + macsec->replayprotect_en = 0; +} + +void +ixgbe_dev_macsec_register_enable(struct rte_eth_dev *dev, + struct ixgbe_macsec_setting *macsec_setting) +{ + struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t ctrl; + uint8_t en = macsec_setting->encrypt_en; + uint8_t rp = macsec_setting->replayprotect_en; + + /** + * Workaround: + * As no ixgbe_disable_sec_rx_path equivalent is + * implemented for tx in the base code, and we are + * not allowed to modify the base code in DPDK, so + * just call the hand-written one directly for now. + * The hardware support has been checked by + * ixgbe_disable_sec_rx_path(). + */ + ixgbe_disable_sec_tx_path_generic(hw); + + /* Enable Ethernet CRC (required by MACsec offload) */ + ctrl = IXGBE_READ_REG(hw, IXGBE_HLREG0); + ctrl |= IXGBE_HLREG0_TXCRCEN | IXGBE_HLREG0_RXCRCSTRP; + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, ctrl); + + /* Enable the TX and RX crypto engines */ + ctrl = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL); + ctrl &= ~IXGBE_SECTXCTRL_SECTX_DIS; + IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, ctrl); + + ctrl = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); + ctrl &= ~IXGBE_SECRXCTRL_SECRX_DIS; + IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, ctrl); + + ctrl = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG); + ctrl &= ~IXGBE_SECTX_MINSECIFG_MASK; + ctrl |= 0x3; + IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, ctrl); + + /* Enable SA lookup */ + ctrl = IXGBE_READ_REG(hw, IXGBE_LSECTXCTRL); + ctrl &= ~IXGBE_LSECTXCTRL_EN_MASK; + ctrl |= en ? IXGBE_LSECTXCTRL_AUTH_ENCRYPT : + IXGBE_LSECTXCTRL_AUTH; + ctrl |= IXGBE_LSECTXCTRL_AISCI; + ctrl &= ~IXGBE_LSECTXCTRL_PNTHRSH_MASK; + ctrl |= IXGBE_MACSEC_PNTHRSH & IXGBE_LSECTXCTRL_PNTHRSH_MASK; + IXGBE_WRITE_REG(hw, IXGBE_LSECTXCTRL, ctrl); + + ctrl = IXGBE_READ_REG(hw, IXGBE_LSECRXCTRL); + ctrl &= ~IXGBE_LSECRXCTRL_EN_MASK; + ctrl |= IXGBE_LSECRXCTRL_STRICT << IXGBE_LSECRXCTRL_EN_SHIFT; + ctrl &= ~IXGBE_LSECRXCTRL_PLSH; + if (rp) + ctrl |= IXGBE_LSECRXCTRL_RP; + else + ctrl &= ~IXGBE_LSECRXCTRL_RP; + IXGBE_WRITE_REG(hw, IXGBE_LSECRXCTRL, ctrl); + + /* Start the data paths */ + ixgbe_enable_sec_rx_path(hw); + /** + * Workaround: + * As no ixgbe_enable_sec_rx_path equivalent is + * implemented for tx in the base code, and we are + * not allowed to modify the base code in DPDK, so + * just call the hand-written one directly for now. + */ + ixgbe_enable_sec_tx_path_generic(hw); +} + +void +ixgbe_dev_macsec_register_disable(struct rte_eth_dev *dev) +{ + struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t ctrl; + + /** + * Workaround: + * As no ixgbe_disable_sec_rx_path equivalent is + * implemented for tx in the base code, and we are + * not allowed to modify the base code in DPDK, so + * just call the hand-written one directly for now. + * The hardware support has been checked by + * ixgbe_disable_sec_rx_path(). + */ + ixgbe_disable_sec_tx_path_generic(hw); + + /* Disable the TX and RX crypto engines */ + ctrl = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL); + ctrl |= IXGBE_SECTXCTRL_SECTX_DIS; + IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, ctrl); + + ctrl = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); + ctrl |= IXGBE_SECRXCTRL_SECRX_DIS; + IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, ctrl); + + /* Disable SA lookup */ + ctrl = IXGBE_READ_REG(hw, IXGBE_LSECTXCTRL); + ctrl &= ~IXGBE_LSECTXCTRL_EN_MASK; + ctrl |= IXGBE_LSECTXCTRL_DISABLE; + IXGBE_WRITE_REG(hw, IXGBE_LSECTXCTRL, ctrl); + + ctrl = IXGBE_READ_REG(hw, IXGBE_LSECRXCTRL); + ctrl &= ~IXGBE_LSECRXCTRL_EN_MASK; + ctrl |= IXGBE_LSECRXCTRL_DISABLE << IXGBE_LSECRXCTRL_EN_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_LSECRXCTRL, ctrl); + + /* Start the data paths */ + ixgbe_enable_sec_rx_path(hw); + /** + * Workaround: + * As no ixgbe_enable_sec_rx_path equivalent is + * implemented for tx in the base code, and we are + * not allowed to modify the base code in DPDK, so + * just call the hand-written one directly for now. + */ + ixgbe_enable_sec_tx_path_generic(hw); +} + RTE_PMD_REGISTER_PCI(net_ixgbe, rte_ixgbe_pmd); RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe, pci_id_ixgbe_map); RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe, "* igb_uio | uio_pci_generic | vfio-pci"); @@ -8731,4 +8989,21 @@ RTE_INIT(ixgbe_init_log) ixgbe_logtype_driver = rte_log_register("pmd.net.ixgbe.driver"); if (ixgbe_logtype_driver >= 0) rte_log_set_level(ixgbe_logtype_driver, RTE_LOG_NOTICE); +#ifdef RTE_LIBRTE_IXGBE_DEBUG_RX + ixgbe_logtype_rx = rte_log_register("pmd.net.ixgbe.rx"); + if (ixgbe_logtype_rx >= 0) + rte_log_set_level(ixgbe_logtype_rx, RTE_LOG_DEBUG); +#endif + +#ifdef RTE_LIBRTE_IXGBE_DEBUG_TX + ixgbe_logtype_tx = rte_log_register("pmd.net.ixgbe.tx"); + if (ixgbe_logtype_tx >= 0) + rte_log_set_level(ixgbe_logtype_tx, RTE_LOG_DEBUG); +#endif + +#ifdef RTE_LIBRTE_IXGBE_DEBUG_TX_FREE + ixgbe_logtype_tx_free = rte_log_register("pmd.net.ixgbe.tx_free"); + if (ixgbe_logtype_tx_free >= 0) + rte_log_set_level(ixgbe_logtype_tx_free, RTE_LOG_DEBUG); +#endif }