Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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/firmware.h>
 19 #include <linux/etherdevice.h>
 20 #include <linux/delay.h>
 21 #include <linux/crc32.h>
 22 #include <net/mac80211.h>
 23 
 24 #include "p54.h"
 25 #include "p54usb.h"
 26 
 27 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
 28 MODULE_DESCRIPTION("Prism54 USB wireless driver");
 29 MODULE_LICENSE("GPL");
 30 MODULE_ALIAS("prism54usb");
 31 
 32 static struct usb_device_id p54u_table[] __devinitdata = {
 33         /* Version 1 devices (pci chip + net2280) */
 34         {USB_DEVICE(0x0506, 0x0a11)},   /* 3COM 3CRWE254G72 */
 35         {USB_DEVICE(0x0707, 0xee06)},   /* SMC 2862W-G */
 36         {USB_DEVICE(0x083a, 0x4501)},   /* Accton 802.11g WN4501 USB */
 37         {USB_DEVICE(0x083a, 0x4502)},   /* Siemens Gigaset USB Adapter */
 38         {USB_DEVICE(0x083a, 0x5501)},   /* Phillips CPWUA054 */
 39         {USB_DEVICE(0x0846, 0x4200)},   /* Netgear WG121 */
 40         {USB_DEVICE(0x0846, 0x4210)},   /* Netgear WG121 the second ? */
 41         {USB_DEVICE(0x0846, 0x4220)},   /* Netgear WG111 */
 42         {USB_DEVICE(0x0cde, 0x0006)},   /* Medion 40900, Roper Europe */
 43         {USB_DEVICE(0x124a, 0x4023)},   /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
 44         {USB_DEVICE(0x1915, 0x2234)},   /* Linksys WUSB54G OEM */
 45         {USB_DEVICE(0x1915, 0x2235)},   /* Linksys WUSB54G Portable OEM */
 46         {USB_DEVICE(0x2001, 0x3701)},   /* DLink DWL-G120 Spinnaker */
 47         {USB_DEVICE(0x2001, 0x3703)},   /* DLink DWL-G122 */
 48         {USB_DEVICE(0x5041, 0x2234)},   /* Linksys WUSB54G */
 49         {USB_DEVICE(0x5041, 0x2235)},   /* Linksys WUSB54G Portable */
 50 
 51         /* Version 2 devices (3887) */
 52         {USB_DEVICE(0x050d, 0x7050)},   /* Belkin F5D7050 ver 1000 */
 53         {USB_DEVICE(0x0572, 0x2000)},   /* Cohiba Proto board */
 54         {USB_DEVICE(0x0572, 0x2002)},   /* Cohiba Proto board */
 55         {USB_DEVICE(0x0707, 0xee13)},   /* SMC 2862W-G version 2 */
 56         {USB_DEVICE(0x083a, 0x4521)},   /* Siemens Gigaset USB Adapter 54 version 2 */
 57         {USB_DEVICE(0x0846, 0x4240)},   /* Netgear WG111 (v2) */
 58         {USB_DEVICE(0x0915, 0x2000)},   /* Cohiba Proto board */
 59         {USB_DEVICE(0x0915, 0x2002)},   /* Cohiba Proto board */
 60         {USB_DEVICE(0x0baf, 0x0118)},   /* U.S. Robotics U5 802.11g Adapter*/
 61         {USB_DEVICE(0x0bf8, 0x1009)},   /* FUJITSU E-5400 USB D1700*/
 62         {USB_DEVICE(0x0cde, 0x0006)},   /* Medion MD40900 */
 63         {USB_DEVICE(0x0cde, 0x0008)},   /* Sagem XG703A */
 64         {USB_DEVICE(0x0d8e, 0x3762)},   /* DLink DWL-G120 Cohiba */
 65         {USB_DEVICE(0x09aa, 0x1000)},   /* Spinnaker Proto board */
 66         {USB_DEVICE(0x124a, 0x4025)},   /* IOGear GWU513 (GW3887IK chip) */
 67         {USB_DEVICE(0x13b1, 0x000a)},   /* Linksys WUSB54G ver 2 */
 68         {USB_DEVICE(0x13B1, 0x000C)},   /* Linksys WUSB54AG */
 69         {USB_DEVICE(0x1435, 0x0427)},   /* Inventel UR054G */
 70         {USB_DEVICE(0x2001, 0x3704)},   /* DLink DWL-G122 rev A2 */
 71         {USB_DEVICE(0x413c, 0x8102)},   /* Spinnaker DUT */
 72         {USB_DEVICE(0x413c, 0x8104)},   /* Cohiba Proto board */
 73         {}
 74 };
 75 
 76 MODULE_DEVICE_TABLE(usb, p54u_table);
 77 
 78 static void p54u_rx_cb(struct urb *urb)
 79 {
 80         struct sk_buff *skb = (struct sk_buff *) urb->context;
 81         struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
 82         struct ieee80211_hw *dev = info->dev;
 83         struct p54u_priv *priv = dev->priv;
 84 
 85         if (unlikely(urb->status)) {
 86                 info->urb = NULL;
 87                 usb_free_urb(urb);
 88                 return;
 89         }
 90 
 91         skb_unlink(skb, &priv->rx_queue);
 92         skb_put(skb, urb->actual_length);
 93         if (!priv->hw_type)
 94                 skb_pull(skb, sizeof(struct net2280_tx_hdr));
 95 
 96         if (p54_rx(dev, skb)) {
 97                 skb = dev_alloc_skb(MAX_RX_SIZE);
 98                 if (unlikely(!skb)) {
 99                         usb_free_urb(urb);
100                         /* TODO check rx queue length and refill *somewhere* */
101                         return;
102                 }
103 
104                 info = (struct p54u_rx_info *) skb->cb;
105                 info->urb = urb;
106                 info->dev = dev;
107                 urb->transfer_buffer = skb_tail_pointer(skb);
108                 urb->context = skb;
109                 skb_queue_tail(&priv->rx_queue, skb);
110         } else {
111                 skb_trim(skb, 0);
112                 skb_queue_tail(&priv->rx_queue, skb);
113         }
114 
115         usb_submit_urb(urb, GFP_ATOMIC);
116 }
117 
118 static void p54u_tx_cb(struct urb *urb)
119 {
120         usb_free_urb(urb);
121 }
122 
123 static void p54u_tx_free_cb(struct urb *urb)
124 {
125         kfree(urb->transfer_buffer);
126         usb_free_urb(urb);
127 }
128 
129 static int p54u_init_urbs(struct ieee80211_hw *dev)
130 {
131         struct p54u_priv *priv = dev->priv;
132         struct urb *entry;
133         struct sk_buff *skb;
134         struct p54u_rx_info *info;
135 
136         while (skb_queue_len(&priv->rx_queue) < 32) {
137                 skb = __dev_alloc_skb(MAX_RX_SIZE, GFP_KERNEL);
138                 if (!skb)
139                         break;
140                 entry = usb_alloc_urb(0, GFP_KERNEL);
141                 if (!entry) {
142                         kfree_skb(skb);
143                         break;
144                 }
145                 usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), skb_tail_pointer(skb), MAX_RX_SIZE, p54u_rx_cb, skb);
146                 info = (struct p54u_rx_info *) skb->cb;
147                 info->urb = entry;
148                 info->dev = dev;
149                 skb_queue_tail(&priv->rx_queue, skb);
150                 usb_submit_urb(entry, GFP_KERNEL);
151         }
152 
153         return 0;
154 }
155 
156 static void p54u_free_urbs(struct ieee80211_hw *dev)
157 {
158         struct p54u_priv *priv = dev->priv;
159         struct p54u_rx_info *info;
160         struct sk_buff *skb;
161 
162         while ((skb = skb_dequeue(&priv->rx_queue))) {
163                 info = (struct p54u_rx_info *) skb->cb;
164                 if (!info->urb)
165                         continue;
166 
167                 usb_kill_urb(info->urb);
168                 kfree_skb(skb);
169         }
170 }
171 
172 static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
173                          size_t len, int free_on_tx)
174 {
175         struct p54u_priv *priv = dev->priv;
176         struct urb *addr_urb, *data_urb;
177 
178         addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
179         if (!addr_urb)
180                 return;
181 
182         data_urb = usb_alloc_urb(0, GFP_ATOMIC);
183         if (!data_urb) {
184                 usb_free_urb(addr_urb);
185                 return;
186         }
187 
188         usb_fill_bulk_urb(addr_urb, priv->udev,
189                 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id,
190                 sizeof(data->req_id), p54u_tx_cb, dev);
191         usb_fill_bulk_urb(data_urb, priv->udev,
192                 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len,
193                 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
194 
195         usb_submit_urb(addr_urb, GFP_ATOMIC);
196         usb_submit_urb(data_urb, GFP_ATOMIC);
197 }
198 
199 static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
200                             size_t len, int free_on_tx)
201 {
202         struct p54u_priv *priv = dev->priv;
203         struct urb *int_urb, *data_urb;
204         struct net2280_tx_hdr *hdr;
205         struct net2280_reg_write *reg;
206 
207         reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
208         if (!reg)
209                 return;
210 
211         int_urb = usb_alloc_urb(0, GFP_ATOMIC);
212         if (!int_urb) {
213                 kfree(reg);
214                 return;
215         }
216 
217         data_urb = usb_alloc_urb(0, GFP_ATOMIC);
218         if (!data_urb) {
219                 kfree(reg);
220                 usb_free_urb(int_urb);
221                 return;
222         }
223 
224         reg->port = cpu_to_le16(NET2280_DEV_U32);
225         reg->addr = cpu_to_le32(P54U_DEV_BASE);
226         reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
227 
228         len += sizeof(*data);
229         hdr = (void *)data - sizeof(*hdr);
230         memset(hdr, 0, sizeof(*hdr));
231         hdr->device_addr = data->req_id;
232         hdr->len = cpu_to_le16(len);
233 
234         usb_fill_bulk_urb(int_urb, priv->udev,
235                 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
236                 p54u_tx_free_cb, dev);
237         usb_submit_urb(int_urb, GFP_ATOMIC);
238 
239         usb_fill_bulk_urb(data_urb, priv->udev,
240                 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr),
241                 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
242         usb_submit_urb(data_urb, GFP_ATOMIC);
243 }
244 
245 static int p54u_write(struct p54u_priv *priv,
246                       struct net2280_reg_write *buf,
247                       enum net2280_op_type type,
248                       __le32 addr, __le32 val)
249 {
250         unsigned int ep;
251         int alen;
252 
253         if (type & 0x0800)
254                 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
255         else
256                 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
257 
258         buf->port = cpu_to_le16(type);
259         buf->addr = addr;
260         buf->val = val;
261 
262         return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
263 }
264 
265 static int p54u_read(struct p54u_priv *priv, void *buf,
266                      enum net2280_op_type type,
267                      __le32 addr, __le32 *val)
268 {
269         struct net2280_reg_read *read = buf;
270         __le32 *reg = buf;
271         unsigned int ep;
272         int alen, err;
273 
274         if (type & 0x0800)
275                 ep = P54U_PIPE_DEV;
276         else
277                 ep = P54U_PIPE_BRG;
278 
279         read->port = cpu_to_le16(type);
280         read->addr = addr;
281 
282         err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
283                            read, sizeof(*read), &alen, 1000);
284         if (err)
285                 return err;
286 
287         err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
288                            reg, sizeof(*reg), &alen, 1000);
289         if (err)
290                 return err;
291 
292         *val = *reg;
293         return 0;
294 }
295 
296 static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
297                          void *data, size_t len)
298 {
299         int alen;
300         return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
301                             data, len, &alen, 2000);
302 }
303 
304 static int p54u_read_eeprom(struct ieee80211_hw *dev)
305 {
306         struct p54u_priv *priv = dev->priv;
307         void *buf;
308         struct p54_control_hdr *hdr;
309         int err, alen;
310         size_t offset = priv->hw_type ? 0x10 : 0x20;
311 
312         buf = kmalloc(0x2020, GFP_KERNEL);
313         if (!buf) {
314                 printk(KERN_ERR "prism54usb: cannot allocate memory for "
315                        "eeprom readback!\n");
316                 return -ENOMEM;
317         }
318 
319         if (priv->hw_type) {
320                 *((u32 *) buf) = priv->common.rx_start;
321                 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
322                 if (err) {
323                         printk(KERN_ERR "prism54usb: addr send failed\n");
324                         goto fail;
325                 }
326         } else {
327                 struct net2280_reg_write *reg = buf;
328                 reg->port = cpu_to_le16(NET2280_DEV_U32);
329                 reg->addr = cpu_to_le32(P54U_DEV_BASE);
330                 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
331                 err = p54u_bulk_msg(priv, P54U_PIPE_DEV, buf, sizeof(*reg));
332                 if (err) {
333                         printk(KERN_ERR "prism54usb: dev_int send failed\n");
334                         goto fail;
335                 }
336         }
337 
338         hdr = buf + priv->common.tx_hdr_len;
339         p54_fill_eeprom_readback(hdr);
340         hdr->req_id = cpu_to_le32(priv->common.rx_start);
341         if (priv->common.tx_hdr_len) {
342                 struct net2280_tx_hdr *tx_hdr = buf;
343                 tx_hdr->device_addr = hdr->req_id;
344                 tx_hdr->len = cpu_to_le16(EEPROM_READBACK_LEN);
345         }
346 
347         /* we can just pretend to send 0x2000 bytes of nothing in the headers */
348         err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf,
349                             EEPROM_READBACK_LEN + priv->common.tx_hdr_len);
350         if (err) {
351                 printk(KERN_ERR "prism54usb: eeprom req send failed\n");
352                 goto fail;
353         }
354 
355         err = usb_bulk_msg(priv->udev,
356                            usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
357                            buf, 0x2020, &alen, 1000);
358         if (!err && alen > offset) {
359                 p54_parse_eeprom(dev, (u8 *)buf + offset, alen - offset);
360         } else {
361                 printk(KERN_ERR "prism54usb: eeprom read failed!\n");
362                 err = -EINVAL;
363                 goto fail;
364         }
365 
366  fail:
367         kfree(buf);
368         return err;
369 }
370 
371 static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
372 {
373         static char start_string[] = "~~~~<\r";
374         struct p54u_priv *priv = dev->priv;
375         const struct firmware *fw_entry = NULL;
376         int err, alen;
377         u8 carry = 0;
378         u8 *buf, *tmp, *data;
379         unsigned int left, remains, block_size;
380         struct x2_header *hdr;
381         unsigned long timeout;
382 
383         tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
384         if (!buf) {
385                 printk(KERN_ERR "p54usb: cannot allocate firmware upload buffer!\n");
386                 err = -ENOMEM;
387                 goto err_bufalloc;
388         }
389 
390         memcpy(buf, start_string, 4);
391         err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
392         if (err) {
393                 printk(KERN_ERR "p54usb: reset failed! (%d)\n", err);
394                 goto err_reset;
395         }
396 
397         err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev);
398         if (err) {
399                 printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb_bare)!\n");
400                 goto err_req_fw_failed;
401         }
402 
403         p54_parse_firmware(dev, fw_entry);
404 
405         left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
406         strcpy(buf, start_string);
407         left -= strlen(start_string);
408         tmp += strlen(start_string);
409 
410         data = fw_entry->data;
411         remains = fw_entry->size;
412 
413         hdr = (struct x2_header *)(buf + strlen(start_string));
414         memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
415         hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
416         hdr->fw_length = cpu_to_le32(fw_entry->size);
417         hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
418                                          sizeof(u32)*2));
419         left -= sizeof(*hdr);
420         tmp += sizeof(*hdr);
421 
422         while (remains) {
423                 while (left--) {
424                         if (carry) {
425                                 *tmp++ = carry;
426                                 carry = 0;
427                                 remains--;
428                                 continue;
429                         }
430                         switch (*data) {
431                         case '~':
432                                 *tmp++ = '}';
433                                 carry = '^';
434                                 break;
435                         case '}':
436                                 *tmp++ = '}';
437                                 carry = ']';
438                                 break;
439                         default:
440                                 *tmp++ = *data;
441                                 remains--;
442                                 break;
443                         }
444                         data++;
445                 }
446 
447                 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
448                 if (err) {
449                         printk(KERN_ERR "prism54usb: firmware upload failed!\n");
450                         goto err_upload_failed;
451                 }
452 
453                 tmp = buf;
454                 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
455         }
456 
457         *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
458         err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
459         if (err) {
460                 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
461                 goto err_upload_failed;
462         }
463 
464         timeout = jiffies + msecs_to_jiffies(1000);
465         while (!(err = usb_bulk_msg(priv->udev,
466                 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
467                 if (alen > 2 && !memcmp(buf, "OK", 2))
468                         break;
469 
470                 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
471                         printk(KERN_INFO "prism54usb: firmware upload failed!\n");
472                         err = -EINVAL;
473                         break;
474                 }
475 
476                 if (time_after(jiffies, timeout)) {
477                         printk(KERN_ERR "prism54usb: firmware boot timed out!\n");
478                         err = -ETIMEDOUT;
479                         break;
480                 }
481         }
482         if (err)
483                 goto err_upload_failed;
484 
485         buf[0] = 'g';
486         buf[1] = '\r';
487         err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
488         if (err) {
489                 printk(KERN_ERR "prism54usb: firmware boot failed!\n");
490                 goto err_upload_failed;
491         }
492 
493         timeout = jiffies + msecs_to_jiffies(1000);
494         while (!(err = usb_bulk_msg(priv->udev,
495                 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
496                 if (alen > 0 && buf[0] == 'g')
497                         break;
498 
499                 if (time_after(jiffies, timeout)) {
500                         err = -ETIMEDOUT;
501                         break;
502                 }
503         }
504         if (err)
505                 goto err_upload_failed;
506 
507   err_upload_failed:
508         release_firmware(fw_entry);
509   err_req_fw_failed:
510   err_reset:
511         kfree(buf);
512   err_bufalloc:
513         return err;
514 }
515 
516 static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
517 {
518         struct p54u_priv *priv = dev->priv;
519         const struct firmware *fw_entry = NULL;
520         const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
521         int err, alen;
522         void *buf;
523         __le32 reg;
524         unsigned int remains, offset;
525         u8 *data;
526 
527         buf = kmalloc(512, GFP_KERNEL);
528         if (!buf) {
529                 printk(KERN_ERR "p54usb: firmware buffer alloc failed!\n");
530                 return -ENOMEM;
531         }
532 
533         err = request_firmware(&fw_entry, "isl3890usb", &priv->udev->dev);
534         if (err) {
535                 printk(KERN_ERR "p54usb: cannot find firmware (isl3890usb)!\n");
536                 kfree(buf);
537                 return err;
538         }
539 
540         p54_parse_firmware(dev, fw_entry);
541 
542 #define P54U_WRITE(type, addr, data) \
543         do {\
544                 err = p54u_write(priv, buf, type,\
545                                  cpu_to_le32((u32)(unsigned long)addr), data);\
546                 if (err) \
547                         goto fail;\
548         } while (0)
549 
550 #define P54U_READ(type, addr) \
551         do {\
552                 err = p54u_read(priv, buf, type,\
553                                 cpu_to_le32((u32)(unsigned long)addr), &reg);\
554                 if (err)\
555                         goto fail;\
556         } while (0)
557 
558         /* power down net2280 bridge */
559         P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
560         reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
561         reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
562         P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
563 
564         mdelay(100);
565 
566         /* power up bridge */
567         reg |= cpu_to_le32(P54U_BRG_POWER_UP);
568         reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
569         P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
570 
571         mdelay(100);
572 
573         P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
574                    cpu_to_le32(NET2280_CLK_30Mhz |
575                                NET2280_PCI_ENABLE |
576                                NET2280_PCI_SOFT_RESET));
577 
578         mdelay(20);
579 
580         P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
581                    cpu_to_le32(PCI_COMMAND_MEMORY |
582                                PCI_COMMAND_MASTER));
583 
584         P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
585                    cpu_to_le32(NET2280_BASE));
586 
587         P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
588         reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
589         P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
590 
591         // TODO: we really need this?
592         P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
593 
594         P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
595                    cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
596         P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
597                    cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
598 
599         P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
600                    cpu_to_le32(NET2280_BASE2));
601 
602         /* finally done setting up the bridge */
603 
604         P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
605                    cpu_to_le32(PCI_COMMAND_MEMORY |
606                                PCI_COMMAND_MASTER));
607 
608         P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
609         P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
610                    cpu_to_le32(P54U_DEV_BASE));
611 
612         P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
613         P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
614                    cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
615 
616         /* do romboot */
617         P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
618 
619         P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
620         reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
621         reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
622         reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
623         P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
624 
625         mdelay(20);
626 
627         reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
628         P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
629 
630         mdelay(20);
631 
632         reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
633         P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
634 
635         mdelay(100);
636 
637         P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
638         P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
639 
640         /* finally, we can upload firmware now! */
641         remains = fw_entry->size;
642         data = fw_entry->data;
643         offset = ISL38XX_DEV_FIRMWARE_ADDR;
644 
645         while (remains) {
646                 unsigned int block_len = min(remains, (unsigned int)512);
647                 memcpy(buf, data, block_len);
648 
649                 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
650                 if (err) {
651                         printk(KERN_ERR "prism54usb: firmware block upload "
652                                "failed\n");
653                         goto fail;
654                 }
655 
656                 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
657                            cpu_to_le32(0xc0000f00));
658 
659                 P54U_WRITE(NET2280_DEV_U32,
660                            0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
661                 P54U_WRITE(NET2280_DEV_U32,
662                            0x0020 | (unsigned long)&devreg->direct_mem_win,
663                            cpu_to_le32(1));
664 
665                 P54U_WRITE(NET2280_DEV_U32,
666                            0x0024 | (unsigned long)&devreg->direct_mem_win,
667                            cpu_to_le32(block_len));
668                 P54U_WRITE(NET2280_DEV_U32,
669                            0x0028 | (unsigned long)&devreg->direct_mem_win,
670                            cpu_to_le32(offset));
671 
672                 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
673                            cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
674                 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
675                            cpu_to_le32(block_len >> 2));
676                 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
677                            cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
678 
679                 mdelay(10);
680 
681                 P54U_READ(NET2280_DEV_U32,
682                           0x002C | (unsigned long)&devreg->direct_mem_win);
683                 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
684                     !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
685                         printk(KERN_ERR "prism54usb: firmware DMA transfer "
686                                "failed\n");
687                         goto fail;
688                 }
689 
690                 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
691                            cpu_to_le32(NET2280_FIFO_FLUSH));
692 
693                 remains -= block_len;
694                 data += block_len;
695                 offset += block_len;
696         }
697 
698         /* do ramboot */
699         P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
700         reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
701         reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
702         reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
703         P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
704 
705         mdelay(20);
706 
707         reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
708         P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
709 
710         reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
711         P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
712 
713         mdelay(100);
714 
715         P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
716         P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
717 
718         /* start up the firmware */
719         P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
720                    cpu_to_le32(ISL38XX_INT_IDENT_INIT));
721 
722         P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
723                    cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
724 
725         P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
726                    cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
727                                NET2280_USB_INTERRUPT_ENABLE));
728 
729         P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
730                    cpu_to_le32(ISL38XX_DEV_INT_RESET));
731 
732         err = usb_interrupt_msg(priv->udev,
733                                 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
734                                 buf, sizeof(__le32), &alen, 1000);
735         if (err || alen != sizeof(__le32))
736                 goto fail;
737 
738         P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
739         P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
740 
741         if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
742                 err = -EINVAL;
743 
744         P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
745         P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
746                    cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
747 
748 #undef P54U_WRITE
749 #undef P54U_READ
750 
751  fail:
752         release_firmware(fw_entry);
753         kfree(buf);
754         return err;
755 }
756 
757 static int p54u_open(struct ieee80211_hw *dev)
758 {
759         struct p54u_priv *priv = dev->priv;
760         int err;
761 
762         err = p54u_init_urbs(dev);
763         if (err) {
764                 return err;
765         }
766 
767         priv->common.open = p54u_init_urbs;
768 
769         return 0;
770 }
771 
772 static void p54u_stop(struct ieee80211_hw *dev)
773 {
774         /* TODO: figure out how to reliably stop the 3887 and net2280 so
775            the hardware is still usable next time we want to start it.
776            until then, we just stop listening to the hardware.. */
777         p54u_free_urbs(dev);
778         return;
779 }
780 
781 static int __devinit p54u_probe(struct usb_interface *intf,
782                                 const struct usb_device_id *id)
783 {
784         struct usb_device *udev = interface_to_usbdev(intf);
785         struct ieee80211_hw *dev;
786         struct p54u_priv *priv;
787         int err;
788         unsigned int i, recognized_pipes;
789         DECLARE_MAC_BUF(mac);
790 
791         dev = p54_init_common(sizeof(*priv));
792         if (!dev) {
793                 printk(KERN_ERR "prism54usb: ieee80211 alloc failed\n");
794                 return -ENOMEM;
795         }
796 
797         priv = dev->priv;
798 
799         SET_IEEE80211_DEV(dev, &intf->dev);
800         usb_set_intfdata(intf, dev);
801         priv->udev = udev;
802 
803         usb_get_dev(udev);
804 
805         /* really lazy and simple way of figuring out if we're a 3887 */
806         /* TODO: should just stick the identification in the device table */
807         i = intf->altsetting->desc.bNumEndpoints;
808         recognized_pipes = 0;
809         while (i--) {
810                 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
811                 case P54U_PIPE_DATA:
812                 case P54U_PIPE_MGMT:
813                 case P54U_PIPE_BRG:
814                 case P54U_PIPE_DEV:
815                 case P54U_PIPE_DATA | USB_DIR_IN:
816                 case P54U_PIPE_MGMT | USB_DIR_IN:
817                 case P54U_PIPE_BRG | USB_DIR_IN:
818                 case P54U_PIPE_DEV | USB_DIR_IN:
819                 case P54U_PIPE_INT | USB_DIR_IN:
820                         recognized_pipes++;
821                 }
822         }
823         priv->common.open = p54u_open;
824 
825         if (recognized_pipes < P54U_PIPE_NUMBER) {
826                 priv->hw_type = P54U_3887;
827                 priv->common.tx = p54u_tx_3887;
828         } else {
829                 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
830                 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
831                 priv->common.tx = p54u_tx_net2280;
832         }
833         priv->common.stop = p54u_stop;
834 
835         if (priv->hw_type)
836                 err = p54u_upload_firmware_3887(dev);
837         else
838                 err = p54u_upload_firmware_net2280(dev);
839         if (err)
840                 goto err_free_dev;
841 
842         err = p54u_read_eeprom(dev);
843         if (err)
844                 goto err_free_dev;
845 
846         if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
847                 u8 perm_addr[ETH_ALEN];
848 
849                 printk(KERN_WARNING "prism54usb: Invalid hwaddr! Using randomly generated MAC addr\n");
850                 random_ether_addr(perm_addr);
851                 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
852         }
853 
854         skb_queue_head_init(&priv->rx_queue);
855 
856         err = ieee80211_register_hw(dev);
857         if (err) {
858                 printk(KERN_ERR "prism54usb: Cannot register netdevice\n");
859                 goto err_free_dev;
860         }
861 
862         printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
863                wiphy_name(dev->wiphy),
864                print_mac(mac, dev->wiphy->perm_addr),
865                priv->common.version);
866 
867         return 0;
868 
869  err_free_dev:
870         ieee80211_free_hw(dev);
871         usb_set_intfdata(intf, NULL);
872         usb_put_dev(udev);
873         return err;
874 }
875 
876 static void __devexit p54u_disconnect(struct usb_interface *intf)
877 {
878         struct ieee80211_hw *dev = usb_get_intfdata(intf);
879         struct p54u_priv *priv;
880 
881         if (!dev)
882                 return;
883 
884         ieee80211_unregister_hw(dev);
885 
886         priv = dev->priv;
887         usb_put_dev(interface_to_usbdev(intf));
888         p54_free_common(dev);
889         ieee80211_free_hw(dev);
890 }
891 
892 static struct usb_driver p54u_driver = {
893         .name   = "prism54usb",
894         .id_table = p54u_table,
895         .probe = p54u_probe,
896         .disconnect = p54u_disconnect,
897 };
898 
899 static int __init p54u_init(void)
900 {
901         return usb_register(&p54u_driver);
902 }
903 
904 static void __exit p54u_exit(void)
905 {
906         usb_deregister(&p54u_driver);
907 }
908 
909 module_init(p54u_init);
910 module_exit(p54u_exit);
911 
  This page was automatically generated by the LXR engine.