OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [usb/] [catc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  Copyright (c) 2001 Vojtech Pavlik
3
 *
4
 *  CATC EL1210A NetMate USB Ethernet driver
5
 *
6
 *  Sponsored by SuSE
7
 *
8
 *  Based on the work of
9
 *              Donald Becker
10
 *
11
 *  Old chipset support added by Simon Evans <spse@secret.org.uk> 2002
12
 *    - adds support for Belkin F5U011
13
 */
14
 
15
/*
16
 * This program is free software; you can redistribute it and/or modify
17
 * it under the terms of the GNU General Public License as published by
18
 * the Free Software Foundation; either version 2 of the License, or
19
 * (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU General Public License
27
 * along with this program; if not, write to the Free Software
28
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29
 *
30
 * Should you need to contact me, the author, you can do so either by
31
 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
32
 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
33
 */
34
 
35
#include <linux/init.h>
36
#include <linux/module.h>
37
#include <linux/kernel.h>
38
#include <linux/string.h>
39
#include <linux/slab.h>
40
#include <linux/netdevice.h>
41
#include <linux/etherdevice.h>
42
#include <linux/skbuff.h>
43
#include <linux/spinlock.h>
44
#include <linux/ethtool.h>
45
#include <linux/crc32.h>
46
#include <asm/bitops.h>
47
#include <asm/uaccess.h>
48
 
49
#undef DEBUG
50
 
51
#include <linux/usb.h>
52
 
53
/*
54
 * Version information.
55
 */
56
 
57
#define DRIVER_VERSION "v2.8"
58
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@suse.cz>"
59
#define DRIVER_DESC "CATC EL1210A NetMate USB Ethernet driver"
60
#define SHORT_DRIVER_DESC "EL1210A NetMate USB Ethernet"
61
 
62
MODULE_AUTHOR(DRIVER_AUTHOR);
63
MODULE_DESCRIPTION(DRIVER_DESC);
64
MODULE_LICENSE("GPL");
65
 
66
static const char driver_name[] = "catc";
67
 
68
/*
69
 * Some defines.
70
 */
71
 
72
#define STATS_UPDATE            (HZ)    /* Time between stats updates */
73
#define TX_TIMEOUT              (5*HZ)  /* Max time the queue can be stopped */
74
#define PKT_SZ                  1536    /* Max Ethernet packet size */
75
#define RX_MAX_BURST            15      /* Max packets per rx buffer (> 0, < 16) */
76
#define TX_MAX_BURST            15      /* Max full sized packets per tx buffer (> 0) */
77
#define CTRL_QUEUE              16      /* Max control requests in flight (power of two) */
78
#define RX_PKT_SZ               1600    /* Max size of receive packet for F5U011 */
79
 
80
/*
81
 * Control requests.
82
 */
83
 
84
enum control_requests {
85
        ReadMem =       0xf1,
86
        GetMac =        0xf2,
87
        Reset =         0xf4,
88
        SetMac =        0xf5,
89
        SetRxMode =     0xf5,  /* F5U011 only */
90
        WriteROM =      0xf8,
91
        SetReg =        0xfa,
92
        GetReg =        0xfb,
93
        WriteMem =      0xfc,
94
        ReadROM =       0xfd,
95
};
96
 
97
/*
98
 * Registers.
99
 */
100
 
101
enum register_offsets {
102
        TxBufCount =    0x20,
103
        RxBufCount =    0x21,
104
        OpModes =       0x22,
105
        TxQed =         0x23,
106
        RxQed =         0x24,
107
        MaxBurst =      0x25,
108
        RxUnit =        0x60,
109
        EthStatus =     0x61,
110
        StationAddr0 =  0x67,
111
        EthStats =      0x69,
112
        LEDCtrl =       0x81,
113
};
114
 
115
enum eth_stats {
116
        TxSingleColl =  0x00,
117
        TxMultiColl =   0x02,
118
        TxExcessColl =  0x04,
119
        RxFramErr =     0x06,
120
};
121
 
122
enum op_mode_bits {
123
        Op3MemWaits =   0x03,
124
        OpLenInclude =  0x08,
125
        OpRxMerge =     0x10,
126
        OpTxMerge =     0x20,
127
        OpWin95bugfix = 0x40,
128
        OpLoopback =    0x80,
129
};
130
 
131
enum rx_filter_bits {
132
        RxEnable =      0x01,
133
        RxPolarity =    0x02,
134
        RxForceOK =     0x04,
135
        RxMultiCast =   0x08,
136
        RxPromisc =     0x10,
137
        AltRxPromisc =  0x20, /* F5U011 uses different bit */
138
};
139
 
140
enum led_values {
141
        LEDFast =       0x01,
142
        LEDSlow =       0x02,
143
        LEDFlash =      0x03,
144
        LEDPulse =      0x04,
145
        LEDLink =       0x08,
146
};
147
 
148
enum link_status {
149
        LinkNoChange = 0,
150
        LinkGood     = 1,
151
        LinkBad      = 2
152
};
153
 
154
/*
155
 * The catc struct.
156
 */
157
 
158
#define CTRL_RUNNING    0
159
#define RX_RUNNING      1
160
#define TX_RUNNING      2
161
 
162
struct catc {
163
        struct net_device *netdev;
164
        struct usb_device *usbdev;
165
 
166
        struct net_device_stats stats;
167
        unsigned long flags;
168
 
169
        unsigned int tx_ptr, tx_idx;
170
        unsigned int ctrl_head, ctrl_tail;
171
        spinlock_t tx_lock, ctrl_lock;
172
 
173
        u8 tx_buf[2][TX_MAX_BURST * (PKT_SZ + 2)];
174
        u8 rx_buf[RX_MAX_BURST * (PKT_SZ + 2)];
175
        u8 irq_buf[2];
176
        u8 ctrl_buf[64];
177
        struct usb_ctrlrequest ctrl_dr;
178
 
179
        struct timer_list timer;
180
        u8 stats_buf[8];
181
        u16 stats_vals[4];
182
        unsigned long last_stats;
183
 
184
        u8 multicast[64];
185
 
186
        struct ctrl_queue {
187
                u8 dir;
188
                u8 request;
189
                u16 value;
190
                u16 index;
191
                void *buf;
192
                int len;
193
                void (*callback)(struct catc *catc, struct ctrl_queue *q);
194
        } ctrl_queue[CTRL_QUEUE];
195
 
196
        struct urb tx_urb, rx_urb, irq_urb, ctrl_urb;
197
 
198
        u8 is_f5u011;   /* Set if device is an F5U011 */
199
        u8 rxmode[2];   /* Used for F5U011 */
200
        atomic_t recq_sz; /* Used for F5U011 - counter of waiting rx packets */
201
};
202
 
203
/*
204
 * Useful macros.
205
 */
206
 
207
#define catc_get_mac(catc, mac)                         catc_ctrl_msg(catc, USB_DIR_IN,  GetMac, 0, 0, mac,  6)
208
#define catc_reset(catc)                                catc_ctrl_msg(catc, USB_DIR_OUT, Reset, 0, 0, NULL, 0)
209
#define catc_set_reg(catc, reg, val)                    catc_ctrl_msg(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0)
210
#define catc_get_reg(catc, reg, buf)                    catc_ctrl_msg(catc, USB_DIR_IN,  GetReg, 0, reg, buf, 1)
211
#define catc_write_mem(catc, addr, buf, size)           catc_ctrl_msg(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size)
212
#define catc_read_mem(catc, addr, buf, size)            catc_ctrl_msg(catc, USB_DIR_IN,  ReadMem, 0, addr, buf, size)
213
 
214
#define f5u011_rxmode(catc, rxmode)                     catc_ctrl_msg(catc, USB_DIR_OUT, SetRxMode, 0, 1, rxmode, 2)
215
#define f5u011_rxmode_async(catc, rxmode)               catc_ctrl_async(catc, USB_DIR_OUT, SetRxMode, 0, 1, &rxmode, 2, NULL)
216
#define f5u011_mchash_async(catc, hash)                 catc_ctrl_async(catc, USB_DIR_OUT, SetRxMode, 0, 2, &hash, 8, NULL)
217
 
218
#define catc_set_reg_async(catc, reg, val)              catc_ctrl_async(catc, USB_DIR_OUT, SetReg, val, reg, NULL, 0, NULL)
219
#define catc_get_reg_async(catc, reg, cb)               catc_ctrl_async(catc, USB_DIR_IN, GetReg, 0, reg, NULL, 1, cb)
220
#define catc_write_mem_async(catc, addr, buf, size)     catc_ctrl_async(catc, USB_DIR_OUT, WriteMem, 0, addr, buf, size, NULL)
221
 
222
/*
223
 * Receive routines.
224
 */
225
 
226
static void catc_rx_done(struct urb *urb)
227
{
228
        struct catc *catc = urb->context;
229
        u8 *pkt_start = urb->transfer_buffer;
230
        struct sk_buff *skb;
231
        int pkt_len, pkt_offset = 0;
232
 
233
        if (!catc->is_f5u011) {
234
                clear_bit(RX_RUNNING, &catc->flags);
235
                pkt_offset = 2;
236
        }
237
 
238
        if (urb->status) {
239
                dbg("rx_done, status %d, length %d", urb->status, urb->actual_length);
240
                return;
241
        }
242
 
243
        do {
244
                if(!catc->is_f5u011) {
245
                        pkt_len = le16_to_cpup((u16*)pkt_start);
246
                        if (pkt_len > urb->actual_length) {
247
                                catc->stats.rx_length_errors++;
248
                                catc->stats.rx_errors++;
249
                                break;
250
                        }
251
                } else {
252
                        pkt_len = urb->actual_length;
253
                }
254
 
255
                if (!(skb = dev_alloc_skb(pkt_len)))
256
                        return;
257
 
258
                skb->dev = catc->netdev;
259
                eth_copy_and_sum(skb, pkt_start + pkt_offset, pkt_len, 0);
260
                skb_put(skb, pkt_len);
261
 
262
                skb->protocol = eth_type_trans(skb, catc->netdev);
263
                netif_rx(skb);
264
 
265
                catc->stats.rx_packets++;
266
                catc->stats.rx_bytes += pkt_len;
267
 
268
                /* F5U011 only does one packet per RX */
269
                if (catc->is_f5u011)
270
                        break;
271
                pkt_start += (((pkt_len + 1) >> 6) + 1) << 6;
272
 
273
        } while (pkt_start - (u8 *) urb->transfer_buffer < urb->actual_length);
274
 
275
        catc->netdev->last_rx = jiffies;
276
 
277
        if (catc->is_f5u011) {
278
                if (atomic_read(&catc->recq_sz)) {
279
                        int status;
280
                        atomic_dec(&catc->recq_sz);
281
                        dbg("getting extra packet");
282
                        urb->dev = catc->usbdev;
283
                        if ((status = usb_submit_urb(urb)) < 0) {
284
                                dbg("submit(rx_urb) status %d", status);
285
                        }
286
                } else {
287
                        clear_bit(RX_RUNNING, &catc->flags);
288
                }
289
        }
290
}
291
 
292
static void catc_irq_done(struct urb *urb)
293
{
294
        struct catc *catc = urb->context;
295
        u8 *data = urb->transfer_buffer;
296
        int status;
297
        unsigned int hasdata = 0, linksts = LinkNoChange;
298
 
299
        if (!catc->is_f5u011) {
300
                hasdata = data[1] & 0x80;
301
                if (data[1] & 0x40)
302
                        linksts = LinkGood;
303
                else if (data[1] & 0x20)
304
                        linksts = LinkBad;
305
        } else {
306
                hasdata = (unsigned int)(be16_to_cpup((u16*)data) & 0x0fff);
307
                if (data[0] == 0x90)
308
                        linksts = LinkGood;
309
                else if (data[0] == 0xA0)
310
                        linksts = LinkBad;
311
        }
312
 
313
        if (urb->status) {
314
                dbg("irq_done, status %d, data %02x %02x.", urb->status, data[0], data[1]);
315
                return;
316
        }
317
 
318
        if (linksts == LinkGood) {
319
                netif_carrier_on(catc->netdev);
320
                dbg("link ok");
321
        }
322
 
323
        if (linksts == LinkBad) {
324
                netif_carrier_off(catc->netdev);
325
                dbg("link bad");
326
        }
327
 
328
        if (hasdata) {
329
                if (test_and_set_bit(RX_RUNNING, &catc->flags)) {
330
                        if (catc->is_f5u011)
331
                                atomic_inc(&catc->recq_sz);
332
                } else {
333
                        catc->rx_urb.dev = catc->usbdev;
334
                        if ((status = usb_submit_urb(&catc->rx_urb)) < 0) {
335
                                err("submit(rx_urb) status %d", status);
336
                        }
337
                }
338
        }
339
}
340
 
341
/*
342
 * Transmit routines.
343
 */
344
 
345
static void catc_tx_run(struct catc *catc)
346
{
347
        int status;
348
 
349
        if (catc->is_f5u011)
350
                catc->tx_ptr = (catc->tx_ptr + 63) & ~63;
351
 
352
        catc->tx_urb.transfer_buffer_length = catc->tx_ptr;
353
        catc->tx_urb.transfer_buffer = catc->tx_buf[catc->tx_idx];
354
        catc->tx_urb.dev = catc->usbdev;
355
 
356
        if ((status = usb_submit_urb(&catc->tx_urb)) < 0)
357
                err("submit(tx_urb), status %d", status);
358
 
359
        catc->tx_idx = !catc->tx_idx;
360
        catc->tx_ptr = 0;
361
 
362
        catc->netdev->trans_start = jiffies;
363
}
364
 
365
static void catc_tx_done(struct urb *urb)
366
{
367
        struct catc *catc = urb->context;
368
        unsigned long flags;
369
 
370
        if (urb->status == -ECONNRESET) {
371
                dbg("Tx Reset.");
372
                urb->transfer_flags &= ~USB_ASYNC_UNLINK;
373
                urb->status = 0;
374
                catc->netdev->trans_start = jiffies;
375
                catc->stats.tx_errors++;
376
                clear_bit(TX_RUNNING, &catc->flags);
377
                netif_wake_queue(catc->netdev);
378
                return;
379
        }
380
 
381
        if (urb->status) {
382
                dbg("tx_done, status %d, length %d", urb->status, urb->actual_length);
383
                return;
384
        }
385
 
386
        spin_lock_irqsave(&catc->tx_lock, flags);
387
 
388
        if (catc->tx_ptr)
389
                catc_tx_run(catc);
390
        else
391
                clear_bit(TX_RUNNING, &catc->flags);
392
 
393
        netif_wake_queue(catc->netdev);
394
 
395
        spin_unlock_irqrestore(&catc->tx_lock, flags);
396
}
397
 
398
static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
399
{
400
        struct catc *catc = netdev->priv;
401
        unsigned long flags;
402
        char *tx_buf;
403
 
404
        spin_lock_irqsave(&catc->tx_lock, flags);
405
 
406
        catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6;
407
        tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr;
408
        *((u16*)tx_buf) = (catc->is_f5u011) ?
409
                cpu_to_be16((u16)skb->len) : cpu_to_le16((u16)skb->len);
410
        memcpy(tx_buf + 2, skb->data, skb->len);
411
        catc->tx_ptr += skb->len + 2;
412
 
413
        if (!test_and_set_bit(TX_RUNNING, &catc->flags))
414
                catc_tx_run(catc);
415
 
416
        if ((catc->is_f5u011 && catc->tx_ptr)
417
             || (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2))))
418
                netif_stop_queue(netdev);
419
 
420
        spin_unlock_irqrestore(&catc->tx_lock, flags);
421
 
422
        catc->stats.tx_bytes += skb->len;
423
        catc->stats.tx_packets++;
424
 
425
        dev_kfree_skb(skb);
426
 
427
        return 0;
428
}
429
 
430
static void catc_tx_timeout(struct net_device *netdev)
431
{
432
        struct catc *catc = netdev->priv;
433
 
434
        warn("Transmit timed out.");
435
        catc->tx_urb.transfer_flags |= USB_ASYNC_UNLINK;
436
        usb_unlink_urb(&catc->tx_urb);
437
}
438
 
439
/*
440
 * Control messages.
441
 */
442
 
443
static int catc_ctrl_msg(struct catc *catc, u8 dir, u8 request, u16 value, u16 index, void *buf, int len)
444
{
445
        int retval = usb_control_msg(catc->usbdev,
446
                dir ? usb_rcvctrlpipe(catc->usbdev, 0) : usb_sndctrlpipe(catc->usbdev, 0),
447
                 request, 0x40 | dir, value, index, buf, len, HZ);
448
        return retval < 0 ? retval : 0;
449
}
450
 
451
static void catc_ctrl_run(struct catc *catc)
452
{
453
        struct ctrl_queue *q = catc->ctrl_queue + catc->ctrl_tail;
454
        struct usb_device *usbdev = catc->usbdev;
455
        struct urb *urb = &catc->ctrl_urb;
456
        struct usb_ctrlrequest *dr = &catc->ctrl_dr;
457
        int status;
458
 
459
        dr->bRequest = q->request;
460
        dr->bRequestType = 0x40 | q->dir;
461
        dr->wValue = cpu_to_le16(q->value);
462
        dr->wIndex = cpu_to_le16(q->index);
463
        dr->wLength = cpu_to_le16(q->len);
464
 
465
        urb->pipe = q->dir ? usb_rcvctrlpipe(usbdev, 0) : usb_sndctrlpipe(usbdev, 0);
466
        urb->transfer_buffer_length = q->len;
467
        urb->transfer_buffer = catc->ctrl_buf;
468
        urb->setup_packet = (void *) dr;
469
        urb->dev = usbdev;
470
 
471
        if (!q->dir && q->buf && q->len)
472
                memcpy(catc->ctrl_buf, q->buf, q->len);
473
 
474
        if ((status = usb_submit_urb(&catc->ctrl_urb)))
475
                err("submit(ctrl_urb) status %d", status);
476
}
477
 
478
static void catc_ctrl_done(struct urb *urb)
479
{
480
        struct catc *catc = urb->context;
481
        struct ctrl_queue *q;
482
        unsigned long flags;
483
 
484
        if (urb->status)
485
                dbg("ctrl_done, status %d, len %d.", urb->status, urb->actual_length);
486
 
487
        spin_lock_irqsave(&catc->ctrl_lock, flags);
488
 
489
        q = catc->ctrl_queue + catc->ctrl_tail;
490
 
491
        if (q->dir) {
492
                if (q->buf && q->len)
493
                        memcpy(q->buf, catc->ctrl_buf, q->len);
494
                else
495
                        q->buf = catc->ctrl_buf;
496
        }
497
 
498
        if (q->callback)
499
                q->callback(catc, q);
500
 
501
        catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1);
502
 
503
        if (catc->ctrl_head != catc->ctrl_tail)
504
                catc_ctrl_run(catc);
505
        else
506
                clear_bit(CTRL_RUNNING, &catc->flags);
507
 
508
        spin_unlock_irqrestore(&catc->ctrl_lock, flags);
509
}
510
 
511
static int catc_ctrl_async(struct catc *catc, u8 dir, u8 request, u16 value,
512
        u16 index, void *buf, int len, void (*callback)(struct catc *catc, struct ctrl_queue *q))
513
{
514
        struct ctrl_queue *q;
515
        int retval = 0;
516
        unsigned long flags;
517
 
518
        spin_lock_irqsave(&catc->ctrl_lock, flags);
519
 
520
        q = catc->ctrl_queue + catc->ctrl_head;
521
 
522
        q->dir = dir;
523
        q->request = request;
524
        q->value = value;
525
        q->index = index;
526
        q->buf = buf;
527
        q->len = len;
528
        q->callback = callback;
529
 
530
        catc->ctrl_head = (catc->ctrl_head + 1) & (CTRL_QUEUE - 1);
531
 
532
        if (catc->ctrl_head == catc->ctrl_tail) {
533
                err("ctrl queue full");
534
                catc->ctrl_tail = (catc->ctrl_tail + 1) & (CTRL_QUEUE - 1);
535
                retval = -1;
536
        }
537
 
538
        if (!test_and_set_bit(CTRL_RUNNING, &catc->flags))
539
                catc_ctrl_run(catc);
540
 
541
        spin_unlock_irqrestore(&catc->ctrl_lock, flags);
542
 
543
        return retval;
544
}
545
 
546
/*
547
 * Statistics.
548
 */
549
 
550
static void catc_stats_done(struct catc *catc, struct ctrl_queue *q)
551
{
552
        int index = q->index - EthStats;
553
        u16 data, last;
554
 
555
        catc->stats_buf[index] = *((char *)q->buf);
556
 
557
        if (index & 1)
558
                return;
559
 
560
        data = ((u16)catc->stats_buf[index] << 8) | catc->stats_buf[index + 1];
561
        last = catc->stats_vals[index >> 1];
562
 
563
        switch (index) {
564
                case TxSingleColl:
565
                case TxMultiColl:
566
                        catc->stats.collisions += data - last;
567
                        break;
568
                case TxExcessColl:
569
                        catc->stats.tx_aborted_errors += data - last;
570
                        catc->stats.tx_errors += data - last;
571
                        break;
572
                case RxFramErr:
573
                        catc->stats.rx_frame_errors += data - last;
574
                        catc->stats.rx_errors += data - last;
575
                        break;
576
        }
577
 
578
        catc->stats_vals[index >> 1] = data;
579
}
580
 
581
static void catc_stats_timer(unsigned long data)
582
{
583
        struct catc *catc = (void *) data;
584
        int i;
585
 
586
        for (i = 0; i < 8; i++)
587
                catc_get_reg_async(catc, EthStats + 7 - i, catc_stats_done);
588
 
589
        mod_timer(&catc->timer, jiffies + STATS_UPDATE);
590
}
591
 
592
static struct net_device_stats *catc_get_stats(struct net_device *netdev)
593
{
594
        struct catc *catc = netdev->priv;
595
        return &catc->stats;
596
}
597
 
598
/*
599
 * Receive modes. Broadcast, Multicast, Promisc.
600
 */
601
 
602
static void catc_multicast(unsigned char *addr, u8 *multicast)
603
{
604
        u32 crc = ether_crc_le(6, addr);
605
        multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7);
606
}
607
 
608
static void catc_set_multicast_list(struct net_device *netdev)
609
{
610
        struct catc *catc = netdev->priv;
611
        struct dev_mc_list *mc;
612
        u8 broadcast[6];
613
        u8 rx = RxEnable | RxPolarity | RxMultiCast;
614
        int i;
615
 
616
        memset(broadcast, 0xff, 6);
617
        memset(catc->multicast, 0, 64);
618
 
619
        catc_multicast(broadcast, catc->multicast);
620
        catc_multicast(netdev->dev_addr, catc->multicast);
621
 
622
        if (netdev->flags & IFF_PROMISC) {
623
                memset(catc->multicast, 0xff, 64);
624
                rx |= (!catc->is_f5u011) ? RxPromisc : AltRxPromisc;
625
        }
626
 
627
        if (netdev->flags & IFF_ALLMULTI) {
628
                memset(catc->multicast, 0xff, 64);
629
        } else {
630
                for (i = 0, mc = netdev->mc_list; mc && i < netdev->mc_count; i++, mc = mc->next) {
631
                        u32 crc = ether_crc_le(6, mc->dmi_addr);
632
                        if (!catc->is_f5u011) {
633
                                catc->multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7);
634
                        } else {
635
                                catc->multicast[7-(crc >> 29)] |= 1 << ((crc >> 26) & 7);
636
                        }
637
                }
638
        }
639
        if (!catc->is_f5u011) {
640
                catc_set_reg_async(catc, RxUnit, rx);
641
                catc_write_mem_async(catc, 0xfa80, catc->multicast, 64);
642
        } else {
643
                f5u011_mchash_async(catc, catc->multicast);
644
                if (catc->rxmode[0] != rx) {
645
                        catc->rxmode[0] = rx;
646
                        dbg("Setting RX mode to %2.2X %2.2X", catc->rxmode[0],
647
                            catc->rxmode[1]);
648
                        f5u011_rxmode_async(catc, catc->rxmode);
649
                }
650
        }
651
}
652
 
653
/*
654
 * ioctl's
655
 */
656
static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
657
{
658
        struct catc *catc = dev->priv;
659
        u32 cmd;
660
        char tmp[40];
661
 
662
        if (get_user(cmd, (u32 *)useraddr))
663
                return -EFAULT;
664
 
665
        switch (cmd) {
666
        /* get driver info */
667
        case ETHTOOL_GDRVINFO: {
668
                struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
669
                strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
670
                strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
671
                sprintf(tmp, "usb%d:%d", catc->usbdev->bus->busnum, catc->usbdev->devnum);
672
                strncpy(info.bus_info, tmp,ETHTOOL_BUSINFO_LEN);
673
                if (copy_to_user(useraddr, &info, sizeof(info)))
674
                        return -EFAULT;
675
                return 0;
676
        }
677
 
678
        /* get settings */
679
        case ETHTOOL_GSET:
680
                if (catc->is_f5u011) {
681
                        struct ethtool_cmd ecmd = {
682
                                ETHTOOL_GSET,
683
                                SUPPORTED_10baseT_Half | SUPPORTED_TP,
684
                                ADVERTISED_10baseT_Half | ADVERTISED_TP,
685
                                SPEED_10,
686
                                DUPLEX_HALF,
687
                                PORT_TP,
688
                                0,
689
                                XCVR_INTERNAL,
690
                                AUTONEG_DISABLE,
691
                                1,
692
                                1
693
                        };
694
                        if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
695
                                return -EFAULT;
696
                        return 0;
697
                } else {
698
                        return -EOPNOTSUPP;
699
                }
700
 
701
        /* get link status */
702
        case ETHTOOL_GLINK: {
703
                struct ethtool_value edata = {ETHTOOL_GLINK};
704
                edata.data = netif_carrier_ok(dev);
705
                if (copy_to_user(useraddr, &edata, sizeof(edata)))
706
                        return -EFAULT;
707
                return 0;
708
        }
709
        }
710
        /* Note that the ethtool user space code requires EOPNOTSUPP */
711
        return -EOPNOTSUPP;
712
}
713
 
714
static int catc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
715
{
716
        switch(cmd) {
717
        case SIOCETHTOOL:
718
               return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
719
        default:
720
               return -ENOTTY; /* Apparently this is the standard ioctl errno */
721
        }
722
}
723
 
724
 
725
/*
726
 * Open, close.
727
 */
728
 
729
static int catc_open(struct net_device *netdev)
730
{
731
        struct catc *catc = netdev->priv;
732
        int status;
733
 
734
        catc->irq_urb.dev = catc->usbdev;
735
        if ((status = usb_submit_urb(&catc->irq_urb)) < 0) {
736
                err("submit(irq_urb) status %d", status);
737
                return -1;
738
        }
739
 
740
        netif_start_queue(netdev);
741
 
742
        if (!catc->is_f5u011)
743
                mod_timer(&catc->timer, jiffies + STATS_UPDATE);
744
 
745
        return 0;
746
}
747
 
748
static int catc_stop(struct net_device *netdev)
749
{
750
        struct catc *catc = netdev->priv;
751
 
752
        netif_stop_queue(netdev);
753
 
754
        if (!catc->is_f5u011)
755
                del_timer_sync(&catc->timer);
756
 
757
        usb_unlink_urb(&catc->rx_urb);
758
        usb_unlink_urb(&catc->tx_urb);
759
        usb_unlink_urb(&catc->irq_urb);
760
        usb_unlink_urb(&catc->ctrl_urb);
761
 
762
        return 0;
763
}
764
 
765
/*
766
 * USB probe, disconnect.
767
 */
768
 
769
static void *catc_probe(struct usb_device *usbdev, unsigned int ifnum, const struct usb_device_id *id)
770
{
771
        struct net_device *netdev;
772
        struct catc *catc;
773
        u8 broadcast[6];
774
        int i, pktsz;
775
 
776
        if (usb_set_interface(usbdev, ifnum, 1)) {
777
                err("Can't set altsetting 1.");
778
                return NULL;
779
        }
780
 
781
        catc = kmalloc(sizeof(struct catc), GFP_KERNEL);
782
        if (!catc)
783
                return NULL;
784
 
785
        memset(catc, 0, sizeof(struct catc));
786
 
787
        netdev = init_etherdev(0, 0);
788
        if (!netdev) {
789
                kfree(catc);
790
                return NULL;
791
        }
792
 
793
        netdev->open = catc_open;
794
        netdev->hard_start_xmit = catc_hard_start_xmit;
795
        netdev->stop = catc_stop;
796
        netdev->get_stats = catc_get_stats;
797
        netdev->tx_timeout = catc_tx_timeout;
798
        netdev->watchdog_timeo = TX_TIMEOUT;
799
        netdev->set_multicast_list = catc_set_multicast_list;
800
        netdev->do_ioctl = catc_ioctl;
801
        netdev->priv = catc;
802
 
803
        catc->usbdev = usbdev;
804
        catc->netdev = netdev;
805
 
806
        catc->tx_lock = SPIN_LOCK_UNLOCKED;
807
        catc->ctrl_lock = SPIN_LOCK_UNLOCKED;
808
 
809
        init_timer(&catc->timer);
810
        catc->timer.data = (long) catc;
811
        catc->timer.function = catc_stats_timer;
812
 
813
        /* The F5U011 has the same vendor/product as the netmate
814
         *  but a device version of 0x130
815
         */
816
        if (usbdev->descriptor.idVendor == 0x0423 &&
817
            usbdev->descriptor.idProduct == 0xa &&
818
            catc->usbdev->descriptor.bcdDevice == 0x0130) {
819
                dbg("Testing for f5u011");
820
                catc->is_f5u011 = 1;
821
                atomic_set(&catc->recq_sz, 0);
822
                pktsz = RX_PKT_SZ;
823
        } else {
824
                pktsz = RX_MAX_BURST * (PKT_SZ + 2);
825
        }
826
 
827
        FILL_CONTROL_URB(&catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0),
828
                NULL, NULL, 0, catc_ctrl_done, catc);
829
 
830
        FILL_BULK_URB(&catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1),
831
                NULL, 0, catc_tx_done, catc);
832
 
833
        FILL_BULK_URB(&catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1),
834
                catc->rx_buf, pktsz, catc_rx_done, catc);
835
 
836
        FILL_INT_URB(&catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2),
837
                catc->irq_buf, 2, catc_irq_done, catc, 1);
838
 
839
        if (!catc->is_f5u011) {
840
                dbg("Checking memory size\n");
841
 
842
                i = 0x12345678;
843
                catc_write_mem(catc, 0x7a80, &i, 4);
844
                i = 0x87654321;
845
                catc_write_mem(catc, 0xfa80, &i, 4);
846
                catc_read_mem(catc, 0x7a80, &i, 4);
847
 
848
                switch (i) {
849
                case 0x12345678:
850
                        catc_set_reg(catc, TxBufCount, 8);
851
                        catc_set_reg(catc, RxBufCount, 32);
852
                        dbg("64k Memory\n");
853
                        break;
854
                default:
855
                        warn("Couldn't detect memory size, assuming 32k");
856
                case 0x87654321:
857
                        catc_set_reg(catc, TxBufCount, 4);
858
                        catc_set_reg(catc, RxBufCount, 16);
859
                        dbg("32k Memory\n");
860
                        break;
861
                }
862
 
863
                dbg("Getting MAC from SEEROM.");
864
 
865
                catc_get_mac(catc, netdev->dev_addr);
866
 
867
                dbg("Setting MAC into registers.");
868
 
869
                for (i = 0; i < 6; i++)
870
                        catc_set_reg(catc, StationAddr0 - i, netdev->dev_addr[i]);
871
 
872
                dbg("Filling the multicast list.");
873
 
874
                memset(broadcast, 0xff, 6);
875
                catc_multicast(broadcast, catc->multicast);
876
                catc_multicast(netdev->dev_addr, catc->multicast);
877
                catc_write_mem(catc, 0xfa80, catc->multicast, 64);
878
 
879
                dbg("Clearing error counters.");
880
 
881
                for (i = 0; i < 8; i++)
882
                        catc_set_reg(catc, EthStats + i, 0);
883
                catc->last_stats = jiffies;
884
 
885
                dbg("Enabling.");
886
 
887
                catc_set_reg(catc, MaxBurst, RX_MAX_BURST);
888
                catc_set_reg(catc, OpModes, OpTxMerge | OpRxMerge | OpLenInclude | Op3MemWaits);
889
                catc_set_reg(catc, LEDCtrl, LEDLink);
890
                catc_set_reg(catc, RxUnit, RxEnable | RxPolarity | RxMultiCast);
891
        } else {
892
                dbg("Performing reset\n");
893
                catc_reset(catc);
894
                catc_get_mac(catc, netdev->dev_addr);
895
 
896
                dbg("Setting RX Mode");
897
                catc->rxmode[0] = RxEnable | RxPolarity | RxMultiCast;
898
                catc->rxmode[1] = 0;
899
                f5u011_rxmode(catc, catc->rxmode);
900
        }
901
        dbg("Init done.");
902
        printk(KERN_INFO "%s: %s USB Ethernet at usb%d:%d.%d, ",
903
               netdev->name, (catc->is_f5u011) ? "Belkin F5U011" : "CATC EL1210A NetMate",
904
               usbdev->bus->busnum, usbdev->devnum, ifnum);
905
        for (i = 0; i < 5; i++) printk("%2.2x:", netdev->dev_addr[i]);
906
        printk("%2.2x.\n", netdev->dev_addr[i]);
907
        return catc;
908
}
909
 
910
static void catc_disconnect(struct usb_device *usbdev, void *dev_ptr)
911
{
912
        struct catc *catc = dev_ptr;
913
        unregister_netdev(catc->netdev);
914
        kfree(catc->netdev);
915
        kfree(catc);
916
}
917
 
918
/*
919
 * Module functions and tables.
920
 */
921
 
922
static struct usb_device_id catc_id_table [] = {
923
        { USB_DEVICE(0x0423, 0xa) },    /* CATC Netmate, Belkin F5U011 */
924
        { USB_DEVICE(0x0423, 0xc) },    /* CATC Netmate II, Belkin F5U111 */
925
        { USB_DEVICE(0x08d1, 0x1) },    /* smartBridges smartNIC */
926
        { }
927
};
928
 
929
MODULE_DEVICE_TABLE(usb, catc_id_table);
930
 
931
static struct usb_driver catc_driver = {
932
        name:           driver_name,
933
        probe:          catc_probe,
934
        disconnect:     catc_disconnect,
935
        id_table:       catc_id_table,
936
};
937
 
938
static int __init catc_init(void)
939
{
940
        info(DRIVER_VERSION " " DRIVER_DESC);
941
        usb_register(&catc_driver);
942
        return 0;
943
}
944
 
945
static void __exit catc_exit(void)
946
{
947
        usb_deregister(&catc_driver);
948
}
949
 
950
module_init(catc_init);
951
module_exit(catc_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.