Skip to content

Commit

Permalink
sfc: Own header for nic-specific sriov functions, single instance of …
Browse files Browse the repository at this point in the history
…netdev_ops and sriov removed from Falcon code

By putting all the efx_{siena,ef10}_sriov_* declarations in
{siena,ef10}_sriov.h, ensure they cannot be called from nic-generic code.
Also fixes up an instance of this, where mcdi.c was calling
efx_siena_sriov_flr.

The single instance of netdev_ops should call general high level
functions that can then call something adapter specific in efx_nic_type.
We should only do adapter specialisation via efx_nic_type.

Removal of sriov functionality from the Falcon code means that tests
are needed for the presence of some callbacks.

Signed-off-by: Shradha Shah <sshah@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Shradha Shah authored and David S. Miller committed Apr 8, 2015
1 parent b5de97b commit d92916f
Show file tree
Hide file tree
Showing 15 changed files with 368 additions and 207 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/sfc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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) += siena_sriov.o
sfc-$(CONFIG_SFC_SRIOV) += sriov.o siena_sriov.o

obj-$(CONFIG_SFC) += sfc.o
6 changes: 6 additions & 0 deletions drivers/net/ethernet/sfc/ef10.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#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>
Expand Down Expand Up @@ -3694,6 +3695,11 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.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),
Expand Down
56 changes: 56 additions & 0 deletions drivers/net/ethernet/sfc/ef10_sriov.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/****************************************************************************
* 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;
}

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 */
95 changes: 41 additions & 54 deletions drivers/net/ethernet/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "efx.h"
#include "nic.h"
#include "selftest.h"
#include "sriov.h"

#include "mcdi.h"
#include "workarounds.h"
Expand Down Expand Up @@ -1314,15 +1315,19 @@ 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
*/
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);
#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);
}
}
#endif

return count;
}
Expand Down Expand Up @@ -1426,10 +1431,13 @@ static int efx_probe_interrupts(struct efx_nic *efx)
}

/* RSS might be usable on VFs even if it is disabled on the PF */

efx->rss_spread = ((efx->n_rx_channels > 1 ||
!efx->type->sriov_wanted(efx)) ?
efx->n_rx_channels : efx_vf_size(efx));
#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

return 0;
}
Expand Down Expand Up @@ -2168,7 +2176,8 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
}

ether_addr_copy(net_dev->dev_addr, new_addr);
efx->type->sriov_mac_address_changed(efx);
if (efx->type->sriov_mac_address_changed)
efx->type->sriov_mac_address_changed(efx);

/* Reconfigure the MAC */
mutex_lock(&efx->mac_lock);
Expand Down Expand Up @@ -2199,7 +2208,7 @@ static int efx_set_features(struct net_device *net_dev, netdev_features_t data)
return 0;
}

static const struct net_device_ops efx_farch_netdev_ops = {
static const struct net_device_ops efx_netdev_ops = {
.ndo_open = efx_net_open,
.ndo_stop = efx_net_stop,
.ndo_get_stats64 = efx_net_stats,
Expand All @@ -2212,10 +2221,10 @@ static const struct net_device_ops efx_farch_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_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,
.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,
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = efx_netpoll,
Expand All @@ -2229,29 +2238,6 @@ static const struct net_device_ops efx_farch_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);
Expand All @@ -2264,8 +2250,7 @@ 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_farch_netdev_ops ||
net_dev->netdev_ops == &efx_ef10_netdev_ops) &&
if ((net_dev->netdev_ops == &efx_netdev_ops) &&
event == NETDEV_CHANGENAME)
efx_update_name(netdev_priv(net_dev));

Expand All @@ -2292,12 +2277,9 @@ static int efx_register_netdev(struct efx_nic *efx)

net_dev->watchdog_timeo = 5 * HZ;
net_dev->irq = efx->pci_dev->irq;
if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) {
net_dev->netdev_ops = &efx_ef10_netdev_ops;
net_dev->netdev_ops = &efx_netdev_ops;
if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0)
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;

Expand Down Expand Up @@ -2435,7 +2417,8 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
if (rc)
goto fail;
efx_restore_filters(efx);
efx->type->sriov_reset(efx);
if (efx->type->sriov_reset)
efx->type->sriov_reset(efx);

mutex_unlock(&efx->mac_lock);

Expand Down Expand Up @@ -2828,7 +2811,9 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
efx_disable_interrupts(efx);
rtnl_unlock();

efx->type->sriov_fini(efx);
if (efx->type->sriov_fini)
efx->type->sriov_fini(efx);

efx_unregister_netdev(efx);

efx_mtd_remove(efx);
Expand Down Expand Up @@ -3025,10 +3010,12 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
if (rc)
goto fail4;

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);
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);
}

netif_dbg(efx, probe, efx->net_dev, "initialisation successful\n");

Expand Down
7 changes: 7 additions & 0 deletions drivers/net/ethernet/sfc/efx.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,13 @@ 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,
Expand Down
10 changes: 0 additions & 10 deletions drivers/net/ethernet/sfc/falcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -2766,11 +2766,6 @@ 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,
Expand Down Expand Up @@ -2867,11 +2862,6 @@ 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,
Expand Down
48 changes: 27 additions & 21 deletions drivers/net/ethernet/sfc/farch.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "efx.h"
#include "nic.h"
#include "farch_regs.h"
#include "sriov.h"
#include "siena_sriov.h"
#include "io.h"
#include "workarounds.h"

Expand Down Expand Up @@ -1685,28 +1687,32 @@ 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(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;
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);
}
vi_count += efx->vf_count * efx_vf_size(efx);
}
#endif

Expand Down
4 changes: 3 additions & 1 deletion drivers/net/ethernet/sfc/mcdi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,9 @@ void efx_mcdi_process_event(struct efx_channel *channel,
/* MAC stats are gather lazily. We can ignore this. */
break;
case MCDI_EVENT_CODE_FLR:
efx_siena_sriov_flr(efx, MCDI_EVENT_FIELD(*event, FLR_VF));
if (efx->type->sriov_flr)
efx->type->sriov_flr(efx,
MCDI_EVENT_FIELD(*event, FLR_VF));
break;
case MCDI_EVENT_CODE_PTP_RX:
case MCDI_EVENT_CODE_PTP_FAULT:
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/sfc/net_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,14 @@ struct efx_nic_type {
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;
Expand Down
Loading

0 comments on commit d92916f

Please sign in to comment.