GNU Linux-libre 4.14.332-gnu1
[releases.git] / drivers / net / ethernet / qualcomm / emac / emac-ethtool.c
1 /* Copyright (c) 2016, The Linux Foundation. All rights reserved.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 and
5  * only version 2 as published by the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  */
12
13 #include <linux/ethtool.h>
14 #include <linux/phy.h>
15
16 #include "emac.h"
17
18 static const char * const emac_ethtool_stat_strings[] = {
19         "rx_ok",
20         "rx_bcast",
21         "rx_mcast",
22         "rx_pause",
23         "rx_ctrl",
24         "rx_fcs_err",
25         "rx_len_err",
26         "rx_byte_cnt",
27         "rx_runt",
28         "rx_frag",
29         "rx_sz_64",
30         "rx_sz_65_127",
31         "rx_sz_128_255",
32         "rx_sz_256_511",
33         "rx_sz_512_1023",
34         "rx_sz_1024_1518",
35         "rx_sz_1519_max",
36         "rx_sz_ov",
37         "rx_rxf_ov",
38         "rx_align_err",
39         "rx_bcast_byte_cnt",
40         "rx_mcast_byte_cnt",
41         "rx_err_addr",
42         "rx_crc_align",
43         "rx_jabbers",
44         "tx_ok",
45         "tx_bcast",
46         "tx_mcast",
47         "tx_pause",
48         "tx_exc_defer",
49         "tx_ctrl",
50         "tx_defer",
51         "tx_byte_cnt",
52         "tx_sz_64",
53         "tx_sz_65_127",
54         "tx_sz_128_255",
55         "tx_sz_256_511",
56         "tx_sz_512_1023",
57         "tx_sz_1024_1518",
58         "tx_sz_1519_max",
59         "tx_1_col",
60         "tx_2_col",
61         "tx_late_col",
62         "tx_abort_col",
63         "tx_underrun",
64         "tx_rd_eop",
65         "tx_len_err",
66         "tx_trunc",
67         "tx_bcast_byte",
68         "tx_mcast_byte",
69         "tx_col",
70 };
71
72 #define EMAC_STATS_LEN  ARRAY_SIZE(emac_ethtool_stat_strings)
73
74 static u32 emac_get_msglevel(struct net_device *netdev)
75 {
76         struct emac_adapter *adpt = netdev_priv(netdev);
77
78         return adpt->msg_enable;
79 }
80
81 static void emac_set_msglevel(struct net_device *netdev, u32 data)
82 {
83         struct emac_adapter *adpt = netdev_priv(netdev);
84
85         adpt->msg_enable = data;
86 }
87
88 static int emac_get_sset_count(struct net_device *netdev, int sset)
89 {
90         switch (sset) {
91         case ETH_SS_PRIV_FLAGS:
92                 return 1;
93         case ETH_SS_STATS:
94                 return EMAC_STATS_LEN;
95         default:
96                 return -EOPNOTSUPP;
97         }
98 }
99
100 static void emac_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
101 {
102         unsigned int i;
103
104         switch (stringset) {
105         case ETH_SS_PRIV_FLAGS:
106                 strcpy(data, "single-pause-mode");
107                 break;
108
109         case ETH_SS_STATS:
110                 for (i = 0; i < EMAC_STATS_LEN; i++) {
111                         strlcpy(data, emac_ethtool_stat_strings[i],
112                                 ETH_GSTRING_LEN);
113                         data += ETH_GSTRING_LEN;
114                 }
115                 break;
116         }
117 }
118
119 static void emac_get_ethtool_stats(struct net_device *netdev,
120                                    struct ethtool_stats *stats,
121                                    u64 *data)
122 {
123         struct emac_adapter *adpt = netdev_priv(netdev);
124
125         spin_lock(&adpt->stats.lock);
126
127         emac_update_hw_stats(adpt);
128         memcpy(data, &adpt->stats, EMAC_STATS_LEN * sizeof(u64));
129
130         spin_unlock(&adpt->stats.lock);
131 }
132
133 static int emac_nway_reset(struct net_device *netdev)
134 {
135         struct phy_device *phydev = netdev->phydev;
136
137         if (!phydev)
138                 return -ENODEV;
139
140         return genphy_restart_aneg(phydev);
141 }
142
143 static void emac_get_ringparam(struct net_device *netdev,
144                                struct ethtool_ringparam *ring)
145 {
146         struct emac_adapter *adpt = netdev_priv(netdev);
147
148         ring->rx_max_pending = EMAC_MAX_RX_DESCS;
149         ring->tx_max_pending = EMAC_MAX_TX_DESCS;
150         ring->rx_pending = adpt->rx_desc_cnt;
151         ring->tx_pending = adpt->tx_desc_cnt;
152 }
153
154 static int emac_set_ringparam(struct net_device *netdev,
155                               struct ethtool_ringparam *ring)
156 {
157         struct emac_adapter *adpt = netdev_priv(netdev);
158
159         /* We don't have separate queues/rings for small/large frames, so
160          * reject any attempt to specify those values separately.
161          */
162         if (ring->rx_mini_pending || ring->rx_jumbo_pending)
163                 return -EINVAL;
164
165         adpt->tx_desc_cnt =
166                 clamp_val(ring->tx_pending, EMAC_MIN_TX_DESCS, EMAC_MAX_TX_DESCS);
167
168         adpt->rx_desc_cnt =
169                 clamp_val(ring->rx_pending, EMAC_MIN_RX_DESCS, EMAC_MAX_RX_DESCS);
170
171         if (netif_running(netdev))
172                 return emac_reinit_locked(adpt);
173
174         return 0;
175 }
176
177 static void emac_get_pauseparam(struct net_device *netdev,
178                                 struct ethtool_pauseparam *pause)
179 {
180         struct emac_adapter *adpt = netdev_priv(netdev);
181
182         pause->autoneg = adpt->automatic ? AUTONEG_ENABLE : AUTONEG_DISABLE;
183         pause->rx_pause = adpt->rx_flow_control ? 1 : 0;
184         pause->tx_pause = adpt->tx_flow_control ? 1 : 0;
185 }
186
187 static int emac_set_pauseparam(struct net_device *netdev,
188                                struct ethtool_pauseparam *pause)
189 {
190         struct emac_adapter *adpt = netdev_priv(netdev);
191
192         adpt->automatic = pause->autoneg == AUTONEG_ENABLE;
193         adpt->rx_flow_control = pause->rx_pause != 0;
194         adpt->tx_flow_control = pause->tx_pause != 0;
195
196         if (netif_running(netdev))
197                 return emac_reinit_locked(adpt);
198
199         return 0;
200 }
201
202 /* Selected registers that might want to track during runtime. */
203 static const u16 emac_regs[] = {
204         EMAC_DMA_MAS_CTRL,
205         EMAC_MAC_CTRL,
206         EMAC_TXQ_CTRL_0,
207         EMAC_RXQ_CTRL_0,
208         EMAC_DMA_CTRL,
209         EMAC_INT_MASK,
210         EMAC_AXI_MAST_CTRL,
211         EMAC_CORE_HW_VERSION,
212         EMAC_MISC_CTRL,
213 };
214
215 /* Every time emac_regs[] above is changed, increase this version number. */
216 #define EMAC_REGS_VERSION       0
217
218 #define EMAC_MAX_REG_SIZE       ARRAY_SIZE(emac_regs)
219
220 static void emac_get_regs(struct net_device *netdev,
221                           struct ethtool_regs *regs, void *buff)
222 {
223         struct emac_adapter *adpt = netdev_priv(netdev);
224         u32 *val = buff;
225         unsigned int i;
226
227         regs->version = EMAC_REGS_VERSION;
228         regs->len = EMAC_MAX_REG_SIZE * sizeof(u32);
229
230         for (i = 0; i < EMAC_MAX_REG_SIZE; i++)
231                 val[i] = readl(adpt->base + emac_regs[i]);
232 }
233
234 static int emac_get_regs_len(struct net_device *netdev)
235 {
236         return EMAC_MAX_REG_SIZE * sizeof(u32);
237 }
238
239 #define EMAC_PRIV_ENABLE_SINGLE_PAUSE   BIT(0)
240
241 static int emac_set_priv_flags(struct net_device *netdev, u32 flags)
242 {
243         struct emac_adapter *adpt = netdev_priv(netdev);
244
245         adpt->single_pause_mode = !!(flags & EMAC_PRIV_ENABLE_SINGLE_PAUSE);
246
247         if (netif_running(netdev))
248                 return emac_reinit_locked(adpt);
249
250         return 0;
251 }
252
253 static u32 emac_get_priv_flags(struct net_device *netdev)
254 {
255         struct emac_adapter *adpt = netdev_priv(netdev);
256
257         return adpt->single_pause_mode ? EMAC_PRIV_ENABLE_SINGLE_PAUSE : 0;
258 }
259
260 static const struct ethtool_ops emac_ethtool_ops = {
261         .get_link_ksettings = phy_ethtool_get_link_ksettings,
262         .set_link_ksettings = phy_ethtool_set_link_ksettings,
263
264         .get_msglevel    = emac_get_msglevel,
265         .set_msglevel    = emac_set_msglevel,
266
267         .get_sset_count  = emac_get_sset_count,
268         .get_strings = emac_get_strings,
269         .get_ethtool_stats = emac_get_ethtool_stats,
270
271         .get_ringparam = emac_get_ringparam,
272         .set_ringparam = emac_set_ringparam,
273
274         .get_pauseparam = emac_get_pauseparam,
275         .set_pauseparam = emac_set_pauseparam,
276
277         .nway_reset = emac_nway_reset,
278
279         .get_link = ethtool_op_get_link,
280
281         .get_regs_len    = emac_get_regs_len,
282         .get_regs        = emac_get_regs,
283
284         .set_priv_flags = emac_set_priv_flags,
285         .get_priv_flags = emac_get_priv_flags,
286 };
287
288 void emac_set_ethtool_ops(struct net_device *netdev)
289 {
290         netdev->ethtool_ops = &emac_ethtool_ops;
291 }