2 * Atheros AR71xx built-in ethernet mac driver
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 * Based on Atheros' AG7100 driver
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
15 #include <linux/version.h>
17 static int ag71xx_ethtool_get_settings(struct net_device
*dev
,
18 struct ethtool_cmd
*cmd
)
20 struct ag71xx
*ag
= netdev_priv(dev
);
21 struct phy_device
*phydev
= ag
->phy_dev
;
26 #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
27 return phy_ethtool_gset(phydev
, cmd
);
29 return phy_ethtool_ioctl(phydev
, cmd
);
33 static int ag71xx_ethtool_set_settings(struct net_device
*dev
,
34 struct ethtool_cmd
*cmd
)
36 struct ag71xx
*ag
= netdev_priv(dev
);
37 struct phy_device
*phydev
= ag
->phy_dev
;
42 #if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
43 return phy_ethtool_sset(phydev
, cmd
);
45 return phy_ethtool_ioctl(phydev
, cmd
);
49 static void ag71xx_ethtool_get_drvinfo(struct net_device
*dev
,
50 struct ethtool_drvinfo
*info
)
52 struct ag71xx
*ag
= netdev_priv(dev
);
54 strcpy(info
->driver
, ag
->pdev
->dev
.driver
->name
);
55 strcpy(info
->version
, AG71XX_DRV_VERSION
);
56 strcpy(info
->bus_info
, dev_name(&ag
->pdev
->dev
));
59 static u32
ag71xx_ethtool_get_msglevel(struct net_device
*dev
)
61 struct ag71xx
*ag
= netdev_priv(dev
);
63 return ag
->msg_enable
;
66 static void ag71xx_ethtool_set_msglevel(struct net_device
*dev
, u32 msg_level
)
68 struct ag71xx
*ag
= netdev_priv(dev
);
70 ag
->msg_enable
= msg_level
;
73 static void ag71xx_ethtool_get_ringparam(struct net_device
*dev
,
74 struct ethtool_ringparam
*er
)
76 struct ag71xx
*ag
= netdev_priv(dev
);
78 er
->tx_max_pending
= AG71XX_TX_RING_SIZE_MAX
;
79 er
->rx_max_pending
= AG71XX_RX_RING_SIZE_MAX
;
80 er
->rx_mini_max_pending
= 0;
81 er
->rx_jumbo_max_pending
= 0;
83 er
->tx_pending
= BIT(ag
->tx_ring
.order
);
84 er
->rx_pending
= BIT(ag
->rx_ring
.order
);
85 er
->rx_mini_pending
= 0;
86 er
->rx_jumbo_pending
= 0;
88 if (ag
->tx_ring
.desc_split
)
89 er
->tx_pending
/= AG71XX_TX_RING_DS_PER_PKT
;
92 static int ag71xx_ethtool_set_ringparam(struct net_device
*dev
,
93 struct ethtool_ringparam
*er
)
95 struct ag71xx
*ag
= netdev_priv(dev
);
100 if (er
->rx_mini_pending
!= 0||
101 er
->rx_jumbo_pending
!= 0 ||
102 er
->rx_pending
== 0 ||
106 tx_size
= er
->tx_pending
< AG71XX_TX_RING_SIZE_MAX
?
107 er
->tx_pending
: AG71XX_TX_RING_SIZE_MAX
;
109 rx_size
= er
->rx_pending
< AG71XX_RX_RING_SIZE_MAX
?
110 er
->rx_pending
: AG71XX_RX_RING_SIZE_MAX
;
112 if (netif_running(dev
)) {
113 err
= dev
->netdev_ops
->ndo_stop(dev
);
118 if (ag
->tx_ring
.desc_split
)
119 tx_size
*= AG71XX_TX_RING_DS_PER_PKT
;
121 ag
->tx_ring
.order
= ag71xx_ring_size_order(tx_size
);
122 ag
->rx_ring
.order
= ag71xx_ring_size_order(rx_size
);
124 if (netif_running(dev
))
125 err
= dev
->netdev_ops
->ndo_open(dev
);
130 struct ethtool_ops ag71xx_ethtool_ops
= {
131 .set_settings
= ag71xx_ethtool_set_settings
,
132 .get_settings
= ag71xx_ethtool_get_settings
,
133 .get_drvinfo
= ag71xx_ethtool_get_drvinfo
,
134 .get_msglevel
= ag71xx_ethtool_get_msglevel
,
135 .set_msglevel
= ag71xx_ethtool_set_msglevel
,
136 .get_ringparam
= ag71xx_ethtool_get_ringparam
,
137 .set_ringparam
= ag71xx_ethtool_set_ringparam
,
138 .get_link
= ethtool_op_get_link
,
139 .get_ts_info
= ethtool_op_get_ts_info
,