This is pre8 ...
[linux-2.6/linux-mips.git] / drivers / usb / pegasus.c
blob8c588f79ef7ad90a25773c1f92c88a84aef86367
1 /*
2 ** Pegasus: USB 10/100Mbps/HomePNA (1Mbps) Controller
3 **
4 ** Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@spct.net)
5 **
6 **
7 ** ChangeLog:
8 ** .... Most of the time spend reading sources & docs.
9 ** v0.2.x First official release for the Linux kernel.
10 ** v0.3.0 Beutified and structured, some bugs fixed.
11 ** v0.3.x URBifying bulk requests and bugfixing. First relatively
12 ** stable release. Still can touch device's registers only
13 ** from top-halves.
14 ** v0.4.0 Control messages remained unurbified are now URBs.
15 ** Now we can touch the HW at any time.
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #include <linux/module.h>
36 #include <linux/sched.h>
37 #include <linux/malloc.h>
38 #include <linux/init.h>
39 #include <linux/delay.h>
40 #include <linux/netdevice.h>
41 #include <linux/etherdevice.h>
42 #include <linux/usb.h>
45 static const char *version = __FILE__ ": v0.4.0 2000/06/15 (C) 1999-2000 Petko Manolov (petkan@spct.net)\n";
48 #define PEGASUS_MTU 1500
49 #define PEGASUS_MAX_MTU 1536
50 #define SROM_WRITE 0x01
51 #define SROM_READ 0x02
52 #define PEGASUS_TX_TIMEOUT (HZ*5)
53 #define PEGASUS_CTRL_TIMEOUT 1000
54 #define PEGASUS_RESET 1
55 #define ALIGN(x) x __attribute__((aligned(L1_CACHE_BYTES)))
58 enum pegasus_registers {
59 EthCtrl0 = 0,
60 EthCtrl1 = 1,
61 EthCtrl2 = 2,
62 EthID = 0x10,
63 EpromOffset = 0x20,
64 EpromData = 0x21, /* 0x21 low, 0x22 high byte */
65 EpromCtrl = 0x23,
66 PhyAddr = 0x25,
67 PhyData = 0x26, /* 0x26 low, 0x27 high byte */
68 PhyCtrl = 0x28,
69 UsbStst = 0x2a,
70 EthTxStat0 = 0x2b,
71 EthTxStat1 = 0x2c,
72 EthRxStat = 0x2d,
73 Gpio0 = 0x7e,
74 Gpio1 = 0x7f,
78 struct pegasus {
79 struct usb_device *usb;
80 struct net_device *net;
81 struct net_device_stats stats;
82 int flags;
83 spinlock_t pegasus_lock, ctrl_lock;
84 struct urb rx_urb, tx_urb, intr_urb, ctrl_urb;
85 devrequest dr;
86 unsigned char ALIGN(rx_buff[PEGASUS_MAX_MTU]);
87 unsigned char ALIGN(tx_buff[PEGASUS_MAX_MTU]);
88 unsigned char ALIGN(intr_buff[8]);
91 struct usb_eth_dev {
92 char *name;
93 __u16 vendor;
94 __u16 device;
95 void *private;
99 static int loopback = 0;
100 static int multicast_filter_limit = 32;
103 MODULE_AUTHOR("Petko Manolov <petkan@spct.net>");
104 MODULE_DESCRIPTION("ADMtek AN986 Pegasus USB Ethernet driver");
105 MODULE_PARM(loopback, "i");
108 static struct usb_eth_dev usb_dev_id[] = {
109 {"Billionton USB-100", 0x08dd, 0x0986, NULL},
110 {"Corega FEter USB-TX", 0x7aa, 0x0004, NULL},
111 {"MELCO/BUFFALO LUA-TX", 0x0411, 0x0001, NULL},
112 {"D-Link DSB-650TX", 0x2001, 0x4001, NULL},
113 {"D-Link DSB-650TX", 0x2001, 0x4002, NULL},
114 {"D-Link DSB-650TX(PNA)", 0x2001, 0x4003, NULL},
115 {"D-Link DU-E10", 0x07b8, 0xabc1, NULL},
116 {"D-Link DU-E100", 0x07b8, 0x4002, NULL},
117 {"Linksys USB100TX", 0x066b, 0x2203, NULL},
118 {"Linksys USB100TX", 0x066b, 0x2204, NULL},
119 {"Linksys USB Ethernet Adapter", 0x066b, 0x2206, NULL},
120 {"SMC 202 USB Ethernet", 0x0707, 0x0200, NULL},
121 {"ADMtek AN986 \"Pegasus\" USB Ethernet (eval board)", 0x07a6, 0x0986, NULL},
122 {"Accton USB 10/100 Ethernet Adapter", 0x083a, 0x1046, NULL},
123 {"IO DATA USB ET/TX", 0x04bb, 0x0904, NULL},
124 {"LANEED USB Ethernet LD-USB/TX", 0x056e, 0x4002, NULL},
125 {NULL, 0, 0, NULL}
130 static void pegasus_ctrl_end( urb_t *urb )
132 if ( urb->status )
133 warn("ctrl_urb end status %d", urb->status);
137 static int pegasus_ctrl_timeout( urb_t *ctrl_urb )
139 int timeout=0;
141 while ( ctrl_urb->status == -EINPROGRESS ) {
142 if ( timeout++ < PEGASUS_CTRL_TIMEOUT ) {
143 udelay(100);
144 continue;
146 err("ctrl urb busy %d", ctrl_urb->status);
147 usb_unlink_urb( ctrl_urb );
148 return ctrl_urb->status;
150 return 0;
154 static int pegasus_get_registers( struct pegasus *pegasus, __u16 indx, __u16 size, void *data )
156 int ret;
159 spin_lock( &pegasus->ctrl_lock );
160 pegasus->dr.requesttype = 0xc0;
161 pegasus->dr.request = 0xf0;
162 pegasus->dr.value = 0x0;
163 pegasus->dr.index = indx;
164 pegasus->dr.length = pegasus->ctrl_urb.transfer_buffer_length = size;
166 FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
167 usb_rcvctrlpipe(pegasus->usb,0), (char *)&pegasus->dr,
168 data, size, pegasus_ctrl_end, pegasus );
170 if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) )
171 err("BAD CTRLs %d", ret);
172 else
173 ret = pegasus_ctrl_timeout( &pegasus->ctrl_urb );
175 spin_unlock( &pegasus->ctrl_lock );
177 return ret;
181 static int pegasus_set_registers( struct pegasus *pegasus, __u16 indx, __u16 size, void *data )
183 int ret;
186 spin_lock( &pegasus->ctrl_lock );
187 pegasus->dr.requesttype = 0x40;
188 pegasus->dr.request = 0xf1;
189 pegasus->dr.value = 0x0;
190 pegasus->dr.index = indx;
191 pegasus->dr.length = pegasus->ctrl_urb.transfer_buffer_length = size;
193 FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
194 usb_sndctrlpipe(pegasus->usb,0), (char *)&pegasus->dr,
195 data, size, pegasus_ctrl_end, pegasus );
197 if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) )
198 err("BAD CTRL %d", ret);
199 else
200 ret = pegasus_ctrl_timeout( &pegasus->ctrl_urb );
202 spin_unlock( &pegasus->ctrl_lock );
204 return ret;
208 static int pegasus_set_register( struct pegasus *pegasus, __u16 indx,__u8 data )
210 int ret;
213 spin_lock( &pegasus->ctrl_lock );
214 pegasus->dr.requesttype = 0x40;
215 pegasus->dr.request = 0xf1;
216 pegasus->dr.value = data;
217 pegasus->dr.index = indx;
218 pegasus->dr.length = pegasus->ctrl_urb.transfer_buffer_length = 1;
220 FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
221 usb_sndctrlpipe(pegasus->usb,0), (char *)&pegasus->dr,
222 &data, 1, pegasus_ctrl_end, pegasus );
224 if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) )
225 err("BAD CTRL %d", ret);
226 else
227 ret = pegasus_ctrl_timeout( &pegasus->ctrl_urb );
229 spin_unlock( &pegasus->ctrl_lock );
231 return ret;
235 static int pegasus_read_phy_word(struct pegasus *pegasus, __u8 index, __u16 *regdata)
237 int i;
238 __u8 data[4] = { 1, 0, 0, 0x40 + index };
240 pegasus_set_registers(pegasus, PhyAddr, 4, data);
241 for (i = 0; i < 100; i++) {
242 pegasus_get_registers(pegasus, PhyData, 3, data);
243 if (data[2] & 0x80) {
244 *regdata = *(__u16 *)(data);
245 return 0;
247 udelay(100);
250 warn("read_phy_word() failed");
251 return 1;
255 static int pegasus_write_phy_word(struct pegasus *pegasus, __u8 index, __u16 regdata)
257 int i;
258 __u8 data[4] = { 1, regdata, regdata >> 8, 0x20 + index };
260 pegasus_set_registers(pegasus, PhyAddr, 4, data);
261 for (i = 0; i < 100; i++) {
262 pegasus_get_registers(pegasus, PhyCtrl, 1, data);
263 if (data[0] & 0x80)
264 return 0;
265 udelay(100);
268 warn("write_phy_word() failed");
269 return 1;
273 static int pegasus_rw_eprom_word(struct pegasus *pegasus, __u8 index, __u16 *retdata, __u8 direction)
275 int i;
276 __u8 data[4] = { index, 0, 0, direction };
278 pegasus_set_registers(pegasus, EpromOffset, 4, data);
279 for (i = 0; i < 100; i++) {
280 pegasus_get_registers(pegasus, EpromCtrl, 1, data);
281 if (data[0] & 4) {
282 pegasus_get_registers(pegasus, EpromData, 2, data);
283 *retdata = *(__u16 *)data;
284 return 0;
288 warn("pegasus_rw_eprom_word() failed");
289 return 1;
293 static int pegasus_get_node_id(struct pegasus *pegasus, __u8 *id)
295 int i;
296 for (i = 0; i < 3; i++)
297 if (pegasus_rw_eprom_word(pegasus,i,(__u16 *)&id[i*2],SROM_READ))
298 return 1;
299 return 0;
303 static int pegasus_reset_mac(struct pegasus *pegasus)
305 __u8 data = 0x8;
306 int i;
308 pegasus_set_register(pegasus, EthCtrl1, data);
309 for (i = 0; i < 100; i++) {
310 pegasus_get_registers(pegasus, EthCtrl1, 1, &data);
311 if (~data & 0x08) {
312 if (loopback & 1)
313 return 0;
314 if (loopback & 2)
315 pegasus_write_phy_word(pegasus, 0, 0x4000);
316 pegasus_set_register(pegasus, Gpio0, 0x24);
317 pegasus_set_register(pegasus, Gpio0, 0x27);
318 return 0;
322 return 1;
326 static int pegasus_start_net(struct net_device *dev, struct usb_device *usb)
328 __u16 partmedia, temp;
329 __u8 node_id[6];
330 __u8 data[4];
331 struct pegasus *pegasus = dev->priv;
333 if (pegasus_get_node_id(pegasus, node_id))
334 return 1;
336 pegasus_set_registers(pegasus, EthID, 6, node_id);
337 memcpy(dev->dev_addr, node_id, 6);
338 if (pegasus_read_phy_word(pegasus, 1, &temp))
339 return 2;
341 if ((~temp & 4) && !loopback) {
342 warn("%s: link NOT established (0x%x) - check the cable.",
343 dev->name, temp);
346 if (pegasus_read_phy_word(pegasus, 5, &partmedia))
347 return 4;
349 if ((partmedia & 0x1f) != 1) {
350 warn("party FAIL %x", partmedia);
351 /* return 5; FIXME */
354 data[0] = 0xc9;
355 data[1] = (partmedia & 0x100) ? 0x30 : ((partmedia & 0x80) ? 0x10 : 0);
356 data[2] = (loopback & 1) ? 0x09 : 0x01;
358 pegasus_set_registers(pegasus, EthCtrl0, 3, data);
360 return 0;
364 static void pegasus_read_bulk(struct urb *urb)
366 struct pegasus *pegasus = urb->context;
367 struct net_device *net = pegasus->net;
368 int count = urb->actual_length, res;
369 int rx_status = *(int *)(pegasus->rx_buff + count - 4);
370 struct sk_buff *skb;
371 __u16 pkt_len;
373 if (urb->status) {
374 dbg("%s: RX status %d", net->name, urb->status);
375 goto goon;
378 if (!count)
379 goto goon;
380 #if 0
381 if (rx_status & 0x00010000)
382 goto goon;
383 #endif
384 if (rx_status & 0x000e0000) {
386 dbg("%s: error receiving packet %x", net->name, rx_status & 0xe0000);
387 pegasus->stats.rx_errors++;
388 if(rx_status & 0x060000) pegasus->stats.rx_length_errors++;
389 if(rx_status & 0x080000) pegasus->stats.rx_crc_errors++;
390 if(rx_status & 0x100000) pegasus->stats.rx_frame_errors++;
392 goto goon;
395 pkt_len = (rx_status & 0xfff) - 8;
397 if(!(skb = dev_alloc_skb(pkt_len+2)))
398 goto goon;
400 skb->dev = net;
401 skb_reserve(skb, 2);
402 eth_copy_and_sum(skb, pegasus->rx_buff, pkt_len, 0);
403 skb_put(skb, pkt_len);
405 skb->protocol = eth_type_trans(skb, net);
406 netif_rx(skb);
407 pegasus->stats.rx_packets++;
408 pegasus->stats.rx_bytes += pkt_len;
410 goon:
411 if ((res = usb_submit_urb(&pegasus->rx_urb)))
412 warn("(prb)failed rx_urb %d", res);
416 static void pegasus_irq(urb_t *urb)
418 __u8 *d = urb->transfer_buffer;
420 if ( d[0] )
421 dbg("txst0=0x%2x", d[0]);
425 static void pegasus_write_bulk(struct urb *urb)
427 struct pegasus *pegasus = urb->context;
430 if (urb->status)
431 info("%s: TX status %d", pegasus->net->name, urb->status);
432 #if 1 /* Should be fixed */
433 if (urb->status == -ETIMEDOUT)
434 pegasus_reset_mac(pegasus);
435 #endif
436 netif_wake_queue(pegasus->net);
439 static void pegasus_tx_timeout(struct net_device *net)
441 struct pegasus *pegasus = net->priv;
444 usb_unlink_urb(&pegasus->tx_urb);
445 warn("%s: Tx timed out. Reseting...", net->name);
446 pegasus_reset_mac( pegasus );
447 pegasus->stats.tx_errors++;
448 net->trans_start = jiffies;
450 netif_wake_queue(net);
454 static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
456 struct pegasus *pegasus = net->priv;
457 int count = ((skb->len+2) & 0x3f) ? skb->len+2 : skb->len+3;
458 int res;
460 spin_lock(&pegasus->pegasus_lock);
462 netif_stop_queue(net);
464 ((__u16 *)pegasus->tx_buff)[0] = skb->len;
465 memcpy(pegasus->tx_buff+2, skb->data, skb->len);
466 (&pegasus->tx_urb)->transfer_buffer_length = count;
468 if ((res = usb_submit_urb(&pegasus->tx_urb))) {
469 warn("failed tx_urb %d", res);
470 pegasus->stats.tx_errors++;
471 netif_start_queue(net);
472 } else {
473 pegasus->stats.tx_packets++;
474 pegasus->stats.tx_bytes += skb->len;
475 net->trans_start = jiffies;
478 dev_kfree_skb(skb);
480 spin_unlock(&pegasus->pegasus_lock);
482 return 0;
486 static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
488 return &((struct pegasus *)dev->priv)->stats;
492 static int pegasus_open(struct net_device *net)
494 struct pegasus *pegasus = (struct pegasus *)net->priv;
495 int res;
497 if ((res = pegasus_start_net(net, pegasus->usb))) {
498 err("can't start_net() - %d", res);
499 return -EIO;
502 if ((res = usb_submit_urb(&pegasus->rx_urb)))
503 warn("(open)failed rx_urb %d", res);
505 if ((res = usb_submit_urb(&pegasus->intr_urb)))
506 warn("(open)failed intr_urb %d", res);
508 netif_start_queue(net);
510 MOD_INC_USE_COUNT;
512 return 0;
516 static int pegasus_close(struct net_device *net)
518 struct pegasus *pegasus = net->priv;
520 netif_stop_queue(net);
522 if ( pegasus->ctrl_urb.status == -EINPROGRESS )
523 usb_unlink_urb(&pegasus->ctrl_urb);
524 if ( pegasus->rx_urb.status == -EINPROGRESS )
525 usb_unlink_urb(&pegasus->rx_urb);
526 if ( pegasus->tx_urb.status == -EINPROGRESS )
527 usb_unlink_urb(&pegasus->tx_urb);
528 if ( pegasus->intr_urb.status == -EINPROGRESS )
529 usb_unlink_urb(&pegasus->intr_urb);
531 MOD_DEC_USE_COUNT;
533 return 0;
537 static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
539 __u16 *data = (__u16 *)&rq->ifr_data;
540 struct pegasus *pegasus = net->priv;
542 switch(cmd) {
543 case SIOCDEVPRIVATE:
544 data[0] = 1;
545 case SIOCDEVPRIVATE+1:
546 pegasus_read_phy_word(pegasus, data[1] & 0x1f, &data[3]);
547 return 0;
548 case SIOCDEVPRIVATE+2:
549 if (!capable(CAP_NET_ADMIN))
550 return -EPERM;
551 pegasus_write_phy_word(pegasus, data[1] & 0x1f, data[2]);
552 return 0;
553 default:
554 return -EOPNOTSUPP;
559 static void pegasus_set_rx_mode(struct net_device *net)
561 struct pegasus *pegasus = net->priv;
562 __u8 tmp;
564 netif_stop_queue(net);
566 if (net->flags & IFF_PROMISC) {
567 info("%s: Promiscuous mode enabled", net->name);
568 pegasus_get_registers(pegasus, EthCtrl2, 1, &tmp);
569 pegasus_set_register(pegasus, EthCtrl2, tmp | 4);
570 } else if ((net->mc_count > multicast_filter_limit) ||
571 (net->flags & IFF_ALLMULTI)) {
572 pegasus_set_register(pegasus, EthCtrl0, 0xfa);
573 pegasus_set_register(pegasus, EthCtrl2, 0);
574 info("%s set allmulti", net->name);
575 } else {
576 info("%s: set Rx mode", net->name);
577 pegasus_get_registers(pegasus, EthCtrl2, 1, &tmp);
578 pegasus_set_register(pegasus, EthCtrl2, tmp & ~4);
581 netif_wake_queue(net);
585 static int check_device_ids( __u16 vendor, __u16 product )
587 int i=0;
589 while ( usb_dev_id[i].name ) {
590 if ( (usb_dev_id[i].vendor == vendor) &&
591 (usb_dev_id[i].device == product) )
592 return i;
593 i++;
595 return -1;
599 static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
601 struct net_device *net;
602 struct pegasus *pegasus;
603 int dev_indx;
605 if ( (dev_indx = check_device_ids(dev->descriptor.idVendor, dev->descriptor.idProduct)) == -1 ) {
606 return NULL;
609 if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
610 err("usb_set_configuration() failed");
611 return NULL;
614 if(!(pegasus = kmalloc(sizeof(struct pegasus), GFP_KERNEL))) {
615 err("out of memory allocating device structure");
616 return NULL;
618 memset(pegasus, 0, sizeof(struct pegasus));
620 net = init_etherdev(0, 0);
621 net->priv = pegasus;
622 net->open = pegasus_open;
623 net->stop = pegasus_close;
624 net->watchdog_timeo = PEGASUS_TX_TIMEOUT;
625 net->tx_timeout = pegasus_tx_timeout;
626 net->do_ioctl = pegasus_ioctl;
627 net->hard_start_xmit = pegasus_start_xmit;
628 net->set_multicast_list = pegasus_set_rx_mode;
629 net->get_stats = pegasus_netdev_stats;
630 net->mtu = PEGASUS_MTU;
632 pegasus->usb = dev;
633 pegasus->net = net;
634 pegasus->pegasus_lock = SPIN_LOCK_UNLOCKED;
635 pegasus->ctrl_lock = SPIN_LOCK_UNLOCKED;
637 FILL_BULK_URB(&pegasus->rx_urb, dev, usb_rcvbulkpipe(dev, 1),
638 pegasus->rx_buff, PEGASUS_MAX_MTU, pegasus_read_bulk,
639 pegasus);
640 FILL_BULK_URB(&pegasus->tx_urb, dev, usb_sndbulkpipe(dev, 2),
641 pegasus->tx_buff, PEGASUS_MAX_MTU, pegasus_write_bulk,
642 pegasus);
643 FILL_INT_URB(&pegasus->intr_urb, dev, usb_rcvintpipe(dev, 3),
644 pegasus->intr_buff, 8, pegasus_irq, pegasus, 500);
646 if (pegasus_reset_mac(pegasus)) {
647 err("can't reset MAC");
648 kfree(pegasus);
649 return NULL;
652 printk(KERN_INFO "%s: %s\n", net->name, usb_dev_id[dev_indx].name);
654 return pegasus;
658 static void pegasus_disconnect(struct usb_device *dev, void *ptr)
660 struct pegasus *pegasus = ptr;
662 if (!pegasus) {
663 warn("unregistering non-existant device");
664 return;
667 if (pegasus->net->flags & IFF_UP)
668 dev_close(pegasus->net);
670 unregister_netdev(pegasus->net);
672 if ( pegasus->ctrl_urb.status == -EINPROGRESS )
673 usb_unlink_urb(&pegasus->ctrl_urb);
674 if ( pegasus->rx_urb.status == -EINPROGRESS )
675 usb_unlink_urb(&pegasus->rx_urb);
676 if ( pegasus->tx_urb.status == -EINPROGRESS )
677 usb_unlink_urb(&pegasus->tx_urb);
678 if ( pegasus->intr_urb.status == -EINPROGRESS )
679 usb_unlink_urb(&pegasus->intr_urb);
681 kfree(pegasus);
685 static struct usb_driver pegasus_driver = {
686 name: "pegasus",
687 probe: pegasus_probe,
688 disconnect: pegasus_disconnect,
691 int __init pegasus_init(void)
693 printk( version );
694 return usb_register(&pegasus_driver);
697 void __exit pegasus_exit(void)
699 usb_deregister(&pegasus_driver);
702 module_init(pegasus_init);
703 module_exit(pegasus_exit);