Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-microblaze.git] / drivers / net / ethernet / atheros / atl1e / atl1e_ethtool.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright(c) 2007 Atheros Corporation. All rights reserved.
4  *
5  * Derived from Intel e1000 driver
6  * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
7  */
8
9 #include <linux/netdevice.h>
10 #include <linux/ethtool.h>
11 #include <linux/slab.h>
12
13 #include "atl1e.h"
14
15 static int atl1e_get_link_ksettings(struct net_device *netdev,
16                                     struct ethtool_link_ksettings *cmd)
17 {
18         struct atl1e_adapter *adapter = netdev_priv(netdev);
19         struct atl1e_hw *hw = &adapter->hw;
20         u32 supported, advertising;
21
22         supported = (SUPPORTED_10baseT_Half  |
23                            SUPPORTED_10baseT_Full  |
24                            SUPPORTED_100baseT_Half |
25                            SUPPORTED_100baseT_Full |
26                            SUPPORTED_Autoneg       |
27                            SUPPORTED_TP);
28         if (hw->nic_type == athr_l1e)
29                 supported |= SUPPORTED_1000baseT_Full;
30
31         advertising = ADVERTISED_TP;
32
33         advertising |= ADVERTISED_Autoneg;
34         advertising |= hw->autoneg_advertised;
35
36         cmd->base.port = PORT_TP;
37         cmd->base.phy_address = 0;
38
39         if (adapter->link_speed != SPEED_0) {
40                 cmd->base.speed = adapter->link_speed;
41                 if (adapter->link_duplex == FULL_DUPLEX)
42                         cmd->base.duplex = DUPLEX_FULL;
43                 else
44                         cmd->base.duplex = DUPLEX_HALF;
45         } else {
46                 cmd->base.speed = SPEED_UNKNOWN;
47                 cmd->base.duplex = DUPLEX_UNKNOWN;
48         }
49
50         cmd->base.autoneg = AUTONEG_ENABLE;
51
52         ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
53                                                 supported);
54         ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
55                                                 advertising);
56
57         return 0;
58 }
59
60 static int atl1e_set_link_ksettings(struct net_device *netdev,
61                                     const struct ethtool_link_ksettings *cmd)
62 {
63         struct atl1e_adapter *adapter = netdev_priv(netdev);
64         struct atl1e_hw *hw = &adapter->hw;
65         u32 advertising;
66
67         ethtool_convert_link_mode_to_legacy_u32(&advertising,
68                                                 cmd->link_modes.advertising);
69
70         while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
71                 msleep(1);
72
73         if (cmd->base.autoneg == AUTONEG_ENABLE) {
74                 u16 adv4, adv9;
75
76                 if (advertising & ADVERTISE_1000_FULL) {
77                         if (hw->nic_type == athr_l1e) {
78                                 hw->autoneg_advertised =
79                                         advertising & AT_ADV_MASK;
80                         } else {
81                                 clear_bit(__AT_RESETTING, &adapter->flags);
82                                 return -EINVAL;
83                         }
84                 } else if (advertising & ADVERTISE_1000_HALF) {
85                         clear_bit(__AT_RESETTING, &adapter->flags);
86                         return -EINVAL;
87                 } else {
88                         hw->autoneg_advertised =
89                                 advertising & AT_ADV_MASK;
90                 }
91                 advertising = hw->autoneg_advertised |
92                                     ADVERTISED_TP | ADVERTISED_Autoneg;
93
94                 adv4 = hw->mii_autoneg_adv_reg & ~ADVERTISE_ALL;
95                 adv9 = hw->mii_1000t_ctrl_reg & ~MII_AT001_CR_1000T_SPEED_MASK;
96                 if (hw->autoneg_advertised & ADVERTISE_10_HALF)
97                         adv4 |= ADVERTISE_10HALF;
98                 if (hw->autoneg_advertised & ADVERTISE_10_FULL)
99                         adv4 |= ADVERTISE_10FULL;
100                 if (hw->autoneg_advertised & ADVERTISE_100_HALF)
101                         adv4 |= ADVERTISE_100HALF;
102                 if (hw->autoneg_advertised & ADVERTISE_100_FULL)
103                         adv4 |= ADVERTISE_100FULL;
104                 if (hw->autoneg_advertised & ADVERTISE_1000_FULL)
105                         adv9 |= ADVERTISE_1000FULL;
106
107                 if (adv4 != hw->mii_autoneg_adv_reg ||
108                                 adv9 != hw->mii_1000t_ctrl_reg) {
109                         hw->mii_autoneg_adv_reg = adv4;
110                         hw->mii_1000t_ctrl_reg = adv9;
111                         hw->re_autoneg = true;
112                 }
113
114         } else {
115                 clear_bit(__AT_RESETTING, &adapter->flags);
116                 return -EINVAL;
117         }
118
119         /* reset the link */
120
121         if (netif_running(adapter->netdev)) {
122                 atl1e_down(adapter);
123                 atl1e_up(adapter);
124         } else
125                 atl1e_reset_hw(&adapter->hw);
126
127         clear_bit(__AT_RESETTING, &adapter->flags);
128         return 0;
129 }
130
131 static u32 atl1e_get_msglevel(struct net_device *netdev)
132 {
133 #ifdef DBG
134         return 1;
135 #else
136         return 0;
137 #endif
138 }
139
140 static int atl1e_get_regs_len(struct net_device *netdev)
141 {
142         return AT_REGS_LEN * sizeof(u32);
143 }
144
145 static void atl1e_get_regs(struct net_device *netdev,
146                            struct ethtool_regs *regs, void *p)
147 {
148         struct atl1e_adapter *adapter = netdev_priv(netdev);
149         struct atl1e_hw *hw = &adapter->hw;
150         u32 *regs_buff = p;
151         u16 phy_data;
152
153         memset(p, 0, AT_REGS_LEN * sizeof(u32));
154
155         regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
156
157         regs_buff[0]  = AT_READ_REG(hw, REG_VPD_CAP);
158         regs_buff[1]  = AT_READ_REG(hw, REG_SPI_FLASH_CTRL);
159         regs_buff[2]  = AT_READ_REG(hw, REG_SPI_FLASH_CONFIG);
160         regs_buff[3]  = AT_READ_REG(hw, REG_TWSI_CTRL);
161         regs_buff[4]  = AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL);
162         regs_buff[5]  = AT_READ_REG(hw, REG_MASTER_CTRL);
163         regs_buff[6]  = AT_READ_REG(hw, REG_MANUAL_TIMER_INIT);
164         regs_buff[7]  = AT_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT);
165         regs_buff[8]  = AT_READ_REG(hw, REG_GPHY_CTRL);
166         regs_buff[9]  = AT_READ_REG(hw, REG_CMBDISDMA_TIMER);
167         regs_buff[10] = AT_READ_REG(hw, REG_IDLE_STATUS);
168         regs_buff[11] = AT_READ_REG(hw, REG_MDIO_CTRL);
169         regs_buff[12] = AT_READ_REG(hw, REG_SERDES_LOCK);
170         regs_buff[13] = AT_READ_REG(hw, REG_MAC_CTRL);
171         regs_buff[14] = AT_READ_REG(hw, REG_MAC_IPG_IFG);
172         regs_buff[15] = AT_READ_REG(hw, REG_MAC_STA_ADDR);
173         regs_buff[16] = AT_READ_REG(hw, REG_MAC_STA_ADDR+4);
174         regs_buff[17] = AT_READ_REG(hw, REG_RX_HASH_TABLE);
175         regs_buff[18] = AT_READ_REG(hw, REG_RX_HASH_TABLE+4);
176         regs_buff[19] = AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL);
177         regs_buff[20] = AT_READ_REG(hw, REG_MTU);
178         regs_buff[21] = AT_READ_REG(hw, REG_WOL_CTRL);
179         regs_buff[22] = AT_READ_REG(hw, REG_SRAM_TRD_ADDR);
180         regs_buff[23] = AT_READ_REG(hw, REG_SRAM_TRD_LEN);
181         regs_buff[24] = AT_READ_REG(hw, REG_SRAM_RXF_ADDR);
182         regs_buff[25] = AT_READ_REG(hw, REG_SRAM_RXF_LEN);
183         regs_buff[26] = AT_READ_REG(hw, REG_SRAM_TXF_ADDR);
184         regs_buff[27] = AT_READ_REG(hw, REG_SRAM_TXF_LEN);
185         regs_buff[28] = AT_READ_REG(hw, REG_SRAM_TCPH_ADDR);
186         regs_buff[29] = AT_READ_REG(hw, REG_SRAM_PKTH_ADDR);
187
188         atl1e_read_phy_reg(hw, MII_BMCR, &phy_data);
189         regs_buff[73] = (u32)phy_data;
190         atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
191         regs_buff[74] = (u32)phy_data;
192 }
193
194 static int atl1e_get_eeprom_len(struct net_device *netdev)
195 {
196         struct atl1e_adapter *adapter = netdev_priv(netdev);
197
198         if (!atl1e_check_eeprom_exist(&adapter->hw))
199                 return AT_EEPROM_LEN;
200         else
201                 return 0;
202 }
203
204 static int atl1e_get_eeprom(struct net_device *netdev,
205                 struct ethtool_eeprom *eeprom, u8 *bytes)
206 {
207         struct atl1e_adapter *adapter = netdev_priv(netdev);
208         struct atl1e_hw *hw = &adapter->hw;
209         u32 *eeprom_buff;
210         int first_dword, last_dword;
211         int ret_val = 0;
212         int i;
213
214         if (eeprom->len == 0)
215                 return -EINVAL;
216
217         if (atl1e_check_eeprom_exist(hw)) /* not exist */
218                 return -EINVAL;
219
220         eeprom->magic = hw->vendor_id | (hw->device_id << 16);
221
222         first_dword = eeprom->offset >> 2;
223         last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
224
225         eeprom_buff = kmalloc_array(last_dword - first_dword + 1, sizeof(u32),
226                                     GFP_KERNEL);
227         if (eeprom_buff == NULL)
228                 return -ENOMEM;
229
230         for (i = first_dword; i < last_dword; i++) {
231                 if (!atl1e_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
232                         kfree(eeprom_buff);
233                         return -EIO;
234                 }
235         }
236
237         memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
238                         eeprom->len);
239         kfree(eeprom_buff);
240
241         return ret_val;
242 }
243
244 static int atl1e_set_eeprom(struct net_device *netdev,
245                             struct ethtool_eeprom *eeprom, u8 *bytes)
246 {
247         struct atl1e_adapter *adapter = netdev_priv(netdev);
248         struct atl1e_hw *hw = &adapter->hw;
249         u32 *eeprom_buff;
250         u32 *ptr;
251         int first_dword, last_dword;
252         int ret_val = 0;
253         int i;
254
255         if (eeprom->len == 0)
256                 return -EOPNOTSUPP;
257
258         if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
259                 return -EINVAL;
260
261         first_dword = eeprom->offset >> 2;
262         last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
263         eeprom_buff = kmalloc(AT_EEPROM_LEN, GFP_KERNEL);
264         if (eeprom_buff == NULL)
265                 return -ENOMEM;
266
267         ptr = eeprom_buff;
268
269         if (eeprom->offset & 3) {
270                 /* need read/modify/write of first changed EEPROM word */
271                 /* only the second byte of the word is being modified */
272                 if (!atl1e_read_eeprom(hw, first_dword * 4, &(eeprom_buff[0]))) {
273                         ret_val = -EIO;
274                         goto out;
275                 }
276                 ptr++;
277         }
278         if (((eeprom->offset + eeprom->len) & 3)) {
279                 /* need read/modify/write of last changed EEPROM word */
280                 /* only the first byte of the word is being modified */
281
282                 if (!atl1e_read_eeprom(hw, last_dword * 4,
283                                 &(eeprom_buff[last_dword - first_dword]))) {
284                         ret_val = -EIO;
285                         goto out;
286                 }
287         }
288
289         /* Device's eeprom is always little-endian, word addressable */
290         memcpy(ptr, bytes, eeprom->len);
291
292         for (i = 0; i < last_dword - first_dword + 1; i++) {
293                 if (!atl1e_write_eeprom(hw, ((first_dword + i) * 4),
294                                   eeprom_buff[i])) {
295                         ret_val = -EIO;
296                         goto out;
297                 }
298         }
299 out:
300         kfree(eeprom_buff);
301         return ret_val;
302 }
303
304 static void atl1e_get_drvinfo(struct net_device *netdev,
305                 struct ethtool_drvinfo *drvinfo)
306 {
307         struct atl1e_adapter *adapter = netdev_priv(netdev);
308
309         strlcpy(drvinfo->driver,  atl1e_driver_name, sizeof(drvinfo->driver));
310         strlcpy(drvinfo->fw_version, "L1e", sizeof(drvinfo->fw_version));
311         strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
312                 sizeof(drvinfo->bus_info));
313 }
314
315 static void atl1e_get_wol(struct net_device *netdev,
316                           struct ethtool_wolinfo *wol)
317 {
318         struct atl1e_adapter *adapter = netdev_priv(netdev);
319
320         wol->supported = WAKE_MAGIC | WAKE_PHY;
321         wol->wolopts = 0;
322
323         if (adapter->wol & AT_WUFC_EX)
324                 wol->wolopts |= WAKE_UCAST;
325         if (adapter->wol & AT_WUFC_MC)
326                 wol->wolopts |= WAKE_MCAST;
327         if (adapter->wol & AT_WUFC_BC)
328                 wol->wolopts |= WAKE_BCAST;
329         if (adapter->wol & AT_WUFC_MAG)
330                 wol->wolopts |= WAKE_MAGIC;
331         if (adapter->wol & AT_WUFC_LNKC)
332                 wol->wolopts |= WAKE_PHY;
333 }
334
335 static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
336 {
337         struct atl1e_adapter *adapter = netdev_priv(netdev);
338
339         if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
340                             WAKE_UCAST | WAKE_MCAST | WAKE_BCAST))
341                 return -EOPNOTSUPP;
342         /* these settings will always override what we currently have */
343         adapter->wol = 0;
344
345         if (wol->wolopts & WAKE_MAGIC)
346                 adapter->wol |= AT_WUFC_MAG;
347         if (wol->wolopts & WAKE_PHY)
348                 adapter->wol |= AT_WUFC_LNKC;
349
350         device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
351
352         return 0;
353 }
354
355 static int atl1e_nway_reset(struct net_device *netdev)
356 {
357         struct atl1e_adapter *adapter = netdev_priv(netdev);
358         if (netif_running(netdev))
359                 atl1e_reinit_locked(adapter);
360         return 0;
361 }
362
363 static const struct ethtool_ops atl1e_ethtool_ops = {
364         .get_drvinfo            = atl1e_get_drvinfo,
365         .get_regs_len           = atl1e_get_regs_len,
366         .get_regs               = atl1e_get_regs,
367         .get_wol                = atl1e_get_wol,
368         .set_wol                = atl1e_set_wol,
369         .get_msglevel           = atl1e_get_msglevel,
370         .nway_reset             = atl1e_nway_reset,
371         .get_link               = ethtool_op_get_link,
372         .get_eeprom_len         = atl1e_get_eeprom_len,
373         .get_eeprom             = atl1e_get_eeprom,
374         .set_eeprom             = atl1e_set_eeprom,
375         .get_link_ksettings     = atl1e_get_link_ksettings,
376         .set_link_ksettings     = atl1e_set_link_ksettings,
377 };
378
379 void atl1e_set_ethtool_ops(struct net_device *netdev)
380 {
381         netdev->ethtool_ops = &atl1e_ethtool_ops;
382 }