diff options
-rw-r--r-- | drivers/net/ethernet/sfc/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/ef10.c | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/ef10_sriov.c | 52 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/ef10_sriov.h | 58 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 118 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/efx.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/falcon.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/farch.c | 48 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/nic.h | 111 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/siena.c | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/siena_sriov.c | 58 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/siena_sriov.h | 79 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/sriov.c | 64 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/sriov.h | 27 |
16 files changed, 207 insertions, 454 deletions
diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile index ce8470fe79d5..3a83c0dca8e6 100644 --- a/drivers/net/ethernet/sfc/Makefile +++ b/drivers/net/ethernet/sfc/Makefile @@ -3,6 +3,6 @@ sfc-y += efx.o nic.o farch.o falcon.o siena.o ef10.o tx.o \ tenxpress.o txc43128_phy.o falcon_boards.o \ mcdi.o mcdi_port.o mcdi_mon.o ptp.o sfc-$(CONFIG_SFC_MTD) += mtd.o -sfc-$(CONFIG_SFC_SRIOV) += sriov.o siena_sriov.o ef10_sriov.o +sfc-$(CONFIG_SFC_SRIOV) += siena_sriov.o obj-$(CONFIG_SFC) += sfc.o diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 68900293ef7b..fbb6cfa0f5f1 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -15,7 +15,6 @@ #include "nic.h" #include "workarounds.h" #include "selftest.h" -#include "ef10_sriov.h" #include <linux/in.h> #include <linux/jhash.h> #include <linux/wait.h> @@ -3690,17 +3689,11 @@ const struct efx_nic_type efx_hunt_a0_nic_type = { .ptp_write_host_time = efx_ef10_ptp_write_host_time, .ptp_set_ts_sync_events = efx_ef10_ptp_set_ts_sync_events, .ptp_set_ts_config = efx_ef10_ptp_set_ts_config, - .sriov_configure = efx_ef10_sriov_configure, .sriov_init = efx_ef10_sriov_init, .sriov_fini = efx_ef10_sriov_fini, .sriov_mac_address_changed = efx_ef10_sriov_mac_address_changed, .sriov_wanted = efx_ef10_sriov_wanted, .sriov_reset = efx_ef10_sriov_reset, - .sriov_flr = efx_ef10_sriov_flr, - .sriov_set_vf_mac = efx_ef10_sriov_set_vf_mac, - .sriov_set_vf_vlan = efx_ef10_sriov_set_vf_vlan, - .sriov_set_vf_spoofchk = efx_ef10_sriov_set_vf_spoofchk, - .sriov_get_vf_config = efx_ef10_sriov_get_vf_config, .revision = EFX_REV_HUNT_A0, .max_dma_mask = DMA_BIT_MASK(ESF_DZ_TX_KER_BUF_ADDR_WIDTH), diff --git a/drivers/net/ethernet/sfc/ef10_sriov.c b/drivers/net/ethernet/sfc/ef10_sriov.c deleted file mode 100644 index 9e6a3e197e01..000000000000 --- a/drivers/net/ethernet/sfc/ef10_sriov.c +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** - * Driver for Solarflare network controllers and boards - * Copyright 2015 Solarflare Communications Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, incorporated herein by reference. - */ -#include <linux/pci.h> -#include <linux/module.h> -#include "net_driver.h" -#include "efx.h" -#include "nic.h" -#include "mcdi_pcol.h" - -#ifdef CONFIG_SFC_SRIOV -static int efx_ef10_pci_sriov_enable(struct efx_nic *efx, int num_vfs) -{ - int rc = 0; - struct pci_dev *dev = efx->pci_dev; - - efx->vf_count = num_vfs; - rc = pci_enable_sriov(dev, num_vfs); - if (rc) { - efx->vf_count = 0; - netif_err(efx, probe, efx->net_dev, - "Failed to enable SRIOV VFs\n"); - } - return rc; -} - -static int efx_ef10_pci_sriov_disable(struct efx_nic *efx) -{ - struct pci_dev *dev = efx->pci_dev; - - efx->vf_count = 0; - pci_disable_sriov(dev); - return 0; -} -#endif - -int efx_ef10_sriov_configure(struct efx_nic *efx, int num_vfs) -{ -#ifdef CONFIG_SFC_SRIOV - if (num_vfs == 0) - return efx_ef10_pci_sriov_disable(efx); - else - return efx_ef10_pci_sriov_enable(efx, num_vfs); -#else - return -EOPNOTSUPP; -#endif -} diff --git a/drivers/net/ethernet/sfc/ef10_sriov.h b/drivers/net/ethernet/sfc/ef10_sriov.h deleted file mode 100644 index 6ea115e3c3f2..000000000000 --- a/drivers/net/ethernet/sfc/ef10_sriov.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** - * Driver for Solarflare network controllers and boards - * Copyright 2015 Solarflare Communications Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, incorporated herein by reference. - */ - -#ifndef EF10_SRIOV_H -#define EF10_SRIOV_H - -#include "net_driver.h" - -static inline bool efx_ef10_sriov_wanted(struct efx_nic *efx) -{ - return false; -} - -int efx_ef10_sriov_configure(struct efx_nic *efx, int num_vfs); - -static inline int efx_ef10_sriov_init(struct efx_nic *efx) -{ - return -EOPNOTSUPP; -} - -static inline void efx_ef10_sriov_mac_address_changed(struct efx_nic *efx) {} -static inline void efx_ef10_sriov_reset(struct efx_nic *efx) {} -static inline void efx_ef10_sriov_fini(struct efx_nic *efx) {} -static inline void efx_ef10_sriov_flr(struct efx_nic *efx, unsigned vf_i) {} - -#ifdef CONFIG_SFC_SRIOV -static inline int efx_ef10_sriov_set_vf_mac(struct efx_nic *efx, int vf, - u8 *mac) -{ - return -EOPNOTSUPP; -} - -static inline int efx_ef10_sriov_set_vf_vlan(struct efx_nic *efx, int vf, - u16 vlan, u8 qos) -{ - return -EOPNOTSUPP; -} - -static inline int efx_ef10_sriov_set_vf_spoofchk(struct efx_nic *efx, int vf, - bool spoofchk) -{ - return -EOPNOTSUPP; -} - -static inline int efx_ef10_sriov_get_vf_config(struct efx_nic *efx, int vf, - struct ifla_vf_info *ivf) -{ - return -EOPNOTSUPP; -} -#endif /* CONFIG_SFC_SRIOV */ - -#endif /* EF10_SRIOV_H */ diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index fa9ce2adf542..33d2f9aa1b53 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -26,7 +26,6 @@ #include "efx.h" #include "nic.h" #include "selftest.h" -#include "sriov.h" #include "mcdi.h" #include "workarounds.h" @@ -1315,19 +1314,15 @@ static unsigned int efx_wanted_parallelism(struct efx_nic *efx) /* If RSS is requested for the PF *and* VFs then we can't write RSS * table entries that are inaccessible to VFs */ -#ifdef CONFIG_SFC_SRIOV - if (efx->type->sriov_wanted) { - if (efx->type->sriov_wanted(efx) && efx_vf_size(efx) > 1 && - count > efx_vf_size(efx)) { - netif_warn(efx, probe, efx->net_dev, - "Reducing number of RSS channels from %u to %u for " - "VF support. Increase vf-msix-limit to use more " - "channels on the PF.\n", - count, efx_vf_size(efx)); - count = efx_vf_size(efx); - } + if (efx->type->sriov_wanted(efx) && efx_vf_size(efx) > 1 && + count > efx_vf_size(efx)) { + netif_warn(efx, probe, efx->net_dev, + "Reducing number of RSS channels from %u to %u for " + "VF support. Increase vf-msix-limit to use more " + "channels on the PF.\n", + count, efx_vf_size(efx)); + count = efx_vf_size(efx); } -#endif return count; } @@ -1431,13 +1426,10 @@ static int efx_probe_interrupts(struct efx_nic *efx) } /* RSS might be usable on VFs even if it is disabled on the PF */ -#ifdef CONFIG_SFC_SRIOV - if (efx->type->sriov_wanted) { - efx->rss_spread = ((efx->n_rx_channels > 1 || - !efx->type->sriov_wanted(efx)) ? - efx->n_rx_channels : efx_vf_size(efx)); - } -#endif + + efx->rss_spread = ((efx->n_rx_channels > 1 || + !efx->type->sriov_wanted(efx)) ? + efx->n_rx_channels : efx_vf_size(efx)); return 0; } @@ -2176,8 +2168,7 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data) } ether_addr_copy(net_dev->dev_addr, new_addr); - if (efx->type->sriov_mac_address_changed) - efx->type->sriov_mac_address_changed(efx); + efx->type->sriov_mac_address_changed(efx); /* Reconfigure the MAC */ mutex_lock(&efx->mac_lock); @@ -2208,7 +2199,7 @@ static int efx_set_features(struct net_device *net_dev, netdev_features_t data) return 0; } -static const struct net_device_ops efx_netdev_ops = { +static const struct net_device_ops efx_farch_netdev_ops = { .ndo_open = efx_net_open, .ndo_stop = efx_net_stop, .ndo_get_stats64 = efx_net_stats, @@ -2221,10 +2212,10 @@ static const struct net_device_ops efx_netdev_ops = { .ndo_set_rx_mode = efx_set_rx_mode, .ndo_set_features = efx_set_features, #ifdef CONFIG_SFC_SRIOV - .ndo_set_vf_mac = efx_sriov_set_vf_mac, - .ndo_set_vf_vlan = efx_sriov_set_vf_vlan, - .ndo_set_vf_spoofchk = efx_sriov_set_vf_spoofchk, - .ndo_get_vf_config = efx_sriov_get_vf_config, + .ndo_set_vf_mac = efx_siena_sriov_set_vf_mac, + .ndo_set_vf_vlan = efx_siena_sriov_set_vf_vlan, + .ndo_set_vf_spoofchk = efx_siena_sriov_set_vf_spoofchk, + .ndo_get_vf_config = efx_siena_sriov_get_vf_config, #endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = efx_netpoll, @@ -2238,6 +2229,29 @@ static const struct net_device_ops efx_netdev_ops = { #endif }; +static const struct net_device_ops efx_ef10_netdev_ops = { + .ndo_open = efx_net_open, + .ndo_stop = efx_net_stop, + .ndo_get_stats64 = efx_net_stats, + .ndo_tx_timeout = efx_watchdog, + .ndo_start_xmit = efx_hard_start_xmit, + .ndo_validate_addr = eth_validate_addr, + .ndo_do_ioctl = efx_ioctl, + .ndo_change_mtu = efx_change_mtu, + .ndo_set_mac_address = efx_set_mac_address, + .ndo_set_rx_mode = efx_set_rx_mode, + .ndo_set_features = efx_set_features, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = efx_netpoll, +#endif +#ifdef CONFIG_NET_RX_BUSY_POLL + .ndo_busy_poll = efx_busy_poll, +#endif +#ifdef CONFIG_RFS_ACCEL + .ndo_rx_flow_steer = efx_filter_rfs, +#endif +}; + static void efx_update_name(struct efx_nic *efx) { strcpy(efx->name, efx->net_dev->name); @@ -2250,7 +2264,8 @@ static int efx_netdev_event(struct notifier_block *this, { struct net_device *net_dev = netdev_notifier_info_to_dev(ptr); - if ((net_dev->netdev_ops == &efx_netdev_ops) && + if ((net_dev->netdev_ops == &efx_farch_netdev_ops || + net_dev->netdev_ops == &efx_ef10_netdev_ops) && event == NETDEV_CHANGENAME) efx_update_name(netdev_priv(net_dev)); @@ -2277,9 +2292,12 @@ static int efx_register_netdev(struct efx_nic *efx) net_dev->watchdog_timeo = 5 * HZ; net_dev->irq = efx->pci_dev->irq; - net_dev->netdev_ops = &efx_netdev_ops; - if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) + if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) { + net_dev->netdev_ops = &efx_ef10_netdev_ops; net_dev->priv_flags |= IFF_UNICAST_FLT; + } else { + net_dev->netdev_ops = &efx_farch_netdev_ops; + } net_dev->ethtool_ops = &efx_ethtool_ops; net_dev->gso_max_segs = EFX_TSO_MAX_SEGS; @@ -2417,8 +2435,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok) if (rc) goto fail; efx_restore_filters(efx); - if (efx->type->sriov_reset) - efx->type->sriov_reset(efx); + efx->type->sriov_reset(efx); mutex_unlock(&efx->mac_lock); @@ -2811,9 +2828,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev) efx_disable_interrupts(efx); rtnl_unlock(); - if (efx->type->sriov_fini) - efx->type->sriov_fini(efx); - + efx->type->sriov_fini(efx); efx_unregister_netdev(efx); efx_mtd_remove(efx); @@ -3010,12 +3025,10 @@ static int efx_pci_probe(struct pci_dev *pci_dev, if (rc) goto fail4; - if (efx->type->sriov_init) { - rc = efx->type->sriov_init(efx); - if (rc) - netif_err(efx, probe, efx->net_dev, - "SR-IOV can't be enabled rc %d\n", rc); - } + rc = efx->type->sriov_init(efx); + if (rc) + netif_err(efx, probe, efx->net_dev, + "SR-IOV can't be enabled rc %d\n", rc); netif_dbg(efx, probe, efx->net_dev, "initialisation successful\n"); @@ -3047,26 +3060,6 @@ static int efx_pci_probe(struct pci_dev *pci_dev, return rc; } -/* efx_pci_sriov_configure returns the actual number of Virtual Functions - * enabled on success - */ -#ifdef CONFIG_SFC_SRIOV -static int efx_pci_sriov_configure(struct pci_dev *dev, int num_vfs) -{ - int rc; - struct efx_nic *efx = pci_get_drvdata(dev); - - if (efx->type->sriov_configure) { - rc = efx->type->sriov_configure(efx, num_vfs); - if (rc) - return rc; - else - return num_vfs; - } else - return -ENOSYS; -} -#endif - static int efx_pm_freeze(struct device *dev) { struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); @@ -3289,9 +3282,6 @@ static struct pci_driver efx_pci_driver = { .remove = efx_pci_remove, .driver.pm = &efx_pm_ops, .err_handler = &efx_err_handlers, -#ifdef CONFIG_SFC_SRIOV - .sriov_configure = efx_pci_sriov_configure, -#endif }; /************************************************************************** diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index bc4e4b3e6aad..2587c582a821 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -220,13 +220,6 @@ static inline void efx_mtd_rename(struct efx_nic *efx) {} static inline void efx_mtd_remove(struct efx_nic *efx) {} #endif -#ifdef CONFIG_SFC_SRIOV -static inline unsigned int efx_vf_size(struct efx_nic *efx) -{ - return 1 << efx->vi_scale; -} -#endif - static inline void efx_schedule_channel(struct efx_channel *channel) { netif_vdbg(channel->efx, intr, channel->efx->net_dev, diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 157037546d30..f166c8ef38a3 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -2766,6 +2766,11 @@ const struct efx_nic_type falcon_a1_nic_type = { .mtd_write = falcon_mtd_write, .mtd_sync = falcon_mtd_sync, #endif + .sriov_init = efx_falcon_sriov_init, + .sriov_fini = efx_falcon_sriov_fini, + .sriov_mac_address_changed = efx_falcon_sriov_mac_address_changed, + .sriov_wanted = efx_falcon_sriov_wanted, + .sriov_reset = efx_falcon_sriov_reset, .revision = EFX_REV_FALCON_A1, .txd_ptr_tbl_base = FR_AA_TX_DESC_PTR_TBL_KER, @@ -2862,6 +2867,11 @@ const struct efx_nic_type falcon_b0_nic_type = { .mtd_write = falcon_mtd_write, .mtd_sync = falcon_mtd_sync, #endif + .sriov_init = efx_falcon_sriov_init, + .sriov_fini = efx_falcon_sriov_fini, + .sriov_mac_address_changed = efx_falcon_sriov_mac_address_changed, + .sriov_wanted = efx_falcon_sriov_wanted, + .sriov_reset = efx_falcon_sriov_reset, .revision = EFX_REV_FALCON_B0, .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index c3a032e97e04..bb89e96a125e 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c @@ -20,8 +20,6 @@ #include "efx.h" #include "nic.h" #include "farch_regs.h" -#include "sriov.h" -#include "siena_sriov.h" #include "io.h" #include "workarounds.h" @@ -1687,32 +1685,28 @@ void efx_farch_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw) vi_count = max(efx->n_channels, efx->n_tx_channels * EFX_TXQ_TYPES); #ifdef CONFIG_SFC_SRIOV - if (efx->type->sriov_wanted) { - if (efx->type->sriov_wanted(efx)) { - unsigned vi_dc_entries, buftbl_free; - unsigned entries_per_vf, vf_limit; - - nic_data->vf_buftbl_base = buftbl_min; - - vi_dc_entries = RX_DC_ENTRIES + TX_DC_ENTRIES; - vi_count = max(vi_count, EFX_VI_BASE); - buftbl_free = (sram_lim_qw - buftbl_min - - vi_count * vi_dc_entries); - - entries_per_vf = ((vi_dc_entries + - EFX_VF_BUFTBL_PER_VI) * - efx_vf_size(efx)); - vf_limit = min(buftbl_free / entries_per_vf, - (1024U - EFX_VI_BASE) >> efx->vi_scale); - - if (efx->vf_count > vf_limit) { - netif_err(efx, probe, efx->net_dev, - "Reducing VF count from from %d to %d\n", - efx->vf_count, vf_limit); - efx->vf_count = vf_limit; - } - vi_count += efx->vf_count * efx_vf_size(efx); + if (efx->type->sriov_wanted(efx)) { + unsigned vi_dc_entries, buftbl_free, entries_per_vf, vf_limit; + + nic_data->vf_buftbl_base = buftbl_min; + + vi_dc_entries = RX_DC_ENTRIES + TX_DC_ENTRIES; + vi_count = max(vi_count, EFX_VI_BASE); + buftbl_free = (sram_lim_qw - buftbl_min - + vi_count * vi_dc_entries); + + entries_per_vf = ((vi_dc_entries + EFX_VF_BUFTBL_PER_VI) * + efx_vf_size(efx)); + vf_limit = min(buftbl_free / entries_per_vf, + (1024U - EFX_VI_BASE) >> efx->vi_scale); + + if (efx->vf_count > vf_limit) { + netif_err(efx, probe, efx->net_dev, + "Reducing VF count from from %d to %d\n", + efx->vf_count, vf_limit); + efx->vf_count = vf_limit; } + vi_count += efx->vf_count * efx_vf_size(efx); } #endif diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 6502ada36d49..d37928f01949 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -1035,9 +1035,7 @@ void efx_mcdi_process_event(struct efx_channel *channel, /* MAC stats are gather lazily. We can ignore this. */ break; case MCDI_EVENT_CODE_FLR: - if (efx->type->sriov_flr) - efx->type->sriov_flr(efx, - MCDI_EVENT_FIELD(*event, FLR_VF)); + efx_siena_sriov_flr(efx, MCDI_EVENT_FIELD(*event, FLR_VF)); break; case MCDI_EVENT_CODE_PTP_RX: case MCDI_EVENT_CODE_PTP_FAULT: diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index a6f4d9aadd40..325dd94bca46 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -1330,20 +1330,11 @@ struct efx_nic_type { int (*ptp_set_ts_sync_events)(struct efx_nic *efx, bool en, bool temp); int (*ptp_set_ts_config)(struct efx_nic *efx, struct hwtstamp_config *init); - int (*sriov_configure)(struct efx_nic *efx, int num_vfs); int (*sriov_init)(struct efx_nic *efx); void (*sriov_fini)(struct efx_nic *efx); void (*sriov_mac_address_changed)(struct efx_nic *efx); bool (*sriov_wanted)(struct efx_nic *efx); void (*sriov_reset)(struct efx_nic *efx); - void (*sriov_flr)(struct efx_nic *efx, unsigned vf_i); - int (*sriov_set_vf_mac)(struct efx_nic *efx, int vf_i, u8 *mac); - int (*sriov_set_vf_vlan)(struct efx_nic *efx, int vf_i, u16 vlan, - u8 qos); - int (*sriov_set_vf_spoofchk)(struct efx_nic *efx, int vf_i, - bool spoofchk); - int (*sriov_get_vf_config)(struct efx_nic *efx, int vf_i, - struct ifla_vf_info *ivi); int revision; unsigned int txd_ptr_tbl_base; diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index ea4ca18df7c5..93d10cbbd1cf 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h @@ -509,9 +509,120 @@ struct efx_ef10_nic_data { u32 datapath_caps; }; +/* + * On the SFC9000 family each port is associated with 1 PCI physical + * function (PF) handled by sfc and a configurable number of virtual + * functions (VFs) that may be handled by some other driver, often in + * a VM guest. The queue pointer registers are mapped in both PF and + * VF BARs such that an 8K region provides access to a single RX, TX + * and event queue (collectively a Virtual Interface, VI or VNIC). + * + * The PF has access to all 1024 VIs while VFs are mapped to VIs + * according to VI_BASE and VI_SCALE: VF i has access to VIs numbered + * in range [VI_BASE + i << VI_SCALE, VI_BASE + i + 1 << VI_SCALE). + * The number of VIs and the VI_SCALE value are configurable but must + * be established at boot time by firmware. + */ + +/* Maximum VI_SCALE parameter supported by Siena */ +#define EFX_VI_SCALE_MAX 6 +/* Base VI to use for SR-IOV. Must be aligned to (1 << EFX_VI_SCALE_MAX), + * so this is the smallest allowed value. */ +#define EFX_VI_BASE 128U +/* Maximum number of VFs allowed */ +#define EFX_VF_COUNT_MAX 127 +/* Limit EVQs on VFs to be only 8k to reduce buffer table reservation */ +#define EFX_MAX_VF_EVQ_SIZE 8192UL +/* The number of buffer table entries reserved for each VI on a VF */ +#define EFX_VF_BUFTBL_PER_VI \ + ((EFX_MAX_VF_EVQ_SIZE + 2 * EFX_MAX_DMAQ_SIZE) * \ + sizeof(efx_qword_t) / EFX_BUF_SIZE) + +#ifdef CONFIG_SFC_SRIOV + +/* SIENA */ +static inline bool efx_siena_sriov_wanted(struct efx_nic *efx) +{ + return efx->vf_count != 0; +} + +static inline bool efx_siena_sriov_enabled(struct efx_nic *efx) +{ + return efx->vf_init_count != 0; +} + +static inline unsigned int efx_vf_size(struct efx_nic *efx) +{ + return 1 << efx->vi_scale; +} + int efx_init_sriov(void); +void efx_siena_sriov_probe(struct efx_nic *efx); +int efx_siena_sriov_init(struct efx_nic *efx); +void efx_siena_sriov_mac_address_changed(struct efx_nic *efx); +void efx_siena_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event); +void efx_siena_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event); +void efx_siena_sriov_event(struct efx_channel *channel, efx_qword_t *event); +void efx_siena_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq); +void efx_siena_sriov_flr(struct efx_nic *efx, unsigned flr); +void efx_siena_sriov_reset(struct efx_nic *efx); +void efx_siena_sriov_fini(struct efx_nic *efx); void efx_fini_sriov(void); +/* EF10 */ +static inline bool efx_ef10_sriov_wanted(struct efx_nic *efx) { return false; } +static inline int efx_ef10_sriov_init(struct efx_nic *efx) { return -EOPNOTSUPP; } +static inline void efx_ef10_sriov_mac_address_changed(struct efx_nic *efx) {} +static inline void efx_ef10_sriov_reset(struct efx_nic *efx) {} +static inline void efx_ef10_sriov_fini(struct efx_nic *efx) {} + +#else + +/* SIENA */ +static inline bool efx_siena_sriov_wanted(struct efx_nic *efx) { return false; } +static inline bool efx_siena_sriov_enabled(struct efx_nic *efx) { return false; } +static inline unsigned int efx_vf_size(struct efx_nic *efx) { return 0; } +static inline int efx_init_sriov(void) { return 0; } +static inline void efx_siena_sriov_probe(struct efx_nic *efx) {} +static inline int efx_siena_sriov_init(struct efx_nic *efx) { return -EOPNOTSUPP; } +static inline void efx_siena_sriov_mac_address_changed(struct efx_nic *efx) {} +static inline void efx_siena_sriov_tx_flush_done(struct efx_nic *efx, + efx_qword_t *event) {} +static inline void efx_siena_sriov_rx_flush_done(struct efx_nic *efx, + efx_qword_t *event) {} +static inline void efx_siena_sriov_event(struct efx_channel *channel, + efx_qword_t *event) {} +static inline void efx_siena_sriov_desc_fetch_err(struct efx_nic *efx, + unsigned dmaq) {} +static inline void efx_siena_sriov_flr(struct efx_nic *efx, unsigned flr) {} +static inline void efx_siena_sriov_reset(struct efx_nic *efx) {} +static inline void efx_siena_sriov_fini(struct efx_nic *efx) {} +static inline void efx_fini_sriov(void) {} + +/* EF10 */ +static inline bool efx_ef10_sriov_wanted(struct efx_nic *efx) { return false; } +static inline int efx_ef10_sriov_init(struct efx_nic *efx) { return -EOPNOTSUPP; } +static inline void efx_ef10_sriov_mac_address_changed(struct efx_nic *efx) {} +static inline void efx_ef10_sriov_reset(struct efx_nic *efx) {} +static inline void efx_ef10_sriov_fini(struct efx_nic *efx) {} + +#endif + +/* FALCON */ +static inline bool efx_falcon_sriov_wanted(struct efx_nic *efx) { return false; } +static inline int efx_falcon_sriov_init(struct efx_nic *efx) { return -EOPNOTSUPP; } +static inline void efx_falcon_sriov_mac_address_changed(struct efx_nic *efx) {} +static inline void efx_falcon_sriov_reset(struct efx_nic *efx) {} +static inline void efx_falcon_sriov_fini(struct efx_nic *efx) {} + +int efx_siena_sriov_set_vf_mac(struct net_device *dev, int vf, u8 *mac); +int efx_siena_sriov_set_vf_vlan(struct net_device *dev, int vf, + u16 vlan, u8 qos); +int efx_siena_sriov_get_vf_config(struct net_device *dev, int vf, + struct ifla_vf_info *ivf); +int efx_siena_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf, + bool spoofchk); + struct ethtool_ts_info; int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel); void efx_ptp_defer_probe_with_channel(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index 49792287dd67..3583f0208a6e 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -25,7 +25,6 @@ #include "mcdi.h" #include "mcdi_pcol.h" #include "selftest.h" -#include "siena_sriov.h" /* Hardware control for SFC9000 family including SFL9021 (aka Siena). */ @@ -998,17 +997,11 @@ const struct efx_nic_type siena_a0_nic_type = { #endif .ptp_write_host_time = siena_ptp_write_host_time, .ptp_set_ts_config = siena_ptp_set_ts_config, - .sriov_configure = efx_siena_sriov_configure, .sriov_init = efx_siena_sriov_init, .sriov_fini = efx_siena_sriov_fini, .sriov_mac_address_changed = efx_siena_sriov_mac_address_changed, .sriov_wanted = efx_siena_sriov_wanted, .sriov_reset = efx_siena_sriov_reset, - .sriov_flr = efx_siena_sriov_flr, - .sriov_set_vf_mac = efx_siena_sriov_set_vf_mac, - .sriov_set_vf_vlan = efx_siena_sriov_set_vf_vlan, - .sriov_set_vf_spoofchk = efx_siena_sriov_set_vf_spoofchk, - .sriov_get_vf_config = efx_siena_sriov_get_vf_config, .revision = EFX_REV_SIENA_A0, .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c index 9366756e6101..fe83430796fd 100644 --- a/drivers/net/ethernet/sfc/siena_sriov.c +++ b/drivers/net/ethernet/sfc/siena_sriov.c @@ -16,7 +16,6 @@ #include "filter.h" #include "mcdi_pcol.h" #include "farch_regs.h" -#include "siena_sriov.h" #include "vfdi.h" /* Number of longs required to track all the VIs in a VF */ @@ -1051,7 +1050,6 @@ static const struct efx_channel_type efx_siena_sriov_channel_type = { void efx_siena_sriov_probe(struct efx_nic *efx) { -#ifdef CONFIG_SFC_SRIOV unsigned count; if (!max_vfs) @@ -1066,10 +1064,8 @@ void efx_siena_sriov_probe(struct efx_nic *efx) efx->vf_count = count; efx->extra_channel_type[EFX_EXTRA_CHANNEL_IOV] = &efx_siena_sriov_channel_type; -#endif } -#ifdef CONFIG_SFC_SRIOV /* Copy the list of individual addresses into the vfdi_status.peers * array and auxiliary pages, protected by %local_lock. Drop that lock * and then broadcast the address list to every VF. @@ -1280,11 +1276,9 @@ fail: efx_siena_sriov_vfs_fini(efx); return rc; } -#endif int efx_siena_sriov_init(struct efx_nic *efx) { -#ifdef CONFIG_SFC_SRIOV struct net_device *net_dev = efx->net_dev; struct siena_nic_data *nic_data = efx->nic_data; struct vfdi_status *vfdi_status; @@ -1363,14 +1357,10 @@ fail_status: efx_siena_sriov_cmd(efx, false, NULL, NULL); fail_cmd: return rc; -#else /* CONFIG_SFC_SRIOV */ - return -EOPNOTSUPP; -#endif } void efx_siena_sriov_fini(struct efx_nic *efx) { -#ifdef CONFIG_SFC_SRIOV struct efx_vf *vf; unsigned int pos; struct siena_nic_data *nic_data = efx->nic_data; @@ -1401,12 +1391,10 @@ void efx_siena_sriov_fini(struct efx_nic *efx) kfree(efx->vf); efx_nic_free_buffer(efx, &nic_data->vfdi_status); efx_siena_sriov_cmd(efx, false, NULL, NULL); -#endif /* CONFIG_SFC_SRIOV*/ } void efx_siena_sriov_event(struct efx_channel *channel, efx_qword_t *event) { -#ifdef CONFIG_SFC_SRIOV struct efx_nic *efx = channel->efx; struct efx_vf *vf; unsigned qid, seq, type, data; @@ -1460,12 +1448,10 @@ error: /* Reset the request and sequence number */ vf->req_type = VFDI_EV_TYPE_REQ_WORD0; vf->req_seqno = seq + 1; -#endif /* CONFIG_SFC_SRIOV */ } void efx_siena_sriov_flr(struct efx_nic *efx, unsigned vf_i) { -#ifdef CONFIG_SFC_SRIOV struct efx_vf *vf; if (vf_i > efx->vf_init_count) @@ -1479,12 +1465,10 @@ void efx_siena_sriov_flr(struct efx_nic *efx, unsigned vf_i) efx_vfdi_flush_clear(vf); vf->evq0_count = 0; -#endif /* CONFIG_SFC_SRIOV */ } void efx_siena_sriov_mac_address_changed(struct efx_nic *efx) { -#ifdef CONFIG_SFC_SRIOV struct siena_nic_data *nic_data = efx->nic_data; struct vfdi_status *vfdi_status = nic_data->vfdi_status.addr; @@ -1493,12 +1477,10 @@ void efx_siena_sriov_mac_address_changed(struct efx_nic *efx) ether_addr_copy(vfdi_status->peers[0].mac_addr, efx->net_dev->dev_addr); queue_work(vfdi_workqueue, &nic_data->peer_work); -#endif /* CONFIG_SFC_SRIOV */ } void efx_siena_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event) { -#ifdef CONFIG_SFC_SRIOV struct efx_vf *vf; unsigned queue, qid; @@ -1514,12 +1496,10 @@ void efx_siena_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event) if (efx_vfdi_flush_wake(vf)) wake_up(&vf->flush_waitq); -#endif /* CONFIG_SFC_SRIOV */ } void efx_siena_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event) { -#ifdef CONFIG_SFC_SRIOV struct efx_vf *vf; unsigned ev_failed, queue, qid; @@ -1540,13 +1520,11 @@ void efx_siena_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event) } if (efx_vfdi_flush_wake(vf)) wake_up(&vf->flush_waitq); -#endif /* CONFIG_SFC_SRIOV */ } /* Called from napi. Schedule the reset work item */ void efx_siena_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq) { -#ifdef CONFIG_SFC_SRIOV struct efx_vf *vf; unsigned int rel; @@ -1558,13 +1536,11 @@ void efx_siena_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq) "VF %d DMA Q %d reports descriptor fetch error.\n", vf->index, rel); queue_work(vfdi_workqueue, &vf->reset_work); -#endif /* CONFIG_SFC_SRIOV */ } /* Reset all VFs */ void efx_siena_sriov_reset(struct efx_nic *efx) { -#ifdef CONFIG_SFC_SRIOV unsigned int vf_i; struct efx_buffer buf; struct efx_vf *vf; @@ -1586,12 +1562,10 @@ void efx_siena_sriov_reset(struct efx_nic *efx) } efx_nic_free_buffer(efx, &buf); -#endif /* CONFIG_SFC_SRIOV */ } int efx_init_sriov(void) { -#ifdef CONFIG_SFC_SRIOV /* A single threaded workqueue is sufficient. efx_siena_sriov_vfdi() and * efx_siena_sriov_peer_work() spend almost all their time sleeping for * MCDI to complete anyway @@ -1599,20 +1573,18 @@ int efx_init_sriov(void) vfdi_workqueue = create_singlethread_workqueue("sfc_vfdi"); if (!vfdi_workqueue) return -ENOMEM; -#endif + return 0; } void efx_fini_sriov(void) { -#ifdef CONFIG_SFC_SRIOV destroy_workqueue(vfdi_workqueue); -#endif } -#ifdef CONFIG_SFC_SRIOV -int efx_siena_sriov_set_vf_mac(struct efx_nic *efx, int vf_i, u8 *mac) +int efx_siena_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac) { + struct efx_nic *efx = netdev_priv(net_dev); struct efx_vf *vf; if (vf_i >= efx->vf_init_count) @@ -1627,9 +1599,10 @@ int efx_siena_sriov_set_vf_mac(struct efx_nic *efx, int vf_i, u8 *mac) return 0; } -int efx_siena_sriov_set_vf_vlan(struct efx_nic *efx, int vf_i, +int efx_siena_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan, u8 qos) { + struct efx_nic *efx = netdev_priv(net_dev); struct efx_vf *vf; u16 tci; @@ -1646,9 +1619,10 @@ int efx_siena_sriov_set_vf_vlan(struct efx_nic *efx, int vf_i, return 0; } -int efx_siena_sriov_set_vf_spoofchk(struct efx_nic *efx, int vf_i, +int efx_siena_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i, bool spoofchk) { + struct efx_nic *efx = netdev_priv(net_dev); struct efx_vf *vf; int rc; @@ -1669,9 +1643,10 @@ int efx_siena_sriov_set_vf_spoofchk(struct efx_nic *efx, int vf_i, return rc; } -int efx_siena_sriov_get_vf_config(struct efx_nic *efx, int vf_i, +int efx_siena_sriov_get_vf_config(struct net_device *net_dev, int vf_i, struct ifla_vf_info *ivi) { + struct efx_nic *efx = netdev_priv(net_dev); struct efx_vf *vf; u16 tci; @@ -1691,18 +1666,3 @@ int efx_siena_sriov_get_vf_config(struct efx_nic *efx, int vf_i, return 0; } -#endif /* CONFIG_SFC_SRIOV */ - -bool efx_siena_sriov_wanted(struct efx_nic *efx) -{ -#ifdef CONFIG_SFC_SRIOV - return efx->vf_count != 0; -#else - return false; -#endif -} - -int efx_siena_sriov_configure(struct efx_nic *efx, int num_vfs) -{ - return 0; -} diff --git a/drivers/net/ethernet/sfc/siena_sriov.h b/drivers/net/ethernet/sfc/siena_sriov.h deleted file mode 100644 index 8b2ca430a4ea..000000000000 --- a/drivers/net/ethernet/sfc/siena_sriov.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** - * Driver for Solarflare network controllers and boards - * Copyright 2015 Solarflare Communications Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, incorporated herein by reference. - */ - -#ifndef SIENA_SRIOV_H -#define SIENA_SRIOV_H - -#include "net_driver.h" - -/* On the SFC9000 family each port is associated with 1 PCI physical - * function (PF) handled by sfc and a configurable number of virtual - * functions (VFs) that may be handled by some other driver, often in - * a VM guest. The queue pointer registers are mapped in both PF and - * VF BARs such that an 8K region provides access to a single RX, TX - * and event queue (collectively a Virtual Interface, VI or VNIC). - * - * The PF has access to all 1024 VIs while VFs are mapped to VIs - * according to VI_BASE and VI_SCALE: VF i has access to VIs numbered - * in range [VI_BASE + i << VI_SCALE, VI_BASE + i + 1 << VI_SCALE). - * The number of VIs and the VI_SCALE value are configurable but must - * be established at boot time by firmware. - */ - -/* Maximum VI_SCALE parameter supported by Siena */ -#define EFX_VI_SCALE_MAX 6 -/* Base VI to use for SR-IOV. Must be aligned to (1 << EFX_VI_SCALE_MAX), - * so this is the smallest allowed value. - */ -#define EFX_VI_BASE 128U -/* Maximum number of VFs allowed */ -#define EFX_VF_COUNT_MAX 127 -/* Limit EVQs on VFs to be only 8k to reduce buffer table reservation */ -#define EFX_MAX_VF_EVQ_SIZE 8192UL -/* The number of buffer table entries reserved for each VI on a VF */ -#define EFX_VF_BUFTBL_PER_VI \ - ((EFX_MAX_VF_EVQ_SIZE + 2 * EFX_MAX_DMAQ_SIZE) * \ - sizeof(efx_qword_t) / EFX_BUF_SIZE) - -int efx_siena_sriov_configure(struct efx_nic *efx, int num_vfs); -int efx_siena_sriov_init(struct efx_nic *efx); -void efx_siena_sriov_fini(struct efx_nic *efx); -void efx_siena_sriov_mac_address_changed(struct efx_nic *efx); -bool efx_siena_sriov_wanted(struct efx_nic *efx); -void efx_siena_sriov_reset(struct efx_nic *efx); -void efx_siena_sriov_flr(struct efx_nic *efx, unsigned flr); - -#ifdef CONFIG_SFC_SRIOV - -int efx_siena_sriov_set_vf_mac(struct efx_nic *efx, int vf, u8 *mac); -int efx_siena_sriov_set_vf_vlan(struct efx_nic *efx, int vf, - u16 vlan, u8 qos); -int efx_siena_sriov_set_vf_spoofchk(struct efx_nic *efx, int vf, - bool spoofchk); -int efx_siena_sriov_get_vf_config(struct efx_nic *efx, int vf, - struct ifla_vf_info *ivf); - -static inline bool efx_siena_sriov_enabled(struct efx_nic *efx) -{ - return efx->vf_init_count != 0; -} -#else /* !CONFIG_SFC_SRIOV */ -static inline bool efx_siena_sriov_enabled(struct efx_nic *efx) -{ - return false; -} -#endif /* CONFIG_SFC_SRIOV */ - -void efx_siena_sriov_probe(struct efx_nic *efx); -void efx_siena_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event); -void efx_siena_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event); -void efx_siena_sriov_event(struct efx_channel *channel, efx_qword_t *event); -void efx_siena_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq); - -#endif /* SIENA_SRIOV_H */ diff --git a/drivers/net/ethernet/sfc/sriov.c b/drivers/net/ethernet/sfc/sriov.c deleted file mode 100644 index ea0b6e763887..000000000000 --- a/drivers/net/ethernet/sfc/sriov.c +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** - * Driver for Solarflare network controllers and boards - * Copyright 2014-2015 Solarflare Communications Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, incorporated herein by reference. - */ -#include <linux/module.h> -#include "net_driver.h" -#include "nic.h" -#include "sriov.h" - -#ifdef CONFIG_SFC_SRIOV - -int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac) -{ - struct efx_nic *efx = netdev_priv(net_dev); - - if (efx->type->sriov_set_vf_mac) - return efx->type->sriov_set_vf_mac(efx, vf_i, mac); - else - return -EOPNOTSUPP; -} - -int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan, - u8 qos) -{ - struct efx_nic *efx = netdev_priv(net_dev); - - if (efx->type->sriov_set_vf_vlan) { - if ((vlan & ~VLAN_VID_MASK) || - (qos & ~(VLAN_PRIO_MASK >> VLAN_PRIO_SHIFT))) - return -EINVAL; - - return efx->type->sriov_set_vf_vlan(efx, vf_i, vlan, qos); - } else { - return -EOPNOTSUPP; - } -} - -int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i, - bool spoofchk) -{ - struct efx_nic *efx = netdev_priv(net_dev); - - if (efx->type->sriov_set_vf_spoofchk) - return efx->type->sriov_set_vf_spoofchk(efx, vf_i, spoofchk); - else - return -EOPNOTSUPP; -} - -int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i, - struct ifla_vf_info *ivi) -{ - struct efx_nic *efx = netdev_priv(net_dev); - - if (efx->type->sriov_get_vf_config) - return efx->type->sriov_get_vf_config(efx, vf_i, ivi); - else - return -EOPNOTSUPP; -} - -#endif diff --git a/drivers/net/ethernet/sfc/sriov.h b/drivers/net/ethernet/sfc/sriov.h deleted file mode 100644 index 0b9f0f6acf3b..000000000000 --- a/drivers/net/ethernet/sfc/sriov.h +++ /dev/null @@ -1,27 +0,0 @@ -/**************************************************************************** - * Driver for Solarflare network controllers and boards - * Copyright 2014-2015 Solarflare Communications Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, incorporated herein by reference. - */ - -#ifndef EFX_SRIOV_H -#define EFX_SRIOV_H - -#include "net_driver.h" - -#ifdef CONFIG_SFC_SRIOV - -int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac); -int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan, - u8 qos); -int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i, - bool spoofchk); -int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i, - struct ifla_vf_info *ivi); - -#endif /* CONFIG_SFC_SRIOV */ - -#endif /* EFX_SRIOV_H */ |