linux/drivers/net/wireless/p54/p54usb.c
<<
>>
Prefs
   1
   2/*
   3 * Linux device driver for USB based Prism54
   4 *
   5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
   6 *
   7 * Based on the islsm (softmac prism54) driver, which is:
   8 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 */
  14
  15#include <linux/init.h>
  16#include <linux/usb.h>
  17#include <linux/pci.h>
  18#include <linux/slab.h>
  19#include <linux/firmware.h>
  20#include <linux/etherdevice.h>
  21#include <linux/delay.h>
  22#include <linux/crc32.h>
  23#include <net/mac80211.h>
  24
  25#include "p54.h"
  26#include "lmac.h"
  27#include "p54usb.h"
  28
  29MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
  30MODULE_DESCRIPTION("Prism54 USB wireless driver");
  31MODULE_LICENSE("GPL");
  32MODULE_ALIAS("prism54usb");
  33MODULE_FIRMWARE("isl3886usb");
  34MODULE_FIRMWARE("isl3887usb");
  35
  36static struct usb_device_id p54u_table[] __devinitdata = {
  37        /* Version 1 devices (pci chip + net2280) */
  38        {USB_DEVICE(0x0506, 0x0a11)},   /* 3COM 3CRWE254G72 */
  39        {USB_DEVICE(0x06b9, 0x0120)},   /* Thomson SpeedTouch 120g */
  40        {USB_DEVICE(0x0707, 0xee06)},   /* SMC 2862W-G */
  41        {USB_DEVICE(0x07aa, 0x001c)},   /* Corega CG-WLUSB2GT */
  42        {USB_DEVICE(0x083a, 0x4501)},   /* Accton 802.11g WN4501 USB */
  43        {USB_DEVICE(0x083a, 0x4502)},   /* Siemens Gigaset USB Adapter */
  44        {USB_DEVICE(0x083a, 0x5501)},   /* Phillips CPWUA054 */
  45        {USB_DEVICE(0x0846, 0x4200)},   /* Netgear WG121 */
  46        {USB_DEVICE(0x0846, 0x4210)},   /* Netgear WG121 the second ? */
  47        {USB_DEVICE(0x0846, 0x4220)},   /* Netgear WG111 */
  48        {USB_DEVICE(0x09aa, 0x1000)},   /* Spinnaker Proto board */
  49        {USB_DEVICE(0x0cde, 0x0006)},   /* Medion 40900, Roper Europe */
  50        {USB_DEVICE(0x124a, 0x4023)},   /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
  51        {USB_DEVICE(0x1915, 0x2234)},   /* Linksys WUSB54G OEM */
  52        {USB_DEVICE(0x1915, 0x2235)},   /* Linksys WUSB54G Portable OEM */
  53        {USB_DEVICE(0x2001, 0x3701)},   /* DLink DWL-G120 Spinnaker */
  54        {USB_DEVICE(0x2001, 0x3703)},   /* DLink DWL-G122 */
  55        {USB_DEVICE(0x5041, 0x2234)},   /* Linksys WUSB54G */
  56        {USB_DEVICE(0x5041, 0x2235)},   /* Linksys WUSB54G Portable */
  57
  58        /* Version 2 devices (3887) */
  59        {USB_DEVICE(0x0471, 0x1230)},   /* Philips CPWUA054/00 */
  60        {USB_DEVICE(0x050d, 0x7050)},   /* Belkin F5D7050 ver 1000 */
  61        {USB_DEVICE(0x0572, 0x2000)},   /* Cohiba Proto board */
  62        {USB_DEVICE(0x0572, 0x2002)},   /* Cohiba Proto board */
  63        {USB_DEVICE(0x06b9, 0x0121)},   /* Thomson SpeedTouch 121g */
  64        {USB_DEVICE(0x0707, 0xee13)},   /* SMC 2862W-G version 2 */
  65        {USB_DEVICE(0x083a, 0x4521)},   /* Siemens Gigaset USB Adapter 54 version 2 */
  66        {USB_DEVICE(0x083a, 0xf503)},   /* Accton FD7050E ver 1010ec  */
  67        {USB_DEVICE(0x0846, 0x4240)},   /* Netgear WG111 (v2) */
  68        {USB_DEVICE(0x0915, 0x2000)},   /* Cohiba Proto board */
  69        {USB_DEVICE(0x0915, 0x2002)},   /* Cohiba Proto board */
  70        {USB_DEVICE(0x0baf, 0x0118)},   /* U.S. Robotics U5 802.11g Adapter*/
  71        {USB_DEVICE(0x0bf8, 0x1009)},   /* FUJITSU E-5400 USB D1700*/
  72        {USB_DEVICE(0x0cde, 0x0006)},   /* Medion MD40900 */
  73        {USB_DEVICE(0x0cde, 0x0008)},   /* Sagem XG703A */
  74        {USB_DEVICE(0x0cde, 0x0015)},   /* Zcomax XG-705A */
  75        {USB_DEVICE(0x0d8e, 0x3762)},   /* DLink DWL-G120 Cohiba */
  76        {USB_DEVICE(0x124a, 0x4025)},   /* IOGear GWU513 (GW3887IK chip) */
  77        {USB_DEVICE(0x1260, 0xee22)},   /* SMC 2862W-G version 2 */
  78        {USB_DEVICE(0x13b1, 0x000a)},   /* Linksys WUSB54G ver 2 */
  79        {USB_DEVICE(0x13B1, 0x000C)},   /* Linksys WUSB54AG */
  80        {USB_DEVICE(0x1413, 0x5400)},   /* Telsey 802.11g USB2.0 Adapter */
  81        {USB_DEVICE(0x1435, 0x0427)},   /* Inventel UR054G */
  82        {USB_DEVICE(0x2001, 0x3704)},   /* DLink DWL-G122 rev A2 */
  83        {USB_DEVICE(0x413c, 0x8102)},   /* Spinnaker DUT */
  84        {USB_DEVICE(0x413c, 0x8104)},   /* Cohiba Proto board */
  85        {}
  86};
  87
  88MODULE_DEVICE_TABLE(usb, p54u_table);
  89
  90static const struct {
  91        u32 intf;
  92        enum p54u_hw_type type;
  93        const char *fw;
  94        const char *fw_legacy;
  95        char hw[20];
  96} p54u_fwlist[__NUM_P54U_HWTYPES] = {
  97        {
  98                .type = P54U_NET2280,
  99                .intf = FW_LM86,
 100                .fw = "isl3886usb",
 101                .fw_legacy = "isl3890usb",
 102                .hw = "ISL3886 + net2280",
 103        },
 104        {
 105                .type = P54U_3887,
 106                .intf = FW_LM87,
 107                .fw = "isl3887usb",
 108                .fw_legacy = "isl3887usb_bare",
 109                .hw = "ISL3887",
 110        },
 111};
 112
 113static void p54u_rx_cb(struct urb *urb)
 114{
 115        struct sk_buff *skb = (struct sk_buff *) urb->context;
 116        struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
 117        struct ieee80211_hw *dev = info->dev;
 118        struct p54u_priv *priv = dev->priv;
 119
 120        skb_unlink(skb, &priv->rx_queue);
 121
 122        if (unlikely(urb->status)) {
 123                dev_kfree_skb_irq(skb);
 124                return;
 125        }
 126
 127        skb_put(skb, urb->actual_length);
 128
 129        if (priv->hw_type == P54U_NET2280)
 130                skb_pull(skb, priv->common.tx_hdr_len);
 131        if (priv->common.fw_interface == FW_LM87) {
 132                skb_pull(skb, 4);
 133                skb_put(skb, 4);
 134        }
 135
 136        if (p54_rx(dev, skb)) {
 137                skb = dev_alloc_skb(priv->common.rx_mtu + 32);
 138                if (unlikely(!skb)) {
 139                        /* TODO check rx queue length and refill *somewhere* */
 140                        return;
 141                }
 142
 143                info = (struct p54u_rx_info *) skb->cb;
 144                info->urb = urb;
 145                info->dev = dev;
 146                urb->transfer_buffer = skb_tail_pointer(skb);
 147                urb->context = skb;
 148        } else {
 149                if (priv->hw_type == P54U_NET2280)
 150                        skb_push(skb, priv->common.tx_hdr_len);
 151                if (priv->common.fw_interface == FW_LM87) {
 152                        skb_push(skb, 4);
 153                        skb_put(skb, 4);
 154                }
 155                skb_reset_tail_pointer(skb);
 156                skb_trim(skb, 0);
 157                urb->transfer_buffer = skb_tail_pointer(skb);
 158        }
 159        skb_queue_tail(&priv->rx_queue, skb);
 160        usb_anchor_urb(urb, &priv->submitted);
 161        if (usb_submit_urb(urb, GFP_ATOMIC)) {
 162                skb_unlink(skb, &priv->rx_queue);
 163                usb_unanchor_urb(urb);
 164                dev_kfree_skb_irq(skb);
 165        }
 166}
 167
 168static void p54u_tx_cb(struct urb *urb)
 169{
 170        struct sk_buff *skb = urb->context;
 171        struct ieee80211_hw *dev = (struct ieee80211_hw *)
 172                usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
 173
 174        p54_free_skb(dev, skb);
 175}
 176
 177static void p54u_tx_dummy_cb(struct urb *urb) { }
 178
 179static void p54u_free_urbs(struct ieee80211_hw *dev)
 180{
 181        struct p54u_priv *priv = dev->priv;
 182        usb_kill_anchored_urbs(&priv->submitted);
 183}
 184
 185static int p54u_init_urbs(struct ieee80211_hw *dev)
 186{
 187        struct p54u_priv *priv = dev->priv;
 188        struct urb *entry = NULL;
 189        struct sk_buff *skb;
 190        struct p54u_rx_info *info;
 191        int ret = 0;
 192
 193        while (skb_queue_len(&priv->rx_queue) < 32) {
 194                skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);
 195                if (!skb) {
 196                        ret = -ENOMEM;
 197                        goto err;
 198                }
 199                entry = usb_alloc_urb(0, GFP_KERNEL);
 200                if (!entry) {
 201                        ret = -ENOMEM;
 202                        goto err;
 203                }
 204
 205                usb_fill_bulk_urb(entry, priv->udev,
 206                                  usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
 207                                  skb_tail_pointer(skb),
 208                                  priv->common.rx_mtu + 32, p54u_rx_cb, skb);
 209                info = (struct p54u_rx_info *) skb->cb;
 210                info->urb = entry;
 211                info->dev = dev;
 212                skb_queue_tail(&priv->rx_queue, skb);
 213
 214                usb_anchor_urb(entry, &priv->submitted);
 215                ret = usb_submit_urb(entry, GFP_KERNEL);
 216                if (ret) {
 217                        skb_unlink(skb, &priv->rx_queue);
 218                        usb_unanchor_urb(entry);
 219                        goto err;
 220                }
 221                usb_free_urb(entry);
 222                entry = NULL;
 223        }
 224
 225        return 0;
 226
 227 err:
 228        usb_free_urb(entry);
 229        kfree_skb(skb);
 230        p54u_free_urbs(dev);
 231        return ret;
 232}
 233
 234static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
 235{
 236        u32 chk = 0;
 237
 238        length >>= 2;
 239        while (length--) {
 240                chk ^= le32_to_cpu(*data++);
 241                chk = (chk >> 5) ^ (chk << 3);
 242        }
 243
 244        return cpu_to_le32(chk);
 245}
 246
 247static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
 248{
 249        struct p54u_priv *priv = dev->priv;
 250        struct urb *data_urb;
 251        struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
 252
 253        data_urb = usb_alloc_urb(0, GFP_ATOMIC);
 254        if (!data_urb) {
 255                p54_free_skb(dev, skb);
 256                return;
 257        }
 258
 259        hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
 260        hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
 261
 262        usb_fill_bulk_urb(data_urb, priv->udev,
 263                          usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
 264                          hdr, skb->len + sizeof(*hdr),  FREE_AFTER_TX(skb) ?
 265                          p54u_tx_cb : p54u_tx_dummy_cb, skb);
 266        data_urb->transfer_flags |= URB_ZERO_PACKET;
 267
 268        usb_anchor_urb(data_urb, &priv->submitted);
 269        if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
 270                usb_unanchor_urb(data_urb);
 271                p54_free_skb(dev, skb);
 272        }
 273        usb_free_urb(data_urb);
 274}
 275
 276static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
 277{
 278        struct p54u_priv *priv = dev->priv;
 279        struct urb *int_urb = NULL, *data_urb = NULL;
 280        struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
 281        struct net2280_reg_write *reg = NULL;
 282        int err = -ENOMEM;
 283
 284        reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
 285        if (!reg)
 286                goto out;
 287
 288        int_urb = usb_alloc_urb(0, GFP_ATOMIC);
 289        if (!int_urb)
 290                goto out;
 291
 292        data_urb = usb_alloc_urb(0, GFP_ATOMIC);
 293        if (!data_urb)
 294                goto out;
 295
 296        reg->port = cpu_to_le16(NET2280_DEV_U32);
 297        reg->addr = cpu_to_le32(P54U_DEV_BASE);
 298        reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
 299
 300        memset(hdr, 0, sizeof(*hdr));
 301        hdr->len = cpu_to_le16(skb->len);
 302        hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id;
 303
 304        usb_fill_bulk_urb(int_urb, priv->udev,
 305                usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
 306                p54u_tx_dummy_cb, dev);
 307
 308        /*
 309         * URB_FREE_BUFFER triggers a code path in the USB subsystem that will
 310         * free what is inside the transfer_buffer after the last reference to
 311         * the int_urb is dropped.
 312         */
 313        int_urb->transfer_flags |= URB_FREE_BUFFER | URB_ZERO_PACKET;
 314        reg = NULL;
 315
 316        usb_fill_bulk_urb(data_urb, priv->udev,
 317                          usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
 318                          hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
 319                          p54u_tx_cb : p54u_tx_dummy_cb, skb);
 320        data_urb->transfer_flags |= URB_ZERO_PACKET;
 321
 322        usb_anchor_urb(int_urb, &priv->submitted);
 323        err = usb_submit_urb(int_urb, GFP_ATOMIC);
 324        if (err) {
 325                usb_unanchor_urb(int_urb);
 326                goto out;
 327        }
 328
 329        usb_anchor_urb(data_urb, &priv->submitted);
 330        err = usb_submit_urb(data_urb, GFP_ATOMIC);
 331        if (err) {
 332                usb_unanchor_urb(data_urb);
 333                goto out;
 334        }
 335out:
 336        usb_free_urb(int_urb);
 337        usb_free_urb(data_urb);
 338
 339        if (err) {
 340                kfree(reg);
 341                p54_free_skb(dev, skb);
 342        }
 343}
 344
 345static int p54u_write(struct p54u_priv *priv,
 346                      struct net2280_reg_write *buf,
 347                      enum net2280_op_type type,
 348                      __le32 addr, __le32 val)
 349{
 350        unsigned int ep;
 351        int alen;
 352
 353        if (type & 0x0800)
 354                ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
 355        else
 356                ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
 357
 358        buf->port = cpu_to_le16(type);
 359        buf->addr = addr;
 360        buf->val = val;
 361
 362        return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
 363}
 364
 365static int p54u_read(struct p54u_priv *priv, void *buf,
 366                     enum net2280_op_type type,
 367                     __le32 addr, __le32 *val)
 368{
 369        struct net2280_reg_read *read = buf;
 370        __le32 *reg = buf;
 371        unsigned int ep;
 372        int alen, err;
 373
 374        if (type & 0x0800)
 375                ep = P54U_PIPE_DEV;
 376        else
 377                ep = P54U_PIPE_BRG;
 378
 379        read->port = cpu_to_le16(type);
 380        read->addr = addr;
 381
 382        err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
 383                           read, sizeof(*read), &alen, 1000);
 384        if (err)
 385                return err;
 386
 387        err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
 388                           reg, sizeof(*reg), &alen, 1000);
 389        if (err)
 390                return err;
 391
 392        *val = *reg;
 393        return 0;
 394}
 395
 396static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
 397                         void *data, size_t len)
 398{
 399        int alen;
 400        return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
 401                            data, len, &alen, 2000);
 402}
 403
 404static int p54u_device_reset(struct ieee80211_hw *dev)
 405{
 406        struct p54u_priv *priv = dev->priv;
 407        int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING);
 408
 409        if (lock) {
 410                ret = usb_lock_device_for_reset(priv->udev, priv->intf);
 411                if (ret < 0) {
 412                        dev_err(&priv->udev->dev, "(p54usb) unable to lock "
 413                                "device for reset (%d)!\n", ret);
 414                        return ret;
 415                }
 416        }
 417
 418        ret = usb_reset_device(priv->udev);
 419        if (lock)
 420                usb_unlock_device(priv->udev);
 421
 422        if (ret)
 423                dev_err(&priv->udev->dev, "(p54usb) unable to reset "
 424                        "device (%d)!\n", ret);
 425
 426        return ret;
 427}
 428
 429static const char p54u_romboot_3887[] = "~~~~";
 430static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
 431{
 432        struct p54u_priv *priv = dev->priv;
 433        u8 *buf;
 434        int ret;
 435
 436        buf = kmalloc(4, GFP_KERNEL);
 437        if (!buf)
 438                return -ENOMEM;
 439        memcpy(buf, p54u_romboot_3887, 4);
 440        ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
 441                            buf, 4);
 442        kfree(buf);
 443        if (ret)
 444                dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
 445                        "boot ROM (%d)!\n", ret);
 446
 447        return ret;
 448}
 449
 450static const char p54u_firmware_upload_3887[] = "<\r";
 451static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
 452{
 453        struct p54u_priv *priv = dev->priv;
 454        int err, alen;
 455        u8 carry = 0;
 456        u8 *buf, *tmp;
 457        const u8 *data;
 458        unsigned int left, remains, block_size;
 459        struct x2_header *hdr;
 460        unsigned long timeout;
 461
 462        err = p54u_firmware_reset_3887(dev);
 463        if (err)
 464                return err;
 465
 466        tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
 467        if (!buf) {
 468                dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware"
 469                                          "upload buffer!\n");
 470                return -ENOMEM;
 471        }
 472
 473        left = block_size = min((size_t)P54U_FW_BLOCK, priv->fw->size);
 474        strcpy(buf, p54u_firmware_upload_3887);
 475        left -= strlen(p54u_firmware_upload_3887);
 476        tmp += strlen(p54u_firmware_upload_3887);
 477
 478        data = priv->fw->data;
 479        remains = priv->fw->size;
 480
 481        hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887));
 482        memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
 483        hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
 484        hdr->fw_length = cpu_to_le32(priv->fw->size);
 485        hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
 486                                         sizeof(u32)*2));
 487        left -= sizeof(*hdr);
 488        tmp += sizeof(*hdr);
 489
 490        while (remains) {
 491                while (left--) {
 492                        if (carry) {
 493                                *tmp++ = carry;
 494                                carry = 0;
 495                                remains--;
 496                                continue;
 497                        }
 498                        switch (*data) {
 499                        case '~':
 500                                *tmp++ = '}';
 501                                carry = '^';
 502                                break;
 503                        case '}':
 504                                *tmp++ = '}';
 505                                carry = ']';
 506                                break;
 507                        default:
 508                                *tmp++ = *data;
 509                                remains--;
 510                                break;
 511                        }
 512                        data++;
 513                }
 514
 515                err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
 516                if (err) {
 517                        dev_err(&priv->udev->dev, "(p54usb) firmware "
 518                                                  "upload failed!\n");
 519                        goto err_upload_failed;
 520                }
 521
 522                tmp = buf;
 523                left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
 524        }
 525
 526        *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, priv->fw->data,
 527                                                 priv->fw->size));
 528        err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
 529        if (err) {
 530                dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
 531                goto err_upload_failed;
 532        }
 533        timeout = jiffies + msecs_to_jiffies(1000);
 534        while (!(err = usb_bulk_msg(priv->udev,
 535                usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
 536                if (alen > 2 && !memcmp(buf, "OK", 2))
 537                        break;
 538
 539                if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
 540                        err = -EINVAL;
 541                        break;
 542                }
 543
 544                if (time_after(jiffies, timeout)) {
 545                        dev_err(&priv->udev->dev, "(p54usb) firmware boot "
 546                                                  "timed out!\n");
 547                        err = -ETIMEDOUT;
 548                        break;
 549                }
 550        }
 551        if (err) {
 552                dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
 553                goto err_upload_failed;
 554        }
 555
 556        buf[0] = 'g';
 557        buf[1] = '\r';
 558        err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
 559        if (err) {
 560                dev_err(&priv->udev->dev, "(p54usb) firmware boot failed!\n");
 561                goto err_upload_failed;
 562        }
 563
 564        timeout = jiffies + msecs_to_jiffies(1000);
 565        while (!(err = usb_bulk_msg(priv->udev,
 566                usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
 567                if (alen > 0 && buf[0] == 'g')
 568                        break;
 569
 570                if (time_after(jiffies, timeout)) {
 571                        err = -ETIMEDOUT;
 572                        break;
 573                }
 574        }
 575        if (err)
 576                goto err_upload_failed;
 577
 578err_upload_failed:
 579        kfree(buf);
 580        return err;
 581}
 582
 583static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
 584{
 585        struct p54u_priv *priv = dev->priv;
 586        const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
 587        int err, alen;
 588        void *buf;
 589        __le32 reg;
 590        unsigned int remains, offset;
 591        const u8 *data;
 592
 593        buf = kmalloc(512, GFP_KERNEL);
 594        if (!buf) {
 595                dev_err(&priv->udev->dev, "(p54usb) firmware buffer "
 596                                          "alloc failed!\n");
 597                return -ENOMEM;
 598        }
 599
 600#define P54U_WRITE(type, addr, data) \
 601        do {\
 602                err = p54u_write(priv, buf, type,\
 603                                 cpu_to_le32((u32)(unsigned long)addr), data);\
 604                if (err) \
 605                        goto fail;\
 606        } while (0)
 607
 608#define P54U_READ(type, addr) \
 609        do {\
 610                err = p54u_read(priv, buf, type,\
 611                                cpu_to_le32((u32)(unsigned long)addr), &reg);\
 612                if (err)\
 613                        goto fail;\
 614        } while (0)
 615
 616        /* power down net2280 bridge */
 617        P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
 618        reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
 619        reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
 620        P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
 621
 622        mdelay(100);
 623
 624        /* power up bridge */
 625        reg |= cpu_to_le32(P54U_BRG_POWER_UP);
 626        reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
 627        P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
 628
 629        mdelay(100);
 630
 631        P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
 632                   cpu_to_le32(NET2280_CLK_30Mhz |
 633                               NET2280_PCI_ENABLE |
 634                               NET2280_PCI_SOFT_RESET));
 635
 636        mdelay(20);
 637
 638        P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
 639                   cpu_to_le32(PCI_COMMAND_MEMORY |
 640                               PCI_COMMAND_MASTER));
 641
 642        P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
 643                   cpu_to_le32(NET2280_BASE));
 644
 645        P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
 646        reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
 647        P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
 648
 649        // TODO: we really need this?
 650        P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
 651
 652        P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
 653                   cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
 654        P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
 655                   cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
 656
 657        P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
 658                   cpu_to_le32(NET2280_BASE2));
 659
 660        /* finally done setting up the bridge */
 661
 662        P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
 663                   cpu_to_le32(PCI_COMMAND_MEMORY |
 664                               PCI_COMMAND_MASTER));
 665
 666        P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
 667        P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
 668                   cpu_to_le32(P54U_DEV_BASE));
 669
 670        P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
 671        P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
 672                   cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
 673
 674        /* do romboot */
 675        P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
 676
 677        P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
 678        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
 679        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
 680        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
 681        P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
 682
 683        mdelay(20);
 684
 685        reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
 686        P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
 687
 688        mdelay(20);
 689
 690        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
 691        P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
 692
 693        mdelay(100);
 694
 695        P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
 696        P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
 697
 698        /* finally, we can upload firmware now! */
 699        remains = priv->fw->size;
 700        data = priv->fw->data;
 701        offset = ISL38XX_DEV_FIRMWARE_ADDR;
 702
 703        while (remains) {
 704                unsigned int block_len = min(remains, (unsigned int)512);
 705                memcpy(buf, data, block_len);
 706
 707                err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
 708                if (err) {
 709                        dev_err(&priv->udev->dev, "(p54usb) firmware block "
 710                                                  "upload failed\n");
 711                        goto fail;
 712                }
 713
 714                P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
 715                           cpu_to_le32(0xc0000f00));
 716
 717                P54U_WRITE(NET2280_DEV_U32,
 718                           0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
 719                P54U_WRITE(NET2280_DEV_U32,
 720                           0x0020 | (unsigned long)&devreg->direct_mem_win,
 721                           cpu_to_le32(1));
 722
 723                P54U_WRITE(NET2280_DEV_U32,
 724                           0x0024 | (unsigned long)&devreg->direct_mem_win,
 725                           cpu_to_le32(block_len));
 726                P54U_WRITE(NET2280_DEV_U32,
 727                           0x0028 | (unsigned long)&devreg->direct_mem_win,
 728                           cpu_to_le32(offset));
 729
 730                P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
 731                           cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
 732                P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
 733                           cpu_to_le32(block_len >> 2));
 734                P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
 735                           cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
 736
 737                mdelay(10);
 738
 739                P54U_READ(NET2280_DEV_U32,
 740                          0x002C | (unsigned long)&devreg->direct_mem_win);
 741                if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
 742                    !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
 743                        dev_err(&priv->udev->dev, "(p54usb) firmware DMA "
 744                                                  "transfer failed\n");
 745                        goto fail;
 746                }
 747
 748                P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
 749                           cpu_to_le32(NET2280_FIFO_FLUSH));
 750
 751                remains -= block_len;
 752                data += block_len;
 753                offset += block_len;
 754        }
 755
 756        /* do ramboot */
 757        P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
 758        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
 759        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
 760        reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
 761        P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
 762
 763        mdelay(20);
 764
 765        reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
 766        P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
 767
 768        reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
 769        P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
 770
 771        mdelay(100);
 772
 773        P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
 774        P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
 775
 776        /* start up the firmware */
 777        P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
 778                   cpu_to_le32(ISL38XX_INT_IDENT_INIT));
 779
 780        P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
 781                   cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
 782
 783        P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
 784                   cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
 785                               NET2280_USB_INTERRUPT_ENABLE));
 786
 787        P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
 788                   cpu_to_le32(ISL38XX_DEV_INT_RESET));
 789
 790        err = usb_interrupt_msg(priv->udev,
 791                                usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
 792                                buf, sizeof(__le32), &alen, 1000);
 793        if (err || alen != sizeof(__le32))
 794                goto fail;
 795
 796        P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
 797        P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
 798
 799        if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
 800                err = -EINVAL;
 801
 802        P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
 803        P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
 804                   cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
 805
 806#undef P54U_WRITE
 807#undef P54U_READ
 808
 809fail:
 810        kfree(buf);
 811        return err;
 812}
 813
 814static int p54u_load_firmware(struct ieee80211_hw *dev)
 815{
 816        struct p54u_priv *priv = dev->priv;
 817        int err, i;
 818
 819        BUILD_BUG_ON(ARRAY_SIZE(p54u_fwlist) != __NUM_P54U_HWTYPES);
 820
 821        for (i = 0; i < __NUM_P54U_HWTYPES; i++)
 822                if (p54u_fwlist[i].type == priv->hw_type)
 823                        break;
 824
 825        if (i == __NUM_P54U_HWTYPES)
 826                return -EOPNOTSUPP;
 827
 828        err = request_firmware(&priv->fw, p54u_fwlist[i].fw, &priv->udev->dev);
 829        if (err) {
 830                dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s "
 831                                          "(%d)!\n", p54u_fwlist[i].fw, err);
 832
 833                err = request_firmware(&priv->fw, p54u_fwlist[i].fw_legacy,
 834                                       &priv->udev->dev);
 835                if (err)
 836                        return err;
 837        }
 838
 839        err = p54_parse_firmware(dev, priv->fw);
 840        if (err)
 841                goto out;
 842
 843        if (priv->common.fw_interface != p54u_fwlist[i].intf) {
 844                dev_err(&priv->udev->dev, "wrong firmware, please get "
 845                        "a firmware for \"%s\" and try again.\n",
 846                        p54u_fwlist[i].hw);
 847                err = -EINVAL;
 848        }
 849
 850out:
 851        if (err)
 852                release_firmware(priv->fw);
 853
 854        return err;
 855}
 856
 857static int p54u_open(struct ieee80211_hw *dev)
 858{
 859        struct p54u_priv *priv = dev->priv;
 860        int err;
 861
 862        err = p54u_init_urbs(dev);
 863        if (err) {
 864                return err;
 865        }
 866
 867        priv->common.open = p54u_init_urbs;
 868
 869        return 0;
 870}
 871
 872static void p54u_stop(struct ieee80211_hw *dev)
 873{
 874        /* TODO: figure out how to reliably stop the 3887 and net2280 so
 875           the hardware is still usable next time we want to start it.
 876           until then, we just stop listening to the hardware.. */
 877        p54u_free_urbs(dev);
 878        return;
 879}
 880
 881static int __devinit p54u_probe(struct usb_interface *intf,
 882                                const struct usb_device_id *id)
 883{
 884        struct usb_device *udev = interface_to_usbdev(intf);
 885        struct ieee80211_hw *dev;
 886        struct p54u_priv *priv;
 887        int err;
 888        unsigned int i, recognized_pipes;
 889
 890        dev = p54_init_common(sizeof(*priv));
 891
 892        if (!dev) {
 893                dev_err(&udev->dev, "(p54usb) ieee80211 alloc failed\n");
 894                return -ENOMEM;
 895        }
 896
 897        priv = dev->priv;
 898        priv->hw_type = P54U_INVALID_HW;
 899
 900        SET_IEEE80211_DEV(dev, &intf->dev);
 901        usb_set_intfdata(intf, dev);
 902        priv->udev = udev;
 903        priv->intf = intf;
 904        skb_queue_head_init(&priv->rx_queue);
 905        init_usb_anchor(&priv->submitted);
 906
 907        usb_get_dev(udev);
 908
 909        /* really lazy and simple way of figuring out if we're a 3887 */
 910        /* TODO: should just stick the identification in the device table */
 911        i = intf->altsetting->desc.bNumEndpoints;
 912        recognized_pipes = 0;
 913        while (i--) {
 914                switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
 915                case P54U_PIPE_DATA:
 916                case P54U_PIPE_MGMT:
 917                case P54U_PIPE_BRG:
 918                case P54U_PIPE_DEV:
 919                case P54U_PIPE_DATA | USB_DIR_IN:
 920                case P54U_PIPE_MGMT | USB_DIR_IN:
 921                case P54U_PIPE_BRG | USB_DIR_IN:
 922                case P54U_PIPE_DEV | USB_DIR_IN:
 923                case P54U_PIPE_INT | USB_DIR_IN:
 924                        recognized_pipes++;
 925                }
 926        }
 927        priv->common.open = p54u_open;
 928        priv->common.stop = p54u_stop;
 929        if (recognized_pipes < P54U_PIPE_NUMBER) {
 930#ifdef CONFIG_PM
 931                /* ISL3887 needs a full reset on resume */
 932                udev->reset_resume = 1;
 933                err = p54u_device_reset(dev);
 934#endif
 935
 936                priv->hw_type = P54U_3887;
 937                dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
 938                priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
 939                priv->common.tx = p54u_tx_lm87;
 940                priv->upload_fw = p54u_upload_firmware_3887;
 941        } else {
 942                priv->hw_type = P54U_NET2280;
 943                dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
 944                priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
 945                priv->common.tx = p54u_tx_net2280;
 946                priv->upload_fw = p54u_upload_firmware_net2280;
 947        }
 948        err = p54u_load_firmware(dev);
 949        if (err)
 950                goto err_free_dev;
 951
 952        err = priv->upload_fw(dev);
 953        if (err)
 954                goto err_free_fw;
 955
 956        p54u_open(dev);
 957        err = p54_read_eeprom(dev);
 958        p54u_stop(dev);
 959        if (err)
 960                goto err_free_fw;
 961
 962        err = p54_register_common(dev, &udev->dev);
 963        if (err)
 964                goto err_free_fw;
 965
 966        return 0;
 967
 968err_free_fw:
 969        release_firmware(priv->fw);
 970
 971err_free_dev:
 972        p54_free_common(dev);
 973        usb_set_intfdata(intf, NULL);
 974        usb_put_dev(udev);
 975        return err;
 976}
 977
 978static void __devexit p54u_disconnect(struct usb_interface *intf)
 979{
 980        struct ieee80211_hw *dev = usb_get_intfdata(intf);
 981        struct p54u_priv *priv;
 982
 983        if (!dev)
 984                return;
 985
 986        p54_unregister_common(dev);
 987
 988        priv = dev->priv;
 989        usb_put_dev(interface_to_usbdev(intf));
 990        release_firmware(priv->fw);
 991        p54_free_common(dev);
 992}
 993
 994static int p54u_pre_reset(struct usb_interface *intf)
 995{
 996        struct ieee80211_hw *dev = usb_get_intfdata(intf);
 997
 998        if (!dev)
 999                return -ENODEV;
1000
1001        p54u_stop(dev);
1002        return 0;
1003}
1004
1005static int p54u_resume(struct usb_interface *intf)
1006{
1007        struct ieee80211_hw *dev = usb_get_intfdata(intf);
1008        struct p54u_priv *priv;
1009
1010        if (!dev)
1011                return -ENODEV;
1012
1013        priv = dev->priv;
1014        if (unlikely(!(priv->upload_fw && priv->fw)))
1015                return 0;
1016
1017        return priv->upload_fw(dev);
1018}
1019
1020static int p54u_post_reset(struct usb_interface *intf)
1021{
1022        struct ieee80211_hw *dev = usb_get_intfdata(intf);
1023        struct p54u_priv *priv;
1024        int err;
1025
1026        err = p54u_resume(intf);
1027        if (err)
1028                return err;
1029
1030        /* reinitialize old device state */
1031        priv = dev->priv;
1032        if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED)
1033                ieee80211_restart_hw(dev);
1034
1035        return 0;
1036}
1037
1038#ifdef CONFIG_PM
1039
1040static int p54u_suspend(struct usb_interface *intf, pm_message_t message)
1041{
1042        return p54u_pre_reset(intf);
1043}
1044
1045#endif /* CONFIG_PM */
1046
1047static struct usb_driver p54u_driver = {
1048        .name   = "p54usb",
1049        .id_table = p54u_table,
1050        .probe = p54u_probe,
1051        .disconnect = p54u_disconnect,
1052        .pre_reset = p54u_pre_reset,
1053        .post_reset = p54u_post_reset,
1054#ifdef CONFIG_PM
1055        .suspend = p54u_suspend,
1056        .resume = p54u_resume,
1057        .reset_resume = p54u_resume,
1058#endif /* CONFIG_PM */
1059        .soft_unbind = 1,
1060};
1061
1062static int __init p54u_init(void)
1063{
1064        return usb_register(&p54u_driver);
1065}
1066
1067static void __exit p54u_exit(void)
1068{
1069        usb_deregister(&p54u_driver);
1070}
1071
1072module_init(p54u_init);
1073module_exit(p54u_exit);
1074
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.