X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fsfc_ethdev.c;h=5297159c49778374132e04f8230228d759a7c5b3;hb=a9825ccf5bb8;hp=1d5696fbc2aabc2a09db24e7e59ca42f33dc2727;hpb=af0d9317970c3fa25e0008959c1202b98318a511;p=dpdk.git diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 1d5696fbc2..5297159c49 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -40,7 +40,7 @@ #include "sfc_ev.h" #include "sfc_rx.h" #include "sfc_tx.h" - +#include "sfc_flow.h" static void sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) @@ -92,6 +92,9 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) } #endif + if (sa->tso) + dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO; + dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS; dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS; /* The RXQ hardware requires that the descriptor count is a power @@ -185,17 +188,21 @@ sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete) sfc_log_init(sa, "entry"); - if (sa->state != SFC_ADAPTER_STARTED) - return 0; - retry: EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t)); *(int64_t *)&old_link = rte_atomic64_read((rte_atomic64_t *)dev_link); - if (wait_to_complete) { + if (sa->state != SFC_ADAPTER_STARTED) { + sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, ¤t_link); + if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link, + *(uint64_t *)&old_link, + *(uint64_t *)¤t_link)) + goto retry; + } else if (wait_to_complete) { efx_link_mode_t link_mode; - efx_port_poll(sa->nic, &link_mode); + if (efx_port_poll(sa->nic, &link_mode) != 0) + link_mode = EFX_LINK_UNKNOWN; sfc_port_link_mode_to_info(link_mode, ¤t_link); if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link, @@ -518,6 +525,27 @@ unlock: rte_spinlock_unlock(&port->mac_stats_lock); } +static void +sfc_stats_reset(struct rte_eth_dev *dev) +{ + struct sfc_adapter *sa = dev->data->dev_private; + struct sfc_port *port = &sa->port; + int rc; + + if (sa->state != SFC_ADAPTER_STARTED) { + /* + * The operation cannot be done if port is not started; it + * will be scheduled to be done during the next port start + */ + port->mac_stats_reset_pending = B_TRUE; + return; + } + + rc = sfc_port_reset_mac_stats(sa); + if (rc != 0) + sfc_err(sa, "failed to reset statistics (rc = %d)", rc); +} + static int sfc_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned int xstats_count) @@ -798,8 +826,7 @@ sfc_set_mc_addr_list(struct rte_eth_dev *dev, struct ether_addr *mc_addr_set, uint32_t nb_mc_addr) { struct sfc_adapter *sa = dev->data->dev_private; - uint8_t *mc_addrs_p; - uint8_t *mc_addrs; + uint8_t *mc_addrs_p = NULL; int rc; unsigned int i; @@ -809,16 +836,20 @@ sfc_set_mc_addr_list(struct rte_eth_dev *dev, struct ether_addr *mc_addr_set, return -EINVAL; } - mc_addrs_p = rte_calloc("mc-addrs", nb_mc_addr, EFX_MAC_ADDR_LEN, 0); - if (mc_addrs_p == NULL) - return -ENOMEM; + if (nb_mc_addr != 0) { + uint8_t *mc_addrs; - mc_addrs = mc_addrs_p; + mc_addrs_p = rte_calloc("mc-addrs", nb_mc_addr, + EFX_MAC_ADDR_LEN, 0); + if (mc_addrs_p == NULL) + return -ENOMEM; - for (i = 0; i < nb_mc_addr; ++i) { - (void)rte_memcpy(mc_addrs, mc_addr_set[i].addr_bytes, - EFX_MAC_ADDR_LEN); - mc_addrs += EFX_MAC_ADDR_LEN; + mc_addrs = mc_addrs_p; + for (i = 0; i < nb_mc_addr; ++i) { + (void)rte_memcpy(mc_addrs, mc_addr_set[i].addr_bytes, + EFX_MAC_ADDR_LEN); + mc_addrs += EFX_MAC_ADDR_LEN; + } } rc = efx_mac_multicast_list_set(sa->nic, mc_addrs_p, nb_mc_addr); @@ -1116,8 +1147,123 @@ sfc_dev_rss_reta_query(struct rte_eth_dev *dev, return 0; } + +static int +sfc_dev_rss_reta_update(struct rte_eth_dev *dev, + struct rte_eth_rss_reta_entry64 *reta_conf, + uint16_t reta_size) +{ + struct sfc_adapter *sa = dev->data->dev_private; + unsigned int *rss_tbl_new; + uint16_t entry; + int rc; + + + if ((sa->rss_channels == 1) || + (sa->rss_support != EFX_RX_SCALE_EXCLUSIVE)) { + sfc_err(sa, "RSS is not available"); + return -ENOTSUP; + } + + if (reta_size != EFX_RSS_TBL_SIZE) { + sfc_err(sa, "RETA size is wrong (should be %u)", + EFX_RSS_TBL_SIZE); + return -EINVAL; + } + + rss_tbl_new = rte_zmalloc("rss_tbl_new", sizeof(sa->rss_tbl), 0); + if (rss_tbl_new == NULL) + return -ENOMEM; + + sfc_adapter_lock(sa); + + rte_memcpy(rss_tbl_new, sa->rss_tbl, sizeof(sa->rss_tbl)); + + for (entry = 0; entry < reta_size; entry++) { + int grp_idx = entry % RTE_RETA_GROUP_SIZE; + struct rte_eth_rss_reta_entry64 *grp; + + grp = &reta_conf[entry / RTE_RETA_GROUP_SIZE]; + + if (grp->mask & (1ull << grp_idx)) { + if (grp->reta[grp_idx] >= sa->rss_channels) { + rc = EINVAL; + goto bad_reta_entry; + } + rss_tbl_new[entry] = grp->reta[grp_idx]; + } + } + + rc = efx_rx_scale_tbl_set(sa->nic, rss_tbl_new, EFX_RSS_TBL_SIZE); + if (rc == 0) + rte_memcpy(sa->rss_tbl, rss_tbl_new, sizeof(sa->rss_tbl)); + +bad_reta_entry: + sfc_adapter_unlock(sa); + + rte_free(rss_tbl_new); + + SFC_ASSERT(rc >= 0); + return -rc; +} #endif +static int +sfc_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type, + enum rte_filter_op filter_op, + void *arg) +{ + struct sfc_adapter *sa = dev->data->dev_private; + int rc = ENOTSUP; + + sfc_log_init(sa, "entry"); + + switch (filter_type) { + case RTE_ETH_FILTER_NONE: + sfc_err(sa, "Global filters configuration not supported"); + break; + case RTE_ETH_FILTER_MACVLAN: + sfc_err(sa, "MACVLAN filters not supported"); + break; + case RTE_ETH_FILTER_ETHERTYPE: + sfc_err(sa, "EtherType filters not supported"); + break; + case RTE_ETH_FILTER_FLEXIBLE: + sfc_err(sa, "Flexible filters not supported"); + break; + case RTE_ETH_FILTER_SYN: + sfc_err(sa, "SYN filters not supported"); + break; + case RTE_ETH_FILTER_NTUPLE: + sfc_err(sa, "NTUPLE filters not supported"); + break; + case RTE_ETH_FILTER_TUNNEL: + sfc_err(sa, "Tunnel filters not supported"); + break; + case RTE_ETH_FILTER_FDIR: + sfc_err(sa, "Flow Director filters not supported"); + break; + case RTE_ETH_FILTER_HASH: + sfc_err(sa, "Hash filters not supported"); + break; + case RTE_ETH_FILTER_GENERIC: + if (filter_op != RTE_ETH_FILTER_GET) { + rc = EINVAL; + } else { + *(const void **)arg = &sfc_flow_ops; + rc = 0; + } + break; + default: + sfc_err(sa, "Unknown filter type %u", filter_type); + break; + } + + sfc_log_init(sa, "exit: %d", -rc); + SFC_ASSERT(rc >= 0); + return -rc; +} + static const struct eth_dev_ops sfc_eth_dev_ops = { .dev_configure = sfc_dev_configure, .dev_start = sfc_dev_start, @@ -1131,7 +1277,9 @@ static const struct eth_dev_ops sfc_eth_dev_ops = { .allmulticast_disable = sfc_dev_allmulti_disable, .link_update = sfc_dev_link_update, .stats_get = sfc_stats_get, + .stats_reset = sfc_stats_reset, .xstats_get = sfc_xstats_get, + .xstats_reset = sfc_stats_reset, .xstats_get_names = sfc_xstats_get_names, .dev_infos_get = sfc_dev_infos_get, .dev_supported_ptypes_get = sfc_dev_supported_ptypes_get, @@ -1150,10 +1298,12 @@ static const struct eth_dev_ops sfc_eth_dev_ops = { .flow_ctrl_set = sfc_flow_ctrl_set, .mac_addr_set = sfc_mac_addr_set, #if EFSYS_OPT_RX_SCALE + .reta_update = sfc_dev_rss_reta_update, .reta_query = sfc_dev_rss_reta_query, .rss_hash_update = sfc_dev_rss_hash_update, .rss_hash_conf_get = sfc_dev_rss_hash_conf_get, #endif + .filter_ctrl = sfc_dev_filter_ctrl, .set_mc_addr_list = sfc_set_mc_addr_list, .rxq_info_get = sfc_rx_queue_info_get, .txq_info_get = sfc_tx_queue_info_get, @@ -1286,6 +1436,7 @@ static struct eth_driver sfc_efx_pmd = { RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd.pci_drv); RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map); +RTE_PMD_REGISTER_KMOD_DEP(net_sfc_efx, "* igb_uio | uio_pci_generic | vfio"); RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx, SFC_KVARG_PERF_PROFILE "=" SFC_KVARG_VALUES_PERF_PROFILE " " SFC_KVARG_MCDI_LOGGING "=" SFC_KVARG_VALUES_BOOL " "