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