2 * Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 #include <linux/ethtool.h>
17 #include <linux/netdevice.h>
18 #include <linux/string.h>
21 struct edma_ethtool_stats
{
22 uint8_t stat_string
[ETH_GSTRING_LEN
];
26 #define EDMA_STAT(m) offsetof(struct edma_ethtool_statistics, m)
27 #define DRVINFO_LEN 32
29 /* Array of strings describing statistics
31 static const struct edma_ethtool_stats edma_gstrings_stats
[] = {
32 {"tx_q0_pkt", EDMA_STAT(tx_q0_pkt
)},
33 {"tx_q1_pkt", EDMA_STAT(tx_q1_pkt
)},
34 {"tx_q2_pkt", EDMA_STAT(tx_q2_pkt
)},
35 {"tx_q3_pkt", EDMA_STAT(tx_q3_pkt
)},
36 {"tx_q4_pkt", EDMA_STAT(tx_q4_pkt
)},
37 {"tx_q5_pkt", EDMA_STAT(tx_q5_pkt
)},
38 {"tx_q6_pkt", EDMA_STAT(tx_q6_pkt
)},
39 {"tx_q7_pkt", EDMA_STAT(tx_q7_pkt
)},
40 {"tx_q8_pkt", EDMA_STAT(tx_q8_pkt
)},
41 {"tx_q9_pkt", EDMA_STAT(tx_q9_pkt
)},
42 {"tx_q10_pkt", EDMA_STAT(tx_q10_pkt
)},
43 {"tx_q11_pkt", EDMA_STAT(tx_q11_pkt
)},
44 {"tx_q12_pkt", EDMA_STAT(tx_q12_pkt
)},
45 {"tx_q13_pkt", EDMA_STAT(tx_q13_pkt
)},
46 {"tx_q14_pkt", EDMA_STAT(tx_q14_pkt
)},
47 {"tx_q15_pkt", EDMA_STAT(tx_q15_pkt
)},
48 {"tx_q0_byte", EDMA_STAT(tx_q0_byte
)},
49 {"tx_q1_byte", EDMA_STAT(tx_q1_byte
)},
50 {"tx_q2_byte", EDMA_STAT(tx_q2_byte
)},
51 {"tx_q3_byte", EDMA_STAT(tx_q3_byte
)},
52 {"tx_q4_byte", EDMA_STAT(tx_q4_byte
)},
53 {"tx_q5_byte", EDMA_STAT(tx_q5_byte
)},
54 {"tx_q6_byte", EDMA_STAT(tx_q6_byte
)},
55 {"tx_q7_byte", EDMA_STAT(tx_q7_byte
)},
56 {"tx_q8_byte", EDMA_STAT(tx_q8_byte
)},
57 {"tx_q9_byte", EDMA_STAT(tx_q9_byte
)},
58 {"tx_q10_byte", EDMA_STAT(tx_q10_byte
)},
59 {"tx_q11_byte", EDMA_STAT(tx_q11_byte
)},
60 {"tx_q12_byte", EDMA_STAT(tx_q12_byte
)},
61 {"tx_q13_byte", EDMA_STAT(tx_q13_byte
)},
62 {"tx_q14_byte", EDMA_STAT(tx_q14_byte
)},
63 {"tx_q15_byte", EDMA_STAT(tx_q15_byte
)},
64 {"rx_q0_pkt", EDMA_STAT(rx_q0_pkt
)},
65 {"rx_q1_pkt", EDMA_STAT(rx_q1_pkt
)},
66 {"rx_q2_pkt", EDMA_STAT(rx_q2_pkt
)},
67 {"rx_q3_pkt", EDMA_STAT(rx_q3_pkt
)},
68 {"rx_q4_pkt", EDMA_STAT(rx_q4_pkt
)},
69 {"rx_q5_pkt", EDMA_STAT(rx_q5_pkt
)},
70 {"rx_q6_pkt", EDMA_STAT(rx_q6_pkt
)},
71 {"rx_q7_pkt", EDMA_STAT(rx_q7_pkt
)},
72 {"rx_q0_byte", EDMA_STAT(rx_q0_byte
)},
73 {"rx_q1_byte", EDMA_STAT(rx_q1_byte
)},
74 {"rx_q2_byte", EDMA_STAT(rx_q2_byte
)},
75 {"rx_q3_byte", EDMA_STAT(rx_q3_byte
)},
76 {"rx_q4_byte", EDMA_STAT(rx_q4_byte
)},
77 {"rx_q5_byte", EDMA_STAT(rx_q5_byte
)},
78 {"rx_q6_byte", EDMA_STAT(rx_q6_byte
)},
79 {"rx_q7_byte", EDMA_STAT(rx_q7_byte
)},
80 {"tx_desc_error", EDMA_STAT(tx_desc_error
)},
81 {"rx_alloc_fail_ctr", EDMA_STAT(rx_alloc_fail_ctr
)},
84 #define EDMA_STATS_LEN ARRAY_SIZE(edma_gstrings_stats)
86 /* edma_get_strset_count()
89 static int edma_get_strset_count(struct net_device
*netdev
,
94 return EDMA_STATS_LEN
;
96 netdev_dbg(netdev
, "%s: Invalid string set", __func__
);
102 /* edma_get_strings()
105 static void edma_get_strings(struct net_device
*netdev
, uint32_t stringset
,
113 for (i
= 0; i
< EDMA_STATS_LEN
; i
++) {
114 memcpy(p
, edma_gstrings_stats
[i
].stat_string
,
115 min((size_t)ETH_GSTRING_LEN
,
116 strlen(edma_gstrings_stats
[i
].stat_string
)
118 p
+= ETH_GSTRING_LEN
;
124 /* edma_get_ethtool_stats()
125 * Get ethtool statistics
127 static void edma_get_ethtool_stats(struct net_device
*netdev
,
128 struct ethtool_stats
*stats
, uint64_t *data
)
130 struct edma_adapter
*adapter
= netdev_priv(netdev
);
131 struct edma_common_info
*edma_cinfo
= adapter
->edma_cinfo
;
135 edma_read_append_stats(edma_cinfo
);
137 for(i
= 0; i
< EDMA_STATS_LEN
; i
++) {
138 p
= (uint8_t *)&(edma_cinfo
->edma_ethstats
) +
139 edma_gstrings_stats
[i
].stat_offset
;
140 data
[i
] = *(uint32_t *)p
;
144 /* edma_get_drvinfo()
145 * get edma driver info
147 static void edma_get_drvinfo(struct net_device
*dev
,
148 struct ethtool_drvinfo
*info
)
150 strlcpy(info
->driver
, "ess_edma", DRVINFO_LEN
);
151 strlcpy(info
->bus_info
, "axi", ETHTOOL_BUSINFO_LEN
);
155 * Reset the phy, if available.
157 static int edma_nway_reset(struct net_device
*netdev
)
163 * get wake on lan info
165 static void edma_get_wol(struct net_device
*netdev
,
166 struct ethtool_wolinfo
*wol
)
172 /* edma_get_msglevel()
175 static uint32_t edma_get_msglevel(struct net_device
*netdev
)
180 /* edma_get_settings()
183 static int edma_get_settings(struct net_device
*netdev
,
184 struct ethtool_link_ksettings
*cmd
)
186 struct edma_adapter
*adapter
= netdev_priv(netdev
);
188 if (adapter
->poll_required
) {
189 struct phy_device
*phydev
= NULL
;
192 if ((adapter
->forced_speed
!= SPEED_UNKNOWN
)
193 && !(adapter
->poll_required
))
196 phydev
= adapter
->phydev
;
198 linkmode_copy(cmd
->link_modes
.advertising
, phydev
->advertising
);
199 linkmode_copy(cmd
->link_modes
.supported
, phydev
->supported
);
201 cmd
->base
.autoneg
= phydev
->autoneg
;
203 if (adapter
->link_state
== __EDMA_LINKDOWN
) {
204 cmd
->base
.speed
= SPEED_UNKNOWN
;
205 cmd
->base
.duplex
= DUPLEX_UNKNOWN
;
207 cmd
->base
.speed
= phydev
->speed
;
208 cmd
->base
.duplex
= phydev
->duplex
;
211 cmd
->base
.phy_address
= adapter
->phy_mdio_addr
;
213 phyreg
= (uint16_t)phy_read(adapter
->phydev
, MII_LPA
);
214 if (phyreg
& LPA_10HALF
)
215 linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT
,
216 cmd
->link_modes
.lp_advertising
);
218 if (phyreg
& LPA_10FULL
)
219 linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT
,
220 cmd
->link_modes
.lp_advertising
);
222 if (phyreg
& LPA_100HALF
)
223 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT
,
224 cmd
->link_modes
.lp_advertising
);
226 if (phyreg
& LPA_100FULL
)
227 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT
,
228 cmd
->link_modes
.lp_advertising
);
230 phyreg
= (uint16_t)phy_read(adapter
->phydev
, MII_STAT1000
);
231 if (phyreg
& LPA_1000HALF
)
232 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT
,
233 cmd
->link_modes
.lp_advertising
);
235 if (phyreg
& LPA_1000FULL
)
236 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT
,
237 cmd
->link_modes
.lp_advertising
);
239 /* If the speed/duplex for this GMAC is forced and we
240 * are not polling for link state changes, return the
241 * values as specified by platform. This will be true
242 * for GMACs connected to switch, and interfaces that
245 if (!(adapter
->poll_required
)) {
246 if (adapter
->forced_speed
!= SPEED_UNKNOWN
) {
247 /* set speed and duplex */
248 cmd
->base
.speed
= SPEED_1000
;
249 cmd
->base
.duplex
= DUPLEX_FULL
;
251 /* Populate capabilities advertised by self */
252 linkmode_zero(cmd
->link_modes
.advertising
);
253 cmd
->base
.autoneg
= 0;
254 cmd
->base
.port
= PORT_TP
;
255 cmd
->base
.transceiver
= XCVR_EXTERNAL
;
257 /* non link polled and non
258 * forced speed/duplex interface
268 /* edma_set_settings()
271 static int edma_set_settings(struct net_device
*netdev
,
272 const struct ethtool_link_ksettings
*cmd
)
274 struct edma_adapter
*adapter
= netdev_priv(netdev
);
275 struct phy_device
*phydev
= NULL
;
277 if ((adapter
->forced_speed
!= SPEED_UNKNOWN
) &&
278 !adapter
->poll_required
)
281 phydev
= adapter
->phydev
;
282 linkmode_copy(phydev
->advertising
, cmd
->link_modes
.advertising
);
283 linkmode_copy(phydev
->supported
, cmd
->link_modes
.supported
);
284 phydev
->autoneg
= cmd
->base
.autoneg
;
285 phydev
->speed
= cmd
->base
.speed
;
286 phydev
->duplex
= cmd
->base
.duplex
;
288 genphy_config_aneg(phydev
);
294 * get interrupt mitigation
296 static int edma_get_coalesce(struct net_device
*netdev
,
297 struct ethtool_coalesce
*ec
)
301 edma_get_tx_rx_coalesce(®_val
);
303 /* We read the Interrupt Moderation Timer(IMT) register value,
304 * use lower 16 bit for rx and higher 16 bit for Tx. We do a
305 * left shift by 1, because IMT resolution timer is 2usecs.
306 * Hence the value given by the register is multiplied by 2 to
307 * get the actual time in usecs.
309 ec
->tx_coalesce_usecs
= (((reg_val
>> 16) & 0xffff) << 1);
310 ec
->rx_coalesce_usecs
= ((reg_val
& 0xffff) << 1);
316 * set interrupt mitigation
318 static int edma_set_coalesce(struct net_device
*netdev
,
319 struct ethtool_coalesce
*ec
)
321 if (ec
->tx_coalesce_usecs
)
322 edma_change_tx_coalesce(ec
->tx_coalesce_usecs
);
323 if (ec
->rx_coalesce_usecs
)
324 edma_change_rx_coalesce(ec
->rx_coalesce_usecs
);
329 /* edma_set_priv_flags()
330 * Set EDMA private flags
332 static int edma_set_priv_flags(struct net_device
*netdev
, u32 flags
)
337 /* edma_get_priv_flags()
338 * get edma driver flags
340 static u32
edma_get_priv_flags(struct net_device
*netdev
)
345 /* edma_get_ringparam()
348 static void edma_get_ringparam(struct net_device
*netdev
,
349 struct ethtool_ringparam
*ring
)
351 struct edma_adapter
*adapter
= netdev_priv(netdev
);
352 struct edma_common_info
*edma_cinfo
= adapter
->edma_cinfo
;
354 ring
->tx_max_pending
= edma_cinfo
->tx_ring_count
;
355 ring
->rx_max_pending
= edma_cinfo
->rx_ring_count
;
358 /* Ethtool operations
360 static const struct ethtool_ops edma_ethtool_ops
= {
361 .get_drvinfo
= &edma_get_drvinfo
,
362 .get_link
= ðtool_op_get_link
,
363 .get_msglevel
= &edma_get_msglevel
,
364 .nway_reset
= &edma_nway_reset
,
365 .get_wol
= &edma_get_wol
,
366 .get_link_ksettings
= &edma_get_settings
,
367 .set_link_ksettings
= &edma_set_settings
,
368 .get_strings
= &edma_get_strings
,
369 .get_sset_count
= &edma_get_strset_count
,
370 .get_ethtool_stats
= &edma_get_ethtool_stats
,
371 .get_coalesce
= &edma_get_coalesce
,
372 .set_coalesce
= &edma_set_coalesce
,
373 .get_priv_flags
= edma_get_priv_flags
,
374 .set_priv_flags
= edma_set_priv_flags
,
375 .get_ringparam
= edma_get_ringparam
,
378 /* edma_set_ethtool_ops
379 * Set ethtool operations
381 void edma_set_ethtool_ops(struct net_device
*netdev
)
383 netdev
->ethtool_ops
= &edma_ethtool_ops
;