linux-old/drivers/usb/kaweth.c
<<
>>
Prefs
   1/****************************************************************
   2 *
   3 *     kaweth.c - driver for KL5KUSB101 based USB->Ethernet
   4 *
   5 *     (c) 2000 Interlan Communications
   6 *     (c) 2000 Stephane Alnet
   7 *     (C) 2001 Brad Hards
   8 *     (C) 2002 Oliver Neukum
   9 *
  10 *     Original author: The Zapman <zapman@interlan.net>
  11 *     Inspired by, and much credit goes to Michael Rothwell
  12 *     <rothwell@interlan.net> for the test equipment, help, and patience
  13 *     Based off of (and with thanks to) Petko Manolov's pegaus.c driver.
  14 *     Also many thanks to Joel Silverman and Ed Surprenant at Kawasaki
  15 *     for providing the firmware and driver resources.
  16 *
  17 *     This program is free software; you can redistribute it and/or
  18 *     modify it under the terms of the GNU General Public License as
  19 *     published by the Free Software Foundation; either version 2, or
  20 *     (at your option) any later version.
  21 *
  22 *     This program is distributed in the hope that it will be useful,
  23 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25 *     GNU General Public License for more details.
  26 *
  27 *     You should have received a copy of the GNU General Public License
  28 *     along with this program; if not, write to the Free Software Foundation,
  29 *     Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  30 *
  31 ****************************************************************/
  32
  33/* TODO:
  34 * Fix in_interrupt() problem
  35 * Develop test procedures for USB net interfaces
  36 * Run test procedures
  37 * Fix bugs from previous two steps
  38 * Snoop other OSs for any tricks we're not doing
  39 * SMP locking
  40 * Reduce arbitrary timeouts
  41 * Smart multicast support
  42 * Temporary MAC change support
  43 * Tunable SOFs parameter - ioctl()?
  44 * Ethernet stats collection
  45 * Code formatting improvements
  46 */
  47
  48#include <linux/module.h>
  49#include <linux/sched.h>
  50#include <linux/slab.h>
  51#include <linux/string.h>
  52#include <linux/init.h>
  53#include <linux/delay.h>
  54#include <linux/netdevice.h>
  55#include <linux/etherdevice.h>
  56#include <linux/usb.h>
  57#include <linux/types.h>
  58#include <linux/ethtool.h>
  59#include <asm/uaccess.h>
  60#include <asm/semaphore.h>
  61#include <asm/byteorder.h>
  62
  63#define DEBUG
  64
  65#ifdef DEBUG
  66#define kaweth_dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format "\n" ,##arg)
  67#else
  68#define kaweth_dbg(format, arg...) do {} while (0)
  69#endif
  70#define kaweth_err(format, arg...) printk(KERN_ERR __FILE__ ": " format "\n" ,##arg)
  71#define kaweth_info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" , ##arg)
  72#define kaweth_warn(format, arg...) printk(KERN_WARNING __FILE__ ": " format "\n" , ##arg)
  73
  74
  75#include "kawethfw.h"
  76
  77#define KAWETH_MTU                      1500
  78#define KAWETH_BUF_SIZE                 1664
  79#define KAWETH_TX_TIMEOUT               (5 * HZ)
  80#define KAWETH_SCRATCH_SIZE             32
  81#define KAWETH_FIRMWARE_BUF_SIZE        4096
  82#define KAWETH_CONTROL_TIMEOUT          (30 * HZ)
  83
  84#define KAWETH_STATUS_BROKEN            0x0000001
  85#define KAWETH_STATUS_CLOSING           0x0000002
  86
  87#define KAWETH_PACKET_FILTER_PROMISCUOUS        0x01
  88#define KAWETH_PACKET_FILTER_ALL_MULTICAST      0x02
  89#define KAWETH_PACKET_FILTER_DIRECTED           0x04
  90#define KAWETH_PACKET_FILTER_BROADCAST          0x08
  91#define KAWETH_PACKET_FILTER_MULTICAST          0x10
  92
  93/* Table 7 */
  94#define KAWETH_COMMAND_GET_ETHERNET_DESC        0x00
  95#define KAWETH_COMMAND_MULTICAST_FILTERS        0x01
  96#define KAWETH_COMMAND_SET_PACKET_FILTER        0x02
  97#define KAWETH_COMMAND_STATISTICS               0x03
  98#define KAWETH_COMMAND_SET_TEMP_MAC             0x06
  99#define KAWETH_COMMAND_GET_TEMP_MAC             0x07
 100#define KAWETH_COMMAND_SET_URB_SIZE             0x08
 101#define KAWETH_COMMAND_SET_SOFS_WAIT            0x09
 102#define KAWETH_COMMAND_SCAN                     0xFF
 103
 104#define KAWETH_SOFS_TO_WAIT                     0x05
 105
 106#define INTBUFFERSIZE                           4
 107
 108#define STATE_OFFSET                            0
 109#define STATE_MASK                              0x40
 110#define STATE_SHIFT                             5
 111
 112
 113MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-picardie.fr>, Brad Hards <bhards@bigpond.net.au> and Oliver Neukum <oliver@neukum.org>");
 114MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver");
 115MODULE_LICENSE("GPL");
 116
 117static const char driver_name[] = "kaweth";
 118
 119static void *kaweth_probe(
 120            struct usb_device *dev,             /* the device */
 121            unsigned ifnum,                     /* what interface */
 122            const struct usb_device_id *id      /* from id_table */
 123        );
 124static void kaweth_disconnect(struct usb_device *dev, void *ptr);
 125int kaweth_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe,
 126                                struct usb_ctrlrequest *cmd, void *data,
 127                                int len, int timeout);
 128
 129/****************************************************************
 130 *     usb_device_id
 131 ****************************************************************/
 132static struct usb_device_id usb_klsi_table[] = {
 133        { USB_DEVICE(0x03e8, 0x0008) }, /* AOX Endpoints USB Ethernet */
 134        { USB_DEVICE(0x04bb, 0x0901) }, /* I-O DATA USB-ET/T */
 135        { USB_DEVICE(0x0506, 0x03e8) }, /* 3Com 3C19250 */
 136        { USB_DEVICE(0x0506, 0x11f8) }, /* 3Com 3C460 */
 137        { USB_DEVICE(0x0557, 0x2002) }, /* ATEN USB Ethernet */
 138        { USB_DEVICE(0x0557, 0x4000) }, /* D-Link DSB-650C */
 139        { USB_DEVICE(0x0565, 0x0002) }, /* Peracom Enet */
 140        { USB_DEVICE(0x0565, 0x0003) }, /* Optus@Home UEP1045A */
 141        { USB_DEVICE(0x0565, 0x0005) }, /* Peracom Enet2 */
 142        { USB_DEVICE(0x05e9, 0x0008) }, /* KLSI KL5KUSB101B */
 143        { USB_DEVICE(0x05e9, 0x0009) }, /* KLSI KL5KUSB101B (Board change) */
 144        { USB_DEVICE(0x066b, 0x2202) }, /* Linksys USB10T */
 145        { USB_DEVICE(0x06e1, 0x0008) }, /* ADS USB-10BT */
 146        { USB_DEVICE(0x06e1, 0x0009) }, /* ADS USB-10BT */
 147        { USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */
 148        { USB_DEVICE(0x0785, 0x0002) }, /* NTT-TE MN128 USB-Ethernet Adapter */
 149        { USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */
 150        { USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */
 151        { USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */
 152        { USB_DEVICE(0x0846, 0x1002) }, /* NetGear EA-101 */
 153        { USB_DEVICE(0x085a, 0x0008) }, /* PortGear Ethernet Adapter */
 154        { USB_DEVICE(0x085a, 0x0009) }, /* PortGear Ethernet Adapter */
 155        { USB_DEVICE(0x087d, 0x5704) }, /* Jaton USB Ethernet Device Adapter */
 156        { USB_DEVICE(0x0951, 0x0008) }, /* Kingston Technology USB Ethernet Adapter */
 157        { USB_DEVICE(0x095a, 0x3003) }, /* Portsmith Express Ethernet Adapter */
 158        { USB_DEVICE(0x10bd, 0x1427) }, /* ASANTE USB To Ethernet Adapter */
 159        { USB_DEVICE(0x1342, 0x0204) }, /* Mobility USB-Ethernet Adapter */
 160        { USB_DEVICE(0x13d2, 0x0400) }, /* Shark Pocket Adapter */
 161        { USB_DEVICE(0x1485, 0x0001) }, /* Silicom U2E */
 162        { USB_DEVICE(0x1645, 0x0005) }, /* Entrega E45 */
 163        { USB_DEVICE(0x1645, 0x0008) }, /* Entrega USB Ethernet Adapter */
 164        { USB_DEVICE(0x1645, 0x8005) }, /* PortGear Ethernet Adapter */
 165        { USB_DEVICE(0x2001, 0x4000) }, /* D-link DSB-650C */
 166        {} /* Null terminator */
 167};
 168
 169MODULE_DEVICE_TABLE (usb, usb_klsi_table);
 170
 171/****************************************************************
 172 *     kaweth_driver
 173 ****************************************************************/
 174static struct usb_driver kaweth_driver = {
 175        .name =         driver_name,
 176        .probe =        kaweth_probe,
 177        .disconnect =   kaweth_disconnect,
 178        .id_table =     usb_klsi_table,
 179};
 180
 181typedef __u8 eth_addr_t[6];
 182
 183/****************************************************************
 184 *     usb_eth_dev
 185 ****************************************************************/
 186struct usb_eth_dev {
 187        char *name;
 188        __u16 vendor;
 189        __u16 device;
 190        void *pdata;
 191};
 192
 193/****************************************************************
 194 *     kaweth_ethernet_configuration
 195 *     Refer Table 8
 196 ****************************************************************/
 197struct kaweth_ethernet_configuration
 198{
 199        __u8 size;
 200        __u8 reserved1;
 201        __u8 reserved2;
 202        eth_addr_t hw_addr;
 203        __u32 statistics_mask;
 204        __u16 segment_size;
 205        __u16 max_multicast_filters;
 206        __u8 reserved3;
 207} __attribute__ ((packed));
 208
 209/****************************************************************
 210 *     kaweth_device
 211 ****************************************************************/
 212struct kaweth_device
 213{
 214        spinlock_t device_lock;
 215
 216        __u32 status;
 217        int end;
 218        int removed;
 219        int suspend_lowmem;
 220        int linkstate;
 221
 222        struct usb_device *dev;
 223        struct net_device *net;
 224        wait_queue_head_t term_wait;
 225
 226        struct urb *rx_urb;
 227        struct urb *tx_urb;
 228        struct urb *irq_urb;
 229        
 230        struct sk_buff *tx_skb;
 231
 232        __u8 *firmware_buf;
 233        __u8 scratch[KAWETH_SCRATCH_SIZE];
 234        __u8 rx_buf[KAWETH_BUF_SIZE];
 235        __u8 intbuffer[INTBUFFERSIZE];
 236        __u16 packet_filter_bitmap;
 237
 238        struct kaweth_ethernet_configuration configuration;
 239
 240        struct net_device_stats stats;
 241} __attribute__ ((packed));
 242
 243
 244/****************************************************************
 245 *     kaweth_control
 246 ****************************************************************/
 247static int kaweth_control(struct kaweth_device *kaweth,
 248                          unsigned int pipe,
 249                          __u8 request,
 250                          __u8 requesttype,
 251                          __u16 value,
 252                          __u16 index,
 253                          void *data,
 254                          __u16 size,
 255                          int timeout)
 256{
 257        struct usb_ctrlrequest *dr;
 258
 259        kaweth_dbg("kaweth_control()");
 260
 261        if(in_interrupt()) {
 262                kaweth_dbg("in_interrupt()");
 263                return -EBUSY;
 264        }
 265
 266        dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
 267
 268        if (!dr) {
 269                kaweth_dbg("kmalloc() failed");
 270                return -ENOMEM;
 271        }
 272
 273        dr->bRequestType= requesttype;
 274        dr->bRequest = request;
 275        dr->wValue = cpu_to_le16p(&value);
 276        dr->wIndex = cpu_to_le16p(&index);
 277        dr->wLength = cpu_to_le16p(&size);
 278
 279        return kaweth_internal_control_msg(kaweth->dev,
 280                                        pipe,
 281                                        dr,
 282                                        data,
 283                                        size,
 284                                        timeout);
 285}
 286
 287/****************************************************************
 288 *     kaweth_read_configuration
 289 ****************************************************************/
 290static int kaweth_read_configuration(struct kaweth_device *kaweth)
 291{
 292        int retval;
 293
 294        kaweth_dbg("Reading kaweth configuration");
 295
 296        retval = kaweth_control(kaweth,
 297                                usb_rcvctrlpipe(kaweth->dev, 0),
 298                                KAWETH_COMMAND_GET_ETHERNET_DESC,
 299                                USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
 300                                0,
 301                                0,
 302                                (void *)&kaweth->configuration,
 303                                sizeof(kaweth->configuration),
 304                                KAWETH_CONTROL_TIMEOUT);
 305
 306        return retval;
 307}
 308
 309/****************************************************************
 310 *     kaweth_set_urb_size
 311 ****************************************************************/
 312static int kaweth_set_urb_size(struct kaweth_device *kaweth, __u16 urb_size)
 313{
 314        int retval;
 315
 316        kaweth_dbg("Setting URB size to %d", (unsigned)urb_size);
 317
 318        retval = kaweth_control(kaweth,
 319                                usb_sndctrlpipe(kaweth->dev, 0),
 320                                KAWETH_COMMAND_SET_URB_SIZE,
 321                                USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 322                                urb_size,
 323                                0,
 324                                (void *)&kaweth->scratch,
 325                                0,
 326                                KAWETH_CONTROL_TIMEOUT);
 327
 328        return retval;
 329}
 330
 331/****************************************************************
 332 *     kaweth_set_sofs_wait
 333 ****************************************************************/
 334static int kaweth_set_sofs_wait(struct kaweth_device *kaweth, __u16 sofs_wait)
 335{
 336        int retval;
 337
 338        kaweth_dbg("Set SOFS wait to %d", (unsigned)sofs_wait);
 339
 340        retval = kaweth_control(kaweth,
 341                                usb_sndctrlpipe(kaweth->dev, 0),
 342                                KAWETH_COMMAND_SET_SOFS_WAIT,
 343                                USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 344                                sofs_wait,
 345                                0,
 346                                (void *)&kaweth->scratch,
 347                                0,
 348                                KAWETH_CONTROL_TIMEOUT);
 349
 350        return retval;
 351}
 352
 353/****************************************************************
 354 *     kaweth_set_receive_filter
 355 ****************************************************************/
 356static int kaweth_set_receive_filter(struct kaweth_device *kaweth,
 357                                     __u16 receive_filter)
 358{
 359        int retval;
 360
 361        kaweth_dbg("Set receive filter to %d", (unsigned)receive_filter);
 362
 363        retval = kaweth_control(kaweth,
 364                                usb_sndctrlpipe(kaweth->dev, 0),
 365                                KAWETH_COMMAND_SET_PACKET_FILTER,
 366                                USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 367                                receive_filter,
 368                                0,
 369                                (void *)&kaweth->scratch,
 370                                0,
 371                                KAWETH_CONTROL_TIMEOUT);
 372
 373        return retval;
 374}
 375
 376/****************************************************************
 377 *     kaweth_download_firmware
 378 ****************************************************************/
 379static int kaweth_download_firmware(struct kaweth_device *kaweth,
 380                                    __u8 *data,
 381                                    __u16 data_len,
 382                                    __u8 interrupt,
 383                                    __u8 type)
 384{
 385        if(data_len > KAWETH_FIRMWARE_BUF_SIZE) {
 386                kaweth_err("Firmware too big: %d", data_len);
 387                return -ENOSPC;
 388        }
 389
 390        memcpy(kaweth->firmware_buf, data, data_len);
 391
 392        kaweth->firmware_buf[2] = (data_len & 0xFF) - 7;
 393        kaweth->firmware_buf[3] = data_len >> 8;
 394        kaweth->firmware_buf[4] = type;
 395        kaweth->firmware_buf[5] = interrupt;
 396
 397        kaweth_dbg("High: %i, Low:%i", kaweth->firmware_buf[3],
 398                   kaweth->firmware_buf[2]);
 399
 400        kaweth_dbg("Downloading firmware at %p to kaweth device at %p",
 401            data,
 402            kaweth);
 403        kaweth_dbg("Firmware length: %d", data_len);
 404
 405        return kaweth_control(kaweth,
 406                              usb_sndctrlpipe(kaweth->dev, 0),
 407                              KAWETH_COMMAND_SCAN,
 408                              USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 409                              0,
 410                              0,
 411                              (void *)kaweth->firmware_buf,
 412                              data_len,
 413                              KAWETH_CONTROL_TIMEOUT);
 414}
 415
 416/****************************************************************
 417 *     kaweth_trigger_firmware
 418 ****************************************************************/
 419static int kaweth_trigger_firmware(struct kaweth_device *kaweth,
 420                                   __u8 interrupt)
 421{
 422        kaweth->firmware_buf[0] = 0xB6;
 423        kaweth->firmware_buf[1] = 0xC3;
 424        kaweth->firmware_buf[2] = 0x01;
 425        kaweth->firmware_buf[3] = 0x00;
 426        kaweth->firmware_buf[4] = 0x06;
 427        kaweth->firmware_buf[5] = interrupt;
 428        kaweth->firmware_buf[6] = 0x00;
 429        kaweth->firmware_buf[7] = 0x00;
 430
 431        kaweth_dbg("Triggering firmware");
 432
 433        return kaweth_control(kaweth,
 434                              usb_sndctrlpipe(kaweth->dev, 0),
 435                              KAWETH_COMMAND_SCAN,
 436                              USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 437                              0,
 438                              0,
 439                              (void *)kaweth->firmware_buf,
 440                              8,
 441                              KAWETH_CONTROL_TIMEOUT);
 442}
 443
 444/****************************************************************
 445 *     kaweth_reset
 446 ****************************************************************/
 447static int kaweth_reset(struct kaweth_device *kaweth)
 448{
 449        int result;
 450
 451        kaweth_dbg("kaweth_reset(%p)", kaweth);
 452        result = kaweth_control(kaweth,
 453                                usb_sndctrlpipe(kaweth->dev, 0),
 454                                USB_REQ_SET_CONFIGURATION,
 455                                0,
 456                                kaweth->dev->config[0].bConfigurationValue,
 457                                0,
 458                                NULL,
 459                                0,
 460                                KAWETH_CONTROL_TIMEOUT);
 461
 462        udelay(10000);
 463
 464        kaweth_dbg("kaweth_reset() returns %d.",result);
 465
 466        return result;
 467}
 468
 469static void kaweth_usb_receive(struct urb *);
 470static void kaweth_resubmit_rx_urb(struct kaweth_device *);
 471
 472/****************************************************************
 473        int_callback
 474*****************************************************************/
 475static void int_callback(struct urb *u)
 476{
 477        struct kaweth_device *kaweth = u->context;
 478        int act_state;
 479
 480        /* we abuse the interrupt urb for rebsubmitting under low memory saving a timer */
 481        if (kaweth->suspend_lowmem)
 482                kaweth_resubmit_rx_urb(kaweth);
 483
 484        /* we check the link state to report changes */
 485        if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) {
 486                if (!act_state)
 487                        netif_carrier_on(kaweth->net);
 488                else
 489                        netif_carrier_off(kaweth->net);
 490
 491                kaweth->linkstate = act_state;
 492        }
 493
 494}
 495
 496/****************************************************************
 497 *     kaweth_resubmit_rx_urb
 498 ****************************************************************/
 499static void kaweth_resubmit_rx_urb(struct kaweth_device *kaweth)
 500{
 501        int result;
 502        long flags;
 503
 504        FILL_BULK_URB(kaweth->rx_urb,
 505                      kaweth->dev,
 506                      usb_rcvbulkpipe(kaweth->dev, 1),
 507                      kaweth->rx_buf,
 508                      KAWETH_BUF_SIZE,
 509                      kaweth_usb_receive,
 510                      kaweth);
 511
 512        spin_lock_irqsave(&kaweth->device_lock, flags);
 513        if (!kaweth->removed) { /* no resubmit if disconnecting */
 514                if((result = usb_submit_urb(kaweth->rx_urb))) {
 515                        if (result == -ENOMEM)
 516                                kaweth->suspend_lowmem = 1;
 517                        kaweth_err("resubmitting rx_urb %d failed", result);
 518                } else {
 519                        kaweth->suspend_lowmem = 0;
 520                }
 521        }
 522        spin_unlock_irqrestore(&kaweth->device_lock, flags);
 523}
 524
 525static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth);
 526
 527/****************************************************************
 528 *     kaweth_usb_receive
 529 ****************************************************************/
 530static void kaweth_usb_receive(struct urb *urb)
 531{
 532        struct kaweth_device *kaweth = urb->context;
 533        struct net_device *net = kaweth->net;
 534
 535        int count = urb->actual_length;
 536        int count2 = urb->transfer_buffer_length;
 537
 538        __u16 pkt_len = le16_to_cpup((u16 *)kaweth->rx_buf);
 539
 540        struct sk_buff *skb;
 541
 542        if(urb->status == -ECONNRESET || urb->status == -ECONNABORTED)
 543        /* we are killed - set a flag and wake the disconnect handler */
 544        {
 545                kaweth->end = 1;
 546                wake_up(&kaweth->term_wait);
 547                return;
 548        }
 549
 550        if (kaweth->status & KAWETH_STATUS_CLOSING)
 551                return;
 552
 553        if(urb->status && urb->status != -EREMOTEIO && count != 1) {
 554                kaweth_err("%s RX status: %d count: %d packet_len: %d",
 555                           net->name,
 556                           urb->status,
 557                           count,
 558                           (int)pkt_len);
 559                kaweth_resubmit_rx_urb(kaweth);
 560                return;
 561        }
 562
 563        if(kaweth->net && (count > 2)) {
 564                if(pkt_len > (count - 2)) {
 565                        kaweth_err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count);
 566                        kaweth_err("Packet len & 2047: %x", pkt_len & 2047);
 567                        kaweth_err("Count 2: %x", count2);
 568                        kaweth_resubmit_rx_urb(kaweth);
 569                        return;
 570                }
 571
 572                if(!(skb = dev_alloc_skb(pkt_len+2))) {
 573                        kaweth_resubmit_rx_urb(kaweth);
 574                        return;
 575                }
 576
 577                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
 578
 579                skb->dev = net;
 580
 581                eth_copy_and_sum(skb, kaweth->rx_buf + 2, pkt_len, 0);
 582
 583                skb_put(skb, pkt_len);
 584
 585                skb->protocol = eth_type_trans(skb, net);
 586
 587                netif_rx(skb);
 588
 589                kaweth->stats.rx_packets++;
 590                kaweth->stats.rx_bytes += pkt_len;
 591        }
 592
 593        kaweth_resubmit_rx_urb(kaweth);
 594}
 595
 596/****************************************************************
 597 *     kaweth_open
 598 ****************************************************************/
 599static int kaweth_open(struct net_device *net)
 600{
 601        struct kaweth_device *kaweth = (struct kaweth_device *)net->priv;
 602
 603        kaweth_dbg("Dev usage: %d", kaweth->dev->refcnt.counter);
 604
 605        kaweth_dbg("Opening network device.");
 606
 607        MOD_INC_USE_COUNT;
 608
 609        kaweth_resubmit_rx_urb(kaweth);
 610
 611        FILL_INT_URB(
 612                kaweth->irq_urb,
 613                kaweth->dev,
 614                usb_rcvintpipe(kaweth->dev, 3),
 615                kaweth->intbuffer,
 616                INTBUFFERSIZE,
 617                int_callback,
 618                kaweth,
 619                HZ/4);
 620
 621        usb_submit_urb(kaweth->irq_urb);
 622
 623        netif_start_queue(net);
 624
 625        kaweth_async_set_rx_mode(kaweth);
 626        return 0;
 627}
 628
 629/****************************************************************
 630 *     kaweth_close
 631 ****************************************************************/
 632static int kaweth_close(struct net_device *net)
 633{
 634        struct kaweth_device *kaweth = net->priv;
 635
 636        netif_stop_queue(net);
 637        
 638        spin_lock_irq(&kaweth->device_lock);
 639        kaweth->status |= KAWETH_STATUS_CLOSING;
 640        spin_unlock_irq(&kaweth->device_lock);
 641
 642        usb_unlink_urb(kaweth->irq_urb);
 643        usb_unlink_urb(kaweth->rx_urb);
 644
 645        kaweth->status &= ~KAWETH_STATUS_CLOSING;
 646
 647        MOD_DEC_USE_COUNT;
 648
 649        printk("Dev usage: %d", kaweth->dev->refcnt.counter);
 650
 651        return 0;
 652}
 653
 654static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
 655{
 656        u32 ethcmd;
 657        
 658        if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
 659                return -EFAULT;
 660        
 661        switch (ethcmd) {
 662        case ETHTOOL_GDRVINFO: {
 663                struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
 664                strncpy(info.driver, driver_name, sizeof(info.driver)-1);
 665                if (copy_to_user(useraddr, &info, sizeof(info)))
 666                        return -EFAULT;
 667                return 0;
 668        }
 669        }
 670        
 671        return -EOPNOTSUPP;
 672}
 673
 674/****************************************************************
 675 *     kaweth_ioctl
 676 ****************************************************************/
 677static int kaweth_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 678{
 679        switch (cmd) {
 680        case SIOCETHTOOL:
 681                return netdev_ethtool_ioctl(net, (void *) rq->ifr_data);
 682        }
 683        return -EOPNOTSUPP;
 684}
 685
 686/****************************************************************
 687 *     kaweth_usb_transmit_complete
 688 ****************************************************************/
 689static void kaweth_usb_transmit_complete(struct urb *urb)
 690{
 691        struct kaweth_device *kaweth = urb->context;
 692        struct sk_buff *skb = kaweth->tx_skb;
 693
 694        if (urb->status != 0)
 695                kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status);
 696
 697        netif_wake_queue(kaweth->net);
 698        dev_kfree_skb_irq(skb);
 699}
 700
 701/****************************************************************
 702 *     kaweth_start_xmit
 703 ****************************************************************/
 704static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
 705{
 706        struct kaweth_device *kaweth = net->priv;
 707        u16 *private_header;
 708
 709        int res;
 710
 711        spin_lock(&kaweth->device_lock);
 712
 713        if (kaweth->removed) {
 714        /* our device is undergoing disconnection - we bail out */
 715                spin_unlock(&kaweth->device_lock);
 716                dev_kfree_skb_irq(skb);
 717                return 0;
 718        }
 719
 720        kaweth_async_set_rx_mode(kaweth);
 721        netif_stop_queue(net);
 722
 723        /* We now decide whether we can put our special header into the sk_buff */
 724        if (skb_cloned(skb) || skb_headroom(skb) < 2) {
 725                /* no such luck - we make our own */
 726                struct sk_buff *copied_skb;
 727                copied_skb = skb_copy_expand(skb, 2, 0, GFP_ATOMIC);
 728                dev_kfree_skb_irq(skb);
 729                skb = copied_skb;
 730                if (!copied_skb) {
 731                        kaweth->stats.tx_errors++;
 732                        netif_start_queue(net);
 733                        spin_unlock(&kaweth->device_lock);
 734                        return 0;
 735                }
 736        }
 737
 738        private_header = (u16 *)__skb_push(skb, 2);
 739        *private_header = cpu_to_le16(skb->len-2);
 740        kaweth->tx_skb = skb;
 741
 742        FILL_BULK_URB(kaweth->tx_urb,
 743                      kaweth->dev,
 744                      usb_sndbulkpipe(kaweth->dev, 2),
 745                      private_header,
 746                      skb->len,
 747                      kaweth_usb_transmit_complete,
 748                      kaweth);
 749        kaweth->end = 0;
 750        kaweth->tx_urb->transfer_flags |= USB_ASYNC_UNLINK;
 751
 752        if((res = usb_submit_urb(kaweth->tx_urb)))
 753        {
 754                kaweth_warn("kaweth failed tx_urb %d", res);
 755                kaweth->stats.tx_errors++;
 756
 757                netif_start_queue(net);
 758                dev_kfree_skb_irq(skb);
 759        }
 760        else
 761        {
 762                kaweth->stats.tx_packets++;
 763                kaweth->stats.tx_bytes += skb->len;
 764                net->trans_start = jiffies;
 765        }
 766
 767        spin_unlock(&kaweth->device_lock);
 768
 769        return 0;
 770}
 771
 772/****************************************************************
 773 *     kaweth_set_rx_mode
 774 ****************************************************************/
 775static void kaweth_set_rx_mode(struct net_device *net)
 776{
 777        struct kaweth_device *kaweth = net->priv;
 778
 779        __u16 packet_filter_bitmap = KAWETH_PACKET_FILTER_DIRECTED |
 780                                     KAWETH_PACKET_FILTER_BROADCAST |
 781                                     KAWETH_PACKET_FILTER_MULTICAST;
 782
 783        kaweth_dbg("Setting Rx mode to %d", packet_filter_bitmap);
 784
 785        netif_stop_queue(net);
 786
 787        if (net->flags & IFF_PROMISC) {
 788                packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS;
 789        }
 790        else if ((net->mc_count) || (net->flags & IFF_ALLMULTI)) {
 791                packet_filter_bitmap |= KAWETH_PACKET_FILTER_ALL_MULTICAST;
 792        }
 793
 794        kaweth->packet_filter_bitmap = packet_filter_bitmap;
 795        netif_wake_queue(net);
 796}
 797
 798/****************************************************************
 799 *     kaweth_async_set_rx_mode
 800 ****************************************************************/
 801static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth)
 802{
 803        __u16 packet_filter_bitmap = kaweth->packet_filter_bitmap;
 804        kaweth->packet_filter_bitmap = 0;
 805        if(packet_filter_bitmap == 0) return;
 806
 807        {
 808        int result;
 809        result = kaweth_control(kaweth,
 810                                usb_sndctrlpipe(kaweth->dev, 0),
 811                                KAWETH_COMMAND_SET_PACKET_FILTER,
 812                                USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
 813                                packet_filter_bitmap,
 814                                0,
 815                                (void *)&kaweth->scratch,
 816                                0,
 817                                KAWETH_CONTROL_TIMEOUT);
 818
 819        if(result < 0) {
 820                kaweth_err("Failed to set Rx mode: %d", result);
 821        }
 822        else {
 823                kaweth_dbg("Set Rx mode to %d", packet_filter_bitmap);
 824        }
 825        }
 826}
 827
 828/****************************************************************
 829 *     kaweth_netdev_stats
 830 ****************************************************************/
 831static struct net_device_stats *kaweth_netdev_stats(struct net_device *dev)
 832{
 833        return &((struct kaweth_device *)dev->priv)->stats;
 834}
 835
 836/****************************************************************
 837 *     kaweth_tx_timeout
 838 ****************************************************************/
 839static void kaweth_tx_timeout(struct net_device *net)
 840{
 841        struct kaweth_device *kaweth = net->priv;
 842
 843        kaweth_warn("%s: Tx timed out. Resetting.", net->name);
 844        kaweth->stats.tx_errors++;
 845        net->trans_start = jiffies;
 846
 847        usb_unlink_urb(kaweth->tx_urb);
 848}
 849
 850/****************************************************************
 851 *     kaweth_probe
 852 ****************************************************************/
 853static void *kaweth_probe(
 854            struct usb_device *dev,             /* the device */
 855            unsigned ifnum,                      /* what interface */
 856            const struct usb_device_id *id      /* from id_table */
 857        )
 858{
 859        struct kaweth_device *kaweth;
 860        const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 861        int result = 0;
 862
 863        kaweth_dbg("Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x",
 864                 dev->devnum,
 865                 (int)dev->descriptor.idVendor,
 866                 (int)dev->descriptor.idProduct,
 867                 (int)dev->descriptor.bcdDevice);
 868
 869        kaweth_dbg("Device at %p", dev);
 870
 871        kaweth_dbg("Descriptor length: %x type: %x",
 872                 (int)dev->descriptor.bLength,
 873                 (int)dev->descriptor.bDescriptorType);
 874
 875        if(!(kaweth = kmalloc(sizeof(struct kaweth_device), GFP_KERNEL))) {
 876                kaweth_dbg("out of memory allocating device structure\n");
 877                return NULL;
 878        }
 879
 880        memset(kaweth, 0, sizeof(struct kaweth_device));
 881
 882        kaweth->dev = dev;
 883        spin_lock_init(&kaweth->device_lock);
 884        init_waitqueue_head(&kaweth->term_wait);
 885
 886        kaweth_dbg("Resetting.");
 887
 888        kaweth_reset(kaweth);
 889
 890        /*
 891         * If high byte of bcdDevice is nonzero, firmware is already
 892         * downloaded. Don't try to do it again, or we'll hang the device.
 893         */
 894
 895        if (dev->descriptor.bcdDevice >> 8) {
 896                kaweth_info("Firmware present in device.");
 897        } else {
 898                /* Download the firmware */
 899                kaweth_info("Downloading firmware...");
 900                kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
 901                if ((result = kaweth_download_firmware(kaweth,
 902                                                      kaweth_new_code,
 903                                                      len_kaweth_new_code,
 904                                                      100,
 905                                                      2)) < 0) {
 906                        kaweth_err("Error downloading firmware (%d)", result);
 907                        free_page((unsigned long)kaweth->firmware_buf);
 908                        kfree(kaweth);
 909                        return NULL;
 910                }
 911
 912                if ((result = kaweth_download_firmware(kaweth,
 913                                                      kaweth_new_code_fix,
 914                                                      len_kaweth_new_code_fix,
 915                                                      100,
 916                                                      3)) < 0) {
 917                        kaweth_err("Error downloading firmware fix (%d)", result);
 918                        free_page((unsigned long)kaweth->firmware_buf);
 919                        kfree(kaweth);
 920                        return NULL;
 921                }
 922
 923                if ((result = kaweth_download_firmware(kaweth,
 924                                                      kaweth_trigger_code,
 925                                                      len_kaweth_trigger_code,
 926                                                      126,
 927                                                      2)) < 0) {
 928                        kaweth_err("Error downloading trigger code (%d)", result);
 929                        free_page((unsigned long)kaweth->firmware_buf);
 930                        kfree(kaweth);
 931                        return NULL;
 932                }
 933
 934                if ((result = kaweth_download_firmware(kaweth,
 935                                                      kaweth_trigger_code_fix,
 936                                                      len_kaweth_trigger_code_fix,
 937                                                      126,
 938                                                      3)) < 0) {
 939                        kaweth_err("Error downloading trigger code fix (%d)", result);
 940                        free_page((unsigned long)kaweth->firmware_buf);
 941                        kfree(kaweth);
 942                        return NULL;
 943                }
 944
 945
 946                if ((result = kaweth_trigger_firmware(kaweth, 126)) < 0) {
 947                        kaweth_err("Error triggering firmware (%d)", result);
 948                        free_page((unsigned long)kaweth->firmware_buf);
 949                        kfree(kaweth);
 950                        return NULL;
 951                }
 952
 953                /* Device will now disappear for a moment...  */
 954                kaweth_info("Firmware loaded.  I'll be back...");
 955                free_page((unsigned long)kaweth->firmware_buf);
 956                kfree(kaweth);
 957                return NULL;
 958        }
 959
 960        result = kaweth_read_configuration(kaweth);
 961
 962        if(result < 0) {
 963                kaweth_err("Error reading configuration (%d), no net device created", result);
 964                kfree(kaweth);
 965                return NULL;
 966        }
 967
 968        kaweth_info("Statistics collection: %x", kaweth->configuration.statistics_mask);
 969        kaweth_info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
 970        kaweth_info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size));
 971        kaweth_info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
 972                 (int)kaweth->configuration.hw_addr[0],
 973                 (int)kaweth->configuration.hw_addr[1],
 974                 (int)kaweth->configuration.hw_addr[2],
 975                 (int)kaweth->configuration.hw_addr[3],
 976                 (int)kaweth->configuration.hw_addr[4],
 977                 (int)kaweth->configuration.hw_addr[5]);
 978
 979        if(!memcmp(&kaweth->configuration.hw_addr,
 980                   &bcast_addr,
 981                   sizeof(bcast_addr))) {
 982                kaweth_err("Firmware not functioning properly, no net device created");
 983                kfree(kaweth);
 984                return NULL;
 985        }
 986
 987        if(kaweth_set_urb_size(kaweth, KAWETH_BUF_SIZE) < 0) {
 988                kaweth_dbg("Error setting URB size");
 989                return kaweth;
 990        }
 991
 992        if(kaweth_set_sofs_wait(kaweth, KAWETH_SOFS_TO_WAIT) < 0) {
 993                kaweth_err("Error setting SOFS wait");
 994                return kaweth;
 995        }
 996
 997        result = kaweth_set_receive_filter(kaweth,
 998                                           KAWETH_PACKET_FILTER_DIRECTED |
 999                                           KAWETH_PACKET_FILTER_BROADCAST |
1000                                           KAWETH_PACKET_FILTER_MULTICAST);
1001
1002        if(result < 0) {
1003                kaweth_err("Error setting receive filter");
1004                return kaweth;
1005        }
1006
1007        kaweth_dbg("Initializing net device.");
1008
1009        kaweth->tx_urb = usb_alloc_urb(0);
1010        if (!kaweth->tx_urb)
1011                goto err_no_urb;
1012        kaweth->rx_urb = usb_alloc_urb(0);
1013        if (!kaweth->rx_urb)
1014                goto err_only_tx;
1015        kaweth->irq_urb = usb_alloc_urb(0);
1016        if (!kaweth->irq_urb)
1017                goto err_tx_and_rx;
1018
1019        kaweth->net = init_etherdev(0, 0);
1020        if (!kaweth->net) {
1021                kaweth_err("Error calling init_etherdev.");
1022                return kaweth;
1023        }
1024
1025        memcpy(kaweth->net->broadcast, &bcast_addr, sizeof(bcast_addr));
1026        memcpy(kaweth->net->dev_addr,
1027               &kaweth->configuration.hw_addr,
1028               sizeof(kaweth->configuration.hw_addr));
1029
1030        kaweth->net->priv = kaweth;
1031        kaweth->net->open = kaweth_open;
1032        kaweth->net->stop = kaweth_close;
1033
1034        kaweth->net->watchdog_timeo = KAWETH_TX_TIMEOUT;
1035        kaweth->net->tx_timeout = kaweth_tx_timeout;
1036
1037        kaweth->net->do_ioctl = kaweth_ioctl;
1038        kaweth->net->hard_start_xmit = kaweth_start_xmit;
1039        kaweth->net->set_multicast_list = kaweth_set_rx_mode;
1040        kaweth->net->get_stats = kaweth_netdev_stats;
1041        kaweth->net->mtu = le16_to_cpu(kaweth->configuration.segment_size < KAWETH_MTU ?
1042                                       kaweth->configuration.segment_size : KAWETH_MTU);
1043
1044        memset(&kaweth->stats, 0, sizeof(kaweth->stats));
1045
1046        kaweth_info("kaweth interface created at %s", kaweth->net->name);
1047
1048        kaweth_dbg("Kaweth probe returning.");
1049
1050        return kaweth;
1051
1052err_tx_and_rx:
1053        usb_free_urb(kaweth->rx_urb);
1054err_only_tx:
1055        usb_free_urb(kaweth->tx_urb);
1056err_no_urb:
1057        kfree(kaweth);
1058        return NULL;
1059}
1060
1061/****************************************************************
1062 *     kaweth_disconnect
1063 ****************************************************************/
1064static void kaweth_disconnect(struct usb_device *dev, void *ptr)
1065{
1066        struct kaweth_device *kaweth = ptr;
1067
1068        kaweth_info("Unregistering");
1069
1070        if (!kaweth) {
1071                kaweth_warn("unregistering non-existant device");
1072                return;
1073        }
1074
1075        kaweth->removed = 1;
1076        usb_unlink_urb(kaweth->irq_urb);
1077        usb_unlink_urb(kaweth->rx_urb);
1078
1079        /* we need to wait for the urb to be cancelled, if it is active */
1080        spin_lock_irq(&kaweth->device_lock);
1081        if (usb_unlink_urb(kaweth->tx_urb) == -EINPROGRESS) {
1082                spin_unlock_irq(&kaweth->device_lock);
1083                wait_event(kaweth->term_wait, kaweth->end);
1084        } else {
1085                spin_unlock_irq(&kaweth->device_lock);
1086        }
1087
1088        if(kaweth->net) {
1089                if(kaweth->net->flags & IFF_UP) {
1090                        kaweth_dbg("Closing net device");
1091                        dev_close(kaweth->net);
1092                }
1093
1094                kaweth_dbg("Unregistering net device");
1095                unregister_netdev(kaweth->net);
1096        }
1097
1098        usb_free_urb(kaweth->rx_urb);
1099        usb_free_urb(kaweth->tx_urb);
1100
1101        kfree(kaweth);
1102}
1103
1104
1105// FIXME this completion stuff is a modified clone of
1106// an OLD version of some stuff in usb.c ...
1107struct kw_api_data {
1108        wait_queue_head_t wqh;
1109        int done;
1110};
1111
1112/*-------------------------------------------------------------------*
1113 * completion handler for compatibility wrappers (sync control/bulk) *
1114 *-------------------------------------------------------------------*/
1115static void usb_api_blocking_completion(struct urb *urb)
1116{
1117        struct kw_api_data *awd = (struct kw_api_data *)urb->context;
1118
1119        awd->done=1;
1120        wake_up(&awd->wqh);
1121}
1122
1123/*-------------------------------------------------------------------*
1124 *                         COMPATIBILITY STUFF                       *
1125 *-------------------------------------------------------------------*/
1126
1127// Starts urb and waits for completion or timeout
1128static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
1129{
1130        DECLARE_WAITQUEUE(wait, current);
1131        struct kw_api_data awd;
1132        int status;
1133
1134        init_waitqueue_head(&awd.wqh);
1135        awd.done = 0;
1136
1137        set_current_state(TASK_INTERRUPTIBLE);
1138        add_wait_queue(&awd.wqh, &wait);
1139        urb->context = &awd;
1140        status = usb_submit_urb(urb);
1141        if (status) {
1142                // something went wrong
1143                usb_free_urb(urb);
1144                set_current_state(TASK_RUNNING);
1145                remove_wait_queue(&awd.wqh, &wait);
1146                return status;
1147        }
1148
1149        while (timeout && !awd.done)
1150                timeout = schedule_timeout(timeout);
1151
1152        set_current_state(TASK_RUNNING);
1153        remove_wait_queue(&awd.wqh, &wait);
1154
1155        if (!timeout) {
1156                // timeout
1157                kaweth_warn("usb_control/bulk_msg: timeout");
1158                usb_unlink_urb(urb);  // remove urb safely
1159                status = -ETIMEDOUT;
1160        }
1161        else {
1162                status = urb->status;
1163        }
1164
1165        if (actual_length) {
1166                *actual_length = urb->actual_length;
1167        }
1168
1169        usb_free_urb(urb);
1170        return status;
1171}
1172
1173/*-------------------------------------------------------------------*/
1174// returns status (negative) or length (positive)
1175int kaweth_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe,
1176                            struct usb_ctrlrequest *cmd, void *data, int len,
1177                            int timeout)
1178{
1179        struct urb *urb;
1180        int retv;
1181        int length;
1182
1183        urb = usb_alloc_urb(0);
1184        if (!urb)
1185                return -ENOMEM;
1186
1187        FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data,
1188                         len, (usb_complete_t)usb_api_blocking_completion,0);
1189
1190        retv = usb_start_wait_urb(urb, timeout, &length);
1191        if (retv < 0) {
1192                return retv;
1193        }
1194        else {
1195                return length;
1196        }
1197}
1198
1199
1200/****************************************************************
1201 *     kaweth_init
1202 ****************************************************************/
1203int __init kaweth_init(void)
1204{
1205        kaweth_dbg("Driver loading");
1206        return usb_register(&kaweth_driver);
1207}
1208
1209/****************************************************************
1210 *     kaweth_exit
1211 ****************************************************************/
1212void __exit kaweth_exit(void)
1213{
1214        usb_deregister(&kaweth_driver);
1215}
1216
1217module_init(kaweth_init);
1218module_exit(kaweth_exit);
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.