~ubuntu-branches/ubuntu/natty/linux-backports-modules-2.6.38/natty-proposed

« back to all changes in this revision

Viewing changes to updates/compat-wireless-2.6.36/drivers/net/wireless/p54/p54usb.c

  • Committer: Bazaar Package Importer
  • Author(s): Tim Gardner, Tim Gardner
  • Date: 2011-06-08 10:44:09 UTC
  • Revision ID: james.westby@ubuntu.com-20110608104409-fnl8carkdo15bwsz
Tags: 2.6.38-10.6
[ Tim Gardner ]

Shorten compat-wireless package name to cw to accomodate
CDROM file name length restrictions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
29
 
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
30
 
MODULE_DESCRIPTION("Prism54 USB wireless driver");
31
 
MODULE_LICENSE("GPL");
32
 
MODULE_ALIAS("prism54usb");
33
 
MODULE_FIRMWARE("isl3886usb");
34
 
MODULE_FIRMWARE("isl3887usb");
35
 
 
36
 
static 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 already listed above,
73
 
                                         * just noting it here for clarity */
74
 
        {USB_DEVICE(0x0cde, 0x0008)},   /* Sagem XG703A */
75
 
        {USB_DEVICE(0x0cde, 0x0015)},   /* Zcomax XG-705A */
76
 
        {USB_DEVICE(0x0d8e, 0x3762)},   /* DLink DWL-G120 Cohiba */
77
 
        {USB_DEVICE(0x124a, 0x4025)},   /* IOGear GWU513 (GW3887IK chip) */
78
 
        {USB_DEVICE(0x1260, 0xee22)},   /* SMC 2862W-G version 2 */
79
 
        {USB_DEVICE(0x13b1, 0x000a)},   /* Linksys WUSB54G ver 2 */
80
 
        {USB_DEVICE(0x13B1, 0x000C)},   /* Linksys WUSB54AG */
81
 
        {USB_DEVICE(0x1413, 0x5400)},   /* Telsey 802.11g USB2.0 Adapter */
82
 
        {USB_DEVICE(0x1435, 0x0427)},   /* Inventel UR054G */
83
 
        {USB_DEVICE(0x2001, 0x3704)},   /* DLink DWL-G122 rev A2 */
84
 
        {USB_DEVICE(0x413c, 0x5513)},   /* Dell WLA3310 USB Wireless Adapter */
85
 
        {USB_DEVICE(0x413c, 0x8102)},   /* Spinnaker DUT */
86
 
        {USB_DEVICE(0x413c, 0x8104)},   /* Cohiba Proto board */
87
 
        {}
88
 
};
89
 
 
90
 
MODULE_DEVICE_TABLE(usb, p54u_table);
91
 
 
92
 
static const struct {
93
 
        u32 intf;
94
 
        enum p54u_hw_type type;
95
 
        const char *fw;
96
 
        const char *fw_legacy;
97
 
        char hw[20];
98
 
} p54u_fwlist[__NUM_P54U_HWTYPES] = {
99
 
        {
100
 
                .type = P54U_NET2280,
101
 
                .intf = FW_LM86,
102
 
                .fw = "isl3886usb",
103
 
                .fw_legacy = "isl3890usb",
104
 
                .hw = "ISL3886 + net2280",
105
 
        },
106
 
        {
107
 
                .type = P54U_3887,
108
 
                .intf = FW_LM87,
109
 
                .fw = "isl3887usb",
110
 
                .fw_legacy = "isl3887usb_bare",
111
 
                .hw = "ISL3887",
112
 
        },
113
 
};
114
 
 
115
 
static void p54u_rx_cb(struct urb *urb)
116
 
{
117
 
        struct sk_buff *skb = (struct sk_buff *) urb->context;
118
 
        struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
119
 
        struct ieee80211_hw *dev = info->dev;
120
 
        struct p54u_priv *priv = dev->priv;
121
 
 
122
 
        skb_unlink(skb, &priv->rx_queue);
123
 
 
124
 
        if (unlikely(urb->status)) {
125
 
                dev_kfree_skb_irq(skb);
126
 
                return;
127
 
        }
128
 
 
129
 
        skb_put(skb, urb->actual_length);
130
 
 
131
 
        if (priv->hw_type == P54U_NET2280)
132
 
                skb_pull(skb, priv->common.tx_hdr_len);
133
 
        if (priv->common.fw_interface == FW_LM87) {
134
 
                skb_pull(skb, 4);
135
 
                skb_put(skb, 4);
136
 
        }
137
 
 
138
 
        if (p54_rx(dev, skb)) {
139
 
                skb = dev_alloc_skb(priv->common.rx_mtu + 32);
140
 
                if (unlikely(!skb)) {
141
 
                        /* TODO check rx queue length and refill *somewhere* */
142
 
                        return;
143
 
                }
144
 
 
145
 
                info = (struct p54u_rx_info *) skb->cb;
146
 
                info->urb = urb;
147
 
                info->dev = dev;
148
 
                urb->transfer_buffer = skb_tail_pointer(skb);
149
 
                urb->context = skb;
150
 
        } else {
151
 
                if (priv->hw_type == P54U_NET2280)
152
 
                        skb_push(skb, priv->common.tx_hdr_len);
153
 
                if (priv->common.fw_interface == FW_LM87) {
154
 
                        skb_push(skb, 4);
155
 
                        skb_put(skb, 4);
156
 
                }
157
 
                skb_reset_tail_pointer(skb);
158
 
                skb_trim(skb, 0);
159
 
                urb->transfer_buffer = skb_tail_pointer(skb);
160
 
        }
161
 
        skb_queue_tail(&priv->rx_queue, skb);
162
 
        usb_anchor_urb(urb, &priv->submitted);
163
 
        if (usb_submit_urb(urb, GFP_ATOMIC)) {
164
 
                skb_unlink(skb, &priv->rx_queue);
165
 
                usb_unanchor_urb(urb);
166
 
                dev_kfree_skb_irq(skb);
167
 
        }
168
 
}
169
 
 
170
 
static void p54u_tx_cb(struct urb *urb)
171
 
{
172
 
        struct sk_buff *skb = urb->context;
173
 
        struct ieee80211_hw *dev = (struct ieee80211_hw *)
174
 
                usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
175
 
 
176
 
        p54_free_skb(dev, skb);
177
 
}
178
 
 
179
 
static void p54u_tx_dummy_cb(struct urb *urb) { }
180
 
 
181
 
static void p54u_free_urbs(struct ieee80211_hw *dev)
182
 
{
183
 
        struct p54u_priv *priv = dev->priv;
184
 
        usb_kill_anchored_urbs(&priv->submitted);
185
 
}
186
 
 
187
 
static int p54u_init_urbs(struct ieee80211_hw *dev)
188
 
{
189
 
        struct p54u_priv *priv = dev->priv;
190
 
        struct urb *entry = NULL;
191
 
        struct sk_buff *skb;
192
 
        struct p54u_rx_info *info;
193
 
        int ret = 0;
194
 
 
195
 
        while (skb_queue_len(&priv->rx_queue) < 32) {
196
 
                skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL);
197
 
                if (!skb) {
198
 
                        ret = -ENOMEM;
199
 
                        goto err;
200
 
                }
201
 
                entry = usb_alloc_urb(0, GFP_KERNEL);
202
 
                if (!entry) {
203
 
                        ret = -ENOMEM;
204
 
                        goto err;
205
 
                }
206
 
 
207
 
                usb_fill_bulk_urb(entry, priv->udev,
208
 
                                  usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
209
 
                                  skb_tail_pointer(skb),
210
 
                                  priv->common.rx_mtu + 32, p54u_rx_cb, skb);
211
 
                info = (struct p54u_rx_info *) skb->cb;
212
 
                info->urb = entry;
213
 
                info->dev = dev;
214
 
                skb_queue_tail(&priv->rx_queue, skb);
215
 
 
216
 
                usb_anchor_urb(entry, &priv->submitted);
217
 
                ret = usb_submit_urb(entry, GFP_KERNEL);
218
 
                if (ret) {
219
 
                        skb_unlink(skb, &priv->rx_queue);
220
 
                        usb_unanchor_urb(entry);
221
 
                        goto err;
222
 
                }
223
 
                usb_free_urb(entry);
224
 
                entry = NULL;
225
 
        }
226
 
 
227
 
        return 0;
228
 
 
229
 
 err:
230
 
        usb_free_urb(entry);
231
 
        kfree_skb(skb);
232
 
        p54u_free_urbs(dev);
233
 
        return ret;
234
 
}
235
 
 
236
 
static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
237
 
{
238
 
        u32 chk = 0;
239
 
 
240
 
        length >>= 2;
241
 
        while (length--) {
242
 
                chk ^= le32_to_cpu(*data++);
243
 
                chk = (chk >> 5) ^ (chk << 3);
244
 
        }
245
 
 
246
 
        return cpu_to_le32(chk);
247
 
}
248
 
 
249
 
static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
250
 
{
251
 
        struct p54u_priv *priv = dev->priv;
252
 
        struct urb *data_urb;
253
 
        struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
254
 
 
255
 
        data_urb = usb_alloc_urb(0, GFP_ATOMIC);
256
 
        if (!data_urb) {
257
 
                p54_free_skb(dev, skb);
258
 
                return;
259
 
        }
260
 
 
261
 
        hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
262
 
        hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
263
 
 
264
 
        usb_fill_bulk_urb(data_urb, priv->udev,
265
 
                          usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
266
 
                          hdr, skb->len + sizeof(*hdr),  FREE_AFTER_TX(skb) ?
267
 
                          p54u_tx_cb : p54u_tx_dummy_cb, skb);
268
 
        data_urb->transfer_flags |= URB_ZERO_PACKET;
269
 
 
270
 
        usb_anchor_urb(data_urb, &priv->submitted);
271
 
        if (usb_submit_urb(data_urb, GFP_ATOMIC)) {
272
 
                usb_unanchor_urb(data_urb);
273
 
                p54_free_skb(dev, skb);
274
 
        }
275
 
        usb_free_urb(data_urb);
276
 
}
277
 
 
278
 
static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
279
 
{
280
 
        struct p54u_priv *priv = dev->priv;
281
 
        struct urb *int_urb = NULL, *data_urb = NULL;
282
 
        struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
283
 
        struct net2280_reg_write *reg = NULL;
284
 
        int err = -ENOMEM;
285
 
 
286
 
        reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
287
 
        if (!reg)
288
 
                goto out;
289
 
 
290
 
        int_urb = usb_alloc_urb(0, GFP_ATOMIC);
291
 
        if (!int_urb)
292
 
                goto out;
293
 
 
294
 
        data_urb = usb_alloc_urb(0, GFP_ATOMIC);
295
 
        if (!data_urb)
296
 
                goto out;
297
 
 
298
 
        reg->port = cpu_to_le16(NET2280_DEV_U32);
299
 
        reg->addr = cpu_to_le32(P54U_DEV_BASE);
300
 
        reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
301
 
 
302
 
        memset(hdr, 0, sizeof(*hdr));
303
 
        hdr->len = cpu_to_le16(skb->len);
304
 
        hdr->device_addr = ((struct p54_hdr *) skb->data)->req_id;
305
 
 
306
 
        usb_fill_bulk_urb(int_urb, priv->udev,
307
 
                usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
308
 
                p54u_tx_dummy_cb, dev);
309
 
 
310
 
        /*
311
 
         * URB_FREE_BUFFER triggers a code path in the USB subsystem that will
312
 
         * free what is inside the transfer_buffer after the last reference to
313
 
         * the int_urb is dropped.
314
 
         */
315
 
        int_urb->transfer_flags |= URB_FREE_BUFFER | URB_ZERO_PACKET;
316
 
        reg = NULL;
317
 
 
318
 
        usb_fill_bulk_urb(data_urb, priv->udev,
319
 
                          usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
320
 
                          hdr, skb->len + sizeof(*hdr), FREE_AFTER_TX(skb) ?
321
 
                          p54u_tx_cb : p54u_tx_dummy_cb, skb);
322
 
        data_urb->transfer_flags |= URB_ZERO_PACKET;
323
 
 
324
 
        usb_anchor_urb(int_urb, &priv->submitted);
325
 
        err = usb_submit_urb(int_urb, GFP_ATOMIC);
326
 
        if (err) {
327
 
                usb_unanchor_urb(int_urb);
328
 
                goto out;
329
 
        }
330
 
 
331
 
        usb_anchor_urb(data_urb, &priv->submitted);
332
 
        err = usb_submit_urb(data_urb, GFP_ATOMIC);
333
 
        if (err) {
334
 
                usb_unanchor_urb(data_urb);
335
 
                goto out;
336
 
        }
337
 
out:
338
 
        usb_free_urb(int_urb);
339
 
        usb_free_urb(data_urb);
340
 
 
341
 
        if (err) {
342
 
                kfree(reg);
343
 
                p54_free_skb(dev, skb);
344
 
        }
345
 
}
346
 
 
347
 
static int p54u_write(struct p54u_priv *priv,
348
 
                      struct net2280_reg_write *buf,
349
 
                      enum net2280_op_type type,
350
 
                      __le32 addr, __le32 val)
351
 
{
352
 
        unsigned int ep;
353
 
        int alen;
354
 
 
355
 
        if (type & 0x0800)
356
 
                ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
357
 
        else
358
 
                ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
359
 
 
360
 
        buf->port = cpu_to_le16(type);
361
 
        buf->addr = addr;
362
 
        buf->val = val;
363
 
 
364
 
        return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
365
 
}
366
 
 
367
 
static int p54u_read(struct p54u_priv *priv, void *buf,
368
 
                     enum net2280_op_type type,
369
 
                     __le32 addr, __le32 *val)
370
 
{
371
 
        struct net2280_reg_read *read = buf;
372
 
        __le32 *reg = buf;
373
 
        unsigned int ep;
374
 
        int alen, err;
375
 
 
376
 
        if (type & 0x0800)
377
 
                ep = P54U_PIPE_DEV;
378
 
        else
379
 
                ep = P54U_PIPE_BRG;
380
 
 
381
 
        read->port = cpu_to_le16(type);
382
 
        read->addr = addr;
383
 
 
384
 
        err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
385
 
                           read, sizeof(*read), &alen, 1000);
386
 
        if (err)
387
 
                return err;
388
 
 
389
 
        err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
390
 
                           reg, sizeof(*reg), &alen, 1000);
391
 
        if (err)
392
 
                return err;
393
 
 
394
 
        *val = *reg;
395
 
        return 0;
396
 
}
397
 
 
398
 
static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
399
 
                         void *data, size_t len)
400
 
{
401
 
        int alen;
402
 
        return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
403
 
                            data, len, &alen, 2000);
404
 
}
405
 
 
406
 
static int p54u_device_reset(struct ieee80211_hw *dev)
407
 
{
408
 
        struct p54u_priv *priv = dev->priv;
409
 
        int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING);
410
 
 
411
 
        if (lock) {
412
 
                ret = usb_lock_device_for_reset(priv->udev, priv->intf);
413
 
                if (ret < 0) {
414
 
                        dev_err(&priv->udev->dev, "(p54usb) unable to lock "
415
 
                                "device for reset (%d)!\n", ret);
416
 
                        return ret;
417
 
                }
418
 
        }
419
 
 
420
 
        ret = usb_reset_device(priv->udev);
421
 
        if (lock)
422
 
                usb_unlock_device(priv->udev);
423
 
 
424
 
        if (ret)
425
 
                dev_err(&priv->udev->dev, "(p54usb) unable to reset "
426
 
                        "device (%d)!\n", ret);
427
 
 
428
 
        return ret;
429
 
}
430
 
 
431
 
static const char p54u_romboot_3887[] = "~~~~";
432
 
static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
433
 
{
434
 
        struct p54u_priv *priv = dev->priv;
435
 
        u8 *buf;
436
 
        int ret;
437
 
 
438
 
        buf = kmemdup(p54u_romboot_3887, 4, GFP_KERNEL);
439
 
        if (!buf)
440
 
                return -ENOMEM;
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
 
 
451
 
static const char p54u_firmware_upload_3887[] = "<\r";
452
 
static 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
 
 
579
 
err_upload_failed:
580
 
        kfree(buf);
581
 
        return err;
582
 
}
583
 
 
584
 
static 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
 
 
810
 
fail:
811
 
        kfree(buf);
812
 
        return err;
813
 
}
814
 
 
815
 
static 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
 
 
851
 
out:
852
 
        if (err)
853
 
                release_firmware(priv->fw);
854
 
 
855
 
        return err;
856
 
}
857
 
 
858
 
static 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
 
 
873
 
static 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
 
}
880
 
 
881
 
static 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
 
 
968
 
err_free_fw:
969
 
        release_firmware(priv->fw);
970
 
 
971
 
err_free_dev:
972
 
        p54_free_common(dev);
973
 
        usb_set_intfdata(intf, NULL);
974
 
        usb_put_dev(udev);
975
 
        return err;
976
 
}
977
 
 
978
 
static 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
 
 
994
 
static 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
 
 
1005
 
static 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
 
 
1020
 
static 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
 
 
1040
 
static 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
 
 
1047
 
static 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
 
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
1060
 
        .soft_unbind = 1,
1061
 
#endif
1062
 
};
1063
 
 
1064
 
static int __init p54u_init(void)
1065
 
{
1066
 
        return usb_register(&p54u_driver);
1067
 
}
1068
 
 
1069
 
static void __exit p54u_exit(void)
1070
 
{
1071
 
        usb_deregister(&p54u_driver);
1072
 
}
1073
 
 
1074
 
module_init(p54u_init);
1075
 
module_exit(p54u_exit);