lan743x: Add EEE support
[linux-2.6-block.git] / drivers / net / ethernet / microchip / lan743x_ethtool.c
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /* Copyright (C) 2018 Microchip Technology Inc. */
3
4 #include <linux/netdevice.h>
5 #include "lan743x_main.h"
6 #include "lan743x_ethtool.h"
7 #include <linux/pci.h>
8 #include <linux/phy.h>
9
10 /* eeprom */
11 #define LAN743X_EEPROM_MAGIC                (0x74A5)
12 #define LAN743X_OTP_MAGIC                   (0x74F3)
13 #define EEPROM_INDICATOR_1                  (0xA5)
14 #define EEPROM_INDICATOR_2                  (0xAA)
15 #define EEPROM_MAC_OFFSET                   (0x01)
16 #define MAX_EEPROM_SIZE                     512
17 #define OTP_INDICATOR_1                     (0xF3)
18 #define OTP_INDICATOR_2                     (0xF7)
19
20 static int lan743x_otp_write(struct lan743x_adapter *adapter, u32 offset,
21                              u32 length, u8 *data)
22 {
23         unsigned long timeout;
24         u32 buf;
25         int i;
26
27         buf = lan743x_csr_read(adapter, OTP_PWR_DN);
28
29         if (buf & OTP_PWR_DN_PWRDN_N_) {
30                 /* clear it and wait to be cleared */
31                 lan743x_csr_write(adapter, OTP_PWR_DN, 0);
32
33                 timeout = jiffies + HZ;
34                 do {
35                         udelay(1);
36                         buf = lan743x_csr_read(adapter, OTP_PWR_DN);
37                         if (time_after(jiffies, timeout)) {
38                                 netif_warn(adapter, drv, adapter->netdev,
39                                            "timeout on OTP_PWR_DN completion\n");
40                                 return -EIO;
41                         }
42                 } while (buf & OTP_PWR_DN_PWRDN_N_);
43         }
44
45         /* set to BYTE program mode */
46         lan743x_csr_write(adapter, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_);
47
48         for (i = 0; i < length; i++) {
49                 lan743x_csr_write(adapter, OTP_ADDR1,
50                                   ((offset + i) >> 8) &
51                                   OTP_ADDR1_15_11_MASK_);
52                 lan743x_csr_write(adapter, OTP_ADDR2,
53                                   ((offset + i) &
54                                   OTP_ADDR2_10_3_MASK_));
55                 lan743x_csr_write(adapter, OTP_PRGM_DATA, data[i]);
56                 lan743x_csr_write(adapter, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_);
57                 lan743x_csr_write(adapter, OTP_CMD_GO, OTP_CMD_GO_GO_);
58
59                 timeout = jiffies + HZ;
60                 do {
61                         udelay(1);
62                         buf = lan743x_csr_read(adapter, OTP_STATUS);
63                         if (time_after(jiffies, timeout)) {
64                                 netif_warn(adapter, drv, adapter->netdev,
65                                            "Timeout on OTP_STATUS completion\n");
66                                 return -EIO;
67                         }
68                 } while (buf & OTP_STATUS_BUSY_);
69         }
70
71         return 0;
72 }
73
74 static int lan743x_eeprom_wait(struct lan743x_adapter *adapter)
75 {
76         unsigned long start_time = jiffies;
77         u32 val;
78
79         do {
80                 val = lan743x_csr_read(adapter, E2P_CMD);
81
82                 if (!(val & E2P_CMD_EPC_BUSY_) ||
83                     (val & E2P_CMD_EPC_TIMEOUT_))
84                         break;
85                 usleep_range(40, 100);
86         } while (!time_after(jiffies, start_time + HZ));
87
88         if (val & (E2P_CMD_EPC_TIMEOUT_ | E2P_CMD_EPC_BUSY_)) {
89                 netif_warn(adapter, drv, adapter->netdev,
90                            "EEPROM read operation timeout\n");
91                 return -EIO;
92         }
93
94         return 0;
95 }
96
97 static int lan743x_eeprom_confirm_not_busy(struct lan743x_adapter *adapter)
98 {
99         unsigned long start_time = jiffies;
100         u32 val;
101
102         do {
103                 val = lan743x_csr_read(adapter, E2P_CMD);
104
105                 if (!(val & E2P_CMD_EPC_BUSY_))
106                         return 0;
107
108                 usleep_range(40, 100);
109         } while (!time_after(jiffies, start_time + HZ));
110
111         netif_warn(adapter, drv, adapter->netdev, "EEPROM is busy\n");
112         return -EIO;
113 }
114
115 static int lan743x_eeprom_read(struct lan743x_adapter *adapter,
116                                u32 offset, u32 length, u8 *data)
117 {
118         int retval;
119         u32 val;
120         int i;
121
122         retval = lan743x_eeprom_confirm_not_busy(adapter);
123         if (retval)
124                 return retval;
125
126         for (i = 0; i < length; i++) {
127                 val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_READ_;
128                 val |= (offset & E2P_CMD_EPC_ADDR_MASK_);
129                 lan743x_csr_write(adapter, E2P_CMD, val);
130
131                 retval = lan743x_eeprom_wait(adapter);
132                 if (retval < 0)
133                         return retval;
134
135                 val = lan743x_csr_read(adapter, E2P_DATA);
136                 data[i] = val & 0xFF;
137                 offset++;
138         }
139
140         return 0;
141 }
142
143 static int lan743x_eeprom_write(struct lan743x_adapter *adapter,
144                                 u32 offset, u32 length, u8 *data)
145 {
146         int retval;
147         u32 val;
148         int i;
149
150         retval = lan743x_eeprom_confirm_not_busy(adapter);
151         if (retval)
152                 return retval;
153
154         /* Issue write/erase enable command */
155         val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_EWEN_;
156         lan743x_csr_write(adapter, E2P_CMD, val);
157
158         retval = lan743x_eeprom_wait(adapter);
159         if (retval < 0)
160                 return retval;
161
162         for (i = 0; i < length; i++) {
163                 /* Fill data register */
164                 val = data[i];
165                 lan743x_csr_write(adapter, E2P_DATA, val);
166
167                 /* Send "write" command */
168                 val = E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_WRITE_;
169                 val |= (offset & E2P_CMD_EPC_ADDR_MASK_);
170                 lan743x_csr_write(adapter, E2P_CMD, val);
171
172                 retval = lan743x_eeprom_wait(adapter);
173                 if (retval < 0)
174                         return retval;
175
176                 offset++;
177         }
178
179         return 0;
180 }
181
182 static void lan743x_ethtool_get_drvinfo(struct net_device *netdev,
183                                         struct ethtool_drvinfo *info)
184 {
185         struct lan743x_adapter *adapter = netdev_priv(netdev);
186
187         strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver));
188         strlcpy(info->bus_info,
189                 pci_name(adapter->pdev), sizeof(info->bus_info));
190 }
191
192 static u32 lan743x_ethtool_get_msglevel(struct net_device *netdev)
193 {
194         struct lan743x_adapter *adapter = netdev_priv(netdev);
195
196         return adapter->msg_enable;
197 }
198
199 static void lan743x_ethtool_set_msglevel(struct net_device *netdev,
200                                          u32 msglevel)
201 {
202         struct lan743x_adapter *adapter = netdev_priv(netdev);
203
204         adapter->msg_enable = msglevel;
205 }
206
207 static int lan743x_ethtool_get_eeprom_len(struct net_device *netdev)
208 {
209         return MAX_EEPROM_SIZE;
210 }
211
212 static int lan743x_ethtool_get_eeprom(struct net_device *netdev,
213                                       struct ethtool_eeprom *ee, u8 *data)
214 {
215         struct lan743x_adapter *adapter = netdev_priv(netdev);
216
217         return lan743x_eeprom_read(adapter, ee->offset, ee->len, data);
218 }
219
220 static int lan743x_ethtool_set_eeprom(struct net_device *netdev,
221                                       struct ethtool_eeprom *ee, u8 *data)
222 {
223         struct lan743x_adapter *adapter = netdev_priv(netdev);
224         int ret = -EINVAL;
225
226         if (ee->magic == LAN743X_EEPROM_MAGIC)
227                 ret = lan743x_eeprom_write(adapter, ee->offset, ee->len,
228                                            data);
229         /* Beware!  OTP is One Time Programming ONLY!
230          * So do some strict condition check before messing up
231          */
232         else if ((ee->magic == LAN743X_OTP_MAGIC) &&
233                  (ee->offset == 0) &&
234                  (ee->len == MAX_EEPROM_SIZE) &&
235                  (data[0] == OTP_INDICATOR_1))
236                 ret = lan743x_otp_write(adapter, ee->offset, ee->len, data);
237
238         return ret;
239 }
240
241 static const char lan743x_set0_hw_cnt_strings[][ETH_GSTRING_LEN] = {
242         "RX FCS Errors",
243         "RX Alignment Errors",
244         "Rx Fragment Errors",
245         "RX Jabber Errors",
246         "RX Undersize Frame Errors",
247         "RX Oversize Frame Errors",
248         "RX Dropped Frames",
249         "RX Unicast Byte Count",
250         "RX Broadcast Byte Count",
251         "RX Multicast Byte Count",
252         "RX Unicast Frames",
253         "RX Broadcast Frames",
254         "RX Multicast Frames",
255         "RX Pause Frames",
256         "RX 64 Byte Frames",
257         "RX 65 - 127 Byte Frames",
258         "RX 128 - 255 Byte Frames",
259         "RX 256 - 511 Bytes Frames",
260         "RX 512 - 1023 Byte Frames",
261         "RX 1024 - 1518 Byte Frames",
262         "RX Greater 1518 Byte Frames",
263 };
264
265 static const char lan743x_set1_sw_cnt_strings[][ETH_GSTRING_LEN] = {
266         "RX Queue 0 Frames",
267         "RX Queue 1 Frames",
268         "RX Queue 2 Frames",
269         "RX Queue 3 Frames",
270 };
271
272 static const char lan743x_set2_hw_cnt_strings[][ETH_GSTRING_LEN] = {
273         "RX Total Frames",
274         "EEE RX LPI Transitions",
275         "EEE RX LPI Time",
276         "RX Counter Rollover Status",
277         "TX FCS Errors",
278         "TX Excess Deferral Errors",
279         "TX Carrier Errors",
280         "TX Bad Byte Count",
281         "TX Single Collisions",
282         "TX Multiple Collisions",
283         "TX Excessive Collision",
284         "TX Late Collisions",
285         "TX Unicast Byte Count",
286         "TX Broadcast Byte Count",
287         "TX Multicast Byte Count",
288         "TX Unicast Frames",
289         "TX Broadcast Frames",
290         "TX Multicast Frames",
291         "TX Pause Frames",
292         "TX 64 Byte Frames",
293         "TX 65 - 127 Byte Frames",
294         "TX 128 - 255 Byte Frames",
295         "TX 256 - 511 Bytes Frames",
296         "TX 512 - 1023 Byte Frames",
297         "TX 1024 - 1518 Byte Frames",
298         "TX Greater 1518 Byte Frames",
299         "TX Total Frames",
300         "EEE TX LPI Transitions",
301         "EEE TX LPI Time",
302         "TX Counter Rollover Status",
303 };
304
305 static const u32 lan743x_set0_hw_cnt_addr[] = {
306         STAT_RX_FCS_ERRORS,
307         STAT_RX_ALIGNMENT_ERRORS,
308         STAT_RX_FRAGMENT_ERRORS,
309         STAT_RX_JABBER_ERRORS,
310         STAT_RX_UNDERSIZE_FRAME_ERRORS,
311         STAT_RX_OVERSIZE_FRAME_ERRORS,
312         STAT_RX_DROPPED_FRAMES,
313         STAT_RX_UNICAST_BYTE_COUNT,
314         STAT_RX_BROADCAST_BYTE_COUNT,
315         STAT_RX_MULTICAST_BYTE_COUNT,
316         STAT_RX_UNICAST_FRAMES,
317         STAT_RX_BROADCAST_FRAMES,
318         STAT_RX_MULTICAST_FRAMES,
319         STAT_RX_PAUSE_FRAMES,
320         STAT_RX_64_BYTE_FRAMES,
321         STAT_RX_65_127_BYTE_FRAMES,
322         STAT_RX_128_255_BYTE_FRAMES,
323         STAT_RX_256_511_BYTES_FRAMES,
324         STAT_RX_512_1023_BYTE_FRAMES,
325         STAT_RX_1024_1518_BYTE_FRAMES,
326         STAT_RX_GREATER_1518_BYTE_FRAMES,
327 };
328
329 static const u32 lan743x_set2_hw_cnt_addr[] = {
330         STAT_RX_TOTAL_FRAMES,
331         STAT_EEE_RX_LPI_TRANSITIONS,
332         STAT_EEE_RX_LPI_TIME,
333         STAT_RX_COUNTER_ROLLOVER_STATUS,
334         STAT_TX_FCS_ERRORS,
335         STAT_TX_EXCESS_DEFERRAL_ERRORS,
336         STAT_TX_CARRIER_ERRORS,
337         STAT_TX_BAD_BYTE_COUNT,
338         STAT_TX_SINGLE_COLLISIONS,
339         STAT_TX_MULTIPLE_COLLISIONS,
340         STAT_TX_EXCESSIVE_COLLISION,
341         STAT_TX_LATE_COLLISIONS,
342         STAT_TX_UNICAST_BYTE_COUNT,
343         STAT_TX_BROADCAST_BYTE_COUNT,
344         STAT_TX_MULTICAST_BYTE_COUNT,
345         STAT_TX_UNICAST_FRAMES,
346         STAT_TX_BROADCAST_FRAMES,
347         STAT_TX_MULTICAST_FRAMES,
348         STAT_TX_PAUSE_FRAMES,
349         STAT_TX_64_BYTE_FRAMES,
350         STAT_TX_65_127_BYTE_FRAMES,
351         STAT_TX_128_255_BYTE_FRAMES,
352         STAT_TX_256_511_BYTES_FRAMES,
353         STAT_TX_512_1023_BYTE_FRAMES,
354         STAT_TX_1024_1518_BYTE_FRAMES,
355         STAT_TX_GREATER_1518_BYTE_FRAMES,
356         STAT_TX_TOTAL_FRAMES,
357         STAT_EEE_TX_LPI_TRANSITIONS,
358         STAT_EEE_TX_LPI_TIME,
359         STAT_TX_COUNTER_ROLLOVER_STATUS
360 };
361
362 static void lan743x_ethtool_get_strings(struct net_device *netdev,
363                                         u32 stringset, u8 *data)
364 {
365         switch (stringset) {
366         case ETH_SS_STATS:
367                 memcpy(data, lan743x_set0_hw_cnt_strings,
368                        sizeof(lan743x_set0_hw_cnt_strings));
369                 memcpy(&data[sizeof(lan743x_set0_hw_cnt_strings)],
370                        lan743x_set1_sw_cnt_strings,
371                        sizeof(lan743x_set1_sw_cnt_strings));
372                 memcpy(&data[sizeof(lan743x_set0_hw_cnt_strings) +
373                        sizeof(lan743x_set1_sw_cnt_strings)],
374                        lan743x_set2_hw_cnt_strings,
375                        sizeof(lan743x_set2_hw_cnt_strings));
376                 break;
377         }
378 }
379
380 static void lan743x_ethtool_get_ethtool_stats(struct net_device *netdev,
381                                               struct ethtool_stats *stats,
382                                               u64 *data)
383 {
384         struct lan743x_adapter *adapter = netdev_priv(netdev);
385         int data_index = 0;
386         u32 buf;
387         int i;
388
389         for (i = 0; i < ARRAY_SIZE(lan743x_set0_hw_cnt_addr); i++) {
390                 buf = lan743x_csr_read(adapter, lan743x_set0_hw_cnt_addr[i]);
391                 data[data_index++] = (u64)buf;
392         }
393         for (i = 0; i < ARRAY_SIZE(adapter->rx); i++)
394                 data[data_index++] = (u64)(adapter->rx[i].frame_count);
395         for (i = 0; i < ARRAY_SIZE(lan743x_set2_hw_cnt_addr); i++) {
396                 buf = lan743x_csr_read(adapter, lan743x_set2_hw_cnt_addr[i]);
397                 data[data_index++] = (u64)buf;
398         }
399 }
400
401 static int lan743x_ethtool_get_sset_count(struct net_device *netdev, int sset)
402 {
403         switch (sset) {
404         case ETH_SS_STATS:
405         {
406                 int ret;
407
408                 ret = ARRAY_SIZE(lan743x_set0_hw_cnt_strings);
409                 ret += ARRAY_SIZE(lan743x_set1_sw_cnt_strings);
410                 ret += ARRAY_SIZE(lan743x_set2_hw_cnt_strings);
411                 return ret;
412         }
413         default:
414                 return -EOPNOTSUPP;
415         }
416 }
417
418 static int lan743x_ethtool_get_eee(struct net_device *netdev,
419                                    struct ethtool_eee *eee)
420 {
421         struct lan743x_adapter *adapter = netdev_priv(netdev);
422         struct phy_device *phydev = netdev->phydev;
423         u32 buf;
424         int ret;
425
426         if (!phydev)
427                 return -EIO;
428         if (!phydev->drv) {
429                 netif_err(adapter, drv, adapter->netdev,
430                           "Missing PHY Driver\n");
431                 return -EIO;
432         }
433
434         ret = phy_ethtool_get_eee(phydev, eee);
435         if (ret < 0)
436                 return ret;
437
438         buf = lan743x_csr_read(adapter, MAC_CR);
439         if (buf & MAC_CR_EEE_EN_) {
440                 eee->eee_enabled = true;
441                 eee->eee_active = !!(eee->advertised & eee->lp_advertised);
442                 eee->tx_lpi_enabled = true;
443                 /* EEE_TX_LPI_REQ_DLY & tx_lpi_timer are same uSec unit */
444                 buf = lan743x_csr_read(adapter, MAC_EEE_TX_LPI_REQ_DLY_CNT);
445                 eee->tx_lpi_timer = buf;
446         } else {
447                 eee->eee_enabled = false;
448                 eee->eee_active = false;
449                 eee->tx_lpi_enabled = false;
450                 eee->tx_lpi_timer = 0;
451         }
452
453         return 0;
454 }
455
456 static int lan743x_ethtool_set_eee(struct net_device *netdev,
457                                    struct ethtool_eee *eee)
458 {
459         struct lan743x_adapter *adapter = netdev_priv(netdev);
460         struct phy_device *phydev = NULL;
461         u32 buf = 0;
462         int ret = 0;
463
464         if (!netdev)
465                 return -EINVAL;
466         adapter = netdev_priv(netdev);
467         if (!adapter)
468                 return -EINVAL;
469         phydev = netdev->phydev;
470         if (!phydev)
471                 return -EIO;
472         if (!phydev->drv) {
473                 netif_err(adapter, drv, adapter->netdev,
474                           "Missing PHY Driver\n");
475                 return -EIO;
476         }
477
478         if (eee->eee_enabled) {
479                 ret = phy_init_eee(phydev, 0);
480                 if (ret) {
481                         netif_err(adapter, drv, adapter->netdev,
482                                   "EEE initialization failed\n");
483                         return ret;
484                 }
485
486                 buf = (u32)eee->tx_lpi_timer;
487                 lan743x_csr_write(adapter, MAC_EEE_TX_LPI_REQ_DLY_CNT, buf);
488
489                 buf = lan743x_csr_read(adapter, MAC_CR);
490                 buf |= MAC_CR_EEE_EN_;
491                 lan743x_csr_write(adapter, MAC_CR, buf);
492         } else {
493                 buf = lan743x_csr_read(adapter, MAC_CR);
494                 buf &= ~MAC_CR_EEE_EN_;
495                 lan743x_csr_write(adapter, MAC_CR, buf);
496         }
497
498         return phy_ethtool_set_eee(phydev, eee);
499 }
500
501 #ifdef CONFIG_PM
502 static void lan743x_ethtool_get_wol(struct net_device *netdev,
503                                     struct ethtool_wolinfo *wol)
504 {
505         struct lan743x_adapter *adapter = netdev_priv(netdev);
506
507         wol->supported = 0;
508         wol->wolopts = 0;
509         phy_ethtool_get_wol(netdev->phydev, wol);
510
511         wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST |
512                 WAKE_MAGIC | WAKE_PHY | WAKE_ARP;
513
514         wol->wolopts |= adapter->wolopts;
515 }
516
517 static int lan743x_ethtool_set_wol(struct net_device *netdev,
518                                    struct ethtool_wolinfo *wol)
519 {
520         struct lan743x_adapter *adapter = netdev_priv(netdev);
521
522         adapter->wolopts = 0;
523         if (wol->wolopts & WAKE_UCAST)
524                 adapter->wolopts |= WAKE_UCAST;
525         if (wol->wolopts & WAKE_MCAST)
526                 adapter->wolopts |= WAKE_MCAST;
527         if (wol->wolopts & WAKE_BCAST)
528                 adapter->wolopts |= WAKE_BCAST;
529         if (wol->wolopts & WAKE_MAGIC)
530                 adapter->wolopts |= WAKE_MAGIC;
531         if (wol->wolopts & WAKE_PHY)
532                 adapter->wolopts |= WAKE_PHY;
533         if (wol->wolopts & WAKE_ARP)
534                 adapter->wolopts |= WAKE_ARP;
535
536         device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts);
537
538         phy_ethtool_set_wol(netdev->phydev, wol);
539
540         return 0;
541 }
542 #endif /* CONFIG_PM */
543
544 const struct ethtool_ops lan743x_ethtool_ops = {
545         .get_drvinfo = lan743x_ethtool_get_drvinfo,
546         .get_msglevel = lan743x_ethtool_get_msglevel,
547         .set_msglevel = lan743x_ethtool_set_msglevel,
548         .get_link = ethtool_op_get_link,
549
550         .get_eeprom_len = lan743x_ethtool_get_eeprom_len,
551         .get_eeprom = lan743x_ethtool_get_eeprom,
552         .set_eeprom = lan743x_ethtool_set_eeprom,
553         .get_strings = lan743x_ethtool_get_strings,
554         .get_ethtool_stats = lan743x_ethtool_get_ethtool_stats,
555         .get_sset_count = lan743x_ethtool_get_sset_count,
556         .get_eee = lan743x_ethtool_get_eee,
557         .set_eee = lan743x_ethtool_set_eee,
558         .get_link_ksettings = phy_ethtool_get_link_ksettings,
559         .set_link_ksettings = phy_ethtool_set_link_ksettings,
560 #ifdef CONFIG_PM
561         .get_wol = lan743x_ethtool_get_wol,
562         .set_wol = lan743x_ethtool_set_wol,
563 #endif
564 };