Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0da96c0 authored by Yana Esina's avatar Yana Esina Committed by David S. Miller
Browse files

net: aquantia: implement WOL support



Add WOL support. Currently only magic packet
(ethtool -s <ethX> wol g) feature is implemented.

Remove hw_set_power and move that to FW_OPS set_power:
because WOL configuration behaves differently on 1x and 2x
firmwares

Signed-off-by: default avatarYana Esina <yana.esina@aquantia.com>
Signed-off-by: default avatarNikita Danilov <nikita.danilov@aquantia.com>
Tested-by: default avatarNikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: default avatarIgor Russkikh <igor.russkikh@aquantia.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0e1a0dde
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -285,6 +285,36 @@ static int aq_ethtool_set_coalesce(struct net_device *ndev,
	return aq_nic_update_interrupt_moderation_settings(aq_nic);
}

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

	wol->supported = WAKE_MAGIC;
	wol->wolopts = 0;

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

static int aq_ethtool_set_wol(struct net_device *ndev,
			      struct ethtool_wolinfo *wol)
{
	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);
	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);

	return err;
}

static int aq_ethtool_nway_reset(struct net_device *ndev)
{
	struct aq_nic_s *aq_nic = netdev_priv(ndev);
@@ -403,6 +433,8 @@ const struct ethtool_ops aq_ethtool_ops = {
	.get_drvinfo         = aq_ethtool_get_drvinfo,
	.get_strings         = aq_ethtool_get_strings,
	.get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
	.get_wol             = aq_ethtool_get_wol,
	.set_wol             = aq_ethtool_set_wol,
	.nway_reset          = aq_ethtool_nway_reset,
	.get_ringparam       = aq_get_ringparam,
	.set_ringparam       = aq_set_ringparam,
+3 −1
Original line number Diff line number Diff line
@@ -204,7 +204,6 @@ struct aq_hw_ops {

	int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version);

	int (*hw_set_power)(struct aq_hw_s *self, unsigned int power_state);
};

struct aq_fw_ops {
@@ -228,6 +227,9 @@ struct aq_fw_ops {
	int (*update_stats)(struct aq_hw_s *self);

	int (*set_flow_control)(struct aq_hw_s *self);

	int (*set_power)(struct aq_hw_s *self, unsigned int power_state,
			 u8 *mac);
};

#endif /* AQ_HW_H */
+7 −5
Original line number Diff line number Diff line
@@ -889,11 +889,13 @@ void aq_nic_deinit(struct aq_nic_s *self)
		self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
		aq_vec_deinit(aq_vec);

	if (self->power_state == AQ_HW_POWER_STATE_D0) {
		(void)self->aq_fw_ops->deinit(self->aq_hw);
	} else {
		(void)self->aq_hw_ops->hw_set_power(self->aq_hw,
						   self->power_state);
	self->aq_fw_ops->deinit(self->aq_hw);

	if (self->power_state != AQ_HW_POWER_STATE_D0 ||
	    self->aq_hw->aq_nic_cfg->wol) {
		self->aq_fw_ops->set_power(self->aq_hw,
					   self->power_state,
					   self->ndev->dev_addr);
	}

err_exit:;
+0 −1
Original line number Diff line number Diff line
@@ -877,7 +877,6 @@ static int hw_atl_a0_hw_ring_rx_stop(struct aq_hw_s *self,
const struct aq_hw_ops hw_atl_ops_a0 = {
	.hw_set_mac_address   = hw_atl_a0_hw_mac_addr_set,
	.hw_init              = hw_atl_a0_hw_init,
	.hw_set_power         = hw_atl_utils_hw_set_power,
	.hw_reset             = hw_atl_a0_hw_reset,
	.hw_start             = hw_atl_a0_hw_start,
	.hw_ring_tx_start     = hw_atl_a0_hw_ring_tx_start,
+0 −1
Original line number Diff line number Diff line
@@ -935,7 +935,6 @@ static int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self,
const struct aq_hw_ops hw_atl_ops_b0 = {
	.hw_set_mac_address   = hw_atl_b0_hw_mac_addr_set,
	.hw_init              = hw_atl_b0_hw_init,
	.hw_set_power         = hw_atl_utils_hw_set_power,
	.hw_reset             = hw_atl_b0_hw_reset,
	.hw_start             = hw_atl_b0_hw_start,
	.hw_ring_tx_start     = hw_atl_b0_hw_ring_tx_start,
Loading