2 ** Pegasus: USB 10/100Mbps/HomePNA (1Mbps) Controller
4 ** Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@spct.net)
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
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
{
64 EpromData
= 0x21, /* 0x21 low, 0x22 high byte */
67 PhyData
= 0x26, /* 0x26 low, 0x27 high byte */
79 struct usb_device
*usb
;
80 struct net_device
*net
;
81 struct net_device_stats stats
;
83 spinlock_t pegasus_lock
, ctrl_lock
;
84 struct urb rx_urb
, tx_urb
, intr_urb
, ctrl_urb
;
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]);
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
},
130 static void pegasus_ctrl_end( urb_t
*urb
)
133 warn("ctrl_urb end status %d", urb
->status
);
137 static int pegasus_ctrl_timeout( urb_t
*ctrl_urb
)
141 while ( ctrl_urb
->status
== -EINPROGRESS
) {
142 if ( timeout
++ < PEGASUS_CTRL_TIMEOUT
) {
146 err("ctrl urb busy %d", ctrl_urb
->status
);
147 usb_unlink_urb( ctrl_urb
);
148 return ctrl_urb
->status
;
154 static int pegasus_get_registers( struct pegasus
*pegasus
, __u16 indx
, __u16 size
, void *data
)
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
);
173 ret
= pegasus_ctrl_timeout( &pegasus
->ctrl_urb
);
175 spin_unlock( &pegasus
->ctrl_lock
);
181 static int pegasus_set_registers( struct pegasus
*pegasus
, __u16 indx
, __u16 size
, void *data
)
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
);
200 ret
= pegasus_ctrl_timeout( &pegasus
->ctrl_urb
);
202 spin_unlock( &pegasus
->ctrl_lock
);
208 static int pegasus_set_register( struct pegasus
*pegasus
, __u16 indx
,__u8 data
)
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
);
227 ret
= pegasus_ctrl_timeout( &pegasus
->ctrl_urb
);
229 spin_unlock( &pegasus
->ctrl_lock
);
235 static int pegasus_read_phy_word(struct pegasus
*pegasus
, __u8 index
, __u16
*regdata
)
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
);
250 warn("read_phy_word() failed");
255 static int pegasus_write_phy_word(struct pegasus
*pegasus
, __u8 index
, __u16 regdata
)
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
);
268 warn("write_phy_word() failed");
273 static int pegasus_rw_eprom_word(struct pegasus
*pegasus
, __u8 index
, __u16
*retdata
, __u8 direction
)
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
);
282 pegasus_get_registers(pegasus
, EpromData
, 2, data
);
283 *retdata
= *(__u16
*)data
;
288 warn("pegasus_rw_eprom_word() failed");
293 static int pegasus_get_node_id(struct pegasus
*pegasus
, __u8
*id
)
296 for (i
= 0; i
< 3; i
++)
297 if (pegasus_rw_eprom_word(pegasus
,i
,(__u16
*)&id
[i
*2],SROM_READ
))
303 static int pegasus_reset_mac(struct pegasus
*pegasus
)
308 pegasus_set_register(pegasus
, EthCtrl1
, data
);
309 for (i
= 0; i
< 100; i
++) {
310 pegasus_get_registers(pegasus
, EthCtrl1
, 1, &data
);
315 pegasus_write_phy_word(pegasus
, 0, 0x4000);
316 pegasus_set_register(pegasus
, Gpio0
, 0x24);
317 pegasus_set_register(pegasus
, Gpio0
, 0x27);
326 static int pegasus_start_net(struct net_device
*dev
, struct usb_device
*usb
)
328 __u16 partmedia
, temp
;
331 struct pegasus
*pegasus
= dev
->priv
;
333 if (pegasus_get_node_id(pegasus
, node_id
))
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
))
341 if ((~temp
& 4) && !loopback
) {
342 warn("%s: link NOT established (0x%x) - check the cable.",
346 if (pegasus_read_phy_word(pegasus
, 5, &partmedia
))
349 if ((partmedia
& 0x1f) != 1) {
350 warn("party FAIL %x", partmedia
);
351 /* return 5; FIXME */
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
);
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);
374 dbg("%s: RX status %d", net
->name
, urb
->status
);
381 if (rx_status
& 0x00010000)
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
++;
395 pkt_len
= (rx_status
& 0xfff) - 8;
397 if(!(skb
= dev_alloc_skb(pkt_len
+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
);
407 pegasus
->stats
.rx_packets
++;
408 pegasus
->stats
.rx_bytes
+= pkt_len
;
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
;
421 dbg("txst0=0x%2x", d
[0]);
425 static void pegasus_write_bulk(struct urb
*urb
)
427 struct pegasus
*pegasus
= urb
->context
;
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
);
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;
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
);
473 pegasus
->stats
.tx_packets
++;
474 pegasus
->stats
.tx_bytes
+= skb
->len
;
475 net
->trans_start
= jiffies
;
480 spin_unlock(&pegasus
->pegasus_lock
);
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
;
497 if ((res
= pegasus_start_net(net
, pegasus
->usb
))) {
498 err("can't start_net() - %d", res
);
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
);
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
);
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
;
545 case SIOCDEVPRIVATE
+1:
546 pegasus_read_phy_word(pegasus
, data
[1] & 0x1f, &data
[3]);
548 case SIOCDEVPRIVATE
+2:
549 if (!capable(CAP_NET_ADMIN
))
551 pegasus_write_phy_word(pegasus
, data
[1] & 0x1f, data
[2]);
559 static void pegasus_set_rx_mode(struct net_device
*net
)
561 struct pegasus
*pegasus
= net
->priv
;
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
);
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
)
589 while ( usb_dev_id
[i
].name
) {
590 if ( (usb_dev_id
[i
].vendor
== vendor
) &&
591 (usb_dev_id
[i
].device
== product
) )
599 static void * pegasus_probe(struct usb_device
*dev
, unsigned int ifnum
)
601 struct net_device
*net
;
602 struct pegasus
*pegasus
;
605 if ( (dev_indx
= check_device_ids(dev
->descriptor
.idVendor
, dev
->descriptor
.idProduct
)) == -1 ) {
609 if (usb_set_configuration(dev
, dev
->config
[0].bConfigurationValue
)) {
610 err("usb_set_configuration() failed");
614 if(!(pegasus
= kmalloc(sizeof(struct pegasus
), GFP_KERNEL
))) {
615 err("out of memory allocating device structure");
618 memset(pegasus
, 0, sizeof(struct pegasus
));
620 net
= init_etherdev(0, 0);
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
;
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
,
640 FILL_BULK_URB(&pegasus
->tx_urb
, dev
, usb_sndbulkpipe(dev
, 2),
641 pegasus
->tx_buff
, PEGASUS_MAX_MTU
, pegasus_write_bulk
,
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");
652 printk(KERN_INFO
"%s: %s\n", net
->name
, usb_dev_id
[dev_indx
].name
);
658 static void pegasus_disconnect(struct usb_device
*dev
, void *ptr
)
660 struct pegasus
*pegasus
= ptr
;
663 warn("unregistering non-existant device");
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
);
685 static struct usb_driver pegasus_driver
= {
687 probe
: pegasus_probe
,
688 disconnect
: pegasus_disconnect
,
691 int __init
pegasus_init(void)
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
);