Commit 14e9e262 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'sfc-ethtool-for-EF100-and-related-improvements'



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: default avatarJakub Kicinski <kuba@kernel.org>
parents 30ebaf8e 08bdbcae
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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
+6 −13
Original line number Diff line number Diff line
@@ -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 */
@@ -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)

@@ -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,
@@ -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;

+6 −14
Original line number Diff line number Diff line
@@ -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"

@@ -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;
}
@@ -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;
@@ -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);
@@ -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)
@@ -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);
+5 −33
Original line number Diff line number Diff line
@@ -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"

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

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

@@ -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");
@@ -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
@@ -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
@@ -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);
@@ -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;
	}
	if (rc) {
		netif_err(efx, probe, efx->net_dev,
			  "could not find a suitable DMA mask\n");
Loading