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