hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/drivers/net/ethernet/microchip/lan743x_ethtool.c
....@@ -2,11 +2,11 @@
22 /* Copyright (C) 2018 Microchip Technology Inc. */
33
44 #include <linux/netdevice.h>
5
-#include "lan743x_main.h"
6
-#include "lan743x_ethtool.h"
75 #include <linux/net_tstamp.h>
86 #include <linux/pci.h>
97 #include <linux/phy.h>
8
+#include "lan743x_main.h"
9
+#include "lan743x_ethtool.h"
1010
1111 /* eeprom */
1212 #define LAN743X_EEPROM_MAGIC (0x74A5)
....@@ -14,60 +14,137 @@
1414 #define EEPROM_INDICATOR_1 (0xA5)
1515 #define EEPROM_INDICATOR_2 (0xAA)
1616 #define EEPROM_MAC_OFFSET (0x01)
17
-#define MAX_EEPROM_SIZE 512
17
+#define MAX_EEPROM_SIZE (512)
18
+#define MAX_OTP_SIZE (1024)
1819 #define OTP_INDICATOR_1 (0xF3)
1920 #define OTP_INDICATOR_2 (0xF7)
21
+
22
+static int lan743x_otp_power_up(struct lan743x_adapter *adapter)
23
+{
24
+ u32 reg_value;
25
+
26
+ reg_value = lan743x_csr_read(adapter, OTP_PWR_DN);
27
+
28
+ if (reg_value & OTP_PWR_DN_PWRDN_N_) {
29
+ /* clear it and wait to be cleared */
30
+ reg_value &= ~OTP_PWR_DN_PWRDN_N_;
31
+ lan743x_csr_write(adapter, OTP_PWR_DN, reg_value);
32
+
33
+ usleep_range(100, 20000);
34
+ }
35
+
36
+ return 0;
37
+}
38
+
39
+static void lan743x_otp_power_down(struct lan743x_adapter *adapter)
40
+{
41
+ u32 reg_value;
42
+
43
+ reg_value = lan743x_csr_read(adapter, OTP_PWR_DN);
44
+ if (!(reg_value & OTP_PWR_DN_PWRDN_N_)) {
45
+ /* set power down bit */
46
+ reg_value |= OTP_PWR_DN_PWRDN_N_;
47
+ lan743x_csr_write(adapter, OTP_PWR_DN, reg_value);
48
+ }
49
+}
50
+
51
+static void lan743x_otp_set_address(struct lan743x_adapter *adapter,
52
+ u32 address)
53
+{
54
+ lan743x_csr_write(adapter, OTP_ADDR_HIGH, (address >> 8) & 0x03);
55
+ lan743x_csr_write(adapter, OTP_ADDR_LOW, address & 0xFF);
56
+}
57
+
58
+static void lan743x_otp_read_go(struct lan743x_adapter *adapter)
59
+{
60
+ lan743x_csr_write(adapter, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_);
61
+ lan743x_csr_write(adapter, OTP_CMD_GO, OTP_CMD_GO_GO_);
62
+}
63
+
64
+static int lan743x_otp_wait_till_not_busy(struct lan743x_adapter *adapter)
65
+{
66
+ unsigned long timeout;
67
+ u32 reg_val;
68
+
69
+ timeout = jiffies + HZ;
70
+ do {
71
+ if (time_after(jiffies, timeout)) {
72
+ netif_warn(adapter, drv, adapter->netdev,
73
+ "Timeout on OTP_STATUS completion\n");
74
+ return -EIO;
75
+ }
76
+ udelay(1);
77
+ reg_val = lan743x_csr_read(adapter, OTP_STATUS);
78
+ } while (reg_val & OTP_STATUS_BUSY_);
79
+
80
+ return 0;
81
+}
82
+
83
+static int lan743x_otp_read(struct lan743x_adapter *adapter, u32 offset,
84
+ u32 length, u8 *data)
85
+{
86
+ int ret;
87
+ int i;
88
+
89
+ if (offset + length > MAX_OTP_SIZE)
90
+ return -EINVAL;
91
+
92
+ ret = lan743x_otp_power_up(adapter);
93
+ if (ret < 0)
94
+ return ret;
95
+
96
+ ret = lan743x_otp_wait_till_not_busy(adapter);
97
+ if (ret < 0)
98
+ return ret;
99
+
100
+ for (i = 0; i < length; i++) {
101
+ lan743x_otp_set_address(adapter, offset + i);
102
+
103
+ lan743x_otp_read_go(adapter);
104
+ ret = lan743x_otp_wait_till_not_busy(adapter);
105
+ if (ret < 0)
106
+ return ret;
107
+ data[i] = lan743x_csr_read(adapter, OTP_READ_DATA);
108
+ }
109
+
110
+ lan743x_otp_power_down(adapter);
111
+
112
+ return 0;
113
+}
20114
21115 static int lan743x_otp_write(struct lan743x_adapter *adapter, u32 offset,
22116 u32 length, u8 *data)
23117 {
24
- unsigned long timeout;
25
- u32 buf;
118
+ int ret;
26119 int i;
27120
28
- buf = lan743x_csr_read(adapter, OTP_PWR_DN);
121
+ if (offset + length > MAX_OTP_SIZE)
122
+ return -EINVAL;
29123
30
- if (buf & OTP_PWR_DN_PWRDN_N_) {
31
- /* clear it and wait to be cleared */
32
- lan743x_csr_write(adapter, OTP_PWR_DN, 0);
124
+ ret = lan743x_otp_power_up(adapter);
125
+ if (ret < 0)
126
+ return ret;
33127
34
- timeout = jiffies + HZ;
35
- do {
36
- udelay(1);
37
- buf = lan743x_csr_read(adapter, OTP_PWR_DN);
38
- if (time_after(jiffies, timeout)) {
39
- netif_warn(adapter, drv, adapter->netdev,
40
- "timeout on OTP_PWR_DN completion\n");
41
- return -EIO;
42
- }
43
- } while (buf & OTP_PWR_DN_PWRDN_N_);
44
- }
128
+ ret = lan743x_otp_wait_till_not_busy(adapter);
129
+ if (ret < 0)
130
+ return ret;
45131
46132 /* set to BYTE program mode */
47133 lan743x_csr_write(adapter, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_);
48134
49135 for (i = 0; i < length; i++) {
50
- lan743x_csr_write(adapter, OTP_ADDR1,
51
- ((offset + i) >> 8) &
52
- OTP_ADDR1_15_11_MASK_);
53
- lan743x_csr_write(adapter, OTP_ADDR2,
54
- ((offset + i) &
55
- OTP_ADDR2_10_3_MASK_));
136
+ lan743x_otp_set_address(adapter, offset + i);
137
+
56138 lan743x_csr_write(adapter, OTP_PRGM_DATA, data[i]);
57139 lan743x_csr_write(adapter, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_);
58140 lan743x_csr_write(adapter, OTP_CMD_GO, OTP_CMD_GO_GO_);
59141
60
- timeout = jiffies + HZ;
61
- do {
62
- udelay(1);
63
- buf = lan743x_csr_read(adapter, OTP_STATUS);
64
- if (time_after(jiffies, timeout)) {
65
- netif_warn(adapter, drv, adapter->netdev,
66
- "Timeout on OTP_STATUS completion\n");
67
- return -EIO;
68
- }
69
- } while (buf & OTP_STATUS_BUSY_);
142
+ ret = lan743x_otp_wait_till_not_busy(adapter);
143
+ if (ret < 0)
144
+ return ret;
70145 }
146
+
147
+ lan743x_otp_power_down(adapter);
71148
72149 return 0;
73150 }
....@@ -120,6 +197,9 @@
120197 u32 val;
121198 int i;
122199
200
+ if (offset + length > MAX_EEPROM_SIZE)
201
+ return -EINVAL;
202
+
123203 retval = lan743x_eeprom_confirm_not_busy(adapter);
124204 if (retval)
125205 return retval;
....@@ -147,6 +227,9 @@
147227 int retval;
148228 u32 val;
149229 int i;
230
+
231
+ if (offset + length > MAX_EEPROM_SIZE)
232
+ return -EINVAL;
150233
151234 retval = lan743x_eeprom_confirm_not_busy(adapter);
152235 if (retval)
....@@ -207,6 +290,11 @@
207290
208291 static int lan743x_ethtool_get_eeprom_len(struct net_device *netdev)
209292 {
293
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
294
+
295
+ if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP)
296
+ return MAX_OTP_SIZE;
297
+
210298 return MAX_EEPROM_SIZE;
211299 }
212300
....@@ -214,8 +302,14 @@
214302 struct ethtool_eeprom *ee, u8 *data)
215303 {
216304 struct lan743x_adapter *adapter = netdev_priv(netdev);
305
+ int ret = 0;
217306
218
- return lan743x_eeprom_read(adapter, ee->offset, ee->len, data);
307
+ if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP)
308
+ ret = lan743x_otp_read(adapter, ee->offset, ee->len, data);
309
+ else
310
+ ret = lan743x_eeprom_read(adapter, ee->offset, ee->len, data);
311
+
312
+ return ret;
219313 }
220314
221315 static int lan743x_ethtool_set_eeprom(struct net_device *netdev,
....@@ -224,17 +318,18 @@
224318 struct lan743x_adapter *adapter = netdev_priv(netdev);
225319 int ret = -EINVAL;
226320
227
- if (ee->magic == LAN743X_EEPROM_MAGIC)
228
- ret = lan743x_eeprom_write(adapter, ee->offset, ee->len,
229
- data);
230
- /* Beware! OTP is One Time Programming ONLY!
231
- * So do some strict condition check before messing up
232
- */
233
- else if ((ee->magic == LAN743X_OTP_MAGIC) &&
234
- (ee->offset == 0) &&
235
- (ee->len == MAX_EEPROM_SIZE) &&
236
- (data[0] == OTP_INDICATOR_1))
237
- ret = lan743x_otp_write(adapter, ee->offset, ee->len, data);
321
+ if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP) {
322
+ /* Beware! OTP is One Time Programming ONLY! */
323
+ if (ee->magic == LAN743X_OTP_MAGIC) {
324
+ ret = lan743x_otp_write(adapter, ee->offset,
325
+ ee->len, data);
326
+ }
327
+ } else {
328
+ if (ee->magic == LAN743X_EEPROM_MAGIC) {
329
+ ret = lan743x_eeprom_write(adapter, ee->offset,
330
+ ee->len, data);
331
+ }
332
+ }
238333
239334 return ret;
240335 }
....@@ -360,6 +455,10 @@
360455 STAT_TX_COUNTER_ROLLOVER_STATUS
361456 };
362457
458
+static const char lan743x_priv_flags_strings[][ETH_GSTRING_LEN] = {
459
+ "OTP_ACCESS",
460
+};
461
+
363462 static void lan743x_ethtool_get_strings(struct net_device *netdev,
364463 u32 stringset, u8 *data)
365464 {
....@@ -374,6 +473,10 @@
374473 sizeof(lan743x_set1_sw_cnt_strings)],
375474 lan743x_set2_hw_cnt_strings,
376475 sizeof(lan743x_set2_hw_cnt_strings));
476
+ break;
477
+ case ETH_SS_PRIV_FLAGS:
478
+ memcpy(data, lan743x_priv_flags_strings,
479
+ sizeof(lan743x_priv_flags_strings));
377480 break;
378481 }
379482 }
....@@ -399,6 +502,22 @@
399502 }
400503 }
401504
505
+static u32 lan743x_ethtool_get_priv_flags(struct net_device *netdev)
506
+{
507
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
508
+
509
+ return adapter->flags;
510
+}
511
+
512
+static int lan743x_ethtool_set_priv_flags(struct net_device *netdev, u32 flags)
513
+{
514
+ struct lan743x_adapter *adapter = netdev_priv(netdev);
515
+
516
+ adapter->flags = flags;
517
+
518
+ return 0;
519
+}
520
+
402521 static int lan743x_ethtool_get_sset_count(struct net_device *netdev, int sset)
403522 {
404523 switch (sset) {
....@@ -411,6 +530,8 @@
411530 ret += ARRAY_SIZE(lan743x_set2_hw_cnt_strings);
412531 return ret;
413532 }
533
+ case ETH_SS_PRIV_FLAGS:
534
+ return ARRAY_SIZE(lan743x_priv_flags_strings);
414535 default:
415536 return -EOPNOTSUPP;
416537 }
....@@ -427,7 +548,7 @@
427548 case TCP_V4_FLOW:case UDP_V4_FLOW:
428549 case TCP_V6_FLOW:case UDP_V6_FLOW:
429550 rxnfc->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
430
- /* fall through */
551
+ fallthrough;
431552 case IPV4_FLOW: case IPV6_FLOW:
432553 rxnfc->data |= RXH_IP_SRC | RXH_IP_DST;
433554 return 0;
....@@ -659,9 +780,7 @@
659780
660781 wol->supported = 0;
661782 wol->wolopts = 0;
662
-
663
- if (netdev->phydev)
664
- phy_ethtool_get_wol(netdev->phydev, wol);
783
+ phy_ethtool_get_wol(netdev->phydev, wol);
665784
666785 wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST |
667786 WAKE_MAGIC | WAKE_PHY | WAKE_ARP;
....@@ -690,8 +809,9 @@
690809
691810 device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts);
692811
693
- return netdev->phydev ? phy_ethtool_set_wol(netdev->phydev, wol)
694
- : -ENETDOWN;
812
+ phy_ethtool_set_wol(netdev->phydev, wol);
813
+
814
+ return 0;
695815 }
696816 #endif /* CONFIG_PM */
697817
....@@ -706,6 +826,8 @@
706826 .set_eeprom = lan743x_ethtool_set_eeprom,
707827 .get_strings = lan743x_ethtool_get_strings,
708828 .get_ethtool_stats = lan743x_ethtool_get_ethtool_stats,
829
+ .get_priv_flags = lan743x_ethtool_get_priv_flags,
830
+ .set_priv_flags = lan743x_ethtool_set_priv_flags,
709831 .get_sset_count = lan743x_ethtool_get_sset_count,
710832 .get_rxnfc = lan743x_ethtool_get_rxnfc,
711833 .get_rxfh_key_size = lan743x_ethtool_get_rxfh_key_size,