Commit a9ae1683 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'aquantia-next'



Igor Russkikh says:

====================
Aquantia Marvell atlantic driver updates 11-2019

Here is a bunch of atlantic driver new features and updates.

Shortlist:
- Me adding ethtool private flags for various loopback test modes,
- Nikita is doing some work here on power management, implementing new PM API,
  He also did some checkpatch style cleanup of older driver parts.
- I'm also adding a new UDP GSO offload support and flags for loopback activation
- We are now Marvell, so I am changing email addresses on maintainers list.

v2: styling, ip6 correct handling in udpgso
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7b89c580 362cabda
Loading
Loading
Loading
Loading
+43 −3
Original line number Diff line number Diff line
aQuantia AQtion Driver for the aQuantia Multi-Gigabit PCI Express Family of
Ethernet Adapters
Marvell(Aquantia) AQtion Driver for the aQuantia Multi-Gigabit PCI Express
Family of Ethernet Adapters
=============================================================================

Contents
@@ -325,6 +325,46 @@ Supported ethtool options
 Example:
 ethtool -N eth0 flow-type udp4 action 0 loc 32

 UDP GSO hardware offload
 ---------------------------------
 UDP GSO allows to boost UDP tx rates by offloading UDP headers allocation
 into hardware. A special userspace socket option is required for this,
 could be validated with /kernel/tools/testing/selftests/net/

    udpgso_bench_tx -u -4 -D 10.0.1.1 -s 6300 -S 100

 Will cause sending out of 100 byte sized UDP packets formed from single
 6300 bytes user buffer.

 UDP GSO is configured by:

    ethtool -K eth0 tx-udp-segmentation on

 Private flags (testing)
 ---------------------------------

 Atlantic driver supports private flags for hardware custom features:

	$ ethtool --show-priv-flags ethX

	Private flags for ethX:
	DMASystemLoopback  : off
	PKTSystemLoopback  : off
	DMANetworkLoopback : off
	PHYInternalLoopback: off
	PHYExternalLoopback: off

 Example:

	$ ethtool --set-priv-flags ethX DMASystemLoopback on

 DMASystemLoopback:   DMA Host loopback.
 PKTSystemLoopback:   Packet buffer host loopback.
 DMANetworkLoopback:  Network side loopback on DMA block.
 PHYInternalLoopback: Internal loopback on Phy.
 PHYExternalLoopback: External loopback on Phy (with loopback ethernet cable).


Command Line Parameters
=======================
The following command line parameters are available on atlantic driver:
@@ -426,7 +466,7 @@ Support

If an issue is identified with the released source code on the supported
kernel with a supported adapter, email the specific information related
to the issue to support@aquantia.com
to the issue to aqn_support@marvell.com

License
=======
+2 −2
Original line number Diff line number Diff line
@@ -1182,10 +1182,10 @@ S: Maintained
F:	drivers/media/i2c/aptina-pll.*
AQUANTIA ETHERNET DRIVER (atlantic)
M:	Igor Russkikh <igor.russkikh@aquantia.com>
M:	Igor Russkikh <irusskikh@marvell.com>
L:	netdev@vger.kernel.org
S:	Supported
W:	http://www.aquantia.com
W:	https://www.marvell.com/
Q:	http://patchwork.ozlabs.org/project/netdev/list/
F:	drivers/net/ethernet/aquantia/atlantic/
F:	Documentation/networking/device_drivers/aquantia/atlantic.txt
+0 −7
Original line number Diff line number Diff line
@@ -4,15 +4,8 @@
# aQuantia Ethernet Controller AQtion Linux Driver
# Copyright(c) 2014-2017 aQuantia Corporation.
#
# Contact Information: <rdc-drv@aquantia.com>
# aQuantia Corporation, 105 E. Tasman Dr. San Jose, CA 95134, USA
#
################################################################################

#
# Makefile for the AQtion(tm) Ethernet driver
#

obj-$(CONFIG_AQTION) += atlantic.o

atlantic-objs := aq_main.o \
+3 −6
Original line number Diff line number Diff line
@@ -70,14 +70,11 @@

/*#define AQ_CFG_MAC_ADDR_PERMANENT {0x30, 0x0E, 0xE3, 0x12, 0x34, 0x56}*/

#define AQ_NIC_FC_OFF    0U
#define AQ_NIC_FC_TX     1U
#define AQ_NIC_FC_RX     2U
#define AQ_NIC_FC_FULL   3U
#define AQ_NIC_FC_AUTO   4U

#define AQ_CFG_FC_MODE AQ_NIC_FC_FULL

/* Default WOL modes used on initialization */
#define AQ_CFG_WOL_MODES WAKE_MAGIC

#define AQ_CFG_SPEED_MSK  0xFFFFU	/* 0xFFFFU==auto_neg */

#define AQ_CFG_IS_AUTONEG_DEF       1U
+184 −51
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ static void aq_ethtool_get_regs(struct net_device *ndev,
				struct ethtool_regs *regs, void *p)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	u32 regs_count = aq_nic_get_regs_count(aq_nic);
	u32 regs_count;

	regs_count = aq_nic_get_regs_count(aq_nic);

	memset(p, 0, regs_count * sizeof(u32));
	aq_nic_get_regs(aq_nic, regs, p);
@@ -27,7 +29,9 @@ static void aq_ethtool_get_regs(struct net_device *ndev,
static int aq_ethtool_get_regs_len(struct net_device *ndev)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	u32 regs_count = aq_nic_get_regs_count(aq_nic);
	u32 regs_count;

	regs_count = aq_nic_get_regs_count(aq_nic);

	return regs_count * sizeof(u32);
}
@@ -92,11 +96,21 @@ static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
	"Queue[%d] InErrors",
};

static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
	"DMASystemLoopback",
	"PKTSystemLoopback",
	"DMANetworkLoopback",
	"PHYInternalLoopback",
	"PHYExternalLoopback",
};

static void aq_ethtool_stats(struct net_device *ndev,
			     struct ethtool_stats *stats, u64 *data)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;

	cfg = aq_nic_get_cfg(aq_nic);

	memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
			 ARRAY_SIZE(aq_ethtool_queue_stat_names) *
@@ -107,11 +121,15 @@ static void aq_ethtool_stats(struct net_device *ndev,
static void aq_ethtool_get_drvinfo(struct net_device *ndev,
				   struct ethtool_drvinfo *drvinfo)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
	u32 firmware_version = aq_nic_get_fw_version(aq_nic);
	u32 regs_count = aq_nic_get_regs_count(aq_nic);
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg;
	u32 firmware_version;
	u32 regs_count;

	cfg = aq_nic_get_cfg(aq_nic);
	firmware_version = aq_nic_get_fw_version(aq_nic);
	regs_count = aq_nic_get_regs_count(aq_nic);

	strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
	strlcat(drvinfo->version, AQ_CFG_DRV_VERSION, sizeof(drvinfo->version));
@@ -132,12 +150,15 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev,
static void aq_ethtool_get_strings(struct net_device *ndev,
				   u32 stringset, u8 *data)
{
	int i, si;
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;
	u8 *p = data;
	int i, si;

	if (stringset == ETH_SS_STATS) {
	cfg = aq_nic_get_cfg(aq_nic);

	switch (stringset) {
	case ETH_SS_STATS:
		memcpy(p, aq_ethtool_stat_names,
		       sizeof(aq_ethtool_stat_names));
		p = p + sizeof(aq_ethtool_stat_names);
@@ -150,23 +171,63 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
				p += ETH_GSTRING_LEN;
			}
		}
		break;
	case ETH_SS_PRIV_FLAGS:
		memcpy(p, aq_ethtool_priv_flag_names,
		       sizeof(aq_ethtool_priv_flag_names));
		break;
	}
}

static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
static int aq_ethtool_set_phys_id(struct net_device *ndev,
				  enum ethtool_phys_id_state state)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_hw_s *hw = aq_nic->aq_hw;
	int ret = 0;

	if (!aq_nic->aq_fw_ops->led_control)
		return -EOPNOTSUPP;

	mutex_lock(&aq_nic->fwreq_mutex);

	switch (state) {
	case ETHTOOL_ID_ACTIVE:
		ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK |
				 AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4);
		break;
	case ETHTOOL_ID_INACTIVE:
		ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
		break;
	default:
		break;
	}

	mutex_unlock(&aq_nic->fwreq_mutex);

	return ret;
}

static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;
	int ret = 0;

	cfg = aq_nic_get_cfg(aq_nic);

	switch (stringset) {
	case ETH_SS_STATS:
		ret = ARRAY_SIZE(aq_ethtool_stat_names) +
			cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
		break;
	case ETH_SS_PRIV_FLAGS:
		ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
		break;
	default:
		ret = -EOPNOTSUPP;
	}

	return ret;
}

@@ -178,7 +239,9 @@ static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;

	cfg = aq_nic_get_cfg(aq_nic);

	return sizeof(cfg->aq_rss.hash_secret_key);
}
@@ -187,9 +250,11 @@ static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
			      u8 *hfunc)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;
	unsigned int i = 0U;

	cfg = aq_nic_get_cfg(aq_nic);

	if (hfunc)
		*hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
	if (indir) {
@@ -199,6 +264,7 @@ static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
	if (key)
		memcpy(key, cfg->aq_rss.hash_secret_key,
		       sizeof(cfg->aq_rss.hash_secret_key));

	return 0;
}

@@ -242,9 +308,11 @@ static int aq_ethtool_get_rxnfc(struct net_device *ndev,
				u32 *rule_locs)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;
	int err = 0;

	cfg = aq_nic_get_cfg(aq_nic);

	switch (cmd->cmd) {
	case ETHTOOL_GRXRINGS:
		cmd->data = cfg->vecs;
@@ -269,8 +337,8 @@ static int aq_ethtool_get_rxnfc(struct net_device *ndev,
static int aq_ethtool_set_rxnfc(struct net_device *ndev,
				struct ethtool_rxnfc *cmd)
{
	int err = 0;
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	int err = 0;

	switch (cmd->cmd) {
	case ETHTOOL_SRXCLSRLINS:
@@ -291,7 +359,9 @@ static int aq_ethtool_get_coalesce(struct net_device *ndev,
				   struct ethtool_coalesce *coal)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;

	cfg = aq_nic_get_cfg(aq_nic);

	if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
	    cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
@@ -305,6 +375,7 @@ static int aq_ethtool_get_coalesce(struct net_device *ndev,
		coal->rx_max_coalesced_frames = 1;
		coal->tx_max_coalesced_frames = 1;
	}

	return 0;
}

@@ -312,7 +383,9 @@ static int aq_ethtool_set_coalesce(struct net_device *ndev,
				   struct ethtool_coalesce *coal)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;

	cfg = aq_nic_get_cfg(aq_nic);

	/* This is not yet supported
	 */
@@ -354,13 +427,12 @@ static void aq_ethtool_get_wol(struct net_device *ndev,
			       struct ethtool_wolinfo *wol)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;

	wol->supported = WAKE_MAGIC;
	wol->wolopts = 0;
	cfg = aq_nic_get_cfg(aq_nic);

	if (cfg->wol)
		wol->wolopts |= WAKE_MAGIC;
	wol->supported = AQ_NIC_WOL_MODES;
	wol->wolopts = cfg->wol;
}

static int aq_ethtool_set_wol(struct net_device *ndev,
@@ -368,14 +440,17 @@ static int aq_ethtool_set_wol(struct net_device *ndev,
{
	struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;
	int err = 0;

	if (wol->wolopts & WAKE_MAGIC)
		cfg->wol |= AQ_NIC_WOL_ENABLED;
	else
		cfg->wol &= ~AQ_NIC_WOL_ENABLED;
	err = device_set_wakeup_enable(&pdev->dev, wol->wolopts);
	cfg = aq_nic_get_cfg(aq_nic);

	if (wol->wolopts & ~AQ_NIC_WOL_MODES)
		return -EOPNOTSUPP;

	cfg->wol = wol->wolopts;

	err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol);

	return err;
}
@@ -513,7 +588,7 @@ static void aq_ethtool_get_pauseparam(struct net_device *ndev,
				      struct ethtool_pauseparam *pause)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	u32 fc = aq_nic->aq_nic_cfg.flow_control;
	u32 fc = aq_nic->aq_nic_cfg.fc.req;

	pause->autoneg = 0;

@@ -535,14 +610,14 @@ static int aq_ethtool_set_pauseparam(struct net_device *ndev,
		return -EOPNOTSUPP;

	if (pause->rx_pause)
		aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_RX;
		aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
	else
		aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_RX;
		aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;

	if (pause->tx_pause)
		aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_TX;
		aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
	else
		aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_TX;
		aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;

	mutex_lock(&aq_nic->fwreq_mutex);
	err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
@@ -555,23 +630,28 @@ static void aq_get_ringparam(struct net_device *ndev,
			     struct ethtool_ringparam *ring)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic);
	struct aq_nic_cfg_s *cfg;

	cfg = aq_nic_get_cfg(aq_nic);

	ring->rx_pending = aq_nic_cfg->rxds;
	ring->tx_pending = aq_nic_cfg->txds;
	ring->rx_pending = cfg->rxds;
	ring->tx_pending = cfg->txds;

	ring->rx_max_pending = aq_nic_cfg->aq_hw_caps->rxds_max;
	ring->tx_max_pending = aq_nic_cfg->aq_hw_caps->txds_max;
	ring->rx_max_pending = cfg->aq_hw_caps->rxds_max;
	ring->tx_max_pending = cfg->aq_hw_caps->txds_max;
}

static int aq_set_ringparam(struct net_device *ndev,
			    struct ethtool_ringparam *ring)
{
	int err = 0;
	bool ndev_running = false;
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic);
	const struct aq_hw_caps_s *hw_caps = aq_nic_cfg->aq_hw_caps;
	const struct aq_hw_caps_s *hw_caps;
	bool ndev_running = false;
	struct aq_nic_cfg_s *cfg;
	int err = 0;

	cfg = aq_nic_get_cfg(aq_nic);
	hw_caps = cfg->aq_hw_caps;

	if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
		err = -EOPNOTSUPP;
@@ -585,18 +665,18 @@ static int aq_set_ringparam(struct net_device *ndev,

	aq_nic_free_vectors(aq_nic);

	aq_nic_cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
	aq_nic_cfg->rxds = min(aq_nic_cfg->rxds, hw_caps->rxds_max);
	aq_nic_cfg->rxds = ALIGN(aq_nic_cfg->rxds, AQ_HW_RXD_MULTIPLE);
	cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
	cfg->rxds = min(cfg->rxds, hw_caps->rxds_max);
	cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE);

	aq_nic_cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
	aq_nic_cfg->txds = min(aq_nic_cfg->txds, hw_caps->txds_max);
	aq_nic_cfg->txds = ALIGN(aq_nic_cfg->txds, AQ_HW_TXD_MULTIPLE);
	cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
	cfg->txds = min(cfg->txds, hw_caps->txds_max);
	cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE);

	for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < aq_nic_cfg->vecs;
	for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < cfg->vecs;
	     aq_nic->aq_vecs++) {
		aq_nic->aq_vec[aq_nic->aq_vecs] =
		    aq_vec_alloc(aq_nic, aq_nic->aq_vecs, aq_nic_cfg);
		    aq_vec_alloc(aq_nic, aq_nic->aq_vecs, cfg);
		if (unlikely(!aq_nic->aq_vec[aq_nic->aq_vecs])) {
			err = -ENOMEM;
			goto err_exit;
@@ -609,12 +689,61 @@ static int aq_set_ringparam(struct net_device *ndev,
	return err;
}

static u32 aq_get_msg_level(struct net_device *ndev)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);

	return aq_nic->msg_enable;
}

static void aq_set_msg_level(struct net_device *ndev, u32 data)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);

	aq_nic->msg_enable = data;
}

u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);

	return aq_nic->aq_nic_cfg.priv_flags;
}

int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
	struct aq_nic_cfg_s *cfg;
	u32 priv_flags;

	cfg = aq_nic_get_cfg(aq_nic);
	priv_flags = cfg->priv_flags;

	if (flags & ~AQ_PRIV_FLAGS_MASK)
		return -EOPNOTSUPP;

	cfg->priv_flags = flags;

	if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
		if (netif_running(ndev)) {
			dev_close(ndev);

			dev_open(ndev, NULL);
		}
	} else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
		aq_nic_set_loopback(aq_nic);
	}

	return 0;
}

const struct ethtool_ops aq_ethtool_ops = {
	.get_link            = aq_ethtool_get_link,
	.get_regs_len        = aq_ethtool_get_regs_len,
	.get_regs            = aq_ethtool_get_regs,
	.get_drvinfo         = aq_ethtool_get_drvinfo,
	.get_strings         = aq_ethtool_get_strings,
	.set_phys_id         = aq_ethtool_set_phys_id,
	.get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
	.get_wol             = aq_ethtool_get_wol,
	.set_wol             = aq_ethtool_set_wol,
@@ -630,8 +759,12 @@ const struct ethtool_ops aq_ethtool_ops = {
	.set_rxfh            = aq_ethtool_set_rss,
	.get_rxnfc           = aq_ethtool_get_rxnfc,
	.set_rxnfc           = aq_ethtool_set_rxnfc,
	.get_msglevel        = aq_get_msg_level,
	.set_msglevel        = aq_set_msg_level,
	.get_sset_count      = aq_ethtool_get_sset_count,
	.get_ethtool_stats   = aq_ethtool_stats,
	.get_priv_flags      = aq_ethtool_get_priv_flags,
	.set_priv_flags      = aq_ethtool_set_priv_flags,
	.get_link_ksettings  = aq_ethtool_get_link_ksettings,
	.set_link_ksettings  = aq_ethtool_set_link_ksettings,
	.get_coalesce	     = aq_ethtool_get_coalesce,
Loading