linux-old/drivers/usb/pegasus.c
<<
>>
Prefs
   1/*
   2 *  Copyright (c) 1999-2003 Petko Manolov (petkan@users.sourceforge.net)
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 *      
   8 *
   9 *      ChangeLog:
  10 *              ....    Most of the time spend reading sources & docs.
  11 *              v0.2.x  First official release for the Linux kernel.
  12 *              v0.3.0  Beutified and structured, some bugs fixed.
  13 *              v0.3.x  URBifying bulk requests and bugfixing. First relatively
  14 *                      stable release. Still can touch device's registers only
  15 *                      from top-halves.
  16 *              v0.4.0  Control messages remained unurbified are now URBs.
  17 *                      Now we can touch the HW at any time.
  18 *              v0.4.9  Control urbs again use process context to wait. Argh...
  19 *                      Some long standing bugs (enable_net_traffic) fixed.
  20 *                      Also nasty trick about resubmiting control urb from
  21 *                      interrupt context used. Please let me know how it
  22 *                      behaves. Pegasus II support added since this version.
  23 *                      TODO: suppressing HCD warnings spewage on disconnect.
  24 *              v0.4.13 Ethernet address is now set at probe(), not at open()
  25 *                      time as this seems to break dhcpd. 
  26 *              v0.4.25 ethtool support added.
  27 */
  28
  29#include <linux/sched.h>
  30#include <linux/slab.h>
  31#include <linux/init.h>
  32#include <linux/delay.h>
  33#include <linux/netdevice.h>
  34#include <linux/etherdevice.h>
  35#include <linux/ethtool.h>
  36#include <linux/mii.h>
  37#include <linux/usb.h>
  38#include <linux/module.h>
  39#include <asm/uaccess.h>
  40#include "pegasus.h"
  41
  42/*
  43 * Version Information
  44 */
  45#define DRIVER_VERSION "v0.4.32 (2003/06/06)"
  46#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
  47#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
  48
  49static const char driver_name[] = "pegasus";
  50
  51#define PEGASUS_USE_INTR
  52#define PEGASUS_WRITE_EEPROM
  53#define BMSR_MEDIA      (BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | \
  54                        BMSR_100FULL | BMSR_ANEGCAPABLE)
  55
  56static int loopback = 0;
  57static int mii_mode = 0;
  58static int multicast_filter_limit = 32;
  59
  60static struct usb_eth_dev usb_dev_id[] = {
  61#define PEGASUS_DEV(pn, vid, pid, flags)        \
  62        {name:pn, vendor:vid, device:pid, private:flags},
  63#include "pegasus.h"
  64#undef  PEGASUS_DEV
  65        {NULL, 0, 0, 0}
  66};
  67
  68static struct usb_device_id pegasus_ids[] = {
  69#define PEGASUS_DEV(pn, vid, pid, flags) \
  70        {match_flags: USB_DEVICE_ID_MATCH_DEVICE, idVendor:vid, idProduct:pid},
  71#include "pegasus.h"
  72#undef  PEGASUS_DEV
  73        {}
  74};
  75
  76MODULE_AUTHOR(DRIVER_AUTHOR);
  77MODULE_DESCRIPTION(DRIVER_DESC);
  78MODULE_LICENSE("GPL");
  79MODULE_PARM(loopback, "i");
  80MODULE_PARM(mii_mode, "i");
  81MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)");
  82MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0");
  83
  84MODULE_DEVICE_TABLE(usb, pegasus_ids);
  85
  86static int update_eth_regs_async(pegasus_t *);
  87/* Aargh!!! I _really_ hate such tweaks */
  88static void ctrl_callback(struct urb *urb)
  89{
  90        pegasus_t *pegasus = urb->context;
  91
  92        if (!pegasus)
  93                return;
  94
  95        switch (urb->status) {
  96        case 0:
  97                if (pegasus->flags & ETH_REGS_CHANGE) {
  98                        pegasus->flags &= ~ETH_REGS_CHANGE;
  99                        pegasus->flags |= ETH_REGS_CHANGED;
 100                        update_eth_regs_async(pegasus);
 101                        return;
 102                }
 103                break;
 104        case -EINPROGRESS:
 105                return;
 106        case -ENOENT:
 107                break;
 108        default:
 109                warn("%s: status %d", __FUNCTION__, urb->status);
 110        }
 111        pegasus->flags &= ~ETH_REGS_CHANGED;
 112        wake_up(&pegasus->ctrl_wait);
 113}
 114
 115static int get_registers(pegasus_t * pegasus, u16 indx, u16 size,
 116                         void *data)
 117{
 118        int ret;
 119        char *buffer;
 120        DECLARE_WAITQUEUE(wait, current);
 121
 122        buffer = kmalloc(size, GFP_DMA);
 123        if (!buffer) {
 124                warn("%s: looks like we're out of memory", __FUNCTION__);
 125                return -ENOMEM;
 126        }
 127        add_wait_queue(&pegasus->ctrl_wait, &wait);
 128        set_current_state(TASK_UNINTERRUPTIBLE);
 129        while (pegasus->flags & ETH_REGS_CHANGED)
 130                schedule();
 131        remove_wait_queue(&pegasus->ctrl_wait, &wait);
 132        set_current_state(TASK_RUNNING);
 133
 134        pegasus->dr.bRequestType = PEGASUS_REQT_READ;
 135        pegasus->dr.bRequest = PEGASUS_REQ_GET_REGS;
 136        pegasus->dr.wValue = cpu_to_le16(0);
 137        pegasus->dr.wIndex = cpu_to_le16p(&indx);
 138        pegasus->dr.wLength = cpu_to_le16p(&size);
 139        pegasus->ctrl_urb->transfer_buffer_length = size;
 140
 141        FILL_CONTROL_URB(pegasus->ctrl_urb, pegasus->usb,
 142                         usb_rcvctrlpipe(pegasus->usb, 0),
 143                         (char *) &pegasus->dr,
 144                         buffer, size, ctrl_callback, pegasus);
 145
 146        add_wait_queue(&pegasus->ctrl_wait, &wait);
 147        set_current_state(TASK_UNINTERRUPTIBLE);
 148
 149        if ((ret = usb_submit_urb(pegasus->ctrl_urb))) {
 150                err("%s: BAD CTRLs %d", __FUNCTION__, ret);
 151                goto out;
 152        }
 153
 154        schedule();
 155out:
 156        remove_wait_queue(&pegasus->ctrl_wait, &wait);
 157        memcpy(data, buffer, size);
 158        kfree(buffer);
 159
 160        return ret;
 161}
 162
 163static int set_registers(pegasus_t * pegasus, u16 indx, u16 size,
 164                         void *data)
 165{
 166        int ret;
 167        char *buffer;
 168        DECLARE_WAITQUEUE(wait, current);
 169
 170        buffer = kmalloc(size, GFP_DMA);
 171        if (!buffer) {
 172                warn("%s: looks like we're out of memory", __FUNCTION__);
 173                return -ENOMEM;
 174        }
 175        memcpy(buffer, data, size);
 176
 177        add_wait_queue(&pegasus->ctrl_wait, &wait);
 178        set_current_state(TASK_UNINTERRUPTIBLE);
 179        while (pegasus->flags & ETH_REGS_CHANGED)
 180                schedule();
 181        remove_wait_queue(&pegasus->ctrl_wait, &wait);
 182        set_current_state(TASK_RUNNING);
 183
 184        pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
 185        pegasus->dr.bRequest = PEGASUS_REQ_SET_REGS;
 186        pegasus->dr.wValue = cpu_to_le16(0);
 187        pegasus->dr.wIndex = cpu_to_le16p(&indx);
 188        pegasus->dr.wLength = cpu_to_le16p(&size);
 189        pegasus->ctrl_urb->transfer_buffer_length = size;
 190
 191        FILL_CONTROL_URB(pegasus->ctrl_urb, pegasus->usb,
 192                         usb_sndctrlpipe(pegasus->usb, 0),
 193                         (char *) &pegasus->dr,
 194                         buffer, size, ctrl_callback, pegasus);
 195
 196        add_wait_queue(&pegasus->ctrl_wait, &wait);
 197        set_current_state(TASK_UNINTERRUPTIBLE);
 198
 199        if ((ret = usb_submit_urb(pegasus->ctrl_urb))) {
 200                err("%s: BAD CTRL %d", __FUNCTION__, ret);
 201                goto out;
 202        }
 203
 204        schedule();
 205out:
 206        remove_wait_queue(&pegasus->ctrl_wait, &wait);
 207        kfree(buffer);
 208
 209        return ret;
 210}
 211
 212static int set_register(pegasus_t * pegasus, u16 indx, u8 data)
 213{
 214        int ret;
 215        char *tmp;
 216        DECLARE_WAITQUEUE(wait, current);
 217
 218        tmp = kmalloc(1, GFP_DMA);
 219        if (!tmp) {
 220                warn("%s: looks like we're out of memory", __FUNCTION__);
 221                return -ENOMEM;
 222        }
 223        memcpy(tmp, &data, 1);
 224        add_wait_queue(&pegasus->ctrl_wait, &wait);
 225        set_current_state(TASK_UNINTERRUPTIBLE);
 226        while (pegasus->flags & ETH_REGS_CHANGED)
 227                schedule();
 228        remove_wait_queue(&pegasus->ctrl_wait, &wait);
 229        set_current_state(TASK_RUNNING);
 230
 231        pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
 232        pegasus->dr.bRequest = PEGASUS_REQ_SET_REG;
 233        pegasus->dr.wValue = cpu_to_le16(data);
 234        pegasus->dr.wIndex = cpu_to_le16p(&indx);
 235        pegasus->dr.wLength = cpu_to_le16(1);
 236        pegasus->ctrl_urb->transfer_buffer_length = 1;
 237
 238        FILL_CONTROL_URB(pegasus->ctrl_urb, pegasus->usb,
 239                         usb_sndctrlpipe(pegasus->usb, 0),
 240                         (char *) &pegasus->dr,
 241                         tmp, 1, ctrl_callback, pegasus);
 242
 243        add_wait_queue(&pegasus->ctrl_wait, &wait);
 244        set_current_state(TASK_UNINTERRUPTIBLE);
 245
 246        if ((ret = usb_submit_urb(pegasus->ctrl_urb))) {
 247                err("%s: BAD CTRL %d", __FUNCTION__, ret);
 248                goto out;
 249        }
 250
 251        schedule();
 252out:
 253        remove_wait_queue(&pegasus->ctrl_wait, &wait);
 254        kfree(tmp);
 255
 256        return ret;
 257}
 258
 259static int update_eth_regs_async(pegasus_t * pegasus)
 260{
 261        int ret;
 262
 263        pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
 264        pegasus->dr.bRequest = PEGASUS_REQ_SET_REGS;
 265        pegasus->dr.wValue = 0;
 266        pegasus->dr.wIndex = cpu_to_le16(EthCtrl0);
 267        pegasus->dr.wLength = cpu_to_le16(3);
 268        pegasus->ctrl_urb->transfer_buffer_length = 3;
 269
 270        FILL_CONTROL_URB(pegasus->ctrl_urb, pegasus->usb,
 271                         usb_sndctrlpipe(pegasus->usb, 0),
 272                         (char *) &pegasus->dr,
 273                         pegasus->eth_regs, 3, ctrl_callback, pegasus);
 274
 275        if ((ret = usb_submit_urb(pegasus->ctrl_urb)))
 276                err("%s: BAD CTRL %d, flgs %x", __FUNCTION__, ret,
 277                    pegasus->flags);
 278
 279        return ret;
 280}
 281
 282static int read_mii_word(pegasus_t * pegasus, u8 phy, u8 indx, u16 * regd)
 283{
 284        int i;
 285        u8 data[4] = { phy, 0, 0, indx };
 286        u16 regdi;
 287
 288        set_register(pegasus, PhyCtrl, 0);
 289        set_registers(pegasus, PhyAddr, sizeof(data), data);
 290        set_register(pegasus, PhyCtrl, (indx | PHY_READ));
 291        for (i = 0; i < REG_TIMEOUT; i++) {
 292                get_registers(pegasus, PhyCtrl, 1, data);
 293                if (data[0] & PHY_DONE)
 294                        break;
 295        }
 296        if (i < REG_TIMEOUT) {
 297                get_registers(pegasus, PhyData, 2, &regdi);
 298                *regd = le16_to_cpu(regdi);
 299                return 0;
 300        }
 301        warn("%s: failed", __FUNCTION__);
 302
 303        return 1;
 304}
 305
 306static int mdio_read(struct net_device *dev, int phy_id, int loc)
 307{
 308        pegasus_t *pegasus = (pegasus_t *) dev->priv;
 309        int res;
 310
 311        read_mii_word(pegasus, phy_id, loc, (u16 *) & res);
 312        return res & 0xffff;
 313}
 314
 315static int write_mii_word(pegasus_t * pegasus, u8 phy, u8 indx, u16 regd)
 316{
 317        int i;
 318        u8 data[4] = { phy, 0, 0, indx };
 319
 320        *(data + 1) = cpu_to_le16p(&regd);
 321        set_register(pegasus, PhyCtrl, 0);
 322        set_registers(pegasus, PhyAddr, 4, data);
 323        set_register(pegasus, PhyCtrl, (indx | PHY_WRITE));
 324        for (i = 0; i < REG_TIMEOUT; i++) {
 325                get_registers(pegasus, PhyCtrl, 1, data);
 326                if (data[0] & PHY_DONE)
 327                        break;
 328        }
 329        if (i < REG_TIMEOUT)
 330                return 0;
 331        warn("%s: failed", __FUNCTION__);
 332
 333        return 1;
 334}
 335
 336static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
 337{
 338        pegasus_t *pegasus = (pegasus_t *) dev->priv;
 339
 340        write_mii_word(pegasus, phy_id, loc, val);
 341}
 342
 343static int read_eprom_word(pegasus_t * pegasus, u8 index, u16 * retdata)
 344{
 345        int i;
 346        u8 tmp;
 347        u16 retdatai;
 348
 349        set_register(pegasus, EpromCtrl, 0);
 350        set_register(pegasus, EpromOffset, index);
 351        set_register(pegasus, EpromCtrl, EPROM_READ);
 352
 353        for (i = 0; i < REG_TIMEOUT; i++) {
 354                get_registers(pegasus, EpromCtrl, 1, &tmp);
 355                if (tmp & EPROM_DONE)
 356                        break;
 357        }
 358        if (i < REG_TIMEOUT) {
 359                get_registers(pegasus, EpromData, 2, &retdatai);
 360                *retdata = le16_to_cpu(retdatai);
 361                return 0;
 362        }
 363        warn("%s: failed", __FUNCTION__);
 364
 365        return -1;
 366}
 367
 368#ifdef  PEGASUS_WRITE_EEPROM
 369static inline void enable_eprom_write(pegasus_t * pegasus)
 370{
 371        u8 tmp;
 372
 373        get_registers(pegasus, EthCtrl2, 1, &tmp);
 374        set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
 375}
 376
 377static inline void disable_eprom_write(pegasus_t * pegasus)
 378{
 379        u8 tmp;
 380
 381        get_registers(pegasus, EthCtrl2, 1, &tmp);
 382        set_register(pegasus, EpromCtrl, 0);
 383        set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
 384}
 385
 386static int write_eprom_word(pegasus_t * pegasus, u8 index, u16 data)
 387{
 388        int i, tmp;
 389        u8 d[4] = { 0x3f, 0, 0, EPROM_WRITE };
 390
 391        set_registers(pegasus, EpromOffset, 4, d);
 392        enable_eprom_write(pegasus);
 393        set_register(pegasus, EpromOffset, index);
 394        set_registers(pegasus, EpromData, 2, &data);
 395        set_register(pegasus, EpromCtrl, EPROM_WRITE);
 396
 397        for (i = 0; i < REG_TIMEOUT; i++) {
 398                get_registers(pegasus, EpromCtrl, 1, &tmp);
 399                if (tmp & EPROM_DONE)
 400                        break;
 401        }
 402        disable_eprom_write(pegasus);
 403        if (i < REG_TIMEOUT)
 404                return 0;
 405        warn("%s: failed", __FUNCTION__);
 406        return -1;
 407}
 408#endif                          /* PEGASUS_WRITE_EEPROM */
 409
 410static inline void get_node_id(pegasus_t * pegasus, u8 * id)
 411{
 412        int i;
 413        u16 w16;
 414
 415        for (i = 0; i < 3; i++) {
 416                read_eprom_word(pegasus, i, &w16);
 417                ((u16 *) id)[i] = cpu_to_le16p(&w16);
 418        }
 419}
 420
 421static void set_ethernet_addr(pegasus_t * pegasus)
 422{
 423        u8 node_id[6];
 424
 425        get_node_id(pegasus, node_id);
 426        set_registers(pegasus, EthID, sizeof(node_id), node_id);
 427        memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id));
 428}
 429
 430static inline int reset_mac(pegasus_t * pegasus)
 431{
 432        u8 data = 0x8;
 433        int i;
 434
 435        set_register(pegasus, EthCtrl1, data);
 436        for (i = 0; i < REG_TIMEOUT; i++) {
 437                get_registers(pegasus, EthCtrl1, 1, &data);
 438                if (~data & 0x08) {
 439                        if (loopback & 1)
 440                                break;
 441                        if (mii_mode && (pegasus->features & HAS_HOME_PNA))
 442                                set_register(pegasus, Gpio1, 0x34);
 443                        else
 444                                set_register(pegasus, Gpio1, 0x26);
 445                        set_register(pegasus, Gpio0, pegasus->features);
 446                        set_register(pegasus, Gpio0, DEFAULT_GPIO_SET);
 447                        break;
 448                }
 449        }
 450        if (i == REG_TIMEOUT)
 451                return 1;
 452
 453        if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
 454            usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
 455                u16 auxmode;
 456
 457                read_mii_word(pegasus, 1, 0x1b, &auxmode);
 458                write_mii_word(pegasus, 1, 0x1b, auxmode | 4);
 459        }
 460        if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) {
 461                u16 auxmode;
 462                read_mii_word(pegasus, 3, 0x1b, &auxmode);
 463                write_mii_word(pegasus, 3, 0x1b, auxmode | 4);
 464        }
 465        return 0;
 466}
 467
 468static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
 469{
 470        u16 linkpart, bmsr;
 471        u8 data[4];
 472        pegasus_t *pegasus = dev->priv;
 473
 474        /* read twice 'cos this is a latch bit */
 475        read_mii_word(pegasus, pegasus->phy, MII_BMSR, &bmsr);
 476        read_mii_word(pegasus, pegasus->phy, MII_BMSR, &bmsr);
 477        if (read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart))
 478                return 2;
 479        if (!(linkpart & 1))
 480                warn("link partner stat %x", linkpart);
 481
 482        data[0] = 0xc9;
 483        data[1] = 0;
 484        if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL))
 485                data[1] |= 0x20;        /* set full duplex */
 486        if (linkpart & (ADVERTISE_100FULL | ADVERTISE_100HALF))
 487                data[1] |= 0x10;        /* set 100 Mbps */
 488        if (mii_mode)
 489                data[1] |= 1;
 490        data[2] = (loopback & 1) ? 0x09 : 0x01;
 491        memcpy(pegasus->eth_regs, data, sizeof(data));
 492        set_registers(pegasus, EthCtrl0, 3, data);
 493
 494        return 0;
 495}
 496
 497static void read_bulk_callback(struct urb *urb)
 498{
 499        pegasus_t *pegasus = urb->context;
 500        struct net_device *net;
 501        int count = urb->actual_length, res;
 502        int rx_status;
 503        struct sk_buff *skb;
 504        u16 pkt_len;
 505
 506        if (!pegasus || !(pegasus->flags & PEGASUS_RUNNING))
 507                return;
 508
 509        net = pegasus->net;
 510        if (!netif_device_present(net))
 511                return;
 512
 513        if (pegasus->flags & PEGASUS_RX_BUSY) {
 514                pegasus->stats.rx_errors++;
 515                dbg("pegasus Rx busy");
 516                return;
 517        }
 518        pegasus->flags |= PEGASUS_RX_BUSY;
 519
 520        switch (urb->status) {
 521        case 0:
 522                break;
 523        case -ETIMEDOUT:
 524                dbg("reset MAC");
 525                pegasus->flags &= ~PEGASUS_RX_BUSY;
 526                break;
 527        default:
 528                dbg("%s: RX status %d", net->name, urb->status);
 529                goto goon;
 530        }
 531
 532        if (!count)
 533                goto goon;
 534
 535        rx_status = le32_to_cpu(*(int *) (pegasus->rx_buff + count - 4));
 536        if (rx_status & 0x000e0000) {
 537                dbg("%s: RX packet error %x", net->name, rx_status & 0xe0000);
 538                pegasus->stats.rx_errors++;
 539                if (rx_status & 0x060000)
 540                        pegasus->stats.rx_length_errors++;
 541                if (rx_status & 0x080000)
 542                        pegasus->stats.rx_crc_errors++;
 543                if (rx_status & 0x100000)
 544                        pegasus->stats.rx_frame_errors++;
 545                goto goon;
 546        }
 547
 548        if (pegasus->chip == 0x8513) {
 549                pkt_len = le32_to_cpu(*(int *)pegasus->rx_buff);
 550                pkt_len &= 0x0fff;
 551        } else {
 552                pkt_len = (rx_status & 0x0fff) - 8;
 553        }
 554
 555        if (!(skb = dev_alloc_skb(pkt_len + 2)))
 556                goto goon;
 557
 558        skb->dev = net;
 559        skb_reserve(skb, 2);
 560        eth_copy_and_sum(skb, pegasus->rx_buff, pkt_len, 0);
 561        skb_put(skb, pkt_len);
 562
 563        if (pegasus->chip == 0x8513) {
 564                skb->data += 2;
 565        }
 566
 567        skb->protocol = eth_type_trans(skb, net);
 568        netif_rx(skb);
 569        pegasus->stats.rx_packets++;
 570        pegasus->stats.rx_bytes += pkt_len;
 571
 572goon:
 573        FILL_BULK_URB(pegasus->rx_urb, pegasus->usb,
 574                      usb_rcvbulkpipe(pegasus->usb, 1),
 575                      pegasus->rx_buff, PEGASUS_MAX_MTU,
 576                      read_bulk_callback, pegasus);
 577        if ((res = usb_submit_urb(pegasus->rx_urb)))
 578                warn("%s: failed submint rx_urb %d", __FUNCTION__, res);
 579        pegasus->flags &= ~PEGASUS_RX_BUSY;
 580}
 581
 582static void write_bulk_callback(struct urb *urb)
 583{
 584        pegasus_t *pegasus = urb->context;
 585        struct net_device *net = pegasus->net;
 586
 587        if (!pegasus || !(pegasus->flags & PEGASUS_RUNNING))
 588                return;
 589
 590        if (!netif_device_present(net))
 591                return;
 592
 593        switch (urb->status) {
 594        case -EPIPE:
 595                /* FIXME schedule_work() to clear the tx halt */
 596                netif_stop_queue(net);
 597                warn("%s: no tx stall recovery", net->name);
 598                return;
 599        case -ENOENT:
 600        case -ECONNRESET:
 601        case -ESHUTDOWN:
 602                dbg("%s: tx unlink, %d", net->name, urb->status);
 603                return;
 604        default:
 605                info("%s: TX status %d", net->name, urb->status);
 606                /* FALL THROUGH */
 607        case 0:
 608                break;
 609        }
 610
 611        net->trans_start = jiffies;
 612        netif_wake_queue(net);
 613}
 614
 615#ifdef  PEGASUS_USE_INTR
 616static void intr_callback(struct urb *urb)
 617{
 618        pegasus_t *pegasus = urb->context;
 619        struct net_device *net;
 620        u8 *d;
 621
 622        if (!pegasus)
 623                return;
 624
 625        switch (urb->status) {
 626        case 0:
 627                break;
 628        case -ENOENT:
 629                return;
 630        default:
 631                info("intr status %d", urb->status);
 632        }
 633
 634        d = urb->transfer_buffer;
 635        net = pegasus->net;
 636        if (d[0] & 0xfc) {
 637                pegasus->stats.tx_errors++;
 638                if (d[0] & TX_UNDERRUN)
 639                        pegasus->stats.tx_fifo_errors++;
 640                if (d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT))
 641                        pegasus->stats.tx_aborted_errors++;
 642                if (d[0] & LATE_COL)
 643                        pegasus->stats.tx_window_errors++;
 644                if (d[5] & LINK_STATUS) {
 645                        netif_carrier_on(net);
 646                } else {
 647                        netif_carrier_off(net);
 648                        pegasus->stats.tx_carrier_errors++;
 649                }
 650        }
 651}
 652#endif
 653
 654static void pegasus_tx_timeout(struct net_device *net)
 655{
 656        pegasus_t *pegasus = net->priv;
 657
 658        if (!pegasus)
 659                return;
 660
 661        warn("%s: Tx timed out.", net->name);
 662        pegasus->tx_urb->transfer_flags |= USB_ASYNC_UNLINK;
 663        usb_unlink_urb(pegasus->tx_urb);
 664        pegasus->stats.tx_errors++;
 665}
 666
 667static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
 668{
 669        pegasus_t *pegasus = net->priv;
 670        int count = ((skb->len + 2) & 0x3f) ? skb->len + 2 : skb->len + 3;
 671        int res;
 672        u16 l16 = skb->len;
 673
 674        netif_stop_queue(net);
 675
 676        ((u16 *) pegasus->tx_buff)[0] = cpu_to_le16(l16);
 677        memcpy(pegasus->tx_buff + 2, skb->data, skb->len);
 678        FILL_BULK_URB(pegasus->tx_urb, pegasus->usb,
 679                      usb_sndbulkpipe(pegasus->usb, 2),
 680                      pegasus->tx_buff, PEGASUS_MAX_MTU,
 681                      write_bulk_callback, pegasus);
 682        pegasus->tx_urb->transfer_buffer_length = count;
 683        if ((res = usb_submit_urb(pegasus->tx_urb))) {
 684                switch (res) {
 685                case -EPIPE:    /* stall, or disconnect from TT */
 686                        /* cleanup should already have been scheduled */
 687                        break;
 688                case -ENODEV:   /* disconnect() upcoming */
 689                        break;
 690                default:
 691                        pegasus->stats.tx_errors++;
 692                        netif_start_queue(net);
 693                }
 694        } else {
 695                pegasus->stats.tx_packets++;
 696                pegasus->stats.tx_bytes += skb->len;
 697                net->trans_start = jiffies;
 698        }
 699
 700        dev_kfree_skb(skb);
 701
 702        return 0;
 703}
 704
 705static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
 706{
 707        return &((pegasus_t *) dev->priv)->stats;
 708}
 709
 710static inline void disable_net_traffic(pegasus_t * pegasus)
 711{
 712        int tmp = 0;
 713
 714        set_registers(pegasus, EthCtrl0, 2, &tmp);
 715}
 716
 717static inline void get_interrupt_interval(pegasus_t * pegasus)
 718{
 719        u8 data[2];
 720
 721        read_eprom_word(pegasus, 4, (u16 *) data);
 722        if (data[1] < 0x80) {
 723                info("intr interval will be changed from %ums to %ums",
 724                     data[1], 0x80);
 725                data[1] = 0x80;
 726#ifdef  PEGASUS_WRITE_EEPROM
 727                write_eprom_word(pegasus, 4, *(u16 *) data);
 728#endif
 729        }
 730        pegasus->intr_interval = data[1];
 731}
 732
 733static void set_carrier(struct net_device *net)
 734{
 735        pegasus_t *pegasus;
 736        short tmp;
 737
 738        pegasus = net->priv;
 739        read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp);
 740        if (tmp & BMSR_LSTATUS)
 741                netif_carrier_on(net);
 742        else
 743                netif_carrier_off(net);
 744
 745}
 746
 747static int pegasus_open(struct net_device *net)
 748{
 749        pegasus_t *pegasus = (pegasus_t *) net->priv;
 750        int res;
 751
 752        down(&pegasus->sem);
 753
 754        set_registers(pegasus, EthID, 6, net->dev_addr);
 755        
 756        FILL_BULK_URB(pegasus->rx_urb, pegasus->usb,
 757                      usb_rcvbulkpipe(pegasus->usb, 1),
 758                      pegasus->rx_buff, PEGASUS_MAX_MTU,
 759                      read_bulk_callback, pegasus);
 760        if ((res = usb_submit_urb(pegasus->rx_urb)))
 761                warn("%s: failed rx_urb %d", __FUNCTION__, res);
 762#ifdef  PEGASUS_USE_INTR
 763        FILL_INT_URB(pegasus->intr_urb, pegasus->usb,
 764                     usb_rcvintpipe(pegasus->usb, 3),
 765                     pegasus->intr_buff, sizeof(pegasus->intr_buff),
 766                     intr_callback, pegasus, pegasus->intr_interval);
 767        if ((res = usb_submit_urb(pegasus->intr_urb)))
 768                warn("%s: failed intr_urb %d", __FUNCTION__, res);
 769#endif
 770        netif_start_queue(net);
 771        pegasus->flags |= PEGASUS_RUNNING;
 772        if ((res = enable_net_traffic(net, pegasus->usb))) {
 773                err("can't enable_net_traffic() - %d", res);
 774                res = -EIO;
 775                goto exit;
 776        }
 777
 778        set_carrier(net);
 779        res = 0;
 780exit:
 781        up(&pegasus->sem);
 782
 783        return res;
 784}
 785
 786static int pegasus_close(struct net_device *net)
 787{
 788        pegasus_t *pegasus = net->priv;
 789
 790        down(&pegasus->sem);
 791        pegasus->flags &= ~PEGASUS_RUNNING;
 792        netif_stop_queue(net);
 793        if (!(pegasus->flags & PEGASUS_UNPLUG))
 794                disable_net_traffic(pegasus);
 795
 796        usb_unlink_urb(pegasus->rx_urb);
 797        usb_unlink_urb(pegasus->tx_urb);
 798        usb_unlink_urb(pegasus->ctrl_urb);
 799#ifdef  PEGASUS_USE_INTR
 800        usb_unlink_urb(pegasus->intr_urb);
 801#endif
 802        up(&pegasus->sem);
 803
 804        return 0;
 805}
 806#if CONFIG_MII
 807static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr)
 808{
 809
 810        u32 ethcmd;
 811        pegasus_t *pegasus = dev->priv;
 812
 813        if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
 814                return -EFAULT;
 815
 816        switch (ethcmd) {
 817        /* get driver-specific version/etc. info */
 818        case ETHTOOL_GDRVINFO:{
 819                        struct ethtool_drvinfo info;
 820
 821                        memset (&info, 0, sizeof info);
 822                        info.cmd = ETHTOOL_GDRVINFO;
 823                        strncpy(info.driver, driver_name,
 824                                sizeof (info.driver) - 1);
 825                        strncpy(info.version, DRIVER_VERSION,
 826                                sizeof (info.version) - 1);
 827                        usb_make_path(pegasus->usb, info.bus_info,
 828                                      sizeof info.bus_info);
 829                        if (copy_to_user(useraddr, &info, sizeof (info)))
 830                                return -EFAULT;
 831                        return 0;
 832                }
 833
 834        /* get settings */
 835        case ETHTOOL_GSET:{
 836                        struct ethtool_cmd ecmd = { ETHTOOL_GSET };
 837                        mii_ethtool_gset(&pegasus->mii, &ecmd);
 838                        if (copy_to_user(useraddr, &ecmd, sizeof (ecmd)))
 839                                return -EFAULT;
 840                        return 0;
 841                }
 842        /* set settings */
 843        case ETHTOOL_SSET:{
 844                        int r;
 845                        struct ethtool_cmd ecmd;
 846                        if (copy_from_user(&ecmd, useraddr, sizeof (ecmd)))
 847                                return -EFAULT;
 848                        r = mii_ethtool_sset(&pegasus->mii, &ecmd);
 849                        return r;
 850                }
 851        /* restart autonegotiation */
 852        case ETHTOOL_NWAY_RST:{
 853                        return mii_nway_restart(&pegasus->mii);
 854                }
 855
 856        /* get link status */
 857        case ETHTOOL_GLINK:{
 858                        struct ethtool_value edata = { ETHTOOL_GLINK };
 859                        edata.data = mii_link_ok(&pegasus->mii);
 860                        if (copy_to_user(useraddr, &edata, sizeof (edata)))
 861                                return -EFAULT;
 862                        return 0;
 863                }
 864        /* get message-level */
 865        case ETHTOOL_GMSGLVL:{
 866                        struct ethtool_value edata = { ETHTOOL_GMSGLVL };
 867                        /* edata.data = pegasus->msg_enable; FIXME */
 868                        if (copy_to_user(useraddr, &edata, sizeof (edata)))
 869                                return -EFAULT;
 870                        return 0;
 871                }
 872        /* set message-level */
 873        case ETHTOOL_SMSGLVL:{
 874                        struct ethtool_value edata;
 875                        if (copy_from_user(&edata, useraddr, sizeof (edata)))
 876                                return -EFAULT;
 877                        /* sp->msg_enable = edata.data; FIXME */
 878                        return 0;
 879                }
 880
 881        }
 882
 883        return -EOPNOTSUPP;
 884
 885}
 886#else
 887static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
 888{
 889        pegasus_t *pegasus;
 890        int cmd;
 891
 892        pegasus = net->priv;
 893        if (get_user(cmd, (int *) uaddr))
 894                return -EFAULT;
 895        switch (cmd) {
 896        case ETHTOOL_GDRVINFO:{
 897                        struct ethtool_drvinfo info;
 898
 899                        memset (&info, 0, sizeof info);
 900                        info.cmd = ETHTOOL_GDRVINFO;
 901                        strncpy(info.driver, driver_name,
 902                                sizeof (info.driver) - 1);
 903                        strncpy(info.driver, DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
 904                        strncpy(info.version, DRIVER_VERSION,
 905                                sizeof (info.version) - 1);
 906                        usb_make_path(pegasus->usb, info.bus_info,
 907                                      sizeof (info.bus_info) -1);
 908                        if (copy_to_user(uaddr, &info, sizeof(info)))
 909                                return -EFAULT;
 910                        return 0;
 911                }
 912        case ETHTOOL_GSET:{
 913                        struct ethtool_cmd ecmd;
 914                        short lpa, bmcr;
 915                        u8 port;
 916
 917                        if (copy_from_user(&ecmd, uaddr, sizeof(ecmd)))
 918                                return -EFAULT;
 919                        ecmd.supported = (SUPPORTED_10baseT_Half |
 920                                          SUPPORTED_10baseT_Full |
 921                                          SUPPORTED_100baseT_Half |
 922                                          SUPPORTED_100baseT_Full |
 923                                          SUPPORTED_Autoneg |
 924                                          SUPPORTED_TP | SUPPORTED_MII);
 925                        get_registers(pegasus, Reg7b, 1, &port);
 926                        if (port == 0)
 927                                ecmd.port = PORT_MII;
 928                        else
 929                                ecmd.port = PORT_TP;
 930                        ecmd.transceiver = XCVR_INTERNAL;
 931                        ecmd.phy_address = pegasus->phy;
 932                        read_mii_word(pegasus, pegasus->phy, MII_BMCR, &bmcr);
 933                        read_mii_word(pegasus, pegasus->phy, MII_LPA, &lpa);
 934                        if (bmcr & BMCR_ANENABLE) {
 935                                ecmd.autoneg = AUTONEG_ENABLE;
 936                                ecmd.speed = lpa & (LPA_100HALF | LPA_100FULL) ?
 937                                    SPEED_100 : SPEED_10;
 938                                if (ecmd.speed == SPEED_100)
 939                                        ecmd.duplex = lpa & LPA_100FULL ?
 940                                            DUPLEX_FULL : DUPLEX_HALF;
 941                                else
 942                                        ecmd.duplex = lpa & LPA_10FULL ?
 943                                            DUPLEX_FULL : DUPLEX_HALF;
 944                        } else {
 945                                ecmd.autoneg = AUTONEG_DISABLE;
 946                                ecmd.speed = bmcr & BMCR_SPEED100 ?
 947                                    SPEED_100 : SPEED_10;
 948                                ecmd.duplex = bmcr & BMCR_FULLDPLX ?
 949                                    DUPLEX_FULL : DUPLEX_HALF;
 950                        }
 951                        if (copy_to_user(uaddr, &ecmd, sizeof(ecmd)))
 952                                return -EFAULT;
 953
 954                        return 0;
 955                }
 956        case ETHTOOL_SSET:{
 957                        return -EOPNOTSUPP;
 958                }
 959        case ETHTOOL_GLINK:{
 960                        struct ethtool_value edata = { ETHTOOL_GLINK };
 961                        edata.data = netif_carrier_ok(net);
 962                        if (copy_to_user(uaddr, &edata, sizeof(edata)))
 963                                return -EFAULT;
 964                        return 0;
 965                }
 966        default:
 967                return -EOPNOTSUPP;
 968        }
 969}
 970#endif
 971static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 972{
 973        u16 *data = (u16 *) & rq->ifr_data;
 974        pegasus_t *pegasus = net->priv;
 975        int res;
 976
 977        down(&pegasus->sem);
 978        switch (cmd) {
 979        case SIOCETHTOOL:
 980                res = pegasus_ethtool_ioctl(net, rq->ifr_data);
 981                break;
 982        case SIOCDEVPRIVATE:
 983                data[0] = pegasus->phy;
 984        case SIOCDEVPRIVATE + 1:
 985                read_mii_word(pegasus, data[0], data[1] & 0x1f, &data[3]);
 986                res = 0;
 987                break;
 988        case SIOCDEVPRIVATE + 2:
 989                if (!capable(CAP_NET_ADMIN)) {
 990                        up(&pegasus->sem);
 991                        return -EPERM;
 992                }
 993                write_mii_word(pegasus, pegasus->phy, data[1] & 0x1f, data[2]);
 994                res = 0;
 995                break;
 996        default:
 997                res = -EOPNOTSUPP;
 998        }
 999        up(&pegasus->sem);
1000
1001        return res;
1002}
1003
1004static void pegasus_set_multicast(struct net_device *net)
1005{
1006        pegasus_t *pegasus = net->priv;
1007
1008        netif_stop_queue(net);
1009
1010        if (net->flags & IFF_PROMISC) {
1011                pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS;
1012                info("%s: Promiscuous mode enabled", net->name);
1013        } else if ((net->mc_count > multicast_filter_limit) ||
1014                   (net->flags & IFF_ALLMULTI)) {
1015                pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
1016                pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
1017                info("%s set allmulti", net->name);
1018        } else {
1019                pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST;
1020                pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
1021        }
1022
1023        pegasus->flags |= ETH_REGS_CHANGE;
1024        ctrl_callback(pegasus->ctrl_urb);
1025
1026        netif_wake_queue(net);
1027}
1028
1029static u8 mii_phy_probe(pegasus_t * pegasus)
1030{
1031        int i;
1032        u16 tmp;
1033
1034        for (i = 0; i < 32; i++) {
1035                read_mii_word(pegasus, i, MII_BMSR, &tmp);
1036                if (tmp == 0 || tmp == 0xffff || (tmp & BMSR_MEDIA) == 0)
1037                        continue;
1038                else
1039                        return i;
1040        }
1041
1042        return 0xff;
1043}
1044
1045static inline void setup_pegasus_II(pegasus_t * pegasus)
1046{
1047        u16 data = 0xa5;
1048        
1049        set_register(pegasus, Reg1d, 0);
1050        set_register(pegasus, Reg7b, 1);
1051        mdelay(100);
1052        if ((pegasus->features & HAS_HOME_PNA) && mii_mode)
1053                set_register(pegasus, Reg7b, 0);
1054        else
1055                set_register(pegasus, Reg7b, 2);
1056        
1057        set_register(pegasus, 0x83, data);
1058        get_registers(pegasus, 0x83, 1, &data);
1059        
1060        if (data & 0xa5) {
1061                pegasus->chip = 0x8513;
1062        } else {
1063                pegasus->chip = 0;
1064        }
1065        
1066        set_register( pegasus, 0x80, 0xc0 );
1067        set_register( pegasus, 0x83, 0xff );
1068        set_register( pegasus, 0x84, 0x01 );
1069        
1070        if ((pegasus->features & HAS_HOME_PNA) && mii_mode)
1071                set_register(pegasus, Reg81, 6);
1072        else
1073                set_register(pegasus, Reg81, 2);
1074}
1075
1076static void *pegasus_probe(struct usb_device *dev, unsigned int ifnum,
1077                           const struct usb_device_id *id)
1078{
1079        struct net_device *net;
1080        pegasus_t *pegasus;
1081        int dev_index = id - pegasus_ids;
1082
1083        if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
1084                err("usb_set_configuration() failed");
1085                return NULL;
1086        }
1087
1088        if (!(pegasus = kmalloc(sizeof(struct pegasus), GFP_KERNEL))) {
1089                err("out of memory allocating device structure");
1090                return NULL;
1091        }
1092
1093        usb_inc_dev_use(dev);
1094        memset(pegasus, 0, sizeof(struct pegasus));
1095        pegasus->dev_index = dev_index;
1096        init_waitqueue_head(&pegasus->ctrl_wait);
1097
1098        pegasus->ctrl_urb = usb_alloc_urb(0);
1099        if (!pegasus->ctrl_urb) {
1100                kfree(pegasus);
1101                return NULL;
1102        }
1103        pegasus->rx_urb = usb_alloc_urb(0);
1104        if (!pegasus->rx_urb) {
1105                usb_free_urb(pegasus->ctrl_urb);
1106                kfree(pegasus);
1107                return NULL;
1108        }
1109        pegasus->tx_urb = usb_alloc_urb(0);
1110        if (!pegasus->tx_urb) {
1111                usb_free_urb(pegasus->rx_urb);
1112                usb_free_urb(pegasus->ctrl_urb);
1113                kfree(pegasus);
1114                return NULL;
1115        }
1116        pegasus->intr_urb = usb_alloc_urb(0);
1117        if (!pegasus->intr_urb) {
1118                usb_free_urb(pegasus->tx_urb);
1119                usb_free_urb(pegasus->rx_urb);
1120                usb_free_urb(pegasus->ctrl_urb);
1121                kfree(pegasus);
1122                return NULL;
1123        }
1124
1125        net = init_etherdev(NULL, 0);
1126        if (!net) {
1127                usb_free_urb(pegasus->tx_urb);
1128                usb_free_urb(pegasus->rx_urb);
1129                usb_free_urb(pegasus->ctrl_urb);
1130                kfree(pegasus);
1131                return NULL;
1132        }
1133
1134        init_MUTEX(&pegasus->sem);
1135        down(&pegasus->sem);
1136        pegasus->usb = dev;
1137        pegasus->net = net;
1138        SET_MODULE_OWNER(net);
1139        net->priv = pegasus;
1140        net->open = pegasus_open;
1141        net->stop = pegasus_close;
1142        net->watchdog_timeo = PEGASUS_TX_TIMEOUT;
1143        net->tx_timeout = pegasus_tx_timeout;
1144        net->do_ioctl = pegasus_ioctl;
1145        net->hard_start_xmit = pegasus_start_xmit;
1146        net->set_multicast_list = pegasus_set_multicast;
1147        net->get_stats = pegasus_netdev_stats;
1148        net->mtu = PEGASUS_MTU;
1149        pegasus->mii.dev = net;
1150        pegasus->mii.mdio_read = mdio_read;
1151        pegasus->mii.mdio_write = mdio_write;
1152        pegasus->mii.phy_id_mask = 0x1f;
1153        pegasus->mii.reg_num_mask = 0x1f;
1154
1155        pegasus->features = usb_dev_id[dev_index].private;
1156#ifdef  PEGASUS_USE_INTR
1157        get_interrupt_interval(pegasus);
1158#endif
1159        if (reset_mac(pegasus)) {
1160                err("can't reset MAC");
1161                unregister_netdev(pegasus->net);
1162                usb_free_urb(pegasus->tx_urb);
1163                usb_free_urb(pegasus->rx_urb);
1164                usb_free_urb(pegasus->ctrl_urb);
1165                kfree(pegasus->net);
1166                kfree(pegasus);
1167                pegasus = NULL;
1168                goto exit;
1169        }
1170
1171        info("%s: %s", net->name, usb_dev_id[dev_index].name);
1172
1173        set_ethernet_addr(pegasus);
1174
1175        if (pegasus->features & PEGASUS_II) {
1176                info("setup Pegasus II specific registers");
1177                setup_pegasus_II(pegasus);
1178        }
1179
1180        pegasus->phy = mii_phy_probe(pegasus);
1181        if (pegasus->phy == 0xff) {
1182                warn("can't locate MII phy, using default");
1183                pegasus->phy = 1;
1184        }
1185exit:
1186        up(&pegasus->sem);
1187        
1188        return pegasus;
1189}
1190
1191static void pegasus_disconnect(struct usb_device *dev, void *ptr)
1192{
1193        struct pegasus *pegasus = ptr;
1194
1195        if (!pegasus) {
1196                warn("unregistering non-existant device");
1197                return;
1198        }
1199
1200        pegasus->flags |= PEGASUS_UNPLUG;
1201        unregister_netdev(pegasus->net);
1202        usb_dec_dev_use(dev);
1203        usb_unlink_urb(pegasus->intr_urb);
1204        usb_unlink_urb(pegasus->tx_urb);
1205        usb_unlink_urb(pegasus->rx_urb);
1206        usb_unlink_urb(pegasus->ctrl_urb);
1207        usb_free_urb(pegasus->intr_urb);
1208        usb_free_urb(pegasus->tx_urb);
1209        usb_free_urb(pegasus->rx_urb);
1210        usb_free_urb(pegasus->ctrl_urb);
1211        kfree(pegasus->net);
1212        kfree(pegasus);
1213        pegasus = NULL;
1214}
1215
1216static struct usb_driver pegasus_driver = {
1217        name:           driver_name,
1218        probe:          pegasus_probe,
1219        disconnect:     pegasus_disconnect,
1220        id_table:       pegasus_ids,
1221};
1222
1223int __init pegasus_init(void)
1224{
1225        info(DRIVER_VERSION ":" DRIVER_DESC);
1226        return usb_register(&pegasus_driver);
1227}
1228
1229void __exit pegasus_exit(void)
1230{
1231        usb_deregister(&pegasus_driver);
1232}
1233
1234module_init(pegasus_init);
1235module_exit(pegasus_exit);
1236
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.