1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */
3 
4 #include <linux/pci.h>
5 #include <linux/phy.h>
6 #include <linux/netdevice.h>
7 
8 #include "../libwx/wx_ethtool.h"
9 #include "../libwx/wx_type.h"
10 #include "ngbe_ethtool.h"
11 
12 static void ngbe_get_wol(struct net_device *netdev,
13 			 struct ethtool_wolinfo *wol)
14 {
15 	struct wx *wx = netdev_priv(netdev);
16 
17 	if (!wx->wol_hw_supported)
18 		return;
19 	wol->supported = WAKE_MAGIC;
20 	wol->wolopts = 0;
21 	if (wx->wol & WX_PSR_WKUP_CTL_MAG)
22 		wol->wolopts |= WAKE_MAGIC;
23 }
24 
25 static int ngbe_set_wol(struct net_device *netdev,
26 			struct ethtool_wolinfo *wol)
27 {
28 	struct wx *wx = netdev_priv(netdev);
29 	struct pci_dev *pdev = wx->pdev;
30 
31 	if (!wx->wol_hw_supported)
32 		return -EOPNOTSUPP;
33 
34 	wx->wol = 0;
35 	if (wol->wolopts & WAKE_MAGIC)
36 		wx->wol = WX_PSR_WKUP_CTL_MAG;
37 	netdev->wol_enabled = !!(wx->wol);
38 	wr32(wx, WX_PSR_WKUP_CTL, wx->wol);
39 	device_set_wakeup_enable(&pdev->dev, netdev->wol_enabled);
40 
41 	return 0;
42 }
43 
44 static const struct ethtool_ops ngbe_ethtool_ops = {
45 	.get_drvinfo		= wx_get_drvinfo,
46 	.get_link		= ethtool_op_get_link,
47 	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
48 	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
49 	.nway_reset		= phy_ethtool_nway_reset,
50 	.get_wol		= ngbe_get_wol,
51 	.set_wol		= ngbe_set_wol,
52 };
53 
54 void ngbe_set_ethtool_ops(struct net_device *netdev)
55 {
56 	netdev->ethtool_ops = &ngbe_ethtool_ops;
57 }
58