1 // SPDX-License-Identifier: GPL-2.0
2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org>
12 * Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org>
13 * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com>
16 #include "mtk_eth_soc.h"
20 char name
[ETH_GSTRING_LEN
];
24 #define MTK_HW_STAT(stat) { \
26 .idx = offsetof(struct mtk_hw_stats, stat) / sizeof(u64) \
29 static const struct mtk_stat mtk_ethtool_hw_stats
[] = {
30 MTK_HW_STAT(tx_bytes
),
31 MTK_HW_STAT(tx_packets
),
33 MTK_HW_STAT(tx_collisions
),
34 MTK_HW_STAT(rx_bytes
),
35 MTK_HW_STAT(rx_packets
),
36 MTK_HW_STAT(rx_overflow
),
37 MTK_HW_STAT(rx_fcs_errors
),
38 MTK_HW_STAT(rx_short_errors
),
39 MTK_HW_STAT(rx_long_errors
),
40 MTK_HW_STAT(rx_checksum_errors
),
41 MTK_HW_STAT(rx_flow_control_packets
),
44 #define MTK_HW_STATS_LEN ARRAY_SIZE(mtk_ethtool_hw_stats)
46 static int mtk_get_link_ksettings(struct net_device
*dev
,
47 struct ethtool_link_ksettings
*cmd
)
49 struct mtk_mac
*mac
= netdev_priv(dev
);
55 if (mac
->phy_flags
== MTK_PHY_FLAG_ATTACH
) {
56 err
= phy_read_status(mac
->phy_dev
);
61 phy_ethtool_ksettings_get(mac
->phy_dev
, cmd
);
65 static int mtk_set_link_ksettings(struct net_device
*dev
,
66 const struct ethtool_link_ksettings
*cmd
)
68 struct mtk_mac
*mac
= netdev_priv(dev
);
73 if (cmd
->base
.phy_address
!= mac
->phy_dev
->mdio
.addr
) {
74 if (mac
->hw
->phy
->phy_node
[cmd
->base
.phy_address
]) {
75 mac
->phy_dev
= mac
->hw
->phy
->phy
[cmd
->base
.phy_address
];
76 mac
->phy_flags
= MTK_PHY_FLAG_PORT
;
77 } else if (mac
->hw
->mii_bus
) {
78 mac
->phy_dev
= mdiobus_get_phy(mac
->hw
->mii_bus
,
79 cmd
->base
.phy_address
);
82 mac
->phy_flags
= MTK_PHY_FLAG_ATTACH
;
88 return phy_ethtool_ksettings_set(mac
->phy_dev
, cmd
);
91 static void mtk_get_drvinfo(struct net_device
*dev
,
92 struct ethtool_drvinfo
*info
)
94 struct mtk_mac
*mac
= netdev_priv(dev
);
95 struct mtk_soc_data
*soc
= mac
->hw
->soc
;
97 strlcpy(info
->driver
, mac
->hw
->dev
->driver
->name
, sizeof(info
->driver
));
98 strlcpy(info
->bus_info
, dev_name(mac
->hw
->dev
), sizeof(info
->bus_info
));
100 if (soc
->reg_table
[MTK_REG_MTK_COUNTER_BASE
])
101 info
->n_stats
= MTK_HW_STATS_LEN
;
104 static u32
mtk_get_msglevel(struct net_device
*dev
)
106 struct mtk_mac
*mac
= netdev_priv(dev
);
108 return mac
->hw
->msg_enable
;
111 static void mtk_set_msglevel(struct net_device
*dev
, u32 value
)
113 struct mtk_mac
*mac
= netdev_priv(dev
);
115 mac
->hw
->msg_enable
= value
;
118 static int mtk_nway_reset(struct net_device
*dev
)
120 struct mtk_mac
*mac
= netdev_priv(dev
);
125 return genphy_restart_aneg(mac
->phy_dev
);
128 static u32
mtk_get_link(struct net_device
*dev
)
130 struct mtk_mac
*mac
= netdev_priv(dev
);
136 if (mac
->phy_flags
== MTK_PHY_FLAG_ATTACH
) {
137 err
= genphy_update_link(mac
->phy_dev
);
142 return mac
->phy_dev
->link
;
145 return ethtool_op_get_link(dev
);
148 static int mtk_set_ringparam(struct net_device
*dev
,
149 struct ethtool_ringparam
*ring
)
151 struct mtk_mac
*mac
= netdev_priv(dev
);
153 if ((ring
->tx_pending
< 2) ||
154 (ring
->rx_pending
< 2) ||
155 (ring
->rx_pending
> mac
->hw
->soc
->dma_ring_size
) ||
156 (ring
->tx_pending
> mac
->hw
->soc
->dma_ring_size
))
159 dev
->netdev_ops
->ndo_stop(dev
);
161 mac
->hw
->tx_ring
.tx_ring_size
= BIT(fls(ring
->tx_pending
) - 1);
162 mac
->hw
->rx_ring
[0].rx_ring_size
= BIT(fls(ring
->rx_pending
) - 1);
164 return dev
->netdev_ops
->ndo_open(dev
);
167 static void mtk_get_ringparam(struct net_device
*dev
,
168 struct ethtool_ringparam
*ring
)
170 struct mtk_mac
*mac
= netdev_priv(dev
);
172 ring
->rx_max_pending
= mac
->hw
->soc
->dma_ring_size
;
173 ring
->tx_max_pending
= mac
->hw
->soc
->dma_ring_size
;
174 ring
->rx_pending
= mac
->hw
->rx_ring
[0].rx_ring_size
;
175 ring
->tx_pending
= mac
->hw
->tx_ring
.tx_ring_size
;
178 static void mtk_get_strings(struct net_device
*dev
, u32 stringset
, u8
*data
)
184 for (i
= 0; i
< MTK_HW_STATS_LEN
; i
++) {
185 memcpy(data
, mtk_ethtool_hw_stats
[i
].name
,
187 data
+= ETH_GSTRING_LEN
;
193 static int mtk_get_sset_count(struct net_device
*dev
, int sset
)
197 return MTK_HW_STATS_LEN
;
203 static void mtk_get_ethtool_stats(struct net_device
*dev
,
204 struct ethtool_stats
*stats
, u64
*data
)
206 struct mtk_mac
*mac
= netdev_priv(dev
);
207 struct mtk_hw_stats
*hwstats
= mac
->hw_stats
;
211 if (netif_running(dev
) && netif_device_present(dev
)) {
212 if (spin_trylock(&hwstats
->stats_lock
)) {
213 mtk_stats_update_mac(mac
);
214 spin_unlock(&hwstats
->stats_lock
);
219 start
= u64_stats_fetch_begin_irq(&hwstats
->syncp
);
220 for (i
= 0; i
< MTK_HW_STATS_LEN
; i
++)
221 data
[i
] = ((u64
*)hwstats
)[mtk_ethtool_hw_stats
[i
].idx
];
223 } while (u64_stats_fetch_retry_irq(&hwstats
->syncp
, start
));
226 static struct ethtool_ops mtk_ethtool_ops
= {
227 .get_link_ksettings
= mtk_get_link_ksettings
,
228 .set_link_ksettings
= mtk_set_link_ksettings
,
229 .get_drvinfo
= mtk_get_drvinfo
,
230 .get_msglevel
= mtk_get_msglevel
,
231 .set_msglevel
= mtk_set_msglevel
,
232 .nway_reset
= mtk_nway_reset
,
233 .get_link
= mtk_get_link
,
234 .set_ringparam
= mtk_set_ringparam
,
235 .get_ringparam
= mtk_get_ringparam
,
238 void mtk_set_ethtool_ops(struct net_device
*netdev
)
240 struct mtk_mac
*mac
= netdev_priv(netdev
);
241 struct mtk_soc_data
*soc
= mac
->hw
->soc
;
243 if (soc
->reg_table
[MTK_REG_MTK_COUNTER_BASE
]) {
244 mtk_ethtool_ops
.get_strings
= mtk_get_strings
;
245 mtk_ethtool_ops
.get_sset_count
= mtk_get_sset_count
;
246 mtk_ethtool_ops
.get_ethtool_stats
= mtk_get_ethtool_stats
;
249 netdev
->ethtool_ops
= &mtk_ethtool_ops
;