aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/asix_devices.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/asix_devices.c')
-rw-r--r--drivers/net/usb/asix_devices.c660
1 files changed, 1 insertions, 659 deletions
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index 6564c32d3af..8c513f7921f 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -20,137 +20,7 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23// #define DEBUG // error path messages, extra info 23#include "asix.h"
24// #define VERBOSE // more; success messages
25
26#include <linux/module.h>
27#include <linux/kmod.h>
28#include <linux/init.h>
29#include <linux/netdevice.h>
30#include <linux/etherdevice.h>
31#include <linux/ethtool.h>
32#include <linux/workqueue.h>
33#include <linux/mii.h>
34#include <linux/usb.h>
35#include <linux/crc32.h>
36#include <linux/usb/usbnet.h>
37#include <linux/slab.h>
38#include <linux/if_vlan.h>
39
40#define DRIVER_VERSION "22-Dec-2011"
41#define DRIVER_NAME "asix"
42
43/* ASIX AX8817X based USB 2.0 Ethernet Devices */
44
45#define AX_CMD_SET_SW_MII 0x06
46#define AX_CMD_READ_MII_REG 0x07
47#define AX_CMD_WRITE_MII_REG 0x08
48#define AX_CMD_SET_HW_MII 0x0a
49#define AX_CMD_READ_EEPROM 0x0b
50#define AX_CMD_WRITE_EEPROM 0x0c
51#define AX_CMD_WRITE_ENABLE 0x0d
52#define AX_CMD_WRITE_DISABLE 0x0e
53#define AX_CMD_READ_RX_CTL 0x0f
54#define AX_CMD_WRITE_RX_CTL 0x10
55#define AX_CMD_READ_IPG012 0x11
56#define AX_CMD_WRITE_IPG0 0x12
57#define AX_CMD_WRITE_IPG1 0x13
58#define AX_CMD_READ_NODE_ID 0x13
59#define AX_CMD_WRITE_NODE_ID 0x14
60#define AX_CMD_WRITE_IPG2 0x14
61#define AX_CMD_WRITE_MULTI_FILTER 0x16
62#define AX88172_CMD_READ_NODE_ID 0x17
63#define AX_CMD_READ_PHY_ID 0x19
64#define AX_CMD_READ_MEDIUM_STATUS 0x1a
65#define AX_CMD_WRITE_MEDIUM_MODE 0x1b
66#define AX_CMD_READ_MONITOR_MODE 0x1c
67#define AX_CMD_WRITE_MONITOR_MODE 0x1d
68#define AX_CMD_READ_GPIOS 0x1e
69#define AX_CMD_WRITE_GPIOS 0x1f
70#define AX_CMD_SW_RESET 0x20
71#define AX_CMD_SW_PHY_STATUS 0x21
72#define AX_CMD_SW_PHY_SELECT 0x22
73
74#define AX_MONITOR_MODE 0x01
75#define AX_MONITOR_LINK 0x02
76#define AX_MONITOR_MAGIC 0x04
77#define AX_MONITOR_HSFS 0x10
78
79/* AX88172 Medium Status Register values */
80#define AX88172_MEDIUM_FD 0x02
81#define AX88172_MEDIUM_TX 0x04
82#define AX88172_MEDIUM_FC 0x10
83#define AX88172_MEDIUM_DEFAULT \
84 ( AX88172_MEDIUM_FD | AX88172_MEDIUM_TX | AX88172_MEDIUM_FC )
85
86#define AX_MCAST_FILTER_SIZE 8
87#define AX_MAX_MCAST 64
88
89#define AX_SWRESET_CLEAR 0x00
90#define AX_SWRESET_RR 0x01
91#define AX_SWRESET_RT 0x02
92#define AX_SWRESET_PRTE 0x04
93#define AX_SWRESET_PRL 0x08
94#define AX_SWRESET_BZ 0x10
95#define AX_SWRESET_IPRL 0x20
96#define AX_SWRESET_IPPD 0x40
97
98#define AX88772_IPG0_DEFAULT 0x15
99#define AX88772_IPG1_DEFAULT 0x0c
100#define AX88772_IPG2_DEFAULT 0x12
101
102/* AX88772 & AX88178 Medium Mode Register */
103#define AX_MEDIUM_PF 0x0080
104#define AX_MEDIUM_JFE 0x0040
105#define AX_MEDIUM_TFC 0x0020
106#define AX_MEDIUM_RFC 0x0010
107#define AX_MEDIUM_ENCK 0x0008
108#define AX_MEDIUM_AC 0x0004
109#define AX_MEDIUM_FD 0x0002
110#define AX_MEDIUM_GM 0x0001
111#define AX_MEDIUM_SM 0x1000
112#define AX_MEDIUM_SBP 0x0800
113#define AX_MEDIUM_PS 0x0200
114#define AX_MEDIUM_RE 0x0100
115
116#define AX88178_MEDIUM_DEFAULT \
117 (AX_MEDIUM_PS | AX_MEDIUM_FD | AX_MEDIUM_AC | \
118 AX_MEDIUM_RFC | AX_MEDIUM_TFC | AX_MEDIUM_JFE | \
119 AX_MEDIUM_RE)
120
121#define AX88772_MEDIUM_DEFAULT \
122 (AX_MEDIUM_FD | AX_MEDIUM_RFC | \
123 AX_MEDIUM_TFC | AX_MEDIUM_PS | \
124 AX_MEDIUM_AC | AX_MEDIUM_RE)
125
126/* AX88772 & AX88178 RX_CTL values */
127#define AX_RX_CTL_SO 0x0080
128#define AX_RX_CTL_AP 0x0020
129#define AX_RX_CTL_AM 0x0010
130#define AX_RX_CTL_AB 0x0008
131#define AX_RX_CTL_SEP 0x0004
132#define AX_RX_CTL_AMALL 0x0002
133#define AX_RX_CTL_PRO 0x0001
134#define AX_RX_CTL_MFB_2048 0x0000
135#define AX_RX_CTL_MFB_4096 0x0100
136#define AX_RX_CTL_MFB_8192 0x0200
137#define AX_RX_CTL_MFB_16384 0x0300
138
139#define AX_DEFAULT_RX_CTL (AX_RX_CTL_SO | AX_RX_CTL_AB)
140
141/* GPIO 0 .. 2 toggles */
142#define AX_GPIO_GPO0EN 0x01 /* GPIO0 Output enable */
143#define AX_GPIO_GPO_0 0x02 /* GPIO0 Output value */
144#define AX_GPIO_GPO1EN 0x04 /* GPIO1 Output enable */
145#define AX_GPIO_GPO_1 0x08 /* GPIO1 Output value */
146#define AX_GPIO_GPO2EN 0x10 /* GPIO2 Output enable */
147#define AX_GPIO_GPO_2 0x20 /* GPIO2 Output value */
148#define AX_GPIO_RESERVED 0x40 /* Reserved */
149#define AX_GPIO_RSE 0x80 /* Reload serial EEPROM */
150
151#define AX_EEPROM_MAGIC 0xdeadbeef
152#define AX88172_EEPROM_LEN 0x40
153#define AX88772_EEPROM_LEN 0xff
154 24
155#define PHY_MODE_MARVELL 0x0000 25#define PHY_MODE_MARVELL 0x0000
156#define MII_MARVELL_LED_CTRL 0x0018 26#define MII_MARVELL_LED_CTRL 0x0018
@@ -166,15 +36,6 @@
166 36
167#define PHY_MODE_RTL8211CL 0x000C 37#define PHY_MODE_RTL8211CL 0x000C
168 38
169/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
170struct asix_data {
171 u8 multi_filter[AX_MCAST_FILTER_SIZE];
172 u8 mac_addr[ETH_ALEN];
173 u8 phymode;
174 u8 ledmode;
175 u8 eeprom_len;
176};
177
178struct ax88172_int_data { 39struct ax88172_int_data {
179 __le16 res1; 40 __le16 res1;
180 u8 link; 41 u8 link;
@@ -183,225 +44,6 @@ struct ax88172_int_data {
183 __le16 res3; 44 __le16 res3;
184} __packed; 45} __packed;
185 46
186static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
187 u16 size, void *data)
188{
189 void *buf;
190 int err = -ENOMEM;
191
192 netdev_dbg(dev->net, "asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
193 cmd, value, index, size);
194
195 buf = kmalloc(size, GFP_KERNEL);
196 if (!buf)
197 goto out;
198
199 err = usb_control_msg(
200 dev->udev,
201 usb_rcvctrlpipe(dev->udev, 0),
202 cmd,
203 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
204 value,
205 index,
206 buf,
207 size,
208 USB_CTRL_GET_TIMEOUT);
209 if (err == size)
210 memcpy(data, buf, size);
211 else if (err >= 0)
212 err = -EINVAL;
213 kfree(buf);
214
215out:
216 return err;
217}
218
219static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
220 u16 size, void *data)
221{
222 void *buf = NULL;
223 int err = -ENOMEM;
224
225 netdev_dbg(dev->net, "asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
226 cmd, value, index, size);
227
228 if (data) {
229 buf = kmemdup(data, size, GFP_KERNEL);
230 if (!buf)
231 goto out;
232 }
233
234 err = usb_control_msg(
235 dev->udev,
236 usb_sndctrlpipe(dev->udev, 0),
237 cmd,
238 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
239 value,
240 index,
241 buf,
242 size,
243 USB_CTRL_SET_TIMEOUT);
244 kfree(buf);
245
246out:
247 return err;
248}
249
250static void asix_async_cmd_callback(struct urb *urb)
251{
252 struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
253 int status = urb->status;
254
255 if (status < 0)
256 printk(KERN_DEBUG "asix_async_cmd_callback() failed with %d",
257 status);
258
259 kfree(req);
260 usb_free_urb(urb);
261}
262
263static void
264asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
265 u16 size, void *data)
266{
267 struct usb_ctrlrequest *req;
268 int status;
269 struct urb *urb;
270
271 netdev_dbg(dev->net, "asix_write_cmd_async() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
272 cmd, value, index, size);
273
274 urb = usb_alloc_urb(0, GFP_ATOMIC);
275 if (!urb) {
276 netdev_err(dev->net, "Error allocating URB in write_cmd_async!\n");
277 return;
278 }
279
280 req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
281 if (!req) {
282 netdev_err(dev->net, "Failed to allocate memory for control request\n");
283 usb_free_urb(urb);
284 return;
285 }
286
287 req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
288 req->bRequest = cmd;
289 req->wValue = cpu_to_le16(value);
290 req->wIndex = cpu_to_le16(index);
291 req->wLength = cpu_to_le16(size);
292
293 usb_fill_control_urb(urb, dev->udev,
294 usb_sndctrlpipe(dev->udev, 0),
295 (void *)req, data, size,
296 asix_async_cmd_callback, req);
297
298 status = usb_submit_urb(urb, GFP_ATOMIC);
299 if (status < 0) {
300 netdev_err(dev->net, "Error submitting the control message: status=%d\n",
301 status);
302 kfree(req);
303 usb_free_urb(urb);
304 }
305}
306
307static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
308{
309 int offset = 0;
310
311 while (offset + sizeof(u32) < skb->len) {
312 struct sk_buff *ax_skb;
313 u16 size;
314 u32 header = get_unaligned_le32(skb->data + offset);
315
316 offset += sizeof(u32);
317
318 /* get the packet length */
319 size = (u16) (header & 0x7ff);
320 if (size != ((~header >> 16) & 0x07ff)) {
321 netdev_err(dev->net, "asix_rx_fixup() Bad Header Length\n");
322 return 0;
323 }
324
325 if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) ||
326 (size + offset > skb->len)) {
327 netdev_err(dev->net, "asix_rx_fixup() Bad RX Length %d\n",
328 size);
329 return 0;
330 }
331 ax_skb = netdev_alloc_skb_ip_align(dev->net, size);
332 if (!ax_skb)
333 return 0;
334
335 skb_put(ax_skb, size);
336 memcpy(ax_skb->data, skb->data + offset, size);
337 usbnet_skb_return(dev, ax_skb);
338
339 offset += (size + 1) & 0xfffe;
340 }
341
342 if (skb->len != offset) {
343 netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d\n",
344 skb->len);
345 return 0;
346 }
347 return 1;
348}
349
350static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
351 gfp_t flags)
352{
353 int padlen;
354 int headroom = skb_headroom(skb);
355 int tailroom = skb_tailroom(skb);
356 u32 packet_len;
357 u32 padbytes = 0xffff0000;
358
359 padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4;
360
361 /* We need to push 4 bytes in front of frame (packet_len)
362 * and maybe add 4 bytes after the end (if padlen is 4)
363 *
364 * Avoid skb_copy_expand() expensive call, using following rules :
365 * - We are allowed to push 4 bytes in headroom if skb_header_cloned()
366 * is false (and if we have 4 bytes of headroom)
367 * - We are allowed to put 4 bytes at tail if skb_cloned()
368 * is false (and if we have 4 bytes of tailroom)
369 *
370 * TCP packets for example are cloned, but skb_header_release()
371 * was called in tcp stack, allowing us to use headroom for our needs.
372 */
373 if (!skb_header_cloned(skb) &&
374 !(padlen && skb_cloned(skb)) &&
375 headroom + tailroom >= 4 + padlen) {
376 /* following should not happen, but better be safe */
377 if (headroom < 4 ||
378 tailroom < padlen) {
379 skb->data = memmove(skb->head + 4, skb->data, skb->len);
380 skb_set_tail_pointer(skb, skb->len);
381 }
382 } else {
383 struct sk_buff *skb2;
384
385 skb2 = skb_copy_expand(skb, 4, padlen, flags);
386 dev_kfree_skb_any(skb);
387 skb = skb2;
388 if (!skb)
389 return NULL;
390 }
391
392 packet_len = ((skb->len ^ 0x0000ffff) << 16) + skb->len;
393 skb_push(skb, 4);
394 cpu_to_le32s(&packet_len);
395 skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len));
396
397 if (padlen) {
398 cpu_to_le32s(&padbytes);
399 memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes));
400 skb_put(skb, sizeof(padbytes));
401 }
402 return skb;
403}
404
405static void asix_status(struct usbnet *dev, struct urb *urb) 47static void asix_status(struct usbnet *dev, struct urb *urb)
406{ 48{
407 struct ax88172_int_data *event; 49 struct ax88172_int_data *event;
@@ -422,200 +64,6 @@ static void asix_status(struct usbnet *dev, struct urb *urb)
422 } 64 }
423} 65}
424 66
425static inline int asix_set_sw_mii(struct usbnet *dev)
426{
427 int ret;
428 ret = asix_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL);
429 if (ret < 0)
430 netdev_err(dev->net, "Failed to enable software MII access\n");
431 return ret;
432}
433
434static inline int asix_set_hw_mii(struct usbnet *dev)
435{
436 int ret;
437 ret = asix_write_cmd(dev, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL);
438 if (ret < 0)
439 netdev_err(dev->net, "Failed to enable hardware MII access\n");
440 return ret;
441}
442
443static inline int asix_get_phy_addr(struct usbnet *dev)
444{
445 u8 buf[2];
446 int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
447
448 netdev_dbg(dev->net, "asix_get_phy_addr()\n");
449
450 if (ret < 0) {
451 netdev_err(dev->net, "Error reading PHYID register: %02x\n", ret);
452 goto out;
453 }
454 netdev_dbg(dev->net, "asix_get_phy_addr() returning 0x%04x\n",
455 *((__le16 *)buf));
456 ret = buf[1];
457
458out:
459 return ret;
460}
461
462static int asix_sw_reset(struct usbnet *dev, u8 flags)
463{
464 int ret;
465
466 ret = asix_write_cmd(dev, AX_CMD_SW_RESET, flags, 0, 0, NULL);
467 if (ret < 0)
468 netdev_err(dev->net, "Failed to send software reset: %02x\n", ret);
469
470 return ret;
471}
472
473static u16 asix_read_rx_ctl(struct usbnet *dev)
474{
475 __le16 v;
476 int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v);
477
478 if (ret < 0) {
479 netdev_err(dev->net, "Error reading RX_CTL register: %02x\n", ret);
480 goto out;
481 }
482 ret = le16_to_cpu(v);
483out:
484 return ret;
485}
486
487static int asix_write_rx_ctl(struct usbnet *dev, u16 mode)
488{
489 int ret;
490
491 netdev_dbg(dev->net, "asix_write_rx_ctl() - mode = 0x%04x\n", mode);
492 ret = asix_write_cmd(dev, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL);
493 if (ret < 0)
494 netdev_err(dev->net, "Failed to write RX_CTL mode to 0x%04x: %02x\n",
495 mode, ret);
496
497 return ret;
498}
499
500static u16 asix_read_medium_status(struct usbnet *dev)
501{
502 __le16 v;
503 int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v);
504
505 if (ret < 0) {
506 netdev_err(dev->net, "Error reading Medium Status register: %02x\n",
507 ret);
508 return ret; /* TODO: callers not checking for error ret */
509 }
510
511 return le16_to_cpu(v);
512
513}
514
515static int asix_write_medium_mode(struct usbnet *dev, u16 mode)
516{
517 int ret;
518
519 netdev_dbg(dev->net, "asix_write_medium_mode() - mode = 0x%04x\n", mode);
520 ret = asix_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
521 if (ret < 0)
522 netdev_err(dev->net, "Failed to write Medium Mode mode to 0x%04x: %02x\n",
523 mode, ret);
524
525 return ret;
526}
527
528static int asix_write_gpio(struct usbnet *dev, u16 value, int sleep)
529{
530 int ret;
531
532 netdev_dbg(dev->net, "asix_write_gpio() - value = 0x%04x\n", value);
533 ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL);
534 if (ret < 0)
535 netdev_err(dev->net, "Failed to write GPIO value 0x%04x: %02x\n",
536 value, ret);
537
538 if (sleep)
539 msleep(sleep);
540
541 return ret;
542}
543
544/*
545 * AX88772 & AX88178 have a 16-bit RX_CTL value
546 */
547static void asix_set_multicast(struct net_device *net)
548{
549 struct usbnet *dev = netdev_priv(net);
550 struct asix_data *data = (struct asix_data *)&dev->data;
551 u16 rx_ctl = AX_DEFAULT_RX_CTL;
552
553 if (net->flags & IFF_PROMISC) {
554 rx_ctl |= AX_RX_CTL_PRO;
555 } else if (net->flags & IFF_ALLMULTI ||
556 netdev_mc_count(net) > AX_MAX_MCAST) {
557 rx_ctl |= AX_RX_CTL_AMALL;
558 } else if (netdev_mc_empty(net)) {
559 /* just broadcast and directed */
560 } else {
561 /* We use the 20 byte dev->data
562 * for our 8 byte filter buffer
563 * to avoid allocating memory that
564 * is tricky to free later */
565 struct netdev_hw_addr *ha;
566 u32 crc_bits;
567
568 memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE);
569
570 /* Build the multicast hash filter. */
571 netdev_for_each_mc_addr(ha, net) {
572 crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
573 data->multi_filter[crc_bits >> 3] |=
574 1 << (crc_bits & 7);
575 }
576
577 asix_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
578 AX_MCAST_FILTER_SIZE, data->multi_filter);
579
580 rx_ctl |= AX_RX_CTL_AM;
581 }
582
583 asix_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
584}
585
586static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)
587{
588 struct usbnet *dev = netdev_priv(netdev);
589 __le16 res;
590
591 mutex_lock(&dev->phy_mutex);
592 asix_set_sw_mii(dev);
593 asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
594 (__u16)loc, 2, &res);
595 asix_set_hw_mii(dev);
596 mutex_unlock(&dev->phy_mutex);
597
598 netdev_dbg(dev->net, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n",
599 phy_id, loc, le16_to_cpu(res));
600
601 return le16_to_cpu(res);
602}
603
604static void
605asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
606{
607 struct usbnet *dev = netdev_priv(netdev);
608 __le16 res = cpu_to_le16(val);
609
610 netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n",
611 phy_id, loc, val);
612 mutex_lock(&dev->phy_mutex);
613 asix_set_sw_mii(dev);
614 asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res);
615 asix_set_hw_mii(dev);
616 mutex_unlock(&dev->phy_mutex);
617}
618
619/* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ 67/* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */
620static u32 asix_get_phyid(struct usbnet *dev) 68static u32 asix_get_phyid(struct usbnet *dev)
621{ 69{
@@ -645,88 +93,6 @@ static u32 asix_get_phyid(struct usbnet *dev)
645 return phy_id; 93 return phy_id;
646} 94}
647 95
648static void
649asix_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
650{
651 struct usbnet *dev = netdev_priv(net);
652 u8 opt;
653
654 if (asix_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
655 wolinfo->supported = 0;
656 wolinfo->wolopts = 0;
657 return;
658 }
659 wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
660 wolinfo->wolopts = 0;
661 if (opt & AX_MONITOR_LINK)
662 wolinfo->wolopts |= WAKE_PHY;
663 if (opt & AX_MONITOR_MAGIC)
664 wolinfo->wolopts |= WAKE_MAGIC;
665}
666
667static int
668asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
669{
670 struct usbnet *dev = netdev_priv(net);
671 u8 opt = 0;
672
673 if (wolinfo->wolopts & WAKE_PHY)
674 opt |= AX_MONITOR_LINK;
675 if (wolinfo->wolopts & WAKE_MAGIC)
676 opt |= AX_MONITOR_MAGIC;
677
678 if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE,
679 opt, 0, 0, NULL) < 0)
680 return -EINVAL;
681
682 return 0;
683}
684
685static int asix_get_eeprom_len(struct net_device *net)
686{
687 struct usbnet *dev = netdev_priv(net);
688 struct asix_data *data = (struct asix_data *)&dev->data;
689
690 return data->eeprom_len;
691}
692
693static int asix_get_eeprom(struct net_device *net,
694 struct ethtool_eeprom *eeprom, u8 *data)
695{
696 struct usbnet *dev = netdev_priv(net);
697 __le16 *ebuf = (__le16 *)data;
698 int i;
699
700 /* Crude hack to ensure that we don't overwrite memory
701 * if an odd length is supplied
702 */
703 if (eeprom->len % 2)
704 return -EINVAL;
705
706 eeprom->magic = AX_EEPROM_MAGIC;
707
708 /* ax8817x returns 2 bytes from eeprom on read */
709 for (i=0; i < eeprom->len / 2; i++) {
710 if (asix_read_cmd(dev, AX_CMD_READ_EEPROM,
711 eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
712 return -EINVAL;
713 }
714 return 0;
715}
716
717static void asix_get_drvinfo (struct net_device *net,
718 struct ethtool_drvinfo *info)
719{
720 struct usbnet *dev = netdev_priv(net);
721 struct asix_data *data = (struct asix_data *)&dev->data;
722
723 /* Inherit standard device info */
724 usbnet_get_drvinfo(net, info);
725 strncpy (info->driver, DRIVER_NAME, sizeof info->driver);
726 strncpy (info->version, DRIVER_VERSION, sizeof info->version);
727 info->eedump_len = data->eeprom_len;
728}
729
730static u32 asix_get_link(struct net_device *net) 96static u32 asix_get_link(struct net_device *net)
731{ 97{
732 struct usbnet *dev = netdev_priv(net); 98 struct usbnet *dev = netdev_priv(net);
@@ -741,30 +107,6 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
741 return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); 107 return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
742} 108}
743 109
744static int asix_set_mac_address(struct net_device *net, void *p)
745{
746 struct usbnet *dev = netdev_priv(net);
747 struct asix_data *data = (struct asix_data *)&dev->data;
748 struct sockaddr *addr = p;
749
750 if (netif_running(net))
751 return -EBUSY;
752 if (!is_valid_ether_addr(addr->sa_data))
753 return -EADDRNOTAVAIL;
754
755 memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
756
757 /* We use the 20 byte dev->data
758 * for our 6 byte mac buffer
759 * to avoid allocating memory that
760 * is tricky to free later */
761 memcpy(data->mac_addr, addr->sa_data, ETH_ALEN);
762 asix_write_cmd_async(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
763 data->mac_addr);
764
765 return 0;
766}
767
768/* We need to override some ethtool_ops so we require our 110/* We need to override some ethtool_ops so we require our
769 own structure so we don't interfere with other usbnet 111 own structure so we don't interfere with other usbnet
770 devices that may be connected at the same time. */ 112 devices that may be connected at the same time. */