ee1df7d819b12162f827a71c490e132c84f81350
[people/balajirrao/gpxe.git] / src / drivers / net / usb / asix.c
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <gpxe/if_ether.h>
4 #include <gpxe/usb.h>
5 #include <gpxe/malloc.h>
6 #include <gpxe/ethernet.h>
7 #include <gpxe/iobuf.h>
8 #include <mii.h>
9 #include <errno.h>
10 #include <little_bswap.h>
11
12 #include "asix.h"
13
14 static const char driver_name[] = "asix";
15
16 static int asix_read_cmd(struct asix *asix, uint8_t cmd, uint16_t value, u16 index,
17                             uint16_t size, void *data)
18 {
19         void *buf;
20         int err = -ENOMEM;
21
22         DBG("asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
23                 cmd, value, index, size);
24
25         buf = malloc_dma(size,1);
26         if (!buf)
27                 goto out;
28
29         err = usb_control_msg(asix->udev, &asix->udev->ep_0_in, cmd,
30                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value,
31                         index,  buf, size);
32
33         memcpy(data, buf, size);
34         free_dma(buf, size);
35 out:
36         return err;
37 }
38
39 static int asix_write_cmd(struct asix *asix, uint8_t cmd, uint16_t value, u16 index,
40                              uint16_t size, void *data)
41 {
42         void *buf = NULL;
43         int err = -ENOMEM;
44
45         DBG("asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d\n",
46                 cmd, value, index, size);
47
48         if (data) {
49                 buf = malloc_dma(size, 1);
50                 if (!buf)
51                         goto out;
52                 memcpy(buf, data, size);
53         }
54
55         err = usb_control_msg(asix->udev, &asix->udev->ep_0_out, cmd,
56                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
57                         value, index, buf, size);
58         free_dma(buf, size);
59
60 out:
61         return err;
62 }
63
64 static int asix_write_gpio(struct asix *asix, uint16_t value, int sleep)
65 {
66         int ret;
67
68         DBG("asix_write_gpio() - value = 0x%04x\n", value);
69         ret = asix_write_cmd(asix, AX_CMD_WRITE_GPIOS, value, 0, 0, NULL);
70         if (ret < 0)
71                 DBG("Failed to write GPIO value 0x%04x: %02x\n",
72                         value, ret);
73
74         if (sleep)
75                 mdelay(sleep);
76
77         return ret;
78 }
79
80 static inline int asix_set_sw_mii(struct asix *asix)
81 {
82         int ret;
83         ret = asix_write_cmd(asix, AX_CMD_SET_SW_MII, 0x0000, 0, 0, NULL);
84         if (ret < 0)
85                 DBG("Failed to enable software MII access");
86         return ret;
87 }
88
89 static inline int asix_set_hw_mii(struct asix *asix)
90 {
91         int ret;
92         ret = asix_write_cmd(asix, AX_CMD_SET_HW_MII, 0x0000, 0, 0, NULL);
93         if (ret < 0)
94                 DBG("Failed to enable hardware MII access");
95         return ret;
96 }
97
98 static void
99 asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
100 {
101         struct asix *asix = netdev_priv(netdev);
102         uint16_t res = cpu_to_le16(val);
103
104         DBG("asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", phy_id, loc, val);
105         asix_set_sw_mii(asix);
106         asix_write_cmd(asix, AX_CMD_WRITE_MII_REG, phy_id, (uint16_t)loc, 2, &res);
107         asix_set_hw_mii(asix);
108 }
109
110 static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)
111 {
112         struct asix *asix = netdev_priv(netdev);
113         uint16_t res;
114
115         asix_set_sw_mii(asix);
116         asix_read_cmd(asix, AX_CMD_READ_MII_REG, phy_id,
117                                 (uint16_t)loc, 2, &res);
118         asix_set_hw_mii(asix);
119
120         DBG("asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", phy_id, loc, le16_to_cpu(res));
121
122         return le16_to_cpu(res);
123 }
124
125
126 static int asix_write_medium_mode(struct asix *asix, uint16_t mode)
127 {
128         int ret;
129
130         DBG("asix_write_medium_mode() - mode = 0x%04x\n", mode);
131         ret = asix_write_cmd(asix, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
132         if (ret < 0)
133                 DBG("Failed to write Medium Mode mode to 0x%04x: %02x\n",
134                         mode, ret);
135
136         return ret;
137 }
138
139 static inline int asix_get_phy_addr(struct asix *asix)
140 {
141         uint8_t buf[2];
142         int ret = asix_read_cmd(asix, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
143
144         DBG("asix_get_phy_addr()");
145
146         if (ret < 0) {
147                 DBG("Error reading PHYID register: %02x\n", ret);
148                 goto out;
149         }
150         DBG("asix_get_phy_addr() returning 0x%04x\n", *((uint16_t *)buf));
151         ret = buf[1];
152
153 out:
154         return ret;
155 }
156
157 static int enqueue_one_rx_urb(struct asix *asix)
158 {
159         struct urb *urb;
160         struct io_buffer *iobuf;
161         int ret = -ENOMEM;
162
163         DBG("Enqueing one URB\n");
164         
165         iobuf = alloc_iob(2048);
166         if (!iobuf)
167                 goto err_iobuf_malloc;
168
169         urb = usb_alloc_urb();
170         if (!urb)
171                 goto err_usb_malloc;
172
173         usb_fill_bulk_urb(urb, asix->udev, asix->in, iob_put(iobuf, 2048), 2048);
174
175         ret = usb_submit_urb(urb);
176         if (ret < 0)
177                 goto err_submit_urb;
178         
179         urb->priv = iobuf;
180         list_add_tail(&urb->priv_list, &asix->rx_queue);
181         
182         return 0;
183
184 err_submit_urb:
185         usb_free_urb(urb);
186 err_usb_malloc:
187         free_iob(iobuf);
188 err_iobuf_malloc:
189
190         return ret;
191 }
192
193 int asix_open ( struct net_device *netdev)
194 {
195         enqueue_one_rx_urb(netdev_priv(netdev));
196         return 0;
197 }
198
199 void asix_88178_remove(struct usb_device *udev __unused)
200 {
201
202 }
203
204 void asix_88772_remove(struct usb_device *udev __unused)
205 {
206
207 }
208
209 void asix_close ( struct net_device *netdev ) {
210         
211         netdev++;
212 }
213
214 int asix_transmit ( struct net_device *netdev __unused,
215                           struct io_buffer *iobuf __unused)
216 {
217         struct asix *asix = netdev_priv(netdev);
218         uint32_t length;
219         struct urb *urb = NULL;
220         int status;
221         void *buffer;
222         int padlen;
223         uint32_t packet_len;
224         uint32_t pad_bytes = 0xffff0000;
225         int ret = -ENOMEM;
226
227         length = iob_len(iobuf);
228         padlen = ((length + 4) % 64) ? 0 : 4;
229
230         buffer = malloc_dma(length + padlen + 4, 1);
231         if(!buffer)
232                 goto err_buffer_malloc;
233
234         packet_len = ((length ^ 0x0000ffff) << 16) + (length);
235         
236         packet_len = cpu_to_le32(packet_len);
237
238
239         memcpy(buffer, &packet_len, 4);
240         memcpy(buffer + 4, iobuf->data, length);
241
242         DBG("pad len = %d\n", padlen);  
243
244         if (padlen)
245                 memcpy(buffer + length + 4, &pad_bytes, 4);
246
247         length += (4 + padlen);
248
249
250         urb = usb_alloc_urb();
251         if (!urb)
252                 goto err_alloc_urb;
253
254         usb_fill_bulk_urb (urb, asix->udev, asix->out,
255                         buffer, length);
256
257
258         ret = usb_submit_urb (urb);
259         
260         if (ret < 0)
261                 goto err_submit_urb;
262
263         urb->priv = iobuf;
264         list_add_tail(&urb->priv_list, &asix->tx_queue);
265
266         /* Report successful transmit completions */            
267         list_for_each_entry(urb, &asix->tx_queue, priv_list) {
268                 if ((status = usb_urb_status(urb)) == USB_URB_STATUS_COMPLETE) {
269                         netdev_tx_complete(netdev, urb->priv);
270
271                         list_del(&urb->priv_list);
272
273                         free_dma(urb->transfer_buffer, urb->transfer_buffer_length);
274                         usb_unlink_urb(urb);
275                         
276                         DBG("TX DONE\n");
277                 } else if (status == USB_URB_STATUS_ERROR)
278                         DBG("TX Error\n");
279         }
280         return 0;
281         
282         /* Nothing to do */
283 err_submit_urb:
284         usb_free_urb(urb);
285 err_alloc_urb:
286         free_dma(buffer, length);
287 err_buffer_malloc:
288         return ret;
289 }
290
291
292 void asix_poll ( struct net_device *netdev) {
293         struct asix *asix = netdev_priv(netdev);
294         struct urb *urb;
295         uint8_t *buffer, *packet;
296         struct io_buffer *iobuf;
297         uint8_t status = 0;
298         unsigned int len;
299         uint8_t *head;
300         uint32_t header;
301
302         list_for_each_entry(urb, &asix->rx_queue, priv_list) {
303                 if ((status = usb_urb_status(urb)) == USB_URB_STATUS_COMPLETE) {
304                         if (enqueue_one_rx_urb(asix) < 0)
305                                 DBG("Error enquing packet\n");
306
307                         buffer = urb->transfer_buffer;
308                         head = (uint8_t *) buffer;
309                         memcpy(&header, head, sizeof(header));
310                         header = le32_to_cpu(header);
311                         packet = head + sizeof(header);
312         
313                         if ((short)(header & 0x0000ffff) !=
314                             ~((short)((header & 0xffff0000) >> 16))) {
315                                 DBG("asix_rx_fixup() Bad Header Length");
316                         }
317                         /* get the packet length */
318                         len = (u16) (header & 0x0000ffff);
319                         iobuf = urb->priv;
320                         iob_pull(iobuf, 4);
321                         iob_unput(iobuf, 2048 - (len + 4));
322                         DBG("len = %d ioblen = %d\n", len, iob_len(iobuf));
323                         netdev_rx(netdev, iobuf);
324         
325                         list_del(&urb->priv_list);
326                         usb_unlink_urb(urb);
327                 }
328         }
329 }
330
331 /* asix net device operations */
332 static struct net_device_operations asix_operations = {
333         .open           = asix_open,
334         .close          = asix_close,
335         .transmit       = asix_transmit,
336         .poll           = asix_poll,
337 };
338
339 static int asix_sw_reset(struct asix *asix, uint8_t flags)
340 {
341         int ret;
342
343         ret = asix_write_cmd(asix, AX_CMD_SW_RESET, flags, 0, 0, NULL);
344         if (ret < 0)
345                 DBG("Failed to send software reset: %02x\n", ret);
346
347         return ret;
348 }
349
350 static int asix_write_rx_ctl(struct asix *asix, uint16_t mode)
351 {
352         int ret;
353
354         DBG("asix_write_rx_ctl() - mode = 0x%04x\n", mode);
355         ret = asix_write_cmd(asix, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL);
356         if (ret < 0)
357                 DBG("Failed to write RX_CTL mode to 0x%04x: %02x\n",
358                        mode, ret);
359
360         return ret;
361 }
362
363 /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */
364 static u32 asix_get_phyid(struct asix *asix)
365 {
366         int phy_reg;
367         u32 phy_id;
368
369         phy_reg = asix_mdio_read(asix->net, asix_get_phy_addr(asix), MII_PHYSID1);
370         if (phy_reg < 0)
371                 return 0;
372
373         phy_id = (phy_reg & 0xffff) << 16;
374
375         phy_reg = asix_mdio_read(asix->net, asix_get_phy_addr(asix), MII_PHYSID2);
376         if (phy_reg < 0)
377                 return 0;
378
379         phy_id |= (phy_reg & 0xffff);
380
381         return phy_id;
382 }
383
384 static int marvell_phy_init(struct asix *asix)
385 {
386         uint16_t reg;
387
388         DBG("marvell_phy_init()");
389
390         reg = asix_mdio_read(asix->net, asix_get_phy_addr(asix), MII_MARVELL_STATUS);
391         DBG("MII_MARVELL_STATUS = 0x%04x\n", reg);
392
393         asix_mdio_write(asix->net, asix_get_phy_addr(asix), MII_MARVELL_CTRL,
394                         MARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY);
395
396         return 0;
397 }
398
399 static int mii_nway_restart (struct asix *asix)
400 {
401         int bmcr;
402         int r = -EINVAL;
403
404         /* if autoneg is off, it's an error */
405         bmcr = asix_mdio_read(asix->net, 0, MII_BMCR);
406
407         if (bmcr & BMCR_ANENABLE) {
408                 bmcr |= BMCR_ANRESTART;
409                 asix_mdio_write(asix->net, 0, MII_BMCR, bmcr);
410                 r = 0;
411         }
412
413         return r;
414 }
415
416 int asix_88178_probe(struct usb_device *udev,
417                         const struct usb_device_id *id __unused)
418 {
419         struct net_device *netdev;
420         struct asix *asix;
421         unsigned int i;
422         uint8_t buf[ETH_ALEN];
423         uint16_t eeprom;
424         uint8_t status;
425         int gpio0 = 0;
426         uint32_t phyid;
427         int ret;
428
429         netdev = alloc_etherdev(sizeof(*asix));
430         netdev_init(netdev, &asix_operations);
431
432         if (!netdev) {
433                 DBG("can't allocate %s\n\n", "device");
434                 goto out;
435         }
436
437         asix = netdev_priv(netdev);
438         INIT_LIST_HEAD(&asix->tx_queue);
439         INIT_LIST_HEAD(&asix->rx_done_queue);
440         INIT_LIST_HEAD(&asix->rx_queue);
441
442         asix->udev = udev;
443         asix->net = netdev;
444         netdev->dev = &udev->dev;
445
446         for(i = 0;i < udev->num_endpoints; i++) {
447                 if (usb_ep_xfertype(udev->endpoints[i]) == USB_ENDPOINT_XFER_BULK &&
448                                 usb_ep_dir(udev->endpoints[i]) == USB_DIR_IN)
449                         asix->in = udev->endpoints[i];
450
451                 if (usb_ep_xfertype(udev->endpoints[i]) == USB_ENDPOINT_XFER_BULK &&
452                                 usb_ep_dir(udev->endpoints[i]) == USB_DIR_OUT)
453                         asix->out = udev->endpoints[i];
454         }
455         asix->maxpacket = le16_to_cpu(asix->in->desc.wMaxPacketSize);
456
457         asix_read_cmd(asix, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
458         DBG("GPIO Status: 0x%04x\n", status);
459
460         asix_write_cmd(asix, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL);
461         asix_read_cmd(asix, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom);
462         asix_write_cmd(asix, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL);
463
464         DBG("EEPROM index 0x17 is 0x%04x\n", eeprom);
465
466         if (eeprom == cpu_to_le16(0xffff)) {
467                 asix->phy = PHY_MODE_MARVELL;
468                 gpio0 = 1;
469         } else {
470                 asix->phy = le16_to_cpu(eeprom) & 7;
471                 gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
472         }
473         
474         asix_write_gpio(asix, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
475         if ((le16_to_cpu(eeprom) >> 8) != 1) {
476                 asix_write_gpio(asix, 0x003c, 30);
477                 asix_write_gpio(asix, 0x001c, 300);
478                 asix_write_gpio(asix, 0x003c, 30);
479         } else {
480                 DBG("gpio phymode == 1 path");
481                 asix_write_gpio(asix, AX_GPIO_GPO1EN, 30);
482                 asix_write_gpio(asix, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
483         }
484
485         asix_sw_reset(asix, 0);
486         mdelay(150);
487
488         asix_sw_reset(asix, AX_SWRESET_PRL | AX_SWRESET_IPPD);
489         mdelay(150);
490
491         asix_write_rx_ctl(asix, 0);
492
493         /* Get the MAC address */
494         if ((ret = asix_read_cmd(asix, AX_CMD_READ_NODE_ID,
495                                 0, 0, ETH_ALEN, buf)) < 0) {
496                 DBG("Failed to read MAC address: %d\n", ret);
497                 goto out;
498         }
499         memcpy(netdev->ll_addr, buf, ETH_ALEN);
500         
501         phyid = asix_get_phyid(asix);
502         DBG("PHYID=0x%08lx\n", phyid);
503
504         if (asix->phy == PHY_MODE_MARVELL) {
505                 marvell_phy_init(asix);
506                 mdelay(60);
507         }
508
509         asix_mdio_write(asix->net, asix_get_phy_addr(asix), MII_BMCR,
510                         BMCR_RESET | BMCR_ANENABLE);
511         asix_mdio_write(asix->net, asix_get_phy_addr(asix), MII_ADVERTISE,
512                         ADVERTISE_ALL | ADVERTISE_CSMA | 0x400);
513         asix_mdio_write(asix->net, asix_get_phy_addr(asix), 9,
514                         0x200);
515
516         mii_nway_restart(asix);
517
518         if ((ret = asix_write_medium_mode(asix, AX88178_MEDIUM_DEFAULT)) < 0)
519                 goto out;
520
521         if ((ret = asix_write_rx_ctl(asix, AX_DEFAULT_RX_CTL)) < 0)
522                 goto out;
523         /* Register network device */
524         if ((ret = register_netdev(netdev)) != 0) {
525                 return -1;
526         }
527
528         netdev_link_up(netdev);
529         {
530                 uint8_t status;
531                 asix_read_cmd(asix, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &status);
532                 DBG("statu s= %x\n", status);
533         }
534         return 0;
535
536 out:
537         return ret;
538 }
539
540 static u16 asix_read_rx_ctl(struct asix *asix)
541 {
542         uint16_t v;
543         int ret = asix_read_cmd(asix, AX_CMD_READ_RX_CTL, 0, 0, 2, &v);
544
545         if (ret < 0) {
546                 DBG("Error reading RX_CTL register: %02x", ret);
547                 goto out;
548         }
549         ret = le16_to_cpu(v);
550 out:
551         return ret;
552 }
553
554 static u16 asix_read_medium_status(struct asix *asix)
555 {
556         uint16_t v;
557         int ret = asix_read_cmd(asix, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v);
558
559         if (ret < 0) {
560                 DBG("Error reading Medium Status register: %02x", ret);
561                 goto out;
562         }
563         ret = le16_to_cpu(v);
564 out:
565         return ret;
566 }
567
568 int asix_88772_probe(struct usb_device *udev,
569                         const struct usb_device_id *id __unused)
570 {
571         struct net_device *netdev;
572         struct asix *asix;
573         unsigned int i;
574         uint8_t buf[ETH_ALEN];
575         uint32_t phyid;
576         int ret, embd_phy;
577         uint16_t rx_ctl;
578
579         netdev = alloc_etherdev(sizeof(*asix));
580         netdev_init(netdev, &asix_operations);
581
582         if (!netdev) {
583                 DBG("can't allocate %s\n\n", "device");
584                 goto out;
585         }
586
587         asix = netdev_priv(netdev);
588         INIT_LIST_HEAD(&asix->tx_queue);
589         INIT_LIST_HEAD(&asix->rx_done_queue);
590         INIT_LIST_HEAD(&asix->rx_queue);
591
592         asix->udev = udev;
593         asix->net = netdev;
594         netdev->dev = &udev->dev;
595
596         for(i = 0;i < udev->num_endpoints; i++) {
597                 if (usb_ep_xfertype(udev->endpoints[i]) == USB_ENDPOINT_XFER_BULK &&
598                                 usb_ep_dir(udev->endpoints[i]) == USB_DIR_IN)
599                         asix->in = udev->endpoints[i];
600
601                 if (usb_ep_xfertype(udev->endpoints[i]) == USB_ENDPOINT_XFER_BULK &&
602                                 usb_ep_dir(udev->endpoints[i]) == USB_DIR_OUT)
603                         asix->out = udev->endpoints[i];
604         }
605         asix->maxpacket = le16_to_cpu(asix->in->desc.wMaxPacketSize);
606
607         if ((ret = asix_write_gpio(asix,
608                         AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0)
609                 goto out;
610
611         /* 0x10 is the phy id of the embedded 10/100 ethernet phy */
612         embd_phy = ((asix_get_phy_addr(asix) & 0x1f) == 0x10 ? 1 : 0);
613         if ((ret = asix_write_cmd(asix, AX_CMD_SW_PHY_SELECT,
614                                 embd_phy, 0, 0, NULL)) < 0) {
615                 DBG("Select PHY #1 failed: %d", ret);
616                 goto out;
617         }
618
619         if ((ret = asix_sw_reset(asix, AX_SWRESET_IPPD | AX_SWRESET_PRL)) < 0)
620                 goto out;
621
622         mdelay(150);
623         if ((ret = asix_sw_reset(asix, AX_SWRESET_CLEAR)) < 0)
624                 goto out;
625
626         mdelay(150);
627         if (embd_phy) {
628                 if ((ret = asix_sw_reset(asix, AX_SWRESET_IPRL)) < 0)
629                         goto out;
630         }
631         else {
632                 if ((ret = asix_sw_reset(asix, AX_SWRESET_PRTE)) < 0)
633                         goto out;
634         }
635
636         mdelay(150);
637         rx_ctl = asix_read_rx_ctl(asix);
638         DBG("RX_CTL is 0x%04x after software reset", rx_ctl);
639         if ((ret = asix_write_rx_ctl(asix, 0x0000)) < 0)
640                 goto out;
641
642         rx_ctl = asix_read_rx_ctl(asix);
643         DBG("RX_CTL is 0x%04x setting to 0x0000", rx_ctl);
644
645         /* Get the MAC address */
646         if ((ret = asix_read_cmd(asix, AX_CMD_READ_NODE_ID,
647                                 0, 0, ETH_ALEN, buf)) < 0) {
648                 DBG("Failed to read MAC address: %d", ret);
649                 goto out;
650         }
651         memcpy(netdev->ll_addr, buf, ETH_ALEN);
652
653         phyid = asix_get_phyid(asix);
654         DBG("PHYID=0x%08lx", phyid);
655
656         if ((ret = asix_sw_reset(asix, AX_SWRESET_PRL)) < 0)
657                 goto out;
658
659         mdelay(150);
660
661         if ((ret = asix_sw_reset(asix, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0)
662                 goto out;
663
664         mdelay(150);
665
666         asix_mdio_write(asix->net, asix_get_phyid(asix), MII_BMCR, BMCR_RESET);
667         asix_mdio_write(asix->net, asix_get_phyid(asix), MII_ADVERTISE,
668                         ADVERTISE_ALL | ADVERTISE_CSMA);
669         
670         mii_nway_restart(asix);
671
672         if ((ret = asix_write_medium_mode(asix, AX88772_MEDIUM_DEFAULT)) < 0)
673                 goto out;
674
675         if ((ret = asix_write_cmd(asix, AX_CMD_WRITE_IPG0,
676                                 AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
677                                 AX88772_IPG2_DEFAULT, 0, NULL)) < 0) {
678                 DBG("Write IPG,IPG1,IPG2 failed: %d", ret);
679                 goto out;
680         }
681
682         /* Set RX_CTL to default values with 2k buffer, and enable cactus */
683         if ((ret = asix_write_rx_ctl(asix, AX_DEFAULT_RX_CTL)) < 0)
684                 goto out;
685
686         rx_ctl = asix_read_rx_ctl(asix);
687         DBG("RX_CTL is 0x%04x after all initializations", rx_ctl);
688
689         rx_ctl = asix_read_medium_status(asix);
690         DBG("Medium Status is 0x%04x after all initializations", rx_ctl);
691
692         /* Register network device */
693         if ((ret = register_netdev(netdev)) != 0) {
694                 return -1;
695         }
696
697         netdev_link_up(netdev);
698         {
699                 uint8_t status;
700                 asix_read_cmd(asix, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &status);
701                 DBG("statu s= %x\n", status);
702         }
703         return 0;
704
705 out:
706         return ret;
707 }
708
709 static struct usb_device_id asix_88178_ids[] = {
710 //      {"ASIX AX88178\n",      ,0x0b95, 0x1780},
711 //      {"Linksys USB1000"      ,0x1737, 0x0039},
712 //      {"IO-DATA ETG-US2"      ,0x04bb, 0x0930},
713         {"Belkin F5D5055"       ,0x050d, 0x5055},
714 };
715
716 struct usb_driver asix_88178_usb_driver __usb_driver = {
717         .ids = asix_88178_ids,
718         .id_count = (sizeof(asix_88178_ids) / sizeof(asix_88178_ids[0])),
719         .probe = asix_88178_probe,
720         .remove = asix_88178_remove,
721 };
722
723
724 static struct usb_device_id asix_88772_ids[] = {
725         USB_ROM (0x2001, 0x3c05,"asix","DLink DUB-E100"),
726 };
727
728 struct usb_driver asix_88772_usb_driver __usb_driver = {
729         .ids = asix_88772_ids,
730         .id_count = (sizeof(asix_88772_ids) / sizeof(asix_88772_ids[0])),
731         .probe = asix_88772_probe,
732         .remove = asix_88772_remove,
733 };