Skip to content

Commit

Permalink
Merge branch 'sfc-ethtool-for-EF100-and-related-improvements'
Browse files Browse the repository at this point in the history
Edward Cree says:

====================
sfc: ethtool for EF100 and related improvements

This series adds the ethtool support to the EF100 driver that was held
 back from the original submission as the lack of phy_ops caused issues.
Patch #2, removing the phy_op indirection, deals with this.  There are a
 lot of checkpatch warnings / xmastree violations but they're all in
 pure code movement so I've left the code as it is.
While patch #1 is technically a fix and possibly could go to 'net', I've
 put it in this series since it only becomes triggerable with the added
 'ethtool --reset' support.
====================

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Sep 7, 2020
2 parents 30ebaf8 + 08bdbca commit 14e9e26
Show file tree
Hide file tree
Showing 12 changed files with 688 additions and 753 deletions.
41 changes: 41 additions & 0 deletions drivers/net/ethernet/sfc/ef100_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,49 @@
#include "ef100_ethtool.h"
#include "mcdi_functions.h"

/* This is the maximum number of descriptor rings supported by the QDMA */
#define EFX_EF100_MAX_DMAQ_SIZE 16384UL

static void ef100_ethtool_get_ringparam(struct net_device *net_dev,
struct ethtool_ringparam *ring)
{
struct efx_nic *efx = netdev_priv(net_dev);

ring->rx_max_pending = EFX_EF100_MAX_DMAQ_SIZE;
ring->tx_max_pending = EFX_EF100_MAX_DMAQ_SIZE;
ring->rx_pending = efx->rxq_entries;
ring->tx_pending = efx->txq_entries;
}

/* Ethtool options available
*/
const struct ethtool_ops ef100_ethtool_ops = {
.get_drvinfo = efx_ethtool_get_drvinfo,
.get_msglevel = efx_ethtool_get_msglevel,
.set_msglevel = efx_ethtool_set_msglevel,
.get_pauseparam = efx_ethtool_get_pauseparam,
.set_pauseparam = efx_ethtool_set_pauseparam,
.get_sset_count = efx_ethtool_get_sset_count,
.self_test = efx_ethtool_self_test,
.get_strings = efx_ethtool_get_strings,
.get_link_ksettings = efx_ethtool_get_link_ksettings,
.set_link_ksettings = efx_ethtool_set_link_ksettings,
.get_link = ethtool_op_get_link,
.get_ringparam = ef100_ethtool_get_ringparam,
.get_fecparam = efx_ethtool_get_fecparam,
.set_fecparam = efx_ethtool_set_fecparam,
.get_ethtool_stats = efx_ethtool_get_stats,
.get_rxnfc = efx_ethtool_get_rxnfc,
.set_rxnfc = efx_ethtool_set_rxnfc,
.reset = efx_ethtool_reset,

.get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size,
.get_rxfh_key_size = efx_ethtool_get_rxfh_key_size,
.get_rxfh = efx_ethtool_get_rxfh,
.set_rxfh = efx_ethtool_set_rxfh,
.get_rxfh_context = efx_ethtool_get_rxfh_context,
.set_rxfh_context = efx_ethtool_set_rxfh_context,

.get_module_info = efx_ethtool_get_module_info,
.get_module_eeprom = efx_ethtool_get_module_eeprom,
};
4 changes: 4 additions & 0 deletions drivers/net/ethernet/sfc/ef100_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,13 @@ static const struct net_device_ops ef100_netdev_ops = {
.ndo_open = ef100_net_open,
.ndo_stop = ef100_net_stop,
.ndo_start_xmit = ef100_hard_start_xmit,
.ndo_tx_timeout = efx_watchdog,
.ndo_get_stats64 = efx_net_stats,
.ndo_change_mtu = efx_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = efx_set_mac_address,
.ndo_set_rx_mode = efx_set_rx_mode, /* Lookout */
.ndo_set_features = efx_set_features,
.ndo_get_phys_port_id = efx_get_phys_port_id,
.ndo_get_phys_port_name = efx_get_phys_port_name,
#ifdef CONFIG_RFS_ACCEL
Expand Down
19 changes: 6 additions & 13 deletions drivers/net/ethernet/sfc/ef100_nic.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,24 +428,12 @@ static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
__clear_bit(reset_type, &efx->reset_pending);
rc = dev_open(efx->net_dev, NULL);
} else if (reset_type == RESET_TYPE_ALL) {
/* A RESET_TYPE_ALL will cause filters to be removed, so we remove filters
* and reprobe after reset to avoid removing filters twice
*/
down_write(&efx->filter_sem);
ef100_filter_table_down(efx);
up_write(&efx->filter_sem);
rc = efx_mcdi_reset(efx, reset_type);
if (rc)
return rc;

netif_device_attach(efx->net_dev);

down_write(&efx->filter_sem);
rc = ef100_filter_table_up(efx);
up_write(&efx->filter_sem);
if (rc)
return rc;

rc = dev_open(efx->net_dev, NULL);
} else {
rc = 1; /* Leave the device closed */
Expand Down Expand Up @@ -696,7 +684,7 @@ static unsigned int ef100_check_caps(const struct efx_nic *efx,
/* NIC level access functions
*/
#define EF100_OFFLOAD_FEATURES (NETIF_F_HW_CSUM | NETIF_F_RXCSUM | \
NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_FRAGLIST | \
NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_NTUPLE | \
NETIF_F_RXHASH | NETIF_F_RXFCS | NETIF_F_TSO_ECN | NETIF_F_RXALL | \
NETIF_F_TSO_MANGLEID | NETIF_F_HW_VLAN_CTAG_TX)

Expand Down Expand Up @@ -769,6 +757,7 @@ const struct efx_nic_type ef100_pf_nic_type = {
.rx_restore_rss_contexts = efx_mcdi_rx_restore_rss_contexts,

.reconfigure_mac = ef100_reconfigure_mac,
.reconfigure_port = efx_mcdi_port_reconfigure,
.test_nvram = efx_new_mcdi_nvram_test_all,
.describe_stats = ef100_describe_stats,
.start_stats = efx_mcdi_mac_start_stats,
Expand Down Expand Up @@ -1170,6 +1159,10 @@ static int ef100_probe_main(struct efx_nic *efx)
goto fail;
/* Reset (most) configuration for this function */
rc = efx_mcdi_reset(efx, RESET_TYPE_ALL);
if (rc)
goto fail;
/* Enable event logging */
rc = efx_mcdi_log_ctrl(efx, true, false, 0);
if (rc)
goto fail;

Expand Down
20 changes: 6 additions & 14 deletions drivers/net/ethernet/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include "selftest.h"
#include "sriov.h"

#include "mcdi.h"
#include "mcdi_port_common.h"
#include "mcdi_pcol.h"
#include "workarounds.h"

Expand Down Expand Up @@ -149,23 +149,17 @@ static int efx_init_port(struct efx_nic *efx)

mutex_lock(&efx->mac_lock);

rc = efx->phy_op->init(efx);
if (rc)
goto fail1;

efx->port_initialized = true;

/* Ensure the PHY advertises the correct flow control settings */
rc = efx->phy_op->reconfigure(efx);
rc = efx_mcdi_port_reconfigure(efx);
if (rc && rc != -EPERM)
goto fail2;
goto fail;

mutex_unlock(&efx->mac_lock);
return 0;

fail2:
efx->phy_op->fini(efx);
fail1:
fail:
mutex_unlock(&efx->mac_lock);
return rc;
}
Expand All @@ -177,7 +171,6 @@ static void efx_fini_port(struct efx_nic *efx)
if (!efx->port_initialized)
return;

efx->phy_op->fini(efx);
efx->port_initialized = false;

efx->link_state.up = false;
Expand Down Expand Up @@ -1229,7 +1222,7 @@ static int efx_pm_thaw(struct device *dev)
goto fail;

mutex_lock(&efx->mac_lock);
efx->phy_op->reconfigure(efx);
efx_mcdi_port_reconfigure(efx);
mutex_unlock(&efx->mac_lock);

efx_start_all(efx);
Expand Down Expand Up @@ -1336,7 +1329,7 @@ static int __init efx_init_module(void)
{
int rc;

printk(KERN_INFO "Solarflare NET driver v" EFX_DRIVER_VERSION "\n");
printk(KERN_INFO "Solarflare NET driver\n");

rc = register_netdevice_notifier(&efx_netdev_notifier);
if (rc)
Expand Down Expand Up @@ -1398,4 +1391,3 @@ MODULE_AUTHOR("Solarflare Communications and "
MODULE_DESCRIPTION("Solarflare network driver");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, efx_pci_table);
MODULE_VERSION(EFX_DRIVER_VERSION);
38 changes: 5 additions & 33 deletions drivers/net/ethernet/sfc/efx_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "rx_common.h"
#include "tx_common.h"
#include "nic.h"
#include "mcdi_port_common.h"
#include "io.h"
#include "mcdi_pcol.h"

Expand Down Expand Up @@ -544,7 +545,7 @@ void efx_start_all(struct efx_nic *efx)
* to poll now because we could have missed a change
*/
mutex_lock(&efx->mac_lock);
if (efx->phy_op->poll(efx))
if (efx_mcdi_phy_poll(efx))
efx_link_status_changed(efx);
mutex_unlock(&efx->mac_lock);

Expand Down Expand Up @@ -714,9 +715,6 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method)
mutex_lock(&efx->mac_lock);
down_write(&efx->filter_sem);
mutex_lock(&efx->rss_lock);
if (efx->port_initialized && method != RESET_TYPE_INVISIBLE &&
method != RESET_TYPE_DATAPATH)
efx->phy_op->fini(efx);
efx->type->fini(efx);
}

Expand Down Expand Up @@ -759,10 +757,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)

if (efx->port_initialized && method != RESET_TYPE_INVISIBLE &&
method != RESET_TYPE_DATAPATH) {
rc = efx->phy_op->init(efx);
if (rc)
goto fail;
rc = efx->phy_op->reconfigure(efx);
rc = efx_mcdi_port_reconfigure(efx);
if (rc && rc != -EPERM)
netif_err(efx, drv, efx->net_dev,
"could not restore PHY settings\n");
Expand Down Expand Up @@ -959,7 +954,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)

/**************************************************************************
*
* Dummy PHY/MAC operations
* Dummy NIC operations
*
* Can be used for some unimplemented operations
* Needed so all function pointers are valid and do not have to be tested
Expand All @@ -972,18 +967,6 @@ int efx_port_dummy_op_int(struct efx_nic *efx)
}
void efx_port_dummy_op_void(struct efx_nic *efx) {}

static bool efx_port_dummy_op_poll(struct efx_nic *efx)
{
return false;
}

static const struct efx_phy_operations efx_dummy_phy_operations = {
.init = efx_port_dummy_op_int,
.reconfigure = efx_port_dummy_op_int,
.poll = efx_port_dummy_op_poll,
.fini = efx_port_dummy_op_void,
};

/**************************************************************************
*
* Data housekeeping
Expand Down Expand Up @@ -1037,7 +1020,6 @@ int efx_init_struct(struct efx_nic *efx,
efx->rps_hash_table = kcalloc(EFX_ARFS_HASH_TABLE_SIZE,
sizeof(*efx->rps_hash_table), GFP_KERNEL);
#endif
efx->phy_op = &efx_dummy_phy_operations;
efx->mdio.dev = net_dev;
INIT_WORK(&efx->mac_work, efx_mac_work);
init_waitqueue_head(&efx->flush_wq);
Expand Down Expand Up @@ -1104,17 +1086,7 @@ int efx_init_io(struct efx_nic *efx, int bar, dma_addr_t dma_mask,

pci_set_master(pci_dev);

/* Set the PCI DMA mask. Try all possibilities from our
* genuine mask down to 32 bits, because some architectures
* (e.g. x86_64 with iommu_sac_force set) will allow 40 bit
* masks event though they reject 46 bit masks.
*/
while (dma_mask > 0x7fffffffUL) {
rc = dma_set_mask_and_coherent(&pci_dev->dev, dma_mask);
if (rc == 0)
break;
dma_mask >>= 1;
}
rc = dma_set_mask_and_coherent(&pci_dev->dev, dma_mask);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"could not find a suitable DMA mask\n");
Expand Down
45 changes: 15 additions & 30 deletions drivers/net/ethernet/sfc/ethtool_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "selftest.h"
#include "rx_common.h"
#include "ethtool_common.h"
#include "mcdi_port_common.h"

struct efx_sw_stat_desc {
const char *name;
Expand Down Expand Up @@ -105,7 +106,6 @@ void efx_ethtool_get_drvinfo(struct net_device *net_dev,
struct efx_nic *efx = netdev_priv(net_dev);

strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
strlcpy(info->version, EFX_DRIVER_VERSION, sizeof(info->version));
efx_mcdi_print_fwver(efx, info->fw_version,
sizeof(info->fw_version));
strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info));
Expand Down Expand Up @@ -221,7 +221,7 @@ int efx_ethtool_set_pauseparam(struct net_device *net_dev,
efx_link_set_wanted_fc(efx, wanted_fc);
if (efx->link_advertising[0] != old_adv ||
(efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) {
rc = efx->phy_op->reconfigure(efx);
rc = efx_mcdi_port_reconfigure(efx);
if (rc) {
netif_err(efx, drv, efx->net_dev,
"Unable to advertise requested flow "
Expand Down Expand Up @@ -372,20 +372,15 @@ int efx_ethtool_fill_self_tests(struct efx_nic *efx,
efx_fill_test(n++, strings, data, &tests->registers,
"core", 0, "registers", NULL);

if (efx->phy_op->run_tests != NULL) {
EFX_WARN_ON_PARANOID(efx->phy_op->test_name == NULL);
for (i = 0; true; ++i) {
const char *name;

for (i = 0; true; ++i) {
const char *name;

EFX_WARN_ON_PARANOID(i >= EFX_MAX_PHY_TESTS);
name = efx->phy_op->test_name(efx, i);
if (name == NULL)
break;
EFX_WARN_ON_PARANOID(i >= EFX_MAX_PHY_TESTS);
name = efx_mcdi_phy_test_name(efx, i);
if (name == NULL)
break;

efx_fill_test(n++, strings, data, &tests->phy_ext[i],
"phy", 0, name, NULL);
}
efx_fill_test(n++, strings, data, &tests->phy_ext[i], "phy", 0, name, NULL);
}

/* Loopback tests */
Expand Down Expand Up @@ -571,7 +566,7 @@ int efx_ethtool_get_link_ksettings(struct net_device *net_dev,
u32 supported;

mutex_lock(&efx->mac_lock);
efx->phy_op->get_link_ksettings(efx, cmd);
efx_mcdi_phy_get_link_ksettings(efx, cmd);
mutex_unlock(&efx->mac_lock);

/* Both MACs support pause frames (bidirectional and respond-only) */
Expand Down Expand Up @@ -607,7 +602,7 @@ int efx_ethtool_set_link_ksettings(struct net_device *net_dev,
}

mutex_lock(&efx->mac_lock);
rc = efx->phy_op->set_link_ksettings(efx, cmd);
rc = efx_mcdi_phy_set_link_ksettings(efx, cmd);
mutex_unlock(&efx->mac_lock);
return rc;
}
Expand All @@ -618,10 +613,8 @@ int efx_ethtool_get_fecparam(struct net_device *net_dev,
struct efx_nic *efx = netdev_priv(net_dev);
int rc;

if (!efx->phy_op || !efx->phy_op->get_fecparam)
return -EOPNOTSUPP;
mutex_lock(&efx->mac_lock);
rc = efx->phy_op->get_fecparam(efx, fecparam);
rc = efx_mcdi_phy_get_fecparam(efx, fecparam);
mutex_unlock(&efx->mac_lock);

return rc;
Expand All @@ -633,10 +626,8 @@ int efx_ethtool_set_fecparam(struct net_device *net_dev,
struct efx_nic *efx = netdev_priv(net_dev);
int rc;

if (!efx->phy_op || !efx->phy_op->get_fecparam)
return -EOPNOTSUPP;
mutex_lock(&efx->mac_lock);
rc = efx->phy_op->set_fecparam(efx, fecparam);
rc = efx_mcdi_phy_set_fecparam(efx, fecparam);
mutex_unlock(&efx->mac_lock);

return rc;
Expand Down Expand Up @@ -1332,11 +1323,8 @@ int efx_ethtool_get_module_eeprom(struct net_device *net_dev,
struct efx_nic *efx = netdev_priv(net_dev);
int ret;

if (!efx->phy_op || !efx->phy_op->get_module_eeprom)
return -EOPNOTSUPP;

mutex_lock(&efx->mac_lock);
ret = efx->phy_op->get_module_eeprom(efx, ee, data);
ret = efx_mcdi_phy_get_module_eeprom(efx, ee, data);
mutex_unlock(&efx->mac_lock);

return ret;
Expand All @@ -1348,11 +1336,8 @@ int efx_ethtool_get_module_info(struct net_device *net_dev,
struct efx_nic *efx = netdev_priv(net_dev);
int ret;

if (!efx->phy_op || !efx->phy_op->get_module_info)
return -EOPNOTSUPP;

mutex_lock(&efx->mac_lock);
ret = efx->phy_op->get_module_info(efx, modinfo);
ret = efx_mcdi_phy_get_module_info(efx, modinfo);
mutex_unlock(&efx->mac_lock);

return ret;
Expand Down
Loading

0 comments on commit 14e9e26

Please sign in to comment.