[USB] Kind of works..
[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 //mdelay(100);  
165 //asm volatile ("cpuid");
166         iobuf = alloc_iob(2048);
167         if (!iobuf)
168                 goto err_iobuf_malloc;
169
170         urb = usb_alloc_urb();
171         if (!urb)
172                 goto err_usb_malloc;
173
174         usb_fill_bulk_urb(urb, asix->udev, asix->in, iob_put(iobuf, 2048), 2048);
175
176         ret = usb_submit_urb(urb);
177         if (ret < 0)
178                 goto err_submit_urb;
179         
180         urb->priv = iobuf;
181         list_add_tail(&urb->priv_list, &asix->rx_queue);
182         
183         return 0;
184
185 err_submit_urb:
186         usb_free_urb(urb);
187 err_usb_malloc:
188         free_iob(iobuf);
189 err_iobuf_malloc:
190
191         return ret;
192 }
193
194 int asix_open ( struct net_device *netdev)
195 {
196         enqueue_one_rx_urb(netdev_priv(netdev));
197         return 0;
198 }
199
200 void asix_88178_remove(struct usb_device *udev __unused)
201 {
202
203 }
204
205 void asix_88772_remove(struct usb_device *udev __unused)
206 {
207
208 }
209
210 void asix_close ( struct net_device *netdev ) {
211         
212         netdev++;
213 }
214
215 int asix_transmit ( struct net_device *netdev __unused,
216                           struct io_buffer *iobuf __unused)
217 {
218         struct asix *asix = netdev_priv(netdev);
219         uint32_t length;
220         struct urb *urb = NULL;
221         int status;
222         void *buffer;
223         int padlen;
224         uint32_t packet_len;
225         uint32_t pad_bytes = 0xffff0000;
226         int ret = -ENOMEM;
227
228         length = iob_len(iobuf);
229         padlen = ((length + 4) % 64) ? 0 : 4;
230
231         buffer = malloc_dma(length + padlen + 4, 1);
232         if(!buffer)
233                 goto err_buffer_malloc;
234
235         packet_len = ((length ^ 0x0000ffff) << 16) + (length);
236         
237         packet_len = cpu_to_le32(packet_len);
238
239
240         memcpy(buffer, &packet_len, 4);
241         memcpy(buffer + 4, iobuf->data, length);
242
243 //      DBG("pad len = %d\n", padlen);  
244
245         if (padlen)
246                 memcpy(buffer + length + 4, &pad_bytes, 4);
247
248         length += (4 + padlen);
249
250
251         urb = usb_alloc_urb();
252         if (!urb)
253                 goto err_alloc_urb;
254
255         usb_fill_bulk_urb (urb, asix->udev, asix->out,
256                         buffer, length);
257
258
259         ret = usb_submit_urb (urb);
260         
261         if (ret < 0)
262                 goto err_submit_urb;
263
264         urb->priv = iobuf;
265         list_add_tail(&urb->priv_list, &asix->tx_queue);
266
267         /* Report successful transmit completions */            
268         list_for_each_entry(urb, &asix->tx_queue, priv_list) {
269                 if ((status = usb_urb_status(urb)) == USB_URB_STATUS_COMPLETE) {
270                         netdev_tx_complete(netdev, urb->priv);
271
272                         list_del(&urb->priv_list);
273
274                         free_dma(urb->transfer_buffer, urb->transfer_buffer_length);
275                         usb_unlink_urb(urb);
276                         
277                         DBG("TX DONE\n");
278                 } else if (status == USB_URB_STATUS_ERROR)
279                         DBG("TX Error\n");
280         }
281         return 0;
282         
283         /* Nothing to do */
284 err_submit_urb:
285         usb_free_urb(urb);
286 err_alloc_urb:
287         free_dma(buffer, length);
288 err_buffer_malloc:
289         return ret;
290 }
291
292
293 void asix_poll ( struct net_device *netdev) {
294         struct asix *asix = netdev_priv(netdev);
295         struct urb *urb;
296         uint8_t *buffer, *packet;
297         struct io_buffer *iobuf;
298         uint8_t status = 0;
299         unsigned int len;
300         uint8_t *head;
301         uint32_t header;
302
303         list_for_each_entry(urb, &asix->rx_queue, priv_list) {
304                 if ((status = usb_urb_status(urb)) == USB_URB_STATUS_COMPLETE) {
305                         if (enqueue_one_rx_urb(asix) < 0)
306                                 DBG("Error enquing packet\n");
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         mdelay(2);
328                 }
329         }
330 }
331
332 /* asix net device operations */
333 static struct net_device_operations asix_operations = {
334         .open           = asix_open,
335         .close          = asix_close,
336         .transmit       = asix_transmit,
337         .poll           = asix_poll,
338 };
339
340 static int asix_sw_reset(struct asix *asix, uint8_t flags)
341 {
342         int ret;
343
344         ret = asix_write_cmd(asix, AX_CMD_SW_RESET, flags, 0, 0, NULL);
345         if (ret < 0)
346                 DBG("Failed to send software reset: %02x\n", ret);
347
348         return ret;
349 }
350
351 static int asix_write_rx_ctl(struct asix *asix, uint16_t mode)
352 {
353         int ret;
354
355         DBG("asix_write_rx_ctl() - mode = 0x%04x\n", mode);
356         ret = asix_write_cmd(asix, AX_CMD_WRITE_RX_CTL, mode, 0, 0, NULL);
357         if (ret < 0)
358                 DBG("Failed to write RX_CTL mode to 0x%04x: %02x\n",
359                        mode, ret);
360
361         return ret;
362 }
363
364 /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */
365 static u32 asix_get_phyid(struct asix *asix)
366 {
367         int phy_reg;
368         u32 phy_id;
369
370         phy_reg = asix_mdio_read(asix->net, asix_get_phy_addr(asix), MII_PHYSID1);
371         if (phy_reg < 0)
372                 return 0;
373
374         phy_id = (phy_reg & 0xffff) << 16;
375
376         phy_reg = asix_mdio_read(asix->net, asix_get_phy_addr(asix), MII_PHYSID2);
377         if (phy_reg < 0)
378                 return 0;
379
380         phy_id |= (phy_reg & 0xffff);
381
382         return phy_id;
383 }
384
385 static int marvell_phy_init(struct asix *asix)
386 {
387         uint16_t reg;
388
389         DBG("marvell_phy_init()");
390
391         reg = asix_mdio_read(asix->net, asix_get_phy_addr(asix), MII_MARVELL_STATUS);
392         DBG("MII_MARVELL_STATUS = 0x%04x\n", reg);
393
394         asix_mdio_write(asix->net, asix_get_phy_addr(asix), MII_MARVELL_CTRL,
395                         MARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY);
396
397         return 0;
398 }
399
400 static int mii_nway_restart (struct asix *asix)
401 {
402         int bmcr;
403         int r = -EINVAL;
404
405         /* if autoneg is off, it's an error */
406         bmcr = asix_mdio_read(asix->net, 0, MII_BMCR);
407
408         if (bmcr & BMCR_ANENABLE) {
409                 bmcr |= BMCR_ANRESTART;
410                 asix_mdio_write(asix->net, 0, MII_BMCR, bmcr);
411                 r = 0;
412         }
413
414         return r;
415 }
416
417 int asix_88178_probe(struct usb_device *udev,
418                         const struct usb_device_id *id __unused)
419 {
420         struct net_device *netdev;
421         struct asix *asix;
422         unsigned int i;
423         uint8_t buf[ETH_ALEN];
424         uint16_t eeprom;
425         uint8_t status;
426         int gpio0 = 0;
427         uint32_t phyid;
428         int ret;
429
430         netdev = alloc_etherdev(sizeof(*asix));
431         netdev_init(netdev, &asix_operations);
432
433         if (!netdev) {
434                 DBG("can't allocate %s\n\n", "device");
435                 goto out;
436         }
437
438         asix = netdev_priv(netdev);
439         INIT_LIST_HEAD(&asix->tx_queue);
440         INIT_LIST_HEAD(&asix->rx_done_queue);
441         INIT_LIST_HEAD(&asix->rx_queue);
442
443         asix->udev = udev;
444         asix->net = netdev;
445         netdev->dev = &udev->dev;
446
447         for(i = 0;i < udev->num_endpoints; i++) {
448                 if (usb_ep_xfertype(udev->endpoints[i]) == USB_ENDPOINT_XFER_BULK &&
449                                 usb_ep_dir(udev->endpoints[i]) == USB_DIR_IN)
450                         asix->in = udev->endpoints[i];
451
452                 if (usb_ep_xfertype(udev->endpoints[i]) == USB_ENDPOINT_XFER_BULK &&
453                                 usb_ep_dir(udev->endpoints[i]) == USB_DIR_OUT)
454                         asix->out = udev->endpoints[i];
455         }
456         asix->maxpacket = le16_to_cpu(asix->in->desc.wMaxPacketSize);
457
458         asix_read_cmd(asix, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
459         DBG("GPIO Status: 0x%04x\n", status);
460
461         asix_write_cmd(asix, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL);
462         asix_read_cmd(asix, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom);
463         asix_write_cmd(asix, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL);
464
465         DBG("EEPROM index 0x17 is 0x%04x\n", eeprom);
466
467         if (eeprom == cpu_to_le16(0xffff)) {
468                 asix->phy = PHY_MODE_MARVELL;
469                 gpio0 = 1;
470         } else {
471                 asix->phy = le16_to_cpu(eeprom) & 7;
472                 gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
473         }
474         
475         asix_write_gpio(asix, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
476         if ((le16_to_cpu(eeprom) >> 8) != 1) {
477                 asix_write_gpio(asix, 0x003c, 30);
478                 asix_write_gpio(asix, 0x001c, 300);
479                 asix_write_gpio(asix, 0x003c, 30);
480         } else {
481                 DBG("gpio phymode == 1 path");
482                 asix_write_gpio(asix, AX_GPIO_GPO1EN, 30);
483                 asix_write_gpio(asix, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
484         }
485
486         asix_sw_reset(asix, 0);
487         mdelay(150);
488
489         asix_sw_reset(asix, AX_SWRESET_PRL | AX_SWRESET_IPPD);
490         mdelay(150);
491
492         asix_write_rx_ctl(asix, 0);
493
494         /* Get the MAC address */
495         if ((ret = asix_read_cmd(asix, AX_CMD_READ_NODE_ID,
496                                 0, 0, ETH_ALEN, buf)) < 0) {
497                 DBG("Failed to read MAC address: %d\n", ret);
498                 goto out;
499         }
500         memcpy(netdev->ll_addr, buf, ETH_ALEN);
501         
502         phyid = asix_get_phyid(asix);
503         DBG("PHYID=0x%08lx\n", phyid);
504
505         if (asix->phy == PHY_MODE_MARVELL) {
506                 marvell_phy_init(asix);
507                 mdelay(60);
508         }
509
510         asix_mdio_write(asix->net, asix_get_phy_addr(asix), MII_BMCR,
511                         BMCR_RESET | BMCR_ANENABLE);
512         asix_mdio_write(asix->net, asix_get_phy_addr(asix), MII_ADVERTISE,
513                         ADVERTISE_ALL | ADVERTISE_CSMA | 0x400);
514         asix_mdio_write(asix->net, asix_get_phy_addr(asix), 9,
515                         0x200);
516
517         mii_nway_restart(asix);
518
519         if ((ret = asix_write_medium_mode(asix, AX88178_MEDIUM_DEFAULT)) < 0)
520                 goto out;
521
522         if ((ret = asix_write_rx_ctl(asix, AX_DEFAULT_RX_CTL)) < 0)
523                 goto out;
524         /* Register network device */
525         if ((ret = register_netdev(netdev)) != 0) {
526                 return -1;
527         }
528
529         netdev_link_up(netdev);
530         {
531                 uint8_t status;
532                 asix_read_cmd(asix, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &status);
533                 DBG("statu s= %x\n", status);
534         }
535         return 0;
536
537 out:
538         return ret;
539 }
540
541 static u16 asix_read_rx_ctl(struct asix *asix)
542 {
543         uint16_t v;
544         int ret = asix_read_cmd(asix, AX_CMD_READ_RX_CTL, 0, 0, 2, &v);
545
546         if (ret < 0) {
547                 DBG("Error reading RX_CTL register: %02x", ret);
548                 goto out;
549         }
550         ret = le16_to_cpu(v);
551 out:
552         return ret;
553 }
554
555 static u16 asix_read_medium_status(struct asix *asix)
556 {
557         uint16_t v;
558         int ret = asix_read_cmd(asix, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v);
559
560         if (ret < 0) {
561                 DBG("Error reading Medium Status register: %02x", ret);
562                 goto out;
563         }
564         ret = le16_to_cpu(v);
565 out:
566         return ret;
567 }
568
569 int asix_88772_probe(struct usb_device *udev,
570                         const struct usb_device_id *id __unused)
571 {
572         struct net_device *netdev;
573         struct asix *asix;
574         unsigned int i;
575         uint8_t buf[ETH_ALEN];
576         uint32_t phyid;
577         int ret, embd_phy;
578         uint16_t rx_ctl;
579
580         netdev = alloc_etherdev(sizeof(*asix));
581         netdev_init(netdev, &asix_operations);
582
583         if (!netdev) {
584                 DBG("can't allocate %s\n\n", "device");
585                 goto out;
586         }
587
588         asix = netdev_priv(netdev);
589         INIT_LIST_HEAD(&asix->tx_queue);
590         INIT_LIST_HEAD(&asix->rx_done_queue);
591         INIT_LIST_HEAD(&asix->rx_queue);
592
593         asix->udev = udev;
594         asix->net = netdev;
595         netdev->dev = &udev->dev;
596
597         for(i = 0;i < udev->num_endpoints; i++) {
598                 if (usb_ep_xfertype(udev->endpoints[i]) == USB_ENDPOINT_XFER_BULK &&
599                                 usb_ep_dir(udev->endpoints[i]) == USB_DIR_IN)
600                         asix->in = udev->endpoints[i];
601
602                 if (usb_ep_xfertype(udev->endpoints[i]) == USB_ENDPOINT_XFER_BULK &&
603                                 usb_ep_dir(udev->endpoints[i]) == USB_DIR_OUT)
604                         asix->out = udev->endpoints[i];
605         }
606         asix->maxpacket = le16_to_cpu(asix->in->desc.wMaxPacketSize);
607
608         if ((ret = asix_write_gpio(asix,
609                         AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0)
610                 goto out;
611
612         /* 0x10 is the phy id of the embedded 10/100 ethernet phy */
613         embd_phy = ((asix_get_phy_addr(asix) & 0x1f) == 0x10 ? 1 : 0);
614         if ((ret = asix_write_cmd(asix, AX_CMD_SW_PHY_SELECT,
615                                 embd_phy, 0, 0, NULL)) < 0) {
616                 DBG("Select PHY #1 failed: %d", ret);
617                 goto out;
618         }
619
620         if ((ret = asix_sw_reset(asix, AX_SWRESET_IPPD | AX_SWRESET_PRL)) < 0)
621                 goto out;
622
623         mdelay(150);
624         if ((ret = asix_sw_reset(asix, AX_SWRESET_CLEAR)) < 0)
625                 goto out;
626
627         mdelay(150);
628         if (embd_phy) {
629                 if ((ret = asix_sw_reset(asix, AX_SWRESET_IPRL)) < 0)
630                         goto out;
631         }
632         else {
633                 if ((ret = asix_sw_reset(asix, AX_SWRESET_PRTE)) < 0)
634                         goto out;
635         }
636
637         mdelay(150);
638         rx_ctl = asix_read_rx_ctl(asix);
639         DBG("RX_CTL is 0x%04x after software reset", rx_ctl);
640         if ((ret = asix_write_rx_ctl(asix, 0x0000)) < 0)
641                 goto out;
642
643         rx_ctl = asix_read_rx_ctl(asix);
644         DBG("RX_CTL is 0x%04x setting to 0x0000", rx_ctl);
645
646         /* Get the MAC address */
647         if ((ret = asix_read_cmd(asix, AX_CMD_READ_NODE_ID,
648                                 0, 0, ETH_ALEN, buf)) < 0) {
649                 DBG("Failed to read MAC address: %d", ret);
650                 goto out;
651         }
652         memcpy(netdev->ll_addr, buf, ETH_ALEN);
653
654         phyid = asix_get_phyid(asix);
655         DBG("PHYID=0x%08lx", phyid);
656
657         if ((ret = asix_sw_reset(asix, AX_SWRESET_PRL)) < 0)
658                 goto out;
659
660         mdelay(150);
661
662         if ((ret = asix_sw_reset(asix, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0)
663                 goto out;
664
665         mdelay(150);
666
667         asix_mdio_write(asix->net, asix_get_phyid(asix), MII_BMCR, BMCR_RESET);
668         asix_mdio_write(asix->net, asix_get_phyid(asix), MII_ADVERTISE,
669                         ADVERTISE_ALL | ADVERTISE_CSMA);
670         
671         mii_nway_restart(asix);
672
673         if ((ret = asix_write_medium_mode(asix, AX88772_MEDIUM_DEFAULT)) < 0)
674                 goto out;
675
676         if ((ret = asix_write_cmd(asix, AX_CMD_WRITE_IPG0,
677                                 AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,
678                                 AX88772_IPG2_DEFAULT, 0, NULL)) < 0) {
679                 DBG("Write IPG,IPG1,IPG2 failed: %d", ret);
680                 goto out;
681         }
682
683         /* Set RX_CTL to default values with 2k buffer, and enable cactus */
684         if ((ret = asix_write_rx_ctl(asix, AX_DEFAULT_RX_CTL)) < 0)
685                 goto out;
686
687         rx_ctl = asix_read_rx_ctl(asix);
688         DBG("RX_CTL is 0x%04x after all initializations", rx_ctl);
689
690         rx_ctl = asix_read_medium_status(asix);
691         DBG("Medium Status is 0x%04x after all initializations", rx_ctl);
692
693         /* Register network device */
694         if ((ret = register_netdev(netdev)) != 0) {
695                 return -1;
696         }
697
698         netdev_link_up(netdev);
699         {
700                 uint8_t status;
701                 asix_read_cmd(asix, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &status);
702                 DBG("statu s= %x\n", status);
703         }
704         return 0;
705
706 out:
707         return ret;
708 }
709
710 static struct usb_device_id asix_88178_ids[] = {
711 //      {"ASIX AX88178\n",      ,0x0b95, 0x1780},
712 //      {"Linksys USB1000"      ,0x1737, 0x0039},
713 //      {"IO-DATA ETG-US2"      ,0x04bb, 0x0930},
714         {"Belkin F5D5055"       ,0x050d, 0x5055},
715 };
716
717 struct usb_driver asix_88178_usb_driver __usb_driver = {
718         .ids = asix_88178_ids,
719         .id_count = (sizeof(asix_88178_ids) / sizeof(asix_88178_ids[0])),
720         .probe = asix_88178_probe,
721         .remove = asix_88178_remove,
722 };
723
724
725 static struct usb_device_id asix_88772_ids[] = {
726         USB_ROM (0x2001, 0x3c05,"asix","DLink DUB-E100"),
727 };
728
729 struct usb_driver asix_88772_usb_driver __usb_driver = {
730         .ids = asix_88772_ids,
731         .id_count = (sizeof(asix_88772_ids) / sizeof(asix_88772_ids[0])),
732         .probe = asix_88772_probe,
733         .remove = asix_88772_remove,
734 };