1 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.c linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.c
2 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.c 1970-01-01 01:00:00.000000000 +0100
3 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.c 2006-03-28 22:16:14.000000000 +0200
7 + Broadcom BCM43xx wireless driver
9 + debugfs driver debugging code
11 + Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
13 + This program is free software; you can redistribute it and/or modify
14 + it under the terms of the GNU General Public License as published by
15 + the Free Software Foundation; either version 2 of the License, or
16 + (at your option) any later version.
18 + This program is distributed in the hope that it will be useful,
19 + but WITHOUT ANY WARRANTY; without even the implied warranty of
20 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 + GNU General Public License for more details.
23 + You should have received a copy of the GNU General Public License
24 + along with this program; see the file COPYING. If not, write to
25 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
26 + Boston, MA 02110-1301, USA.
32 +#include <linux/fs.h>
33 +#include <linux/debugfs.h>
34 +#include <linux/slab.h>
35 +#include <linux/netdevice.h>
36 +#include <linux/pci.h>
40 +#include "bcm43xx_main.h"
41 +#include "bcm43xx_debugfs.h"
42 +#include "bcm43xx_dma.h"
43 +#include "bcm43xx_pio.h"
44 +#include "bcm43xx_xmit.h"
46 +#define REALLY_BIG_BUFFER_SIZE (1024*256)
48 +static struct bcm43xx_debugfs fs;
49 +static char really_big_buffer[REALLY_BIG_BUFFER_SIZE];
50 +static DECLARE_MUTEX(big_buffer_sem);
53 +static ssize_t write_file_dummy(struct file *file, const char __user *buf,
54 + size_t count, loff_t *ppos)
59 +static int open_file_generic(struct inode *inode, struct file *file)
61 + file->private_data = inode->u.generic_ip;
65 +#define fappend(fmt, x...) pos += snprintf(buf + pos, len - pos, fmt , ##x)
67 +static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
68 + size_t count, loff_t *ppos)
70 + const size_t len = REALLY_BIG_BUFFER_SIZE;
72 + struct bcm43xx_private *bcm = file->private_data;
73 + char *buf = really_big_buffer;
76 + struct net_device *net_dev;
77 + struct pci_dev *pci_dev;
78 + unsigned long flags;
82 + down(&big_buffer_sem);
84 + bcm43xx_lock_mmio(bcm, flags);
85 + if (!bcm->initialized) {
86 + fappend("Board not initialized.\n");
89 + net_dev = bcm->net_dev;
90 + pci_dev = bcm->pci_dev;
92 + /* This is where the information is written to the "devinfo" file */
93 + fappend("*** %s devinfo ***\n", net_dev->name);
94 + fappend("vendor: 0x%04x device: 0x%04x\n",
95 + pci_dev->vendor, pci_dev->device);
96 + fappend("subsystem_vendor: 0x%04x subsystem_device: 0x%04x\n",
97 + pci_dev->subsystem_vendor, pci_dev->subsystem_device);
98 + fappend("IRQ: %d\n", bcm->irq);
99 + fappend("mmio_addr: 0x%p mmio_len: %u\n", bcm->mmio_addr, bcm->mmio_len);
100 + fappend("chip_id: 0x%04x chip_rev: 0x%02x\n", bcm->chip_id, bcm->chip_rev);
101 + if ((bcm->core_80211[0].rev >= 3) && (bcm43xx_read32(bcm, 0x0158) & (1 << 16)))
102 + fappend("Radio disabled by hardware!\n");
103 + if ((bcm->core_80211[0].rev < 3) && !(bcm43xx_read16(bcm, 0x049A) & (1 << 4)))
104 + fappend("Radio disabled by hardware!\n");
105 + fappend("board_vendor: 0x%04x board_type: 0x%04x\n", bcm->board_vendor,
108 + fappend("\nCores:\n");
109 +#define fappend_core(name, info) fappend("core \"" name "\" %s, %s, id: 0x%04x, " \
110 + "rev: 0x%02x, index: 0x%02x\n", \
112 + ? "available" : "nonavailable", \
114 + ? "enabled" : "disabled", \
115 + (info).id, (info).rev, (info).index)
116 + fappend_core("CHIPCOMMON", bcm->core_chipcommon);
117 + fappend_core("PCI", bcm->core_pci);
118 + fappend_core("first 80211", bcm->core_80211[0]);
119 + fappend_core("second 80211", bcm->core_80211[1]);
121 + tmp16 = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
123 + for (i = 0; i < BCM43xx_NR_LEDS; i++)
124 + fappend("%d ", !!(tmp16 & (1 << i)));
128 + bcm43xx_unlock_mmio(bcm, flags);
129 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
130 + up(&big_buffer_sem);
134 +static ssize_t drvinfo_read_file(struct file *file, char __user *userbuf,
135 + size_t count, loff_t *ppos)
137 + const size_t len = REALLY_BIG_BUFFER_SIZE;
139 + char *buf = really_big_buffer;
143 + down(&big_buffer_sem);
145 + /* This is where the information is written to the "driver" file */
146 + fappend(KBUILD_MODNAME " driver\n");
147 + fappend("Compiled at: %s %s\n", __DATE__, __TIME__);
149 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
150 + up(&big_buffer_sem);
154 +static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
155 + size_t count, loff_t *ppos)
157 + const size_t len = REALLY_BIG_BUFFER_SIZE;
159 + struct bcm43xx_private *bcm = file->private_data;
160 + char *buf = really_big_buffer;
163 + unsigned long flags;
165 + down(&big_buffer_sem);
166 + bcm43xx_lock_mmio(bcm, flags);
167 + if (!bcm->initialized) {
168 + fappend("Board not initialized.\n");
172 + /* This is where the information is written to the "sprom_dump" file */
173 + fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
176 + bcm43xx_unlock_mmio(bcm, flags);
177 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
178 + up(&big_buffer_sem);
182 +static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
183 + size_t count, loff_t *ppos)
185 + const size_t len = REALLY_BIG_BUFFER_SIZE;
187 + struct bcm43xx_private *bcm = file->private_data;
188 + char *buf = really_big_buffer;
191 + unsigned long flags;
194 + down(&big_buffer_sem);
195 + bcm43xx_lock_mmio(bcm, flags);
196 + if (!bcm->initialized) {
197 + fappend("Board not initialized.\n");
200 + bcm43xx_tsf_read(bcm, &tsf);
201 + fappend("0x%08x%08x\n",
202 + (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
203 + (unsigned int)(tsf & 0xFFFFFFFFULL));
206 + bcm43xx_unlock_mmio(bcm, flags);
207 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
208 + up(&big_buffer_sem);
212 +static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
213 + size_t count, loff_t *ppos)
215 + struct bcm43xx_private *bcm = file->private_data;
216 + char *buf = really_big_buffer;
219 + unsigned long flags;
222 + buf_size = min(count, sizeof (really_big_buffer) - 1);
223 + down(&big_buffer_sem);
224 + if (copy_from_user(buf, user_buf, buf_size)) {
228 + bcm43xx_lock_mmio(bcm, flags);
229 + if (!bcm->initialized) {
230 + printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
234 + if (sscanf(buf, "%lli", &tsf) != 1) {
235 + printk(KERN_INFO PFX "debugfs: invalid values for \"tsf\"\n");
239 + bcm43xx_tsf_write(bcm, tsf);
243 + bcm43xx_unlock_mmio(bcm, flags);
245 + up(&big_buffer_sem);
249 +static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
250 + size_t count, loff_t *ppos)
252 + const size_t len = REALLY_BIG_BUFFER_SIZE;
254 + struct bcm43xx_private *bcm = file->private_data;
255 + char *buf = really_big_buffer;
258 + unsigned long flags;
259 + struct bcm43xx_dfsentry *e;
260 + struct bcm43xx_xmitstatus *status;
263 + down(&big_buffer_sem);
264 + bcm43xx_lock(bcm, flags);
266 + fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
267 + BCM43xx_NR_LOGGED_XMITSTATUS);
269 + if (e->xmitstatus_printing == 0) {
270 + /* At the beginning, make a copy of all data to avoid
271 + * concurrency, as this function is called multiple
272 + * times for big logs. Without copying, the data might
273 + * change between reads. This would result in total trash.
275 + e->xmitstatus_printing = 1;
276 + e->saved_xmitstatus_ptr = e->xmitstatus_ptr;
277 + e->saved_xmitstatus_cnt = e->xmitstatus_cnt;
278 + memcpy(e->xmitstatus_print_buffer, e->xmitstatus_buffer,
279 + BCM43xx_NR_LOGGED_XMITSTATUS * sizeof(*(e->xmitstatus_buffer)));
281 + i = e->saved_xmitstatus_ptr - 1;
283 + i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
284 + cnt = e->saved_xmitstatus_cnt;
286 + status = e->xmitstatus_print_buffer + i;
287 + fappend("0x%02x: cookie: 0x%04x, flags: 0x%02x, "
288 + "cnt1: 0x%02x, cnt2: 0x%02x, seq: 0x%04x, "
289 + "unk: 0x%04x\n", j,
290 + status->cookie, status->flags,
291 + status->cnt1, status->cnt2, status->seq,
297 + i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
300 + bcm43xx_unlock(bcm, flags);
301 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
302 + bcm43xx_lock(bcm, flags);
303 + if (*ppos == pos) {
304 + /* Done. Drop the copied data. */
305 + e->xmitstatus_printing = 0;
307 + bcm43xx_unlock(bcm, flags);
308 + up(&big_buffer_sem);
315 +static struct file_operations devinfo_fops = {
316 + .read = devinfo_read_file,
317 + .write = write_file_dummy,
318 + .open = open_file_generic,
321 +static struct file_operations spromdump_fops = {
322 + .read = spromdump_read_file,
323 + .write = write_file_dummy,
324 + .open = open_file_generic,
327 +static struct file_operations drvinfo_fops = {
328 + .read = drvinfo_read_file,
329 + .write = write_file_dummy,
330 + .open = open_file_generic,
333 +static struct file_operations tsf_fops = {
334 + .read = tsf_read_file,
335 + .write = tsf_write_file,
336 + .open = open_file_generic,
339 +static struct file_operations txstat_fops = {
340 + .read = txstat_read_file,
341 + .write = write_file_dummy,
342 + .open = open_file_generic,
346 +void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
348 + struct bcm43xx_dfsentry *e;
349 + char devdir[IFNAMSIZ];
352 + e = kzalloc(sizeof(*e), GFP_KERNEL);
354 + printk(KERN_ERR PFX "out of memory\n");
358 + e->xmitstatus_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
359 + * sizeof(*(e->xmitstatus_buffer)),
361 + if (!e->xmitstatus_buffer) {
362 + printk(KERN_ERR PFX "out of memory\n");
366 + e->xmitstatus_print_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
367 + * sizeof(*(e->xmitstatus_buffer)),
369 + if (!e->xmitstatus_print_buffer) {
370 + printk(KERN_ERR PFX "out of memory\n");
378 + strncpy(devdir, bcm->net_dev->name, ARRAY_SIZE(devdir));
379 + e->subdir = debugfs_create_dir(devdir, fs.root);
380 + e->dentry_devinfo = debugfs_create_file("devinfo", 0444, e->subdir,
381 + bcm, &devinfo_fops);
382 + if (!e->dentry_devinfo)
383 + printk(KERN_ERR PFX "debugfs: creating \"devinfo\" for \"%s\" failed!\n", devdir);
384 + e->dentry_spromdump = debugfs_create_file("sprom_dump", 0444, e->subdir,
385 + bcm, &spromdump_fops);
386 + if (!e->dentry_spromdump)
387 + printk(KERN_ERR PFX "debugfs: creating \"sprom_dump\" for \"%s\" failed!\n", devdir);
388 + e->dentry_tsf = debugfs_create_file("tsf", 0666, e->subdir,
390 + if (!e->dentry_tsf)
391 + printk(KERN_ERR PFX "debugfs: creating \"tsf\" for \"%s\" failed!\n", devdir);
392 + e->dentry_txstat = debugfs_create_file("tx_status", 0444, e->subdir,
393 + bcm, &txstat_fops);
394 + if (!e->dentry_txstat)
395 + printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir);
398 +void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
400 + struct bcm43xx_dfsentry *e;
407 + debugfs_remove(e->dentry_spromdump);
408 + debugfs_remove(e->dentry_devinfo);
409 + debugfs_remove(e->dentry_tsf);
410 + debugfs_remove(e->dentry_txstat);
411 + debugfs_remove(e->subdir);
412 + kfree(e->xmitstatus_buffer);
413 + kfree(e->xmitstatus_print_buffer);
417 +void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
418 + struct bcm43xx_xmitstatus *status)
420 + struct bcm43xx_dfsentry *e;
421 + struct bcm43xx_xmitstatus *savedstatus;
423 + /* This is protected by bcm->_lock */
426 + savedstatus = e->xmitstatus_buffer + e->xmitstatus_ptr;
427 + memcpy(savedstatus, status, sizeof(*status));
428 + e->xmitstatus_ptr++;
429 + if (e->xmitstatus_ptr >= BCM43xx_NR_LOGGED_XMITSTATUS)
430 + e->xmitstatus_ptr = 0;
431 + if (e->xmitstatus_cnt < BCM43xx_NR_LOGGED_XMITSTATUS)
432 + e->xmitstatus_cnt++;
435 +void bcm43xx_debugfs_init(void)
437 + memset(&fs, 0, sizeof(fs));
438 + fs.root = debugfs_create_dir(KBUILD_MODNAME, NULL);
440 + printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "\" subdir failed!\n");
441 + fs.dentry_driverinfo = debugfs_create_file("driver", 0444, fs.root, NULL, &drvinfo_fops);
442 + if (!fs.dentry_driverinfo)
443 + printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "/driver\" failed!\n");
446 +void bcm43xx_debugfs_exit(void)
448 + debugfs_remove(fs.dentry_driverinfo);
449 + debugfs_remove(fs.root);
452 +void bcm43xx_printk_dump(const char *data,
454 + const char *description)
459 + printk(KERN_INFO PFX "Data dump (%s, %u bytes):",
460 + description, size);
461 + for (i = 0; i < size; i++) {
464 + printk("\n" KERN_INFO PFX "0x%08x: 0x%02x, ", i, c & 0xff);
466 + printk("0x%02x, ", c & 0xff);
471 +void bcm43xx_printk_bitdump(const unsigned char *data,
472 + size_t bytes, int msb_to_lsb,
473 + const char *description)
477 + const unsigned char *d;
479 + printk(KERN_INFO PFX "*** Bitdump (%s, %u bytes, %s) ***",
480 + description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB");
481 + for (i = 0; i < bytes; i++) {
484 + printk("\n" KERN_INFO PFX "0x%08x: ", i);
486 + for (j = 7; j >= 0; j--) {
493 + for (j = 0; j < 8; j++) {
504 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.h linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.h
505 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.h 1970-01-01 01:00:00.000000000 +0100
506 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.h 2006-03-28 22:16:14.000000000 +0200
508 +#ifndef BCM43xx_DEBUGFS_H_
509 +#define BCM43xx_DEBUGFS_H_
511 +struct bcm43xx_private;
512 +struct bcm43xx_xmitstatus;
514 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
516 +#include <linux/list.h>
517 +#include <asm/semaphore.h>
521 +/* limited by the size of the "really_big_buffer" */
522 +#define BCM43xx_NR_LOGGED_XMITSTATUS 100
524 +struct bcm43xx_dfsentry {
525 + struct dentry *subdir;
526 + struct dentry *dentry_devinfo;
527 + struct dentry *dentry_spromdump;
528 + struct dentry *dentry_tsf;
529 + struct dentry *dentry_txstat;
531 + struct bcm43xx_private *bcm;
533 + /* saved xmitstatus. */
534 + struct bcm43xx_xmitstatus *xmitstatus_buffer;
535 + int xmitstatus_ptr;
536 + int xmitstatus_cnt;
537 + /* We need a seperate buffer while printing to avoid
538 + * concurrency issues. (New xmitstatus can arrive
539 + * while we are printing).
541 + struct bcm43xx_xmitstatus *xmitstatus_print_buffer;
542 + int saved_xmitstatus_ptr;
543 + int saved_xmitstatus_cnt;
544 + int xmitstatus_printing;
547 +struct bcm43xx_debugfs {
548 + struct dentry *root;
549 + struct dentry *dentry_driverinfo;
552 +void bcm43xx_debugfs_init(void);
553 +void bcm43xx_debugfs_exit(void);
554 +void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm);
555 +void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm);
556 +void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
557 + struct bcm43xx_xmitstatus *status);
559 +/* Debug helper: Dump binary data through printk. */
560 +void bcm43xx_printk_dump(const char *data,
562 + const char *description);
563 +/* Debug helper: Dump bitwise binary data through printk. */
564 +void bcm43xx_printk_bitdump(const unsigned char *data,
565 + size_t bytes, int msb_to_lsb,
566 + const char *description);
567 +#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) \
569 + bcm43xx_printk_bitdump((const unsigned char *)(pointer), \
570 + sizeof(*(pointer)), \
575 +#else /* CONFIG_BCM43XX_D80211_DEBUG*/
578 +void bcm43xx_debugfs_init(void) { }
580 +void bcm43xx_debugfs_exit(void) { }
582 +void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) { }
584 +void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) { }
586 +void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
587 + struct bcm43xx_xmitstatus *status) { }
590 +void bcm43xx_printk_dump(const char *data,
592 + const char *description)
596 +void bcm43xx_printk_bitdump(const unsigned char *data,
597 + size_t bytes, int msb_to_lsb,
598 + const char *description)
601 +#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) do { /* nothing */ } while (0)
603 +#endif /* CONFIG_BCM43XX_D80211_DEBUG*/
605 +/* Ugly helper macros to make incomplete code more verbose on runtime */
611 + printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n", \
612 + __FUNCTION__, __FILE__, __LINE__); \
620 + printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n", \
621 + __FUNCTION__, __FILE__, __LINE__); \
624 +#endif /* BCM43xx_DEBUGFS_H_ */
625 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.c linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.c
626 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.c 1970-01-01 01:00:00.000000000 +0100
627 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.c 2006-03-28 22:16:14.000000000 +0200
631 + Broadcom BCM43xx wireless driver
633 + DMA ringbuffer and descriptor allocation/management
635 + Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
637 + Some code in this file is derived from the b44.c driver
638 + Copyright (C) 2002 David S. Miller
639 + Copyright (C) Pekka Pietikainen
641 + This program is free software; you can redistribute it and/or modify
642 + it under the terms of the GNU General Public License as published by
643 + the Free Software Foundation; either version 2 of the License, or
644 + (at your option) any later version.
646 + This program is distributed in the hope that it will be useful,
647 + but WITHOUT ANY WARRANTY; without even the implied warranty of
648 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
649 + GNU General Public License for more details.
651 + You should have received a copy of the GNU General Public License
652 + along with this program; see the file COPYING. If not, write to
653 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
654 + Boston, MA 02110-1301, USA.
658 +#include "bcm43xx.h"
659 +#include "bcm43xx_dma.h"
660 +#include "bcm43xx_main.h"
661 +#include "bcm43xx_debugfs.h"
662 +#include "bcm43xx_power.h"
663 +#include "bcm43xx_xmit.h"
665 +#include <linux/dma-mapping.h>
666 +#include <linux/pci.h>
667 +#include <linux/delay.h>
668 +#include <linux/skbuff.h>
671 +static inline int free_slots(struct bcm43xx_dmaring *ring)
673 + return (ring->nr_slots - ring->used_slots);
676 +static inline int next_slot(struct bcm43xx_dmaring *ring, int slot)
678 + assert(slot >= -1 && slot <= ring->nr_slots - 1);
679 + if (slot == ring->nr_slots - 1)
684 +static inline int prev_slot(struct bcm43xx_dmaring *ring, int slot)
686 + assert(slot >= 0 && slot <= ring->nr_slots - 1);
688 + return ring->nr_slots - 1;
692 +/* Request a slot for usage. */
694 +int request_slot(struct bcm43xx_dmaring *ring)
699 + assert(!ring->suspended);
700 + assert(free_slots(ring) != 0);
702 + slot = next_slot(ring, ring->current_slot);
703 + ring->current_slot = slot;
704 + ring->used_slots++;
706 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
707 + if (ring->used_slots > ring->max_used_slots)
708 + ring->max_used_slots = ring->used_slots;
709 +#endif /* CONFIG_BCM43XX_D80211_DEBUG*/
714 +/* Return a slot to the free slots. */
716 +void return_slot(struct bcm43xx_dmaring *ring, int slot)
720 + ring->used_slots--;
724 +dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
725 + unsigned char *buf,
729 + dma_addr_t dmaaddr;
732 + dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
736 + dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
745 +void unmap_descbuffer(struct bcm43xx_dmaring *ring,
751 + dma_unmap_single(&ring->bcm->pci_dev->dev,
755 + dma_unmap_single(&ring->bcm->pci_dev->dev,
762 +void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,
768 + dma_sync_single_for_cpu(&ring->bcm->pci_dev->dev,
769 + addr, len, DMA_FROM_DEVICE);
773 +void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,
779 + dma_sync_single_for_device(&ring->bcm->pci_dev->dev,
780 + addr, len, DMA_FROM_DEVICE);
783 +/* Unmap and free a descriptor buffer. */
785 +void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
786 + struct bcm43xx_dmadesc *desc,
787 + struct bcm43xx_dmadesc_meta *meta,
792 + dev_kfree_skb_irq(meta->skb);
794 + dev_kfree_skb(meta->skb);
798 +static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
800 + struct device *dev = &(ring->bcm->pci_dev->dev);
802 + ring->vbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
803 + &(ring->dmabase), GFP_KERNEL);
804 + if (!ring->vbase) {
805 + printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
808 + if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) {
809 + printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G "
810 + "(0x%08x, len: %lu)\n",
811 + ring->dmabase, BCM43xx_DMA_RINGMEMSIZE);
812 + dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
813 + ring->vbase, ring->dmabase);
816 + assert(!(ring->dmabase & 0x000003FF));
817 + memset(ring->vbase, 0, BCM43xx_DMA_RINGMEMSIZE);
822 +static void free_ringmemory(struct bcm43xx_dmaring *ring)
824 + struct device *dev = &(ring->bcm->pci_dev->dev);
826 + dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
827 + ring->vbase, ring->dmabase);
830 +/* Reset the RX DMA channel */
831 +int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
837 + bcm43xx_write32(bcm,
838 + mmio_base + BCM43xx_DMA_RX_CONTROL,
840 + for (i = 0; i < 1000; i++) {
841 + value = bcm43xx_read32(bcm,
842 + mmio_base + BCM43xx_DMA_RX_STATUS);
843 + value &= BCM43xx_DMA_RXSTAT_STAT_MASK;
844 + if (value == BCM43xx_DMA_RXSTAT_STAT_DISABLED) {
851 + printk(KERN_ERR PFX "Error: Wait on DMA RX status timed out.\n");
858 +/* Reset the RX DMA channel */
859 +int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
865 + for (i = 0; i < 1000; i++) {
866 + value = bcm43xx_read32(bcm,
867 + mmio_base + BCM43xx_DMA_TX_STATUS);
868 + value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
869 + if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED ||
870 + value == BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT ||
871 + value == BCM43xx_DMA_TXSTAT_STAT_STOPPED)
875 + bcm43xx_write32(bcm,
876 + mmio_base + BCM43xx_DMA_TX_CONTROL,
878 + for (i = 0; i < 1000; i++) {
879 + value = bcm43xx_read32(bcm,
880 + mmio_base + BCM43xx_DMA_TX_STATUS);
881 + value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
882 + if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED) {
889 + printk(KERN_ERR PFX "Error: Wait on DMA TX status timed out.\n");
892 + /* ensure the reset is completed. */
898 +static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
899 + struct bcm43xx_dmadesc *desc,
900 + struct bcm43xx_dmadesc_meta *meta,
903 + struct bcm43xx_rxhdr *rxhdr;
904 + dma_addr_t dmaaddr;
907 + const int slot = (int)(desc - ring->vbase);
908 + struct sk_buff *skb;
910 + assert(slot >= 0 && slot < ring->nr_slots);
913 + skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
914 + if (unlikely(!skb))
916 + dmaaddr = map_descbuffer(ring, skb->data,
917 + ring->rx_buffersize, 0);
918 + if (unlikely(dmaaddr + ring->rx_buffersize > BCM43xx_DMA_BUSADDRMAX)) {
919 + unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
920 + dev_kfree_skb_any(skb);
921 + printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G "
922 + "(0x%08x, len: %u)\n",
923 + dmaaddr, ring->rx_buffersize);
927 + meta->dmaaddr = dmaaddr;
928 + skb->dev = ring->bcm->net_dev;
929 + desc_addr = (u32)(dmaaddr + ring->memoffset);
930 + desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK &
931 + (u32)(ring->rx_buffersize - ring->frameoffset));
932 + if (slot == ring->nr_slots - 1)
933 + desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
934 + set_desc_addr(desc, desc_addr);
935 + set_desc_ctl(desc, desc_ctl);
937 + rxhdr = (struct bcm43xx_rxhdr *)(skb->data);
938 + rxhdr->frame_length = 0;
944 +/* Allocate the initial descbuffers.
945 + * This is used for an RX ring only.
947 +static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring)
949 + int i, err = -ENOMEM;
950 + struct bcm43xx_dmadesc *desc;
951 + struct bcm43xx_dmadesc_meta *meta;
953 + for (i = 0; i < ring->nr_slots; i++) {
954 + desc = ring->vbase + i;
955 + meta = ring->meta + i;
957 + err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
961 + ring->used_slots = ring->nr_slots;
967 + for (i--; i >= 0; i--) {
968 + desc = ring->vbase + i;
969 + meta = ring->meta + i;
971 + unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
972 + dev_kfree_skb(meta->skb);
977 +/* Do initial setup of the DMA controller.
978 + * Reset the controller, write the ring busaddress
979 + * and switch the "enable" bit on.
981 +static int dmacontroller_setup(struct bcm43xx_dmaring *ring)
987 + /* Set Transmit Control register to "transmit enable" */
988 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
989 + BCM43xx_DMA_TXCTRL_ENABLE);
990 + /* Set Transmit Descriptor ring address. */
991 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING,
992 + ring->dmabase + ring->memoffset);
994 + err = alloc_initial_descbuffers(ring);
997 + /* Set Receive Control "receive enable" and frame offset */
998 + value = (ring->frameoffset << BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT);
999 + value |= BCM43xx_DMA_RXCTRL_ENABLE;
1000 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_CONTROL, value);
1001 + /* Set Receive Descriptor ring address. */
1002 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING,
1003 + ring->dmabase + ring->memoffset);
1004 + /* Init the descriptor pointer. */
1005 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, 200);
1012 +/* Shutdown the DMA controller. */
1013 +static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring)
1016 + bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base);
1017 + /* Zero out Transmit Descriptor ring address. */
1018 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, 0);
1020 + bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base);
1021 + /* Zero out Receive Descriptor ring address. */
1022 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, 0);
1026 +static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
1028 + struct bcm43xx_dmadesc *desc;
1029 + struct bcm43xx_dmadesc_meta *meta;
1032 + if (!ring->used_slots)
1034 + for (i = 0; i < ring->nr_slots; i++) {
1035 + desc = ring->vbase + i;
1036 + meta = ring->meta + i;
1043 + unmap_descbuffer(ring, meta->dmaaddr,
1044 + meta->skb->len, 1);
1046 + unmap_descbuffer(ring, meta->dmaaddr,
1047 + ring->rx_buffersize, 0);
1049 + free_descriptor_buffer(ring, desc, meta, 0);
1053 +/* Main initialization function. */
1055 +struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
1056 + u16 dma_controller_base,
1057 + int nr_descriptor_slots,
1060 + struct bcm43xx_dmaring *ring;
1063 + ring = kzalloc(sizeof(*ring), GFP_KERNEL);
1067 + ring->meta = kzalloc(sizeof(*ring->meta) * nr_descriptor_slots,
1070 + goto err_kfree_ring;
1072 + ring->memoffset = BCM43xx_DMA_DMABUSADDROFFSET;
1073 +#ifdef CONFIG_BCM947XX
1074 + if (bcm->pci_dev->bus->number == 0)
1075 + ring->memoffset = 0;
1079 + ring->nr_slots = nr_descriptor_slots;
1080 + ring->mmio_base = dma_controller_base;
1083 + ring->current_slot = -1;
1085 + switch (dma_controller_base) {
1086 + case BCM43xx_MMIO_DMA1_BASE:
1087 + ring->rx_buffersize = BCM43xx_DMA1_RXBUFFERSIZE;
1088 + ring->frameoffset = BCM43xx_DMA1_RX_FRAMEOFFSET;
1090 + case BCM43xx_MMIO_DMA4_BASE:
1091 + ring->rx_buffersize = BCM43xx_DMA4_RXBUFFERSIZE;
1092 + ring->frameoffset = BCM43xx_DMA4_RX_FRAMEOFFSET;
1099 + err = alloc_ringmemory(ring);
1101 + goto err_kfree_meta;
1102 + err = dmacontroller_setup(ring);
1104 + goto err_free_ringmemory;
1109 +err_free_ringmemory:
1110 + free_ringmemory(ring);
1112 + kfree(ring->meta);
1119 +/* Main cleanup function. */
1120 +static void bcm43xx_destroy_dmaring(struct bcm43xx_dmaring *ring)
1125 + dprintk(KERN_INFO PFX "DMA 0x%04x (%s) max used slots: %d/%d\n",
1127 + (ring->tx) ? "TX" : "RX",
1128 + ring->max_used_slots, ring->nr_slots);
1129 + /* Device IRQs are disabled prior entering this function,
1130 + * so no need to take care of concurrency with rx handler stuff.
1132 + dmacontroller_cleanup(ring);
1133 + free_all_descbuffers(ring);
1134 + free_ringmemory(ring);
1136 + kfree(ring->meta);
1140 +void bcm43xx_dma_free(struct bcm43xx_private *bcm)
1142 + struct bcm43xx_dma *dma;
1144 + if (bcm43xx_using_pio(bcm))
1146 + dma = bcm43xx_current_dma(bcm);
1148 + bcm43xx_destroy_dmaring(dma->rx_ring1);
1149 + dma->rx_ring1 = NULL;
1150 + bcm43xx_destroy_dmaring(dma->rx_ring0);
1151 + dma->rx_ring0 = NULL;
1152 + bcm43xx_destroy_dmaring(dma->tx_ring3);
1153 + dma->tx_ring3 = NULL;
1154 + bcm43xx_destroy_dmaring(dma->tx_ring2);
1155 + dma->tx_ring2 = NULL;
1156 + bcm43xx_destroy_dmaring(dma->tx_ring1);
1157 + dma->tx_ring1 = NULL;
1158 + bcm43xx_destroy_dmaring(dma->tx_ring0);
1159 + dma->tx_ring0 = NULL;
1162 +int bcm43xx_dma_init(struct bcm43xx_private *bcm)
1164 + struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
1165 + struct bcm43xx_dmaring *ring;
1166 + int err = -ENOMEM;
1168 + /* setup TX DMA channels. */
1169 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
1170 + BCM43xx_TXRING_SLOTS, 1);
1173 + dma->tx_ring0 = ring;
1175 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA2_BASE,
1176 + BCM43xx_TXRING_SLOTS, 1);
1178 + goto err_destroy_tx0;
1179 + dma->tx_ring1 = ring;
1181 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA3_BASE,
1182 + BCM43xx_TXRING_SLOTS, 1);
1184 + goto err_destroy_tx1;
1185 + dma->tx_ring2 = ring;
1187 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
1188 + BCM43xx_TXRING_SLOTS, 1);
1190 + goto err_destroy_tx2;
1191 + dma->tx_ring3 = ring;
1193 + /* setup RX DMA channels. */
1194 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
1195 + BCM43xx_RXRING_SLOTS, 0);
1197 + goto err_destroy_tx3;
1198 + dma->rx_ring0 = ring;
1200 + if (bcm->current_core->rev < 5) {
1201 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
1202 + BCM43xx_RXRING_SLOTS, 0);
1204 + goto err_destroy_rx0;
1205 + dma->rx_ring1 = ring;
1208 + dprintk(KERN_INFO PFX "DMA initialized\n");
1214 + bcm43xx_destroy_dmaring(dma->rx_ring0);
1215 + dma->rx_ring0 = NULL;
1217 + bcm43xx_destroy_dmaring(dma->tx_ring3);
1218 + dma->tx_ring3 = NULL;
1220 + bcm43xx_destroy_dmaring(dma->tx_ring2);
1221 + dma->tx_ring2 = NULL;
1223 + bcm43xx_destroy_dmaring(dma->tx_ring1);
1224 + dma->tx_ring1 = NULL;
1226 + bcm43xx_destroy_dmaring(dma->tx_ring0);
1227 + dma->tx_ring0 = NULL;
1231 +/* Generate a cookie for the TX header. */
1232 +static u16 generate_cookie(struct bcm43xx_dmaring *ring,
1235 + u16 cookie = 0x0000;
1237 + /* Use the upper 4 bits of the cookie as
1238 + * DMA controller ID and store the slot number
1239 + * in the lower 12 bits
1241 + switch (ring->mmio_base) {
1244 + case BCM43xx_MMIO_DMA1_BASE:
1246 + case BCM43xx_MMIO_DMA2_BASE:
1249 + case BCM43xx_MMIO_DMA3_BASE:
1252 + case BCM43xx_MMIO_DMA4_BASE:
1256 + assert(((u16)slot & 0xF000) == 0x0000);
1257 + cookie |= (u16)slot;
1262 +/* Inspect a cookie and find out to which controller/slot it belongs. */
1264 +struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm,
1265 + u16 cookie, int *slot)
1267 + struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
1268 + struct bcm43xx_dmaring *ring = NULL;
1270 + switch (cookie & 0xF000) {
1272 + ring = dma->tx_ring0;
1275 + ring = dma->tx_ring1;
1278 + ring = dma->tx_ring2;
1281 + ring = dma->tx_ring3;
1286 + *slot = (cookie & 0x0FFF);
1287 + assert(*slot >= 0 && *slot < ring->nr_slots);
1292 +static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
1295 + /* Everything is ready to start. Buffers are DMA mapped and
1296 + * associated with slots.
1297 + * "slot" is the last slot of the new frame we want to transmit.
1298 + * Close your seat belts now, please.
1301 + slot = next_slot(ring, slot);
1302 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_INDEX,
1303 + (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
1306 +static int dma_tx_fragment(struct bcm43xx_dmaring *ring,
1307 + struct sk_buff *skb,
1308 + struct ieee80211_tx_control *ctl)
1310 + struct sk_buff *hdr_skb;
1312 + struct bcm43xx_dmadesc *desc;
1313 + struct bcm43xx_dmadesc_meta *meta;
1317 + assert(skb_shinfo(skb)->nr_frags == 0);
1319 + hdr_skb = dev_alloc_skb(sizeof(struct bcm43xx_txhdr));
1320 + if (unlikely(!hdr_skb))
1322 + skb_put(hdr_skb, sizeof(struct bcm43xx_txhdr));
1324 + slot = request_slot(ring);
1325 + desc = ring->vbase + slot;
1326 + meta = ring->meta + slot;
1328 + bcm43xx_generate_txhdr(ring->bcm,
1329 + (struct bcm43xx_txhdr *)hdr_skb->data,
1330 + skb->data, skb->len,
1332 + generate_cookie(ring, slot),
1335 + meta->skb = hdr_skb;
1336 + meta->dmaaddr = map_descbuffer(ring, hdr_skb->data, hdr_skb->len, 1);
1337 + if (unlikely(meta->dmaaddr + hdr_skb->len > BCM43xx_DMA_BUSADDRMAX)) {
1338 + return_slot(ring, slot);
1339 + dev_kfree_skb_irq(hdr_skb);
1340 + printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G "
1341 + "(0x%08x, len: %u)\n",
1342 + meta->dmaaddr, hdr_skb->len);
1346 + desc_addr = (u32)(meta->dmaaddr + ring->memoffset);
1347 + desc_ctl = BCM43xx_DMADTOR_FRAMESTART |
1348 + (BCM43xx_DMADTOR_BYTECNT_MASK & (u32)(hdr_skb->len));
1349 + if (slot == ring->nr_slots - 1)
1350 + desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
1351 + set_desc_ctl(desc, desc_ctl);
1352 + set_desc_addr(desc, desc_addr);
1354 + slot = request_slot(ring);
1355 + desc = ring->vbase + slot;
1356 + meta = ring->meta + slot;
1358 + /* We inspect the txstatus on the FRAMESTART descriptor later
1359 + * on xmit-status IRQ.
1361 + meta->must_xmit_txstat = 1;
1362 + memset(&meta->txstat, 0, sizeof(meta->txstat));
1363 + memcpy(&meta->txstat.control, ctl, sizeof(*ctl));
1366 + meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
1367 + if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) {
1368 + return_slot(ring, prev_slot(ring, slot));
1369 + return_slot(ring, slot);
1370 + dev_kfree_skb_irq(hdr_skb);
1371 + printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G "
1372 + "(0x%08x, len: %u)\n",
1373 + meta->dmaaddr, skb->len);
1377 + desc_addr = (u32)(meta->dmaaddr + ring->memoffset);
1378 + desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK & (u32)(skb->len));
1379 + if (slot == ring->nr_slots - 1)
1380 + desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
1382 + desc_ctl |= BCM43xx_DMADTOR_FRAMEEND | BCM43xx_DMADTOR_COMPIRQ;
1383 + set_desc_ctl(desc, desc_ctl);
1384 + set_desc_addr(desc, desc_addr);
1385 + /* Now transfer the whole frame. */
1386 + dmacontroller_poke_tx(ring, slot);
1391 +int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
1392 + struct sk_buff *skb,
1393 + struct ieee80211_tx_control *ctl)
1395 + struct bcm43xx_dmaring *ring = bcm43xx_current_dma(bcm)->tx_ring1;
1400 +#define SLOTS_PER_PACKET 2
1401 + if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
1402 + /* This should never trigger, as the ieee80211 stack
1403 + * recognizes if the device queue is full and does
1404 + * not send data anymore.
1406 + printk(KERN_ERR PFX "DMA queue overflow\n");
1410 + err = dma_tx_fragment(ring, skb, ctl);
1412 + ring->nr_tx_packets++;
1417 +void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
1418 + struct bcm43xx_xmitstatus *status)
1420 + struct bcm43xx_dmaring *ring;
1421 + struct bcm43xx_dmadesc *desc;
1422 + struct bcm43xx_dmadesc_meta *meta;
1423 + int is_last_fragment;
1426 + ring = parse_cookie(bcm, status->cookie, &slot);
1429 + assert(get_desc_ctl(ring->vbase + slot) & BCM43xx_DMADTOR_FRAMESTART);
1431 + assert(slot >= 0 && slot < ring->nr_slots);
1432 + desc = ring->vbase + slot;
1433 + meta = ring->meta + slot;
1435 + is_last_fragment = !!(get_desc_ctl(desc) & BCM43xx_DMADTOR_FRAMEEND);
1436 + unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
1438 + if (meta->must_xmit_txstat) {
1439 + meta->must_xmit_txstat = 0;
1440 + /* Call back to inform the ieee80211 subsystem about the
1441 + * status of the transmission.
1442 + * Some fields of txstat are already filled in dma_tx().
1444 + meta->txstat.ack = !!(status->flags & BCM43xx_TXSTAT_FLAG_ACK);
1445 + meta->txstat.retry_count = status->cnt2 - 1;
1446 + //FIXME: Fill in more information?
1447 + ieee80211_tx_status_irqsafe(bcm->net_dev, meta->skb, &(meta->txstat));
1450 + free_descriptor_buffer(ring, desc, meta, 1);
1451 + /* Everything belonging to the slot is unmapped
1452 + * and freed, so we can return it.
1454 + return_slot(ring, slot);
1456 + if (is_last_fragment)
1458 + slot = next_slot(ring, slot);
1460 + bcm->stats.last_tx = jiffies;
1463 +void bcm43xx_dma_get_tx_stats(struct bcm43xx_private *bcm,
1464 + struct ieee80211_tx_queue_stats *stats)
1466 + struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
1467 + struct bcm43xx_dmaring *ring;
1468 + struct ieee80211_tx_queue_stats_data *data;
1470 + ring = dma->tx_ring1;
1471 + data = &(stats->data[0]);
1472 + data->len = ring->used_slots / SLOTS_PER_PACKET;
1473 + data->limit = ring->nr_slots / SLOTS_PER_PACKET;
1474 + data->count = ring->nr_tx_packets;
1477 +static void dma_rx(struct bcm43xx_dmaring *ring,
1480 + struct bcm43xx_dmadesc *desc;
1481 + struct bcm43xx_dmadesc_meta *meta;
1482 + struct bcm43xx_rxhdr *rxhdr;
1483 + struct sk_buff *skb;
1486 + dma_addr_t dmaaddr;
1488 + desc = ring->vbase + *slot;
1489 + meta = ring->meta + *slot;
1491 + sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
1494 + if (ring->mmio_base == BCM43xx_MMIO_DMA4_BASE) {
1495 + /* We received an xmit status. */
1496 + struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data;
1497 + struct bcm43xx_xmitstatus stat;
1499 + stat.cookie = le16_to_cpu(hw->cookie);
1500 + stat.flags = hw->flags;
1501 + stat.cnt1 = hw->cnt1;
1502 + stat.cnt2 = hw->cnt2;
1503 + stat.seq = le16_to_cpu(hw->seq);
1504 + stat.unknown = le16_to_cpu(hw->unknown);
1506 + bcm43xx_debugfs_log_txstat(ring->bcm, &stat);
1507 + bcm43xx_dma_handle_xmitstatus(ring->bcm, &stat);
1508 + /* recycle the descriptor buffer. */
1509 + sync_descbuffer_for_device(ring, meta->dmaaddr, ring->rx_buffersize);
1513 + rxhdr = (struct bcm43xx_rxhdr *)skb->data;
1514 + len = le16_to_cpu(rxhdr->frame_length);
1521 + len = le16_to_cpu(rxhdr->frame_length);
1522 + } while (len == 0 && i++ < 5);
1523 + if (unlikely(len == 0)) {
1524 + /* recycle the descriptor buffer. */
1525 + sync_descbuffer_for_device(ring, meta->dmaaddr,
1526 + ring->rx_buffersize);
1530 + if (unlikely(len > ring->rx_buffersize)) {
1531 + /* The data did not fit into one descriptor buffer
1532 + * and is split over multiple buffers.
1533 + * This should never happen, as we try to allocate buffers
1534 + * big enough. So simply ignore this packet.
1540 + desc = ring->vbase + *slot;
1541 + meta = ring->meta + *slot;
1542 + /* recycle the descriptor buffer. */
1543 + sync_descbuffer_for_device(ring, meta->dmaaddr,
1544 + ring->rx_buffersize);
1545 + *slot = next_slot(ring, *slot);
1547 + tmp -= ring->rx_buffersize;
1551 + printkl(KERN_ERR PFX "DMA RX buffer too small "
1552 + "(len: %u, buffer: %u, nr-dropped: %d)\n",
1553 + len, ring->rx_buffersize, cnt);
1557 + dmaaddr = meta->dmaaddr;
1558 + err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
1559 + if (unlikely(err)) {
1560 + dprintkl(KERN_ERR PFX "DMA RX: setup_rx_descbuffer() failed\n");
1561 + sync_descbuffer_for_device(ring, dmaaddr,
1562 + ring->rx_buffersize);
1566 + unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
1567 + skb_put(skb, len + ring->frameoffset);
1568 + skb_pull(skb, ring->frameoffset);
1570 + bcm43xx_rx(ring->bcm, skb, rxhdr);
1575 +void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
1579 + int slot, current_slot;
1580 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
1581 + int used_slots = 0;
1584 + assert(!ring->tx);
1585 + status = bcm43xx_dma_read(ring, BCM43xx_DMA_RX_STATUS);
1586 + descptr = (status & BCM43xx_DMA_RXSTAT_DPTR_MASK);
1587 + current_slot = descptr / sizeof(struct bcm43xx_dmadesc);
1588 + assert(current_slot >= 0 && current_slot < ring->nr_slots);
1590 + slot = ring->current_slot;
1591 + for ( ; slot != current_slot; slot = next_slot(ring, slot)) {
1592 + dma_rx(ring, &slot);
1593 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
1594 + if (++used_slots > ring->max_used_slots)
1595 + ring->max_used_slots = used_slots;
1598 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX,
1599 + (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
1600 + ring->current_slot = slot;
1603 +void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring)
1606 + bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1);
1607 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
1608 + bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
1609 + | BCM43xx_DMA_TXCTRL_SUSPEND);
1612 +void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
1615 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
1616 + bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
1617 + & ~BCM43xx_DMA_TXCTRL_SUSPEND);
1618 + bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1);
1620 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.h linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.h
1621 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.h 1970-01-01 01:00:00.000000000 +0100
1622 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.h 2006-03-28 22:16:14.000000000 +0200
1624 +#ifndef BCM43xx_DMA_H_
1625 +#define BCM43xx_DMA_H_
1627 +#include <linux/list.h>
1628 +#include <linux/spinlock.h>
1629 +#include <linux/workqueue.h>
1630 +#include <linux/linkage.h>
1631 +#include <asm/atomic.h>
1633 +#include "bcm43xx.h"
1636 +/* DMA-Interrupt reasons. */
1637 +#define BCM43xx_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \
1638 + | (1 << 14) | (1 << 15))
1639 +#define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13)
1640 +#define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
1642 +/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */
1643 +#define BCM43xx_DMA_TX_CONTROL 0x00
1644 +#define BCM43xx_DMA_TX_DESC_RING 0x04
1645 +#define BCM43xx_DMA_TX_DESC_INDEX 0x08
1646 +#define BCM43xx_DMA_TX_STATUS 0x0c
1647 +#define BCM43xx_DMA_RX_CONTROL 0x10
1648 +#define BCM43xx_DMA_RX_DESC_RING 0x14
1649 +#define BCM43xx_DMA_RX_DESC_INDEX 0x18
1650 +#define BCM43xx_DMA_RX_STATUS 0x1c
1652 +/* DMA controller channel control word values. */
1653 +#define BCM43xx_DMA_TXCTRL_ENABLE (1 << 0)
1654 +#define BCM43xx_DMA_TXCTRL_SUSPEND (1 << 1)
1655 +#define BCM43xx_DMA_TXCTRL_LOOPBACK (1 << 2)
1656 +#define BCM43xx_DMA_TXCTRL_FLUSH (1 << 4)
1657 +#define BCM43xx_DMA_RXCTRL_ENABLE (1 << 0)
1658 +#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK 0x000000fe
1659 +#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT 1
1660 +#define BCM43xx_DMA_RXCTRL_PIO (1 << 8)
1661 +/* DMA controller channel status word values. */
1662 +#define BCM43xx_DMA_TXSTAT_DPTR_MASK 0x00000fff
1663 +#define BCM43xx_DMA_TXSTAT_STAT_MASK 0x0000f000
1664 +#define BCM43xx_DMA_TXSTAT_STAT_DISABLED 0x00000000
1665 +#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE 0x00001000
1666 +#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT 0x00002000
1667 +#define BCM43xx_DMA_TXSTAT_STAT_STOPPED 0x00003000
1668 +#define BCM43xx_DMA_TXSTAT_STAT_SUSP 0x00004000
1669 +#define BCM43xx_DMA_TXSTAT_ERROR_MASK 0x000f0000
1670 +#define BCM43xx_DMA_TXSTAT_FLUSHED (1 << 20)
1671 +#define BCM43xx_DMA_RXSTAT_DPTR_MASK 0x00000fff
1672 +#define BCM43xx_DMA_RXSTAT_STAT_MASK 0x0000f000
1673 +#define BCM43xx_DMA_RXSTAT_STAT_DISABLED 0x00000000
1674 +#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE 0x00001000
1675 +#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT 0x00002000
1676 +#define BCM43xx_DMA_RXSTAT_STAT_RESERVED 0x00003000
1677 +#define BCM43xx_DMA_RXSTAT_STAT_ERRORS 0x00004000
1678 +#define BCM43xx_DMA_RXSTAT_ERROR_MASK 0x000f0000
1680 +/* DMA descriptor control field values. */
1681 +#define BCM43xx_DMADTOR_BYTECNT_MASK 0x00001fff
1682 +#define BCM43xx_DMADTOR_DTABLEEND (1 << 28) /* End of descriptor table */
1683 +#define BCM43xx_DMADTOR_COMPIRQ (1 << 29) /* IRQ on completion request */
1684 +#define BCM43xx_DMADTOR_FRAMEEND (1 << 30)
1685 +#define BCM43xx_DMADTOR_FRAMESTART (1 << 31)
1687 +/* Misc DMA constants */
1688 +#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE
1689 +#define BCM43xx_DMA_BUSADDRMAX 0x3FFFFFFF
1690 +#define BCM43xx_DMA_DMABUSADDROFFSET (1 << 30)
1691 +#define BCM43xx_DMA1_RX_FRAMEOFFSET 30
1692 +#define BCM43xx_DMA4_RX_FRAMEOFFSET 0
1694 +/* DMA engine tuning knobs */
1695 +#define BCM43xx_TXRING_SLOTS 512
1696 +#define BCM43xx_RXRING_SLOTS 64
1697 +#define BCM43xx_DMA1_RXBUFFERSIZE (2304 + 100)
1698 +#define BCM43xx_DMA4_RXBUFFERSIZE 16
1702 +#ifdef CONFIG_BCM43XX_D80211_DMA
1706 +struct bcm43xx_private;
1707 +struct bcm43xx_xmitstatus;
1710 +struct bcm43xx_dmadesc {
1713 +} __attribute__((__packed__));
1715 +/* Macros to access the bcm43xx_dmadesc struct */
1716 +#define get_desc_ctl(desc) le32_to_cpu((desc)->_control)
1717 +#define set_desc_ctl(desc, ctl) do { (desc)->_control = cpu_to_le32(ctl); } while (0)
1718 +#define get_desc_addr(desc) le32_to_cpu((desc)->_address)
1719 +#define set_desc_addr(desc, addr) do { (desc)->_address = cpu_to_le32(addr); } while (0)
1721 +struct bcm43xx_dmadesc_meta {
1722 + /* The kernel DMA-able buffer. */
1723 + struct sk_buff *skb;
1724 + /* DMA base bus-address of the descriptor buffer. */
1725 + dma_addr_t dmaaddr;
1726 + /* ieee80211 TX status. Only used once per 802.11 frag. */
1727 + u8 must_xmit_txstat:1;
1728 + struct ieee80211_tx_status txstat;
1731 +struct bcm43xx_dmaring {
1732 + struct bcm43xx_private *bcm;
1733 + /* Kernel virtual base address of the ring memory. */
1734 + struct bcm43xx_dmadesc *vbase;
1735 + /* DMA memory offset */
1736 + dma_addr_t memoffset;
1737 + /* (Unadjusted) DMA base bus-address of the ring memory. */
1738 + dma_addr_t dmabase;
1739 + /* Meta data about all descriptors. */
1740 + struct bcm43xx_dmadesc_meta *meta;
1741 + /* Number of descriptor slots in the ring. */
1743 + /* Number of used descriptor slots. */
1745 + /* Currently used slot in the ring. */
1747 + /* Total number of packets sent. Statistics only. */
1748 + unsigned int nr_tx_packets;
1749 + /* Frameoffset in octets. */
1751 + /* Descriptor buffer size. */
1752 + u16 rx_buffersize;
1753 + /* The MMIO base register of the DMA controller, this
1754 + * ring is posted to.
1757 + u8 tx:1, /* TRUE, if this is a TX ring. */
1758 + suspended:1; /* TRUE, if transfers are suspended on this ring. */
1759 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
1760 + /* Maximum number of used slots. */
1761 + int max_used_slots;
1762 +#endif /* CONFIG_BCM43XX_D80211_DEBUG*/
1767 +u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring,
1770 + return bcm43xx_read32(ring->bcm, ring->mmio_base + offset);
1774 +void bcm43xx_dma_write(struct bcm43xx_dmaring *ring,
1775 + u16 offset, u32 value)
1777 + bcm43xx_write32(ring->bcm, ring->mmio_base + offset, value);
1781 +int bcm43xx_dma_init(struct bcm43xx_private *bcm);
1782 +void bcm43xx_dma_free(struct bcm43xx_private *bcm);
1784 +int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
1785 + u16 dmacontroller_mmio_base);
1786 +int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
1787 + u16 dmacontroller_mmio_base);
1789 +void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring);
1790 +void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring);
1792 +void bcm43xx_dma_get_tx_stats(struct bcm43xx_private *bcm,
1793 + struct ieee80211_tx_queue_stats *stats);
1795 +int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
1796 + struct sk_buff *skb,
1797 + struct ieee80211_tx_control *ctl);
1798 +void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
1799 + struct bcm43xx_xmitstatus *status);
1801 +void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
1804 +#else /* CONFIG_BCM43XX_D80211_DMA */
1808 +int bcm43xx_dma_init(struct bcm43xx_private *bcm)
1813 +void bcm43xx_dma_free(struct bcm43xx_private *bcm)
1817 +int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
1818 + u16 dmacontroller_mmio_base)
1823 +int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
1824 + u16 dmacontroller_mmio_base)
1829 +void bcm43xx_dma_get_tx_stats(struct bcm43xx_private *bcm,
1830 + struct ieee80211_tx_queue_stats *stats)
1834 +int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
1835 + struct sk_buff *skb,
1836 + struct ieee80211_tx_control *ctl)
1841 +void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
1842 + struct bcm43xx_xmitstatus *status)
1846 +void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
1850 +#endif /* CONFIG_BCM43XX_D80211_DMA */
1851 +#endif /* BCM43xx_DMA_H_ */
1852 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.c linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.c
1853 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100
1854 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.c 2006-03-28 22:16:14.000000000 +0200
1858 + Broadcom BCM43xx wireless driver
1862 + Copyright (c) 2006 Jason Lunz <lunz@falooley.org>
1864 + Some code in this file is derived from the 8139too.c driver
1865 + Copyright (C) 2002 Jeff Garzik
1867 + This program is free software; you can redistribute it and/or modify
1868 + it under the terms of the GNU General Public License as published by
1869 + the Free Software Foundation; either version 2 of the License, or
1870 + (at your option) any later version.
1872 + This program is distributed in the hope that it will be useful,
1873 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1874 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1875 + GNU General Public License for more details.
1877 + You should have received a copy of the GNU General Public License
1878 + along with this program; see the file COPYING. If not, write to
1879 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
1880 + Boston, MA 02110-1301, USA.
1884 +#include "bcm43xx.h"
1885 +#include "bcm43xx_ethtool.h"
1887 +#include <linux/netdevice.h>
1888 +#include <linux/pci.h>
1889 +#include <linux/string.h>
1890 +#include <linux/version.h>
1893 +static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1895 + struct bcm43xx_private *bcm = bcm43xx_priv(dev);
1897 + strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
1898 + strncpy(info->version, UTS_RELEASE, sizeof(info->version));
1899 + strncpy(info->bus_info, pci_name(bcm->pci_dev), ETHTOOL_BUSINFO_LEN);
1902 +struct ethtool_ops bcm43xx_ethtool_ops = {
1903 + .get_drvinfo = bcm43xx_get_drvinfo,
1904 + .get_link = ethtool_op_get_link,
1906 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.h linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.h
1907 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.h 1970-01-01 01:00:00.000000000 +0100
1908 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.h 2006-03-28 22:16:14.000000000 +0200
1910 +#ifndef BCM43xx_ETHTOOL_H_
1911 +#define BCM43xx_ETHTOOL_H_
1913 +#include <linux/ethtool.h>
1915 +extern struct ethtool_ops bcm43xx_ethtool_ops;
1917 +#endif /* BCM43xx_ETHTOOL_H_ */
1918 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h
1919 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h 1970-01-01 01:00:00.000000000 +0100
1920 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h 2006-03-28 22:16:14.000000000 +0200
1925 +#include <linux/version.h>
1926 +#include <linux/kernel.h>
1927 +#include <linux/spinlock.h>
1928 +#include <linux/interrupt.h>
1929 +#include <linux/stringify.h>
1930 +#include <linux/netdevice.h>
1931 +#include <linux/pci.h>
1932 +#include <asm/atomic.h>
1933 +#include <asm/io.h>
1935 +#include <linux/wireless.h>
1936 +#include <net/d80211.h>
1937 +#include <net/d80211_mgmt.h>
1938 +#include <net/d80211_common.h>
1940 +#include "bcm43xx_debugfs.h"
1941 +#include "bcm43xx_leds.h"
1942 +#include "bcm43xx_sysfs.h"
1945 +#define PFX KBUILD_MODNAME ": "
1947 +#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50
1948 +#define BCM43xx_IRQWAIT_MAX_RETRIES 50
1950 +#define BCM43xx_IO_SIZE 8192
1952 +/* Active Core PCI Configuration Register. */
1953 +#define BCM43xx_PCICFG_ACTIVE_CORE 0x80
1954 +/* SPROM control register. */
1955 +#define BCM43xx_PCICFG_SPROMCTL 0x88
1956 +/* Interrupt Control PCI Configuration Register. (Only on PCI cores with rev >= 6) */
1957 +#define BCM43xx_PCICFG_ICR 0x94
1960 +#define BCM43xx_MMIO_DMA1_REASON 0x20
1961 +#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x24
1962 +#define BCM43xx_MMIO_DMA2_REASON 0x28
1963 +#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x2C
1964 +#define BCM43xx_MMIO_DMA3_REASON 0x30
1965 +#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x34
1966 +#define BCM43xx_MMIO_DMA4_REASON 0x38
1967 +#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x3C
1968 +#define BCM43xx_MMIO_STATUS_BITFIELD 0x120
1969 +#define BCM43xx_MMIO_STATUS2_BITFIELD 0x124
1970 +#define BCM43xx_MMIO_GEN_IRQ_REASON 0x128
1971 +#define BCM43xx_MMIO_GEN_IRQ_MASK 0x12C
1972 +#define BCM43xx_MMIO_RAM_CONTROL 0x130
1973 +#define BCM43xx_MMIO_RAM_DATA 0x134
1974 +#define BCM43xx_MMIO_PS_STATUS 0x140
1975 +#define BCM43xx_MMIO_RADIO_HWENABLED_HI 0x158
1976 +#define BCM43xx_MMIO_SHM_CONTROL 0x160
1977 +#define BCM43xx_MMIO_SHM_DATA 0x164
1978 +#define BCM43xx_MMIO_SHM_DATA_UNALIGNED 0x166
1979 +#define BCM43xx_MMIO_XMITSTAT_0 0x170
1980 +#define BCM43xx_MMIO_XMITSTAT_1 0x174
1981 +#define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */
1982 +#define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
1983 +#define BCM43xx_MMIO_DMA1_BASE 0x200
1984 +#define BCM43xx_MMIO_DMA2_BASE 0x220
1985 +#define BCM43xx_MMIO_DMA3_BASE 0x240
1986 +#define BCM43xx_MMIO_DMA4_BASE 0x260
1987 +#define BCM43xx_MMIO_PIO1_BASE 0x300
1988 +#define BCM43xx_MMIO_PIO2_BASE 0x310
1989 +#define BCM43xx_MMIO_PIO3_BASE 0x320
1990 +#define BCM43xx_MMIO_PIO4_BASE 0x330
1991 +#define BCM43xx_MMIO_PHY_VER 0x3E0
1992 +#define BCM43xx_MMIO_PHY_RADIO 0x3E2
1993 +#define BCM43xx_MMIO_ANTENNA 0x3E8
1994 +#define BCM43xx_MMIO_CHANNEL 0x3F0
1995 +#define BCM43xx_MMIO_CHANNEL_EXT 0x3F4
1996 +#define BCM43xx_MMIO_RADIO_CONTROL 0x3F6
1997 +#define BCM43xx_MMIO_RADIO_DATA_HIGH 0x3F8
1998 +#define BCM43xx_MMIO_RADIO_DATA_LOW 0x3FA
1999 +#define BCM43xx_MMIO_PHY_CONTROL 0x3FC
2000 +#define BCM43xx_MMIO_PHY_DATA 0x3FE
2001 +#define BCM43xx_MMIO_MACFILTER_CONTROL 0x420
2002 +#define BCM43xx_MMIO_MACFILTER_DATA 0x422
2003 +#define BCM43xx_MMIO_RADIO_HWENABLED_LO 0x49A
2004 +#define BCM43xx_MMIO_GPIO_CONTROL 0x49C
2005 +#define BCM43xx_MMIO_GPIO_MASK 0x49E
2006 +#define BCM43xx_MMIO_TSF_0 0x632 /* core rev < 3 only */
2007 +#define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */
2008 +#define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */
2009 +#define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */
2010 +#define BCM43xx_MMIO_POWERUP_DELAY 0x6A8
2012 +/* SPROM offsets. */
2013 +#define BCM43xx_SPROM_BASE 0x1000
2014 +#define BCM43xx_SPROM_BOARDFLAGS2 0x1c
2015 +#define BCM43xx_SPROM_IL0MACADDR 0x24
2016 +#define BCM43xx_SPROM_ET0MACADDR 0x27
2017 +#define BCM43xx_SPROM_ET1MACADDR 0x2a
2018 +#define BCM43xx_SPROM_ETHPHY 0x2d
2019 +#define BCM43xx_SPROM_BOARDREV 0x2e
2020 +#define BCM43xx_SPROM_PA0B0 0x2f
2021 +#define BCM43xx_SPROM_PA0B1 0x30
2022 +#define BCM43xx_SPROM_PA0B2 0x31
2023 +#define BCM43xx_SPROM_WL0GPIO0 0x32
2024 +#define BCM43xx_SPROM_WL0GPIO2 0x33
2025 +#define BCM43xx_SPROM_MAXPWR 0x34
2026 +#define BCM43xx_SPROM_PA1B0 0x35
2027 +#define BCM43xx_SPROM_PA1B1 0x36
2028 +#define BCM43xx_SPROM_PA1B2 0x37
2029 +#define BCM43xx_SPROM_IDL_TSSI_TGT 0x38
2030 +#define BCM43xx_SPROM_BOARDFLAGS 0x39
2031 +#define BCM43xx_SPROM_ANTENNA_GAIN 0x3a
2032 +#define BCM43xx_SPROM_VERSION 0x3f
2034 +/* BCM43xx_SPROM_BOARDFLAGS values */
2035 +#define BCM43xx_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
2036 +#define BCM43xx_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */
2037 +#define BCM43xx_BFL_AIRLINEMODE 0x0004 /* implements GPIO 13 radio disable indication */
2038 +#define BCM43xx_BFL_RSSI 0x0008 /* software calculates nrssi slope. */
2039 +#define BCM43xx_BFL_ENETSPI 0x0010 /* has ephy roboswitch spi */
2040 +#define BCM43xx_BFL_XTAL_NOSLOW 0x0020 /* no slow clock available */
2041 +#define BCM43xx_BFL_CCKHIPWR 0x0040 /* can do high power CCK transmission */
2042 +#define BCM43xx_BFL_ENETADM 0x0080 /* has ADMtek switch */
2043 +#define BCM43xx_BFL_ENETVLAN 0x0100 /* can do vlan */
2044 +#define BCM43xx_BFL_AFTERBURNER 0x0200 /* supports Afterburner mode */
2045 +#define BCM43xx_BFL_NOPCI 0x0400 /* leaves PCI floating */
2046 +#define BCM43xx_BFL_FEM 0x0800 /* supports the Front End Module */
2047 +#define BCM43xx_BFL_EXTLNA 0x1000 /* has an external LNA */
2048 +#define BCM43xx_BFL_HGPA 0x2000 /* had high gain PA */
2049 +#define BCM43xx_BFL_BTCMOD 0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */
2050 +#define BCM43xx_BFL_ALTIQ 0x8000 /* alternate I/Q settings */
2052 +/* GPIO register offset, in both ChipCommon and PCI core. */
2053 +#define BCM43xx_GPIO_CONTROL 0x6c
2056 +#define BCM43xx_SHM_SHARED 0x0001
2057 +#define BCM43xx_SHM_WIRELESS 0x0002
2058 +#define BCM43xx_SHM_PCM 0x0003
2059 +#define BCM43xx_SHM_HWMAC 0x0004
2060 +#define BCM43xx_SHM_UCODE 0x0300
2062 +/* MacFilter offsets. */
2063 +#define BCM43xx_MACFILTER_SELF 0x0000
2064 +#define BCM43xx_MACFILTER_ASSOC 0x0003
2066 +/* Chipcommon registers. */
2067 +#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04
2068 +#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0
2069 +#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4
2070 +#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8
2071 +#define BCM43xx_CHIPCOMMON_SYSCLKCTL 0xC0
2073 +/* PCI core specific registers. */
2074 +#define BCM43xx_PCICORE_BCAST_ADDR 0x50
2075 +#define BCM43xx_PCICORE_BCAST_DATA 0x54
2076 +#define BCM43xx_PCICORE_SBTOPCI2 0x108
2078 +/* SBTOPCI2 values. */
2079 +#define BCM43xx_SBTOPCI2_PREFETCH 0x4
2080 +#define BCM43xx_SBTOPCI2_BURST 0x8
2082 +/* Chipcommon capabilities. */
2083 +#define BCM43xx_CAPABILITIES_PCTL 0x00040000
2084 +#define BCM43xx_CAPABILITIES_PLLMASK 0x00030000
2085 +#define BCM43xx_CAPABILITIES_PLLSHIFT 16
2086 +#define BCM43xx_CAPABILITIES_FLASHMASK 0x00000700
2087 +#define BCM43xx_CAPABILITIES_FLASHSHIFT 8
2088 +#define BCM43xx_CAPABILITIES_EXTBUSPRESENT 0x00000040
2089 +#define BCM43xx_CAPABILITIES_UARTGPIO 0x00000020
2090 +#define BCM43xx_CAPABILITIES_UARTCLOCKMASK 0x00000018
2091 +#define BCM43xx_CAPABILITIES_UARTCLOCKSHIFT 3
2092 +#define BCM43xx_CAPABILITIES_MIPSBIGENDIAN 0x00000004
2093 +#define BCM43xx_CAPABILITIES_NRUARTSMASK 0x00000003
2096 +#define BCM43xx_PCTL_IN 0xB0
2097 +#define BCM43xx_PCTL_OUT 0xB4
2098 +#define BCM43xx_PCTL_OUTENABLE 0xB8
2099 +#define BCM43xx_PCTL_XTAL_POWERUP 0x40
2100 +#define BCM43xx_PCTL_PLL_POWERDOWN 0x80
2102 +/* PowerControl Clock Modes */
2103 +#define BCM43xx_PCTL_CLK_FAST 0x00
2104 +#define BCM43xx_PCTL_CLK_SLOW 0x01
2105 +#define BCM43xx_PCTL_CLK_DYNAMIC 0x02
2107 +#define BCM43xx_PCTL_FORCE_SLOW 0x0800
2108 +#define BCM43xx_PCTL_FORCE_PLL 0x1000
2109 +#define BCM43xx_PCTL_DYN_XTAL 0x2000
2112 +#define BCM43xx_COREID_CHIPCOMMON 0x800
2113 +#define BCM43xx_COREID_ILINE20 0x801
2114 +#define BCM43xx_COREID_SDRAM 0x803
2115 +#define BCM43xx_COREID_PCI 0x804
2116 +#define BCM43xx_COREID_MIPS 0x805
2117 +#define BCM43xx_COREID_ETHERNET 0x806
2118 +#define BCM43xx_COREID_V90 0x807
2119 +#define BCM43xx_COREID_USB11_HOSTDEV 0x80a
2120 +#define BCM43xx_COREID_IPSEC 0x80b
2121 +#define BCM43xx_COREID_PCMCIA 0x80d
2122 +#define BCM43xx_COREID_EXT_IF 0x80f
2123 +#define BCM43xx_COREID_80211 0x812
2124 +#define BCM43xx_COREID_MIPS_3302 0x816
2125 +#define BCM43xx_COREID_USB11_HOST 0x817
2126 +#define BCM43xx_COREID_USB11_DEV 0x818
2127 +#define BCM43xx_COREID_USB20_HOST 0x819
2128 +#define BCM43xx_COREID_USB20_DEV 0x81a
2129 +#define BCM43xx_COREID_SDIO_HOST 0x81b
2131 +/* Core Information Registers */
2132 +#define BCM43xx_CIR_BASE 0xf00
2133 +#define BCM43xx_CIR_SBTPSFLAG (BCM43xx_CIR_BASE + 0x18)
2134 +#define BCM43xx_CIR_SBIMSTATE (BCM43xx_CIR_BASE + 0x90)
2135 +#define BCM43xx_CIR_SBINTVEC (BCM43xx_CIR_BASE + 0x94)
2136 +#define BCM43xx_CIR_SBTMSTATELOW (BCM43xx_CIR_BASE + 0x98)
2137 +#define BCM43xx_CIR_SBTMSTATEHIGH (BCM43xx_CIR_BASE + 0x9c)
2138 +#define BCM43xx_CIR_SBIMCONFIGLOW (BCM43xx_CIR_BASE + 0xa8)
2139 +#define BCM43xx_CIR_SB_ID_HI (BCM43xx_CIR_BASE + 0xfc)
2141 +/* Mask to get the Backplane Flag Number from SBTPSFLAG. */
2142 +#define BCM43xx_BACKPLANE_FLAG_NR_MASK 0x3f
2144 +/* SBIMCONFIGLOW values/masks. */
2145 +#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK 0x00000007
2146 +#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT 0
2147 +#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK 0x00000070
2148 +#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT 4
2149 +#define BCM43xx_SBIMCONFIGLOW_CONNID_MASK 0x00ff0000
2150 +#define BCM43xx_SBIMCONFIGLOW_CONNID_SHIFT 16
2152 +/* sbtmstatelow state flags */
2153 +#define BCM43xx_SBTMSTATELOW_RESET 0x01
2154 +#define BCM43xx_SBTMSTATELOW_REJECT 0x02
2155 +#define BCM43xx_SBTMSTATELOW_CLOCK 0x10000
2156 +#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000
2158 +/* sbtmstatehigh state flags */
2159 +#define BCM43xx_SBTMSTATEHIGH_SERROR 0x1
2160 +#define BCM43xx_SBTMSTATEHIGH_BUSY 0x4
2162 +/* sbimstate flags */
2163 +#define BCM43xx_SBIMSTATE_IB_ERROR 0x20000
2164 +#define BCM43xx_SBIMSTATE_TIMEOUT 0x40000
2166 +/* PHYVersioning */
2167 +#define BCM43xx_PHYTYPE_A 0x00
2168 +#define BCM43xx_PHYTYPE_B 0x01
2169 +#define BCM43xx_PHYTYPE_G 0x02
2172 +#define BCM43xx_PHY_ILT_A_CTRL 0x0072
2173 +#define BCM43xx_PHY_ILT_A_DATA1 0x0073
2174 +#define BCM43xx_PHY_ILT_A_DATA2 0x0074
2175 +#define BCM43xx_PHY_G_LO_CONTROL 0x0810
2176 +#define BCM43xx_PHY_ILT_G_CTRL 0x0472
2177 +#define BCM43xx_PHY_ILT_G_DATA1 0x0473
2178 +#define BCM43xx_PHY_ILT_G_DATA2 0x0474
2179 +#define BCM43xx_PHY_A_PCTL 0x007B
2180 +#define BCM43xx_PHY_G_PCTL 0x0029
2181 +#define BCM43xx_PHY_A_CRS 0x0029
2182 +#define BCM43xx_PHY_RADIO_BITFIELD 0x0401
2183 +#define BCM43xx_PHY_G_CRS 0x0429
2184 +#define BCM43xx_PHY_NRSSILT_CTRL 0x0803
2185 +#define BCM43xx_PHY_NRSSILT_DATA 0x0804
2187 +/* RadioRegisters */
2188 +#define BCM43xx_RADIOCTL_ID 0x01
2190 +/* StatusBitField */
2191 +#define BCM43xx_SBF_MAC_ENABLED 0x00000001
2192 +#define BCM43xx_SBF_2 0x00000002 /*FIXME: fix name*/
2193 +#define BCM43xx_SBF_CORE_READY 0x00000004
2194 +#define BCM43xx_SBF_400 0x00000400 /*FIXME: fix name*/
2195 +#define BCM43xx_SBF_4000 0x00004000 /*FIXME: fix name*/
2196 +#define BCM43xx_SBF_8000 0x00008000 /*FIXME: fix name*/
2197 +#define BCM43xx_SBF_XFER_REG_BYTESWAP 0x00010000
2198 +#define BCM43xx_SBF_MODE_NOTADHOC 0x00020000
2199 +#define BCM43xx_SBF_MODE_AP 0x00040000
2200 +#define BCM43xx_SBF_RADIOREG_LOCK 0x00080000
2201 +#define BCM43xx_SBF_MODE_MONITOR 0x00400000
2202 +#define BCM43xx_SBF_MODE_PROMISC 0x01000000
2203 +#define BCM43xx_SBF_PS1 0x02000000
2204 +#define BCM43xx_SBF_PS2 0x04000000
2205 +#define BCM43xx_SBF_NO_SSID_BCAST 0x08000000
2206 +#define BCM43xx_SBF_TIME_UPDATE 0x10000000
2207 +#define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/
2209 +/* MicrocodeFlagsBitfield (addr + lo-word values?)*/
2210 +#define BCM43xx_UCODEFLAGS_OFFSET 0x005E
2212 +#define BCM43xx_UCODEFLAG_AUTODIV 0x0001
2213 +#define BCM43xx_UCODEFLAG_UNKBGPHY 0x0002
2214 +#define BCM43xx_UCODEFLAG_UNKBPHY 0x0004
2215 +#define BCM43xx_UCODEFLAG_UNKGPHY 0x0020
2216 +#define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040
2217 +#define BCM43xx_UCODEFLAG_JAPAN 0x0080
2219 +/* Generic-Interrupt reasons. */
2220 +#define BCM43xx_IRQ_READY (1 << 0)
2221 +#define BCM43xx_IRQ_BEACON (1 << 1)
2222 +#define BCM43xx_IRQ_PS (1 << 2)
2223 +#define BCM43xx_IRQ_REG124 (1 << 5)
2224 +#define BCM43xx_IRQ_PMQ (1 << 6)
2225 +#define BCM43xx_IRQ_PIO_WORKAROUND (1 << 8)
2226 +#define BCM43xx_IRQ_XMIT_ERROR (1 << 11)
2227 +#define BCM43xx_IRQ_RX (1 << 15)
2228 +#define BCM43xx_IRQ_SCAN (1 << 16)
2229 +#define BCM43xx_IRQ_NOISE (1 << 18)
2230 +#define BCM43xx_IRQ_XMIT_STATUS (1 << 29)
2232 +#define BCM43xx_IRQ_ALL 0xffffffff
2233 +#define BCM43xx_IRQ_INITIAL (BCM43xx_IRQ_PS | \
2234 + BCM43xx_IRQ_REG124 | \
2235 + BCM43xx_IRQ_PMQ | \
2236 + BCM43xx_IRQ_XMIT_ERROR | \
2237 + BCM43xx_IRQ_RX | \
2238 + BCM43xx_IRQ_SCAN | \
2239 + BCM43xx_IRQ_NOISE | \
2240 + BCM43xx_IRQ_XMIT_STATUS)
2242 +/* Bus type PCI. */
2243 +#define BCM43xx_BUSTYPE_PCI 0
2244 +/* Bus type Silicone Backplane Bus. */
2245 +#define BCM43xx_BUSTYPE_SB 1
2246 +/* Bus type PCMCIA. */
2247 +#define BCM43xx_BUSTYPE_PCMCIA 2
2250 +#define BCM43xx_CCK_RATE_1MB 0x02
2251 +#define BCM43xx_CCK_RATE_2MB 0x04
2252 +#define BCM43xx_CCK_RATE_5MB 0x0B
2253 +#define BCM43xx_CCK_RATE_11MB 0x16
2254 +#define BCM43xx_OFDM_RATE_6MB 0x0C
2255 +#define BCM43xx_OFDM_RATE_9MB 0x12
2256 +#define BCM43xx_OFDM_RATE_12MB 0x18
2257 +#define BCM43xx_OFDM_RATE_18MB 0x24
2258 +#define BCM43xx_OFDM_RATE_24MB 0x30
2259 +#define BCM43xx_OFDM_RATE_36MB 0x48
2260 +#define BCM43xx_OFDM_RATE_48MB 0x60
2261 +#define BCM43xx_OFDM_RATE_54MB 0x6C
2263 +#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7
2264 +#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4
2266 +/* Max size of a security key */
2267 +#define BCM43xx_SEC_KEYSIZE 16
2268 +/* Security algorithms. */
2270 + BCM43xx_SEC_ALGO_NONE = 0, /* unencrypted, as of TX header. */
2271 + BCM43xx_SEC_ALGO_WEP,
2272 + BCM43xx_SEC_ALGO_UNKNOWN,
2273 + BCM43xx_SEC_ALGO_AES,
2274 + BCM43xx_SEC_ALGO_WEP104,
2275 + BCM43xx_SEC_ALGO_TKIP,
2282 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2283 +#define assert(expr) \
2285 + if (unlikely(!(expr))) { \
2286 + printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", \
2287 + #expr, __FILE__, __LINE__, __FUNCTION__); \
2291 +#define assert(expr) do { /* nothing */ } while (0)
2294 +/* rate limited printk(). */
2298 +#define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0)
2299 +/* rate limited printk() for debugging */
2303 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2304 +# define dprintkl printkl
2306 +# define dprintkl(f, x...) do { /* nothing */ } while (0)
2309 +/* debugging printk() */
2313 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2314 +# define dprintk(f, x...) do { printk(f ,##x); } while (0)
2316 +# define dprintk(f, x...) do { /* nothing */ } while (0)
2322 +struct bcm43xx_dmaring;
2323 +struct bcm43xx_pioqueue;
2325 +struct bcm43xx_initval {
2329 +} __attribute__((__packed__));
2331 +/* Values for bcm430x_sprominfo.locale */
2333 + BCM43xx_LOCALE_WORLD = 0,
2334 + BCM43xx_LOCALE_THAILAND,
2335 + BCM43xx_LOCALE_ISRAEL,
2336 + BCM43xx_LOCALE_JORDAN,
2337 + BCM43xx_LOCALE_CHINA,
2338 + BCM43xx_LOCALE_JAPAN,
2339 + BCM43xx_LOCALE_USA_CANADA_ANZ,
2340 + BCM43xx_LOCALE_EUROPE,
2341 + BCM43xx_LOCALE_USA_LOW,
2342 + BCM43xx_LOCALE_JAPAN_HIGH,
2343 + BCM43xx_LOCALE_ALL,
2344 + BCM43xx_LOCALE_NONE,
2347 +#define BCM43xx_SPROM_SIZE 64 /* in 16-bit words. */
2348 +struct bcm43xx_sprominfo {
2359 + u8 antennas_aphy:2;
2360 + u8 antennas_bgphy:2;
2369 + u8 maxpower_bgphy;
2373 + u8 idle_tssi_tgt_aphy;
2374 + u8 idle_tssi_tgt_bgphy;
2376 + u16 antennagain_aphy;
2377 + u16 antennagain_bgphy;
2380 +/* Value pair to measure the LocalOscillator. */
2381 +struct bcm43xx_lopair {
2386 +#define BCM43xx_LO_COUNT (14*4)
2388 +struct bcm43xx_phyinfo {
2389 + /* Hardware Data */
2393 + u16 antenna_diversity;
2396 + u16 minlowsigpos[2];
2399 + is_locked:1, /* used in bcm43xx_phy_{un}lock() */
2400 + dyn_tssi_tbl:1; /* used in bcm43xx_phy_init_tssi2dbm_table() */
2401 + /* LO Measurement Data.
2402 + * Use bcm43xx_get_lopair() to get a value.
2404 + struct bcm43xx_lopair *_lo_pairs;
2406 + /* TSSI to dBm table in use */
2407 + const s8 *tssi2dbm;
2408 + /* idle TSSI value */
2411 + /* Values from bcm43xx_calc_loopback_gain() */
2412 + u16 loopback_gain[2];
2414 + /* PHY lock for core.rev < 3
2415 + * This lock is only used by bcm43xx_phy_{un}lock()
2421 +struct bcm43xx_radioinfo {
2426 + /* Desired TX power level (in dBm).
2427 + * This is set by the user and adjusted in bcm43xx_phy_xmitpower(). */
2429 + /* TX Power control values. */
2433 + u16 baseband_atten;
2444 + /* Current Interference Mitigation mode */
2446 + /* Stack of saved values from the Interference Mitigation code.
2447 + * Each value in the stack is layed out as follows:
2448 + * bit 0-11: offset
2449 + * bit 12-15: register ID
2450 + * bit 16-32: value
2451 + * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT
2453 +#define BCM43xx_INTERFSTACK_SIZE 26
2454 + u32 interfstack[BCM43xx_INTERFSTACK_SIZE];
2456 + /* Saved values from the NRSSI Slope calculation */
2459 + /* In memory nrssi lookup table. */
2462 + /* current channel */
2464 + u8 initial_channel;
2471 + /* ACI (adjacent channel interference) flags. */
2473 + aci_wlan_automatic:1,
2477 +/* Data structures for DMA transmission, per 80211 core. */
2478 +struct bcm43xx_dma {
2479 + struct bcm43xx_dmaring *tx_ring0;
2480 + struct bcm43xx_dmaring *tx_ring1;
2481 + struct bcm43xx_dmaring *tx_ring2;
2482 + struct bcm43xx_dmaring *tx_ring3;
2483 + struct bcm43xx_dmaring *rx_ring0;
2484 + struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */
2487 +/* Data structures for PIO transmission, per 80211 core. */
2488 +struct bcm43xx_pio {
2489 + struct bcm43xx_pioqueue *queue0;
2490 + struct bcm43xx_pioqueue *queue1;
2491 + struct bcm43xx_pioqueue *queue2;
2492 + struct bcm43xx_pioqueue *queue3;
2495 +#define BCM43xx_MAX_80211_CORES 2
2497 +#ifdef CONFIG_BCM947XX
2498 +#define core_offset(bcm) (bcm)->current_core_offset
2500 +#define core_offset(bcm) 0
2503 +/* Generic information about a core. */
2504 +struct bcm43xx_coreinfo {
2508 + /** core_id ID number */
2510 + /** core_rev revision number */
2512 + /** Index number for _switch_core() */
2516 +/* Additional information for each 80211 core. */
2517 +struct bcm43xx_coreinfo_80211 {
2519 + struct bcm43xx_phyinfo phy;
2520 + /* Radio device. */
2521 + struct bcm43xx_radioinfo radio;
2523 + /* DMA context. */
2524 + struct bcm43xx_dma dma;
2525 + /* PIO context. */
2526 + struct bcm43xx_pio pio;
2530 +/* Context information for a noise calculation (Link Quality). */
2531 +struct bcm43xx_noise_calculation {
2532 + struct bcm43xx_coreinfo *core_at_start;
2533 + u8 channel_at_start;
2534 + u8 calculation_running:1;
2539 +struct bcm43xx_stats {
2541 + /* Store the last TX/RX times here for updating the leds. */
2542 + unsigned long last_tx;
2543 + unsigned long last_rx;
2546 +struct bcm43xx_key {
2551 +struct bcm43xx_private {
2552 + struct bcm43xx_sysfs sysfs;
2554 + struct ieee80211_hw *ieee;
2555 + struct ieee80211_low_level_stats ieee_stats;
2558 + struct net_device *net_dev;
2559 + struct pci_dev *pci_dev;
2562 + void __iomem *mmio_addr;
2563 + unsigned int mmio_len;
2565 + /* Do not use the lock directly. Use the bcm43xx_lock* helper
2566 + * functions, to be MMIO-safe. */
2569 + /* Driver status flags. */
2570 + u32 initialized:1, /* init_board() succeed */
2571 + was_initialized:1, /* for PCI suspend/resume. */
2572 + shutting_down:1, /* free_board() in progress */
2573 + __using_pio:1, /* Internal, use bcm43xx_using_pio(). */
2574 + bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */
2575 + reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */
2576 + powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */
2577 + short_preamble:1, /* TRUE, if short preamble is enabled. */
2578 + short_slot:1, /* TRUE, if short slot timing is enabled. */
2579 + firmware_norelease:1; /* Do not release the firmware. Used on suspend. */
2581 + struct bcm43xx_stats stats;
2583 + /* Bus type we are connected to.
2584 + * This is currently always BCM43xx_BUSTYPE_PCI
2590 + u16 board_revision;
2596 + struct bcm43xx_sprominfo sprom;
2597 +#define BCM43xx_NR_LEDS 4
2598 + struct bcm43xx_led leds[BCM43xx_NR_LEDS];
2600 + /* The currently active core. */
2601 + struct bcm43xx_coreinfo *current_core;
2602 +#ifdef CONFIG_BCM947XX
2603 + /** current core memory offset */
2604 + u32 current_core_offset;
2606 + struct bcm43xx_coreinfo *active_80211_core;
2607 + /* coreinfo structs for all possible cores follow.
2608 + * Note that a core might not exist.
2609 + * So check the coreinfo flags before using it.
2611 + struct bcm43xx_coreinfo core_chipcommon;
2612 + struct bcm43xx_coreinfo core_pci;
2613 + struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
2614 + /* Additional information, specific to the 80211 cores. */
2615 + struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
2616 + /* Index of the current 80211 core. If current_core is not
2617 + * an 80211 core, this is -1.
2619 + int current_80211_core_idx;
2620 + /* Number of available 80211 cores. */
2621 + int nr_80211_available;
2623 + u32 chipcommon_capabilities;
2625 + /* Reason code of the last interrupt. */
2627 + u32 dma_reason[4];
2628 + /* saved irq enable/disable state bitfield. */
2629 + u32 irq_savedstate;
2630 + /* Link Quality calculation context. */
2631 + struct bcm43xx_noise_calculation noisecalc;
2633 + /* Interrupt Service Routine tasklet (bottom-half) */
2634 + struct tasklet_struct isr_tasklet;
2636 + /* Periodic tasks */
2637 + struct timer_list periodic_tasks;
2638 + unsigned int periodic_state;
2640 + struct work_struct restart_work;
2642 + /* Informational stuff. */
2643 + char nick[IW_ESSID_MAX_SIZE + 1];
2644 + u8 bssid[ETH_ALEN];
2646 + /* encryption/decryption */
2647 + u16 security_offset;
2648 + struct bcm43xx_key key[54];
2649 + u8 default_key_idx;
2652 + const struct firmware *ucode;
2653 + const struct firmware *pcm;
2654 + const struct firmware *initvals0;
2655 + const struct firmware *initvals1;
2657 + /* Cached beacon template while uploading the template. */
2658 + struct sk_buff *cached_beacon;
2660 + /* Debugging stuff follows. */
2661 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2662 + struct bcm43xx_dfsentry *dfsentry;
2666 +/* bcm43xx_(un)lock() protect struct bcm43xx_private.
2667 + * Note that _NO_ MMIO writes are allowed. If you want to
2668 + * write to the device through MMIO in the critical section, use
2669 + * the *_mmio lock functions.
2670 + * MMIO read-access is allowed, though.
2672 +#define bcm43xx_lock(bcm, flags) spin_lock_irqsave(&(bcm)->_lock, flags)
2673 +#define bcm43xx_unlock(bcm, flags) spin_unlock_irqrestore(&(bcm)->_lock, flags)
2674 +/* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO.
2675 + * MMIO write-access to the device is allowed.
2676 + * All MMIO writes are flushed on unlock, so it is guaranteed to not
2677 + * interfere with other threads writing MMIO registers.
2679 +#define bcm43xx_lock_mmio(bcm, flags) bcm43xx_lock(bcm, flags)
2680 +#define bcm43xx_unlock_mmio(bcm, flags) do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0)
2683 +struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
2685 + return ieee80211_dev_hw_data(dev);
2688 +/* Helper function, which returns a boolean.
2689 + * TRUE, if PIO is used; FALSE, if DMA is used.
2691 +#if defined(CONFIG_BCM43XX_D80211_DMA) && defined(CONFIG_BCM43XX_D80211_PIO)
2693 +int bcm43xx_using_pio(struct bcm43xx_private *bcm)
2695 + return bcm->__using_pio;
2697 +#elif defined(CONFIG_BCM43XX_D80211_DMA)
2699 +int bcm43xx_using_pio(struct bcm43xx_private *bcm)
2703 +#elif defined(CONFIG_BCM43XX_D80211_PIO)
2705 +int bcm43xx_using_pio(struct bcm43xx_private *bcm)
2710 +# error "Using neither DMA nor PIO? Confused..."
2713 +/* Helper functions to access data structures private to the 80211 cores.
2714 + * Note that we _must_ have an 80211 core mapped when calling
2715 + * any of these functions.
2718 +struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
2720 + assert(bcm43xx_using_pio(bcm));
2721 + assert(bcm->current_80211_core_idx >= 0);
2722 + assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
2723 + return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio);
2726 +struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
2728 + assert(!bcm43xx_using_pio(bcm));
2729 + assert(bcm->current_80211_core_idx >= 0);
2730 + assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
2731 + return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma);
2734 +struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
2736 + assert(bcm->current_80211_core_idx >= 0);
2737 + assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
2738 + return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy);
2741 +struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
2743 + assert(bcm->current_80211_core_idx >= 0);
2744 + assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
2745 + return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio);
2748 +/* Are we running in init_board() context? */
2750 +int bcm43xx_is_initializing(struct bcm43xx_private *bcm)
2752 + if (bcm->initialized)
2754 + if (bcm->shutting_down)
2760 +struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy,
2761 + u16 radio_attenuation,
2762 + u16 baseband_attenuation)
2764 + return phy->_lo_pairs + (radio_attenuation + 14 * (baseband_attenuation / 2));
2769 +u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset)
2771 + return ioread16(bcm->mmio_addr + core_offset(bcm) + offset);
2775 +void bcm43xx_write16(struct bcm43xx_private *bcm, u16 offset, u16 value)
2777 + iowrite16(value, bcm->mmio_addr + core_offset(bcm) + offset);
2781 +u32 bcm43xx_read32(struct bcm43xx_private *bcm, u16 offset)
2783 + return ioread32(bcm->mmio_addr + core_offset(bcm) + offset);
2787 +void bcm43xx_write32(struct bcm43xx_private *bcm, u16 offset, u32 value)
2789 + iowrite32(value, bcm->mmio_addr + core_offset(bcm) + offset);
2793 +int bcm43xx_pci_read_config16(struct bcm43xx_private *bcm, int offset, u16 *value)
2795 + return pci_read_config_word(bcm->pci_dev, offset, value);
2799 +int bcm43xx_pci_read_config32(struct bcm43xx_private *bcm, int offset, u32 *value)
2801 + return pci_read_config_dword(bcm->pci_dev, offset, value);
2805 +int bcm43xx_pci_write_config16(struct bcm43xx_private *bcm, int offset, u16 value)
2807 + return pci_write_config_word(bcm->pci_dev, offset, value);
2811 +int bcm43xx_pci_write_config32(struct bcm43xx_private *bcm, int offset, u32 value)
2813 + return pci_write_config_dword(bcm->pci_dev, offset, value);
2816 +/** Limit a value between two limits */
2818 +# undef limit_value
2820 +#define limit_value(value, min, max) \
2822 + typeof(value) __value = (value); \
2823 + typeof(value) __min = (min); \
2824 + typeof(value) __max = (max); \
2825 + if (__value < __min) \
2826 + __value = __min; \
2827 + else if (__value > __max) \
2828 + __value = __max; \
2832 +/** Helpers to print MAC addresses. */
2833 +#define BCM43xx_MACFMT "%02x:%02x:%02x:%02x:%02x:%02x"
2834 +#define BCM43xx_MACARG(x) ((u8*)(x))[0], ((u8*)(x))[1], \
2835 + ((u8*)(x))[2], ((u8*)(x))[3], \
2836 + ((u8*)(x))[4], ((u8*)(x))[5]
2838 +#endif /* BCM43xx_H_ */
2839 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.c linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.c
2840 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.c 1970-01-01 01:00:00.000000000 +0100
2841 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.c 2006-03-28 22:16:14.000000000 +0200
2845 + Broadcom BCM43xx wireless driver
2847 + Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
2848 + Stefano Brivio <st3@riseup.net>
2849 + Michael Buesch <mbuesch@freenet.de>
2850 + Danny van Dyk <kugelfang@gentoo.org>
2851 + Andreas Jaggi <andreas.jaggi@waterwave.ch>
2853 + This program is free software; you can redistribute it and/or modify
2854 + it under the terms of the GNU General Public License as published by
2855 + the Free Software Foundation; either version 2 of the License, or
2856 + (at your option) any later version.
2858 + This program is distributed in the hope that it will be useful,
2859 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2860 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2861 + GNU General Public License for more details.
2863 + You should have received a copy of the GNU General Public License
2864 + along with this program; see the file COPYING. If not, write to
2865 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
2866 + Boston, MA 02110-1301, USA.
2870 +#include "bcm43xx.h"
2871 +#include "bcm43xx_ilt.h"
2872 +#include "bcm43xx_phy.h"
2875 +/**** Initial Internal Lookup Tables ****/
2877 +const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE] = {
2878 + 0xFEB93FFD, 0xFEC63FFD, /* 0 */
2879 + 0xFED23FFD, 0xFEDF3FFD,
2880 + 0xFEEC3FFE, 0xFEF83FFE,
2881 + 0xFF053FFE, 0xFF113FFE,
2882 + 0xFF1E3FFE, 0xFF2A3FFF, /* 8 */
2883 + 0xFF373FFF, 0xFF443FFF,
2884 + 0xFF503FFF, 0xFF5D3FFF,
2885 + 0xFF693FFF, 0xFF763FFF,
2886 + 0xFF824000, 0xFF8F4000, /* 16 */
2887 + 0xFF9B4000, 0xFFA84000,
2888 + 0xFFB54000, 0xFFC14000,
2889 + 0xFFCE4000, 0xFFDA4000,
2890 + 0xFFE74000, 0xFFF34000, /* 24 */
2891 + 0x00004000, 0x000D4000,
2892 + 0x00194000, 0x00264000,
2893 + 0x00324000, 0x003F4000,
2894 + 0x004B4000, 0x00584000, /* 32 */
2895 + 0x00654000, 0x00714000,
2896 + 0x007E4000, 0x008A3FFF,
2897 + 0x00973FFF, 0x00A33FFF,
2898 + 0x00B03FFF, 0x00BC3FFF, /* 40 */
2899 + 0x00C93FFF, 0x00D63FFF,
2900 + 0x00E23FFE, 0x00EF3FFE,
2901 + 0x00FB3FFE, 0x01083FFE,
2902 + 0x01143FFE, 0x01213FFD, /* 48 */
2903 + 0x012E3FFD, 0x013A3FFD,
2907 +const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE] = {
2908 + 0xDB93CB87, 0xD666CF64, /* 0 */
2909 + 0xD1FDD358, 0xCDA6D826,
2910 + 0xCA38DD9F, 0xC729E2B4,
2911 + 0xC469E88E, 0xC26AEE2B,
2912 + 0xC0DEF46C, 0xC073FA62, /* 8 */
2913 + 0xC01D00D5, 0xC0760743,
2914 + 0xC1560D1E, 0xC2E51369,
2915 + 0xC4ED18FF, 0xC7AC1ED7,
2916 + 0xCB2823B2, 0xCEFA28D9, /* 16 */
2917 + 0xD2F62D3F, 0xD7BB3197,
2918 + 0xDCE53568, 0xE1FE3875,
2919 + 0xE7D13B35, 0xED663D35,
2920 + 0xF39B3EC4, 0xF98E3FA7, /* 24 */
2921 + 0x00004000, 0x06723FA7,
2922 + 0x0C653EC4, 0x129A3D35,
2923 + 0x182F3B35, 0x1E023875,
2924 + 0x231B3568, 0x28453197, /* 32 */
2925 + 0x2D0A2D3F, 0x310628D9,
2926 + 0x34D823B2, 0x38541ED7,
2927 + 0x3B1318FF, 0x3D1B1369,
2928 + 0x3EAA0D1E, 0x3F8A0743, /* 40 */
2929 + 0x3FE300D5, 0x3F8DFA62,
2930 + 0x3F22F46C, 0x3D96EE2B,
2931 + 0x3B97E88E, 0x38D7E2B4,
2932 + 0x35C8DD9F, 0x325AD826, /* 48 */
2933 + 0x2E03D358, 0x299ACF64,
2937 +const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE] = {
2938 + 0x0082, 0x0082, 0x0102, 0x0182, /* 0 */
2939 + 0x0202, 0x0282, 0x0302, 0x0382,
2940 + 0x0402, 0x0482, 0x0502, 0x0582,
2941 + 0x05E2, 0x0662, 0x06E2, 0x0762,
2942 + 0x07E2, 0x0842, 0x08C2, 0x0942, /* 16 */
2943 + 0x09C2, 0x0A22, 0x0AA2, 0x0B02,
2944 + 0x0B82, 0x0BE2, 0x0C62, 0x0CC2,
2945 + 0x0D42, 0x0DA2, 0x0E02, 0x0E62,
2946 + 0x0EE2, 0x0F42, 0x0FA2, 0x1002, /* 32 */
2947 + 0x1062, 0x10C2, 0x1122, 0x1182,
2948 + 0x11E2, 0x1242, 0x12A2, 0x12E2,
2949 + 0x1342, 0x13A2, 0x1402, 0x1442,
2950 + 0x14A2, 0x14E2, 0x1542, 0x1582, /* 48 */
2951 + 0x15E2, 0x1622, 0x1662, 0x16C1,
2952 + 0x1701, 0x1741, 0x1781, 0x17E1,
2953 + 0x1821, 0x1861, 0x18A1, 0x18E1,
2954 + 0x1921, 0x1961, 0x19A1, 0x19E1, /* 64 */
2955 + 0x1A21, 0x1A61, 0x1AA1, 0x1AC1,
2956 + 0x1B01, 0x1B41, 0x1B81, 0x1BA1,
2957 + 0x1BE1, 0x1C21, 0x1C41, 0x1C81,
2958 + 0x1CA1, 0x1CE1, 0x1D01, 0x1D41, /* 80 */
2959 + 0x1D61, 0x1DA1, 0x1DC1, 0x1E01,
2960 + 0x1E21, 0x1E61, 0x1E81, 0x1EA1,
2961 + 0x1EE1, 0x1F01, 0x1F21, 0x1F41,
2962 + 0x1F81, 0x1FA1, 0x1FC1, 0x1FE1, /* 96 */
2963 + 0x2001, 0x2041, 0x2061, 0x2081,
2964 + 0x20A1, 0x20C1, 0x20E1, 0x2101,
2965 + 0x2121, 0x2141, 0x2161, 0x2181,
2966 + 0x21A1, 0x21C1, 0x21E1, 0x2201, /* 112 */
2967 + 0x2221, 0x2241, 0x2261, 0x2281,
2968 + 0x22A1, 0x22C1, 0x22C1, 0x22E1,
2969 + 0x2301, 0x2321, 0x2341, 0x2361,
2970 + 0x2361, 0x2381, 0x23A1, 0x23C1, /* 128 */
2971 + 0x23E1, 0x23E1, 0x2401, 0x2421,
2972 + 0x2441, 0x2441, 0x2461, 0x2481,
2973 + 0x2481, 0x24A1, 0x24C1, 0x24C1,
2974 + 0x24E1, 0x2501, 0x2501, 0x2521, /* 144 */
2975 + 0x2541, 0x2541, 0x2561, 0x2561,
2976 + 0x2581, 0x25A1, 0x25A1, 0x25C1,
2977 + 0x25C1, 0x25E1, 0x2601, 0x2601,
2978 + 0x2621, 0x2621, 0x2641, 0x2641, /* 160 */
2979 + 0x2661, 0x2661, 0x2681, 0x2681,
2980 + 0x26A1, 0x26A1, 0x26C1, 0x26C1,
2981 + 0x26E1, 0x26E1, 0x2701, 0x2701,
2982 + 0x2721, 0x2721, 0x2740, 0x2740, /* 176 */
2983 + 0x2760, 0x2760, 0x2780, 0x2780,
2984 + 0x2780, 0x27A0, 0x27A0, 0x27C0,
2985 + 0x27C0, 0x27E0, 0x27E0, 0x27E0,
2986 + 0x2800, 0x2800, 0x2820, 0x2820, /* 192 */
2987 + 0x2820, 0x2840, 0x2840, 0x2840,
2988 + 0x2860, 0x2860, 0x2880, 0x2880,
2989 + 0x2880, 0x28A0, 0x28A0, 0x28A0,
2990 + 0x28C0, 0x28C0, 0x28C0, 0x28E0, /* 208 */
2991 + 0x28E0, 0x28E0, 0x2900, 0x2900,
2992 + 0x2900, 0x2920, 0x2920, 0x2920,
2993 + 0x2940, 0x2940, 0x2940, 0x2960,
2994 + 0x2960, 0x2960, 0x2960, 0x2980, /* 224 */
2995 + 0x2980, 0x2980, 0x29A0, 0x29A0,
2996 + 0x29A0, 0x29A0, 0x29C0, 0x29C0,
2997 + 0x29C0, 0x29E0, 0x29E0, 0x29E0,
2998 + 0x29E0, 0x2A00, 0x2A00, 0x2A00, /* 240 */
2999 + 0x2A00, 0x2A20, 0x2A20, 0x2A20,
3000 + 0x2A20, 0x2A40, 0x2A40, 0x2A40,
3001 + 0x2A40, 0x2A60, 0x2A60, 0x2A60,
3004 +const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE] = {
3005 + 0x0089, 0x02E9, 0x0409, 0x04E9, /* 0 */
3006 + 0x05A9, 0x0669, 0x0709, 0x0789,
3007 + 0x0829, 0x08A9, 0x0929, 0x0989,
3008 + 0x0A09, 0x0A69, 0x0AC9, 0x0B29,
3009 + 0x0BA9, 0x0BE9, 0x0C49, 0x0CA9, /* 16 */
3010 + 0x0D09, 0x0D69, 0x0DA9, 0x0E09,
3011 + 0x0E69, 0x0EA9, 0x0F09, 0x0F49,
3012 + 0x0FA9, 0x0FE9, 0x1029, 0x1089,
3013 + 0x10C9, 0x1109, 0x1169, 0x11A9, /* 32 */
3014 + 0x11E9, 0x1229, 0x1289, 0x12C9,
3015 + 0x1309, 0x1349, 0x1389, 0x13C9,
3016 + 0x1409, 0x1449, 0x14A9, 0x14E9,
3017 + 0x1529, 0x1569, 0x15A9, 0x15E9, /* 48 */
3018 + 0x1629, 0x1669, 0x16A9, 0x16E8,
3019 + 0x1728, 0x1768, 0x17A8, 0x17E8,
3020 + 0x1828, 0x1868, 0x18A8, 0x18E8,
3021 + 0x1928, 0x1968, 0x19A8, 0x19E8, /* 64 */
3022 + 0x1A28, 0x1A68, 0x1AA8, 0x1AE8,
3023 + 0x1B28, 0x1B68, 0x1BA8, 0x1BE8,
3024 + 0x1C28, 0x1C68, 0x1CA8, 0x1CE8,
3025 + 0x1D28, 0x1D68, 0x1DC8, 0x1E08, /* 80 */
3026 + 0x1E48, 0x1E88, 0x1EC8, 0x1F08,
3027 + 0x1F48, 0x1F88, 0x1FE8, 0x2028,
3028 + 0x2068, 0x20A8, 0x2108, 0x2148,
3029 + 0x2188, 0x21C8, 0x2228, 0x2268, /* 96 */
3030 + 0x22C8, 0x2308, 0x2348, 0x23A8,
3031 + 0x23E8, 0x2448, 0x24A8, 0x24E8,
3032 + 0x2548, 0x25A8, 0x2608, 0x2668,
3033 + 0x26C8, 0x2728, 0x2787, 0x27E7, /* 112 */
3034 + 0x2847, 0x28C7, 0x2947, 0x29A7,
3035 + 0x2A27, 0x2AC7, 0x2B47, 0x2BE7,
3036 + 0x2CA7, 0x2D67, 0x2E47, 0x2F67,
3037 + 0x3247, 0x3526, 0x3646, 0x3726, /* 128 */
3038 + 0x3806, 0x38A6, 0x3946, 0x39E6,
3039 + 0x3A66, 0x3AE6, 0x3B66, 0x3BC6,
3040 + 0x3C45, 0x3CA5, 0x3D05, 0x3D85,
3041 + 0x3DE5, 0x3E45, 0x3EA5, 0x3EE5, /* 144 */
3042 + 0x3F45, 0x3FA5, 0x4005, 0x4045,
3043 + 0x40A5, 0x40E5, 0x4145, 0x4185,
3044 + 0x41E5, 0x4225, 0x4265, 0x42C5,
3045 + 0x4305, 0x4345, 0x43A5, 0x43E5, /* 160 */
3046 + 0x4424, 0x4464, 0x44C4, 0x4504,
3047 + 0x4544, 0x4584, 0x45C4, 0x4604,
3048 + 0x4644, 0x46A4, 0x46E4, 0x4724,
3049 + 0x4764, 0x47A4, 0x47E4, 0x4824, /* 176 */
3050 + 0x4864, 0x48A4, 0x48E4, 0x4924,
3051 + 0x4964, 0x49A4, 0x49E4, 0x4A24,
3052 + 0x4A64, 0x4AA4, 0x4AE4, 0x4B23,
3053 + 0x4B63, 0x4BA3, 0x4BE3, 0x4C23, /* 192 */
3054 + 0x4C63, 0x4CA3, 0x4CE3, 0x4D23,
3055 + 0x4D63, 0x4DA3, 0x4DE3, 0x4E23,
3056 + 0x4E63, 0x4EA3, 0x4EE3, 0x4F23,
3057 + 0x4F63, 0x4FC3, 0x5003, 0x5043, /* 208 */
3058 + 0x5083, 0x50C3, 0x5103, 0x5143,
3059 + 0x5183, 0x51E2, 0x5222, 0x5262,
3060 + 0x52A2, 0x52E2, 0x5342, 0x5382,
3061 + 0x53C2, 0x5402, 0x5462, 0x54A2, /* 224 */
3062 + 0x5502, 0x5542, 0x55A2, 0x55E2,
3063 + 0x5642, 0x5682, 0x56E2, 0x5722,
3064 + 0x5782, 0x57E1, 0x5841, 0x58A1,
3065 + 0x5901, 0x5961, 0x59C1, 0x5A21, /* 240 */
3066 + 0x5AA1, 0x5B01, 0x5B81, 0x5BE1,
3067 + 0x5C61, 0x5D01, 0x5D80, 0x5E20,
3068 + 0x5EE0, 0x5FA0, 0x6080, 0x61C0,
3071 +const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE] = {
3072 + 0x0001, 0x0001, 0x0001, 0xFFFE,
3073 + 0xFFFE, 0x3FFF, 0x1000, 0x0393,
3076 +const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE] = {
3077 + 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
3078 + 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
3081 +const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE] = {
3082 + 0x013C, 0x01F5, 0x031A, 0x0631,
3083 + 0x0001, 0x0001, 0x0001, 0x0001,
3086 +const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE] = {
3087 + 0x5484, 0x3C40, 0x0000, 0x0000,
3088 + 0x0000, 0x0000, 0x0000, 0x0000,
3091 +const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE] = {
3092 + 0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */
3093 + 0x2F2D, 0x2A2A, 0x2527, 0x1F21,
3094 + 0x1A1D, 0x1719, 0x1616, 0x1414,
3095 + 0x1414, 0x1400, 0x1414, 0x1614,
3096 + 0x1716, 0x1A19, 0x1F1D, 0x2521, /* 16 */
3097 + 0x2A27, 0x2F2A, 0x332D, 0x3B35,
3098 + 0x5140, 0x6C62, 0x0077,
3101 +const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE] = {
3102 + 0xD8DD, 0xCBD4, 0xBCC0, 0XB6B7, /* 0 */
3103 + 0xB2B0, 0xADAD, 0xA7A9, 0x9FA1,
3104 + 0x969B, 0x9195, 0x8F8F, 0x8A8A,
3105 + 0x8A8A, 0x8A00, 0x8A8A, 0x8F8A,
3106 + 0x918F, 0x9695, 0x9F9B, 0xA7A1, /* 16 */
3107 + 0xADA9, 0xB2AD, 0xB6B0, 0xBCB7,
3108 + 0xCBC0, 0xD8D4, 0x00DD,
3111 +const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE] = {
3112 + 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 0 */
3113 + 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
3114 + 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
3115 + 0xA4A4, 0xA400, 0xA4A4, 0xA4A4,
3116 + 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 16 */
3117 + 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
3118 + 0xA4A4, 0xA4A4, 0x00A4,
3121 +const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE] = {
3122 + 0x007A, 0x0075, 0x0071, 0x006C, /* 0 */
3123 + 0x0067, 0x0063, 0x005E, 0x0059,
3124 + 0x0054, 0x0050, 0x004B, 0x0046,
3125 + 0x0042, 0x003D, 0x003D, 0x003D,
3126 + 0x003D, 0x003D, 0x003D, 0x003D, /* 16 */
3127 + 0x003D, 0x003D, 0x003D, 0x003D,
3128 + 0x003D, 0x003D, 0x0000, 0x003D,
3129 + 0x003D, 0x003D, 0x003D, 0x003D,
3130 + 0x003D, 0x003D, 0x003D, 0x003D, /* 32 */
3131 + 0x003D, 0x003D, 0x003D, 0x003D,
3132 + 0x0042, 0x0046, 0x004B, 0x0050,
3133 + 0x0054, 0x0059, 0x005E, 0x0063,
3134 + 0x0067, 0x006C, 0x0071, 0x0075, /* 48 */
3138 +const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE] = {
3139 + 0x00DE, 0x00DC, 0x00DA, 0x00D8, /* 0 */
3140 + 0x00D6, 0x00D4, 0x00D2, 0x00CF,
3141 + 0x00CD, 0x00CA, 0x00C7, 0x00C4,
3142 + 0x00C1, 0x00BE, 0x00BE, 0x00BE,
3143 + 0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 16 */
3144 + 0x00BE, 0x00BE, 0x00BE, 0x00BE,
3145 + 0x00BE, 0x00BE, 0x0000, 0x00BE,
3146 + 0x00BE, 0x00BE, 0x00BE, 0x00BE,
3147 + 0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 32 */
3148 + 0x00BE, 0x00BE, 0x00BE, 0x00BE,
3149 + 0x00C1, 0x00C4, 0x00C7, 0x00CA,
3150 + 0x00CD, 0x00CF, 0x00D2, 0x00D4,
3151 + 0x00D6, 0x00D8, 0x00DA, 0x00DC, /* 48 */
3155 +/**** Helper functions to access the device Internal Lookup Tables ****/
3157 +void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
3159 + if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
3160 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
3162 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val);
3164 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
3166 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val);
3170 +u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset)
3172 + if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
3173 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
3174 + return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1);
3176 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
3177 + return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1);
3180 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.h linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.h
3181 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.h 1970-01-01 01:00:00.000000000 +0100
3182 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.h 2006-03-28 22:16:14.000000000 +0200
3184 +#ifndef BCM43xx_ILT_H_
3185 +#define BCM43xx_ILT_H_
3187 +#define BCM43xx_ILT_ROTOR_SIZE 53
3188 +extern const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE];
3189 +#define BCM43xx_ILT_RETARD_SIZE 53
3190 +extern const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE];
3191 +#define BCM43xx_ILT_FINEFREQA_SIZE 256
3192 +extern const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE];
3193 +#define BCM43xx_ILT_FINEFREQG_SIZE 256
3194 +extern const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE];
3195 +#define BCM43xx_ILT_NOISEA2_SIZE 8
3196 +extern const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE];
3197 +#define BCM43xx_ILT_NOISEA3_SIZE 8
3198 +extern const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE];
3199 +#define BCM43xx_ILT_NOISEG1_SIZE 8
3200 +extern const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE];
3201 +#define BCM43xx_ILT_NOISEG2_SIZE 8
3202 +extern const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE];
3203 +#define BCM43xx_ILT_NOISESCALEG_SIZE 27
3204 +extern const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE];
3205 +extern const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE];
3206 +extern const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE];
3207 +#define BCM43xx_ILT_SIGMASQR_SIZE 53
3208 +extern const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE];
3209 +extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE];
3212 +void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
3213 +u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset);
3215 +#endif /* BCM43xx_ILT_H_ */
3216 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_leds.c linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_leds.c
3217 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_leds.c 1970-01-01 01:00:00.000000000 +0100
3218 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_leds.c 2006-03-28 22:16:14.000000000 +0200
3222 + Broadcom BCM43xx wireless driver
3224 + Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
3225 + Stefano Brivio <st3@riseup.net>
3226 + Michael Buesch <mbuesch@freenet.de>
3227 + Danny van Dyk <kugelfang@gentoo.org>
3228 + Andreas Jaggi <andreas.jaggi@waterwave.ch>
3230 + This program is free software; you can redistribute it and/or modify
3231 + it under the terms of the GNU General Public License as published by
3232 + the Free Software Foundation; either version 2 of the License, or
3233 + (at your option) any later version.
3235 + This program is distributed in the hope that it will be useful,
3236 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3237 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3238 + GNU General Public License for more details.
3240 + You should have received a copy of the GNU General Public License
3241 + along with this program; see the file COPYING. If not, write to
3242 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
3243 + Boston, MA 02110-1301, USA.
3247 +#include "bcm43xx_leds.h"
3248 +#include "bcm43xx.h"
3250 +#include <asm/bitops.h>
3253 +static void bcm43xx_led_changestate(struct bcm43xx_led *led)
3255 + struct bcm43xx_private *bcm = led->bcm;
3256 + const int index = bcm43xx_led_index(led);
3257 + const u16 mask = (1 << index);
3260 + assert(index >= 0 && index < BCM43xx_NR_LEDS);
3261 + assert(led->blink_interval);
3262 + ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
3263 + ledctl = (ledctl & mask) ? (ledctl & ~mask) : (ledctl | mask);
3264 + bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
3267 +static void bcm43xx_led_blink(unsigned long d)
3269 + struct bcm43xx_led *led = (struct bcm43xx_led *)d;
3270 + struct bcm43xx_private *bcm = led->bcm;
3271 + unsigned long flags;
3273 + bcm43xx_lock_mmio(bcm, flags);
3274 + if (led->blink_interval) {
3275 + bcm43xx_led_changestate(led);
3276 + mod_timer(&led->blink_timer, jiffies + led->blink_interval);
3278 + bcm43xx_unlock_mmio(bcm, flags);
3281 +static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
3282 + unsigned long interval)
3284 + if (led->blink_interval)
3286 + led->blink_interval = interval;
3287 + bcm43xx_led_changestate(led);
3288 + led->blink_timer.expires = jiffies + interval;
3289 + add_timer(&led->blink_timer);
3292 +static void bcm43xx_led_blink_stop(struct bcm43xx_led *led, int sync)
3294 + struct bcm43xx_private *bcm = led->bcm;
3295 + const int index = bcm43xx_led_index(led);
3298 + if (!led->blink_interval)
3300 + if (unlikely(sync))
3301 + del_timer_sync(&led->blink_timer);
3303 + del_timer(&led->blink_timer);
3304 + led->blink_interval = 0;
3306 + /* Make sure the LED is turned off. */
3307 + assert(index >= 0 && index < BCM43xx_NR_LEDS);
3308 + ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
3309 + if (led->activelow)
3310 + ledctl |= (1 << index);
3312 + ledctl &= ~(1 << index);
3313 + bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
3316 +static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm,
3317 + struct bcm43xx_led *led,
3320 + /* This function is called, if the behaviour (and activelow)
3321 + * information for a LED is missing in the SPROM.
3322 + * We hardcode the behaviour values for various devices here.
3323 + * Note that the BCM43xx_LED_TEST_XXX behaviour values can
3324 + * be used to figure out which led is mapped to which index.
3327 + switch (led_index) {
3329 + led->behaviour = BCM43xx_LED_ACTIVITY;
3330 + if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
3331 + led->behaviour = BCM43xx_LED_RADIO_ALL;
3334 + led->behaviour = BCM43xx_LED_RADIO_B;
3335 + if (bcm->board_vendor == PCI_VENDOR_ID_ASUSTEK)
3336 + led->behaviour = BCM43xx_LED_ASSOC;
3339 + led->behaviour = BCM43xx_LED_RADIO_A;
3342 + led->behaviour = BCM43xx_LED_OFF;
3349 +int bcm43xx_leds_init(struct bcm43xx_private *bcm)