0611a0bcaa8aac3cba313a2832d11230486da0dc
[openwrt/svn-archive/archive.git] / openwrt / target / linux / brcm-2.6 / patches / 005-bcm43xx-dscape-060328.patch
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
4 @@ -0,0 +1,499 @@
5 +/*
6 +
7 + Broadcom BCM43xx wireless driver
8 +
9 + debugfs driver debugging code
10 +
11 + Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
12 +
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.
17 +
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.
22 +
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.
27 +
28 +*/
29 +
30 +
31 +
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>
37 +#include <asm/io.h>
38 +
39 +#include "bcm43xx.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"
45 +
46 +#define REALLY_BIG_BUFFER_SIZE (1024*256)
47 +
48 +static struct bcm43xx_debugfs fs;
49 +static char really_big_buffer[REALLY_BIG_BUFFER_SIZE];
50 +static DECLARE_MUTEX(big_buffer_sem);
51 +
52 +
53 +static ssize_t write_file_dummy(struct file *file, const char __user *buf,
54 + size_t count, loff_t *ppos)
55 +{
56 + return count;
57 +}
58 +
59 +static int open_file_generic(struct inode *inode, struct file *file)
60 +{
61 + file->private_data = inode->u.generic_ip;
62 + return 0;
63 +}
64 +
65 +#define fappend(fmt, x...) pos += snprintf(buf + pos, len - pos, fmt , ##x)
66 +
67 +static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
68 + size_t count, loff_t *ppos)
69 +{
70 + const size_t len = REALLY_BIG_BUFFER_SIZE;
71 +
72 + struct bcm43xx_private *bcm = file->private_data;
73 + char *buf = really_big_buffer;
74 + size_t pos = 0;
75 + ssize_t res;
76 + struct net_device *net_dev;
77 + struct pci_dev *pci_dev;
78 + unsigned long flags;
79 + u16 tmp16;
80 + int i;
81 +
82 + down(&big_buffer_sem);
83 +
84 + bcm43xx_lock_mmio(bcm, flags);
85 + if (!bcm->initialized) {
86 + fappend("Board not initialized.\n");
87 + goto out;
88 + }
89 + net_dev = bcm->net_dev;
90 + pci_dev = bcm->pci_dev;
91 +
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,
106 + bcm->board_type);
107 +
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", \
111 + (info).available \
112 + ? "available" : "nonavailable", \
113 + (info).enabled \
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]);
120 +#undef fappend_core
121 + tmp16 = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
122 + fappend("LEDs: ");
123 + for (i = 0; i < BCM43xx_NR_LEDS; i++)
124 + fappend("%d ", !!(tmp16 & (1 << i)));
125 + fappend("\n");
126 +
127 +out:
128 + bcm43xx_unlock_mmio(bcm, flags);
129 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
130 + up(&big_buffer_sem);
131 + return res;
132 +}
133 +
134 +static ssize_t drvinfo_read_file(struct file *file, char __user *userbuf,
135 + size_t count, loff_t *ppos)
136 +{
137 + const size_t len = REALLY_BIG_BUFFER_SIZE;
138 +
139 + char *buf = really_big_buffer;
140 + size_t pos = 0;
141 + ssize_t res;
142 +
143 + down(&big_buffer_sem);
144 +
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__);
148 +
149 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
150 + up(&big_buffer_sem);
151 + return res;
152 +}
153 +
154 +static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
155 + size_t count, loff_t *ppos)
156 +{
157 + const size_t len = REALLY_BIG_BUFFER_SIZE;
158 +
159 + struct bcm43xx_private *bcm = file->private_data;
160 + char *buf = really_big_buffer;
161 + size_t pos = 0;
162 + ssize_t res;
163 + unsigned long flags;
164 +
165 + down(&big_buffer_sem);
166 + bcm43xx_lock_mmio(bcm, flags);
167 + if (!bcm->initialized) {
168 + fappend("Board not initialized.\n");
169 + goto out;
170 + }
171 +
172 + /* This is where the information is written to the "sprom_dump" file */
173 + fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
174 +
175 +out:
176 + bcm43xx_unlock_mmio(bcm, flags);
177 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
178 + up(&big_buffer_sem);
179 + return res;
180 +}
181 +
182 +static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
183 + size_t count, loff_t *ppos)
184 +{
185 + const size_t len = REALLY_BIG_BUFFER_SIZE;
186 +
187 + struct bcm43xx_private *bcm = file->private_data;
188 + char *buf = really_big_buffer;
189 + size_t pos = 0;
190 + ssize_t res;
191 + unsigned long flags;
192 + u64 tsf;
193 +
194 + down(&big_buffer_sem);
195 + bcm43xx_lock_mmio(bcm, flags);
196 + if (!bcm->initialized) {
197 + fappend("Board not initialized.\n");
198 + goto out;
199 + }
200 + bcm43xx_tsf_read(bcm, &tsf);
201 + fappend("0x%08x%08x\n",
202 + (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
203 + (unsigned int)(tsf & 0xFFFFFFFFULL));
204 +
205 +out:
206 + bcm43xx_unlock_mmio(bcm, flags);
207 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
208 + up(&big_buffer_sem);
209 + return res;
210 +}
211 +
212 +static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
213 + size_t count, loff_t *ppos)
214 +{
215 + struct bcm43xx_private *bcm = file->private_data;
216 + char *buf = really_big_buffer;
217 + ssize_t buf_size;
218 + ssize_t res;
219 + unsigned long flags;
220 + u64 tsf;
221 +
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)) {
225 + res = -EFAULT;
226 + goto out_up;
227 + }
228 + bcm43xx_lock_mmio(bcm, flags);
229 + if (!bcm->initialized) {
230 + printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
231 + res = -EFAULT;
232 + goto out_unlock;
233 + }
234 + if (sscanf(buf, "%lli", &tsf) != 1) {
235 + printk(KERN_INFO PFX "debugfs: invalid values for \"tsf\"\n");
236 + res = -EINVAL;
237 + goto out_unlock;
238 + }
239 + bcm43xx_tsf_write(bcm, tsf);
240 + res = buf_size;
241 +
242 +out_unlock:
243 + bcm43xx_unlock_mmio(bcm, flags);
244 +out_up:
245 + up(&big_buffer_sem);
246 + return res;
247 +}
248 +
249 +static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
250 + size_t count, loff_t *ppos)
251 +{
252 + const size_t len = REALLY_BIG_BUFFER_SIZE;
253 +
254 + struct bcm43xx_private *bcm = file->private_data;
255 + char *buf = really_big_buffer;
256 + size_t pos = 0;
257 + ssize_t res;
258 + unsigned long flags;
259 + struct bcm43xx_dfsentry *e;
260 + struct bcm43xx_xmitstatus *status;
261 + int i, cnt, j = 0;
262 +
263 + down(&big_buffer_sem);
264 + bcm43xx_lock(bcm, flags);
265 +
266 + fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
267 + BCM43xx_NR_LOGGED_XMITSTATUS);
268 + e = bcm->dfsentry;
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.
274 + */
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)));
280 + }
281 + i = e->saved_xmitstatus_ptr - 1;
282 + if (i < 0)
283 + i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
284 + cnt = e->saved_xmitstatus_cnt;
285 + while (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,
292 + status->unknown);
293 + j++;
294 + cnt--;
295 + i--;
296 + if (i < 0)
297 + i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
298 + }
299 +
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;
306 + }
307 + bcm43xx_unlock(bcm, flags);
308 + up(&big_buffer_sem);
309 + return res;
310 +}
311 +
312 +#undef fappend
313 +
314 +
315 +static struct file_operations devinfo_fops = {
316 + .read = devinfo_read_file,
317 + .write = write_file_dummy,
318 + .open = open_file_generic,
319 +};
320 +
321 +static struct file_operations spromdump_fops = {
322 + .read = spromdump_read_file,
323 + .write = write_file_dummy,
324 + .open = open_file_generic,
325 +};
326 +
327 +static struct file_operations drvinfo_fops = {
328 + .read = drvinfo_read_file,
329 + .write = write_file_dummy,
330 + .open = open_file_generic,
331 +};
332 +
333 +static struct file_operations tsf_fops = {
334 + .read = tsf_read_file,
335 + .write = tsf_write_file,
336 + .open = open_file_generic,
337 +};
338 +
339 +static struct file_operations txstat_fops = {
340 + .read = txstat_read_file,
341 + .write = write_file_dummy,
342 + .open = open_file_generic,
343 +};
344 +
345 +
346 +void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
347 +{
348 + struct bcm43xx_dfsentry *e;
349 + char devdir[IFNAMSIZ];
350 +
351 + assert(bcm);
352 + e = kzalloc(sizeof(*e), GFP_KERNEL);
353 + if (!e) {
354 + printk(KERN_ERR PFX "out of memory\n");
355 + return;
356 + }
357 + e->bcm = bcm;
358 + e->xmitstatus_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
359 + * sizeof(*(e->xmitstatus_buffer)),
360 + GFP_KERNEL);
361 + if (!e->xmitstatus_buffer) {
362 + printk(KERN_ERR PFX "out of memory\n");
363 + kfree(e);
364 + return;
365 + }
366 + e->xmitstatus_print_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
367 + * sizeof(*(e->xmitstatus_buffer)),
368 + GFP_KERNEL);
369 + if (!e->xmitstatus_print_buffer) {
370 + printk(KERN_ERR PFX "out of memory\n");
371 + kfree(e);
372 + return;
373 + }
374 +
375 +
376 + bcm->dfsentry = e;
377 +
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,
389 + bcm, &tsf_fops);
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);
396 +}
397 +
398 +void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
399 +{
400 + struct bcm43xx_dfsentry *e;
401 +
402 + if (!bcm)
403 + return;
404 +
405 + e = bcm->dfsentry;
406 + assert(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);
414 + kfree(e);
415 +}
416 +
417 +void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
418 + struct bcm43xx_xmitstatus *status)
419 +{
420 + struct bcm43xx_dfsentry *e;
421 + struct bcm43xx_xmitstatus *savedstatus;
422 +
423 + /* This is protected by bcm->_lock */
424 + e = bcm->dfsentry;
425 + assert(e);
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++;
433 +}
434 +
435 +void bcm43xx_debugfs_init(void)
436 +{
437 + memset(&fs, 0, sizeof(fs));
438 + fs.root = debugfs_create_dir(KBUILD_MODNAME, NULL);
439 + if (!fs.root)
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");
444 +}
445 +
446 +void bcm43xx_debugfs_exit(void)
447 +{
448 + debugfs_remove(fs.dentry_driverinfo);
449 + debugfs_remove(fs.root);
450 +}
451 +
452 +void bcm43xx_printk_dump(const char *data,
453 + size_t size,
454 + const char *description)
455 +{
456 + size_t i;
457 + char c;
458 +
459 + printk(KERN_INFO PFX "Data dump (%s, %u bytes):",
460 + description, size);
461 + for (i = 0; i < size; i++) {
462 + c = data[i];
463 + if (i % 8 == 0)
464 + printk("\n" KERN_INFO PFX "0x%08x: 0x%02x, ", i, c & 0xff);
465 + else
466 + printk("0x%02x, ", c & 0xff);
467 + }
468 + printk("\n");
469 +}
470 +
471 +void bcm43xx_printk_bitdump(const unsigned char *data,
472 + size_t bytes, int msb_to_lsb,
473 + const char *description)
474 +{
475 + size_t i;
476 + int j;
477 + const unsigned char *d;
478 +
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++) {
482 + d = data + i;
483 + if (i % 8 == 0)
484 + printk("\n" KERN_INFO PFX "0x%08x: ", i);
485 + if (msb_to_lsb) {
486 + for (j = 7; j >= 0; j--) {
487 + if (*d & (1 << j))
488 + printk("1");
489 + else
490 + printk("0");
491 + }
492 + } else {
493 + for (j = 0; j < 8; j++) {
494 + if (*d & (1 << j))
495 + printk("1");
496 + else
497 + printk("0");
498 + }
499 + }
500 + printk(" ");
501 + }
502 + printk("\n");
503 +}
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
507 @@ -0,0 +1,117 @@
508 +#ifndef BCM43xx_DEBUGFS_H_
509 +#define BCM43xx_DEBUGFS_H_
510 +
511 +struct bcm43xx_private;
512 +struct bcm43xx_xmitstatus;
513 +
514 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
515 +
516 +#include <linux/list.h>
517 +#include <asm/semaphore.h>
518 +
519 +struct dentry;
520 +
521 +/* limited by the size of the "really_big_buffer" */
522 +#define BCM43xx_NR_LOGGED_XMITSTATUS 100
523 +
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;
530 +
531 + struct bcm43xx_private *bcm;
532 +
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).
540 + */
541 + struct bcm43xx_xmitstatus *xmitstatus_print_buffer;
542 + int saved_xmitstatus_ptr;
543 + int saved_xmitstatus_cnt;
544 + int xmitstatus_printing;
545 +};
546 +
547 +struct bcm43xx_debugfs {
548 + struct dentry *root;
549 + struct dentry *dentry_driverinfo;
550 +};
551 +
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);
558 +
559 +/* Debug helper: Dump binary data through printk. */
560 +void bcm43xx_printk_dump(const char *data,
561 + size_t size,
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) \
568 + do { \
569 + bcm43xx_printk_bitdump((const unsigned char *)(pointer), \
570 + sizeof(*(pointer)), \
571 + (msb_to_lsb), \
572 + (description)); \
573 + } while (0)
574 +
575 +#else /* CONFIG_BCM43XX_D80211_DEBUG*/
576 +
577 +static inline
578 +void bcm43xx_debugfs_init(void) { }
579 +static inline
580 +void bcm43xx_debugfs_exit(void) { }
581 +static inline
582 +void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) { }
583 +static inline
584 +void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) { }
585 +static inline
586 +void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
587 + struct bcm43xx_xmitstatus *status) { }
588 +
589 +static inline
590 +void bcm43xx_printk_dump(const char *data,
591 + size_t size,
592 + const char *description)
593 +{
594 +}
595 +static inline
596 +void bcm43xx_printk_bitdump(const unsigned char *data,
597 + size_t bytes, int msb_to_lsb,
598 + const char *description)
599 +{
600 +}
601 +#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) do { /* nothing */ } while (0)
602 +
603 +#endif /* CONFIG_BCM43XX_D80211_DEBUG*/
604 +
605 +/* Ugly helper macros to make incomplete code more verbose on runtime */
606 +#ifdef TODO
607 +# undef TODO
608 +#endif
609 +#define TODO() \
610 + do { \
611 + printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n", \
612 + __FUNCTION__, __FILE__, __LINE__); \
613 + } while (0)
614 +
615 +#ifdef FIXME
616 +# undef FIXME
617 +#endif
618 +#define FIXME() \
619 + do { \
620 + printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n", \
621 + __FUNCTION__, __FILE__, __LINE__); \
622 + } while (0)
623 +
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
628 @@ -0,0 +1,991 @@
629 +/*
630 +
631 + Broadcom BCM43xx wireless driver
632 +
633 + DMA ringbuffer and descriptor allocation/management
634 +
635 + Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
636 +
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
640 +
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.
645 +
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.
650 +
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.
655 +
656 +*/
657 +
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"
664 +
665 +#include <linux/dma-mapping.h>
666 +#include <linux/pci.h>
667 +#include <linux/delay.h>
668 +#include <linux/skbuff.h>
669 +
670 +
671 +static inline int free_slots(struct bcm43xx_dmaring *ring)
672 +{
673 + return (ring->nr_slots - ring->used_slots);
674 +}
675 +
676 +static inline int next_slot(struct bcm43xx_dmaring *ring, int slot)
677 +{
678 + assert(slot >= -1 && slot <= ring->nr_slots - 1);
679 + if (slot == ring->nr_slots - 1)
680 + return 0;
681 + return slot + 1;
682 +}
683 +
684 +static inline int prev_slot(struct bcm43xx_dmaring *ring, int slot)
685 +{
686 + assert(slot >= 0 && slot <= ring->nr_slots - 1);
687 + if (slot == 0)
688 + return ring->nr_slots - 1;
689 + return slot - 1;
690 +}
691 +
692 +/* Request a slot for usage. */
693 +static inline
694 +int request_slot(struct bcm43xx_dmaring *ring)
695 +{
696 + int slot;
697 +
698 + assert(ring->tx);
699 + assert(!ring->suspended);
700 + assert(free_slots(ring) != 0);
701 +
702 + slot = next_slot(ring, ring->current_slot);
703 + ring->current_slot = slot;
704 + ring->used_slots++;
705 +
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*/
710 +
711 + return slot;
712 +}
713 +
714 +/* Return a slot to the free slots. */
715 +static inline
716 +void return_slot(struct bcm43xx_dmaring *ring, int slot)
717 +{
718 + assert(ring->tx);
719 +
720 + ring->used_slots--;
721 +}
722 +
723 +static inline
724 +dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
725 + unsigned char *buf,
726 + size_t len,
727 + int tx)
728 +{
729 + dma_addr_t dmaaddr;
730 +
731 + if (tx) {
732 + dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
733 + buf, len,
734 + DMA_TO_DEVICE);
735 + } else {
736 + dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
737 + buf, len,
738 + DMA_FROM_DEVICE);
739 + }
740 +
741 + return dmaaddr;
742 +}
743 +
744 +static inline
745 +void unmap_descbuffer(struct bcm43xx_dmaring *ring,
746 + dma_addr_t addr,
747 + size_t len,
748 + int tx)
749 +{
750 + if (tx) {
751 + dma_unmap_single(&ring->bcm->pci_dev->dev,
752 + addr, len,
753 + DMA_TO_DEVICE);
754 + } else {
755 + dma_unmap_single(&ring->bcm->pci_dev->dev,
756 + addr, len,
757 + DMA_FROM_DEVICE);
758 + }
759 +}
760 +
761 +static inline
762 +void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,
763 + dma_addr_t addr,
764 + size_t len)
765 +{
766 + assert(!ring->tx);
767 +
768 + dma_sync_single_for_cpu(&ring->bcm->pci_dev->dev,
769 + addr, len, DMA_FROM_DEVICE);
770 +}
771 +
772 +static inline
773 +void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,
774 + dma_addr_t addr,
775 + size_t len)
776 +{
777 + assert(!ring->tx);
778 +
779 + dma_sync_single_for_device(&ring->bcm->pci_dev->dev,
780 + addr, len, DMA_FROM_DEVICE);
781 +}
782 +
783 +/* Unmap and free a descriptor buffer. */
784 +static inline
785 +void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
786 + struct bcm43xx_dmadesc *desc,
787 + struct bcm43xx_dmadesc_meta *meta,
788 + int irq_context)
789 +{
790 + assert(meta->skb);
791 + if (irq_context)
792 + dev_kfree_skb_irq(meta->skb);
793 + else
794 + dev_kfree_skb(meta->skb);
795 + meta->skb = NULL;
796 +}
797 +
798 +static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
799 +{
800 + struct device *dev = &(ring->bcm->pci_dev->dev);
801 +
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");
806 + return -ENOMEM;
807 + }
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);
814 + return -ENOMEM;
815 + }
816 + assert(!(ring->dmabase & 0x000003FF));
817 + memset(ring->vbase, 0, BCM43xx_DMA_RINGMEMSIZE);
818 +
819 + return 0;
820 +}
821 +
822 +static void free_ringmemory(struct bcm43xx_dmaring *ring)
823 +{
824 + struct device *dev = &(ring->bcm->pci_dev->dev);
825 +
826 + dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
827 + ring->vbase, ring->dmabase);
828 +}
829 +
830 +/* Reset the RX DMA channel */
831 +int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
832 + u16 mmio_base)
833 +{
834 + int i;
835 + u32 value;
836 +
837 + bcm43xx_write32(bcm,
838 + mmio_base + BCM43xx_DMA_RX_CONTROL,
839 + 0x00000000);
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) {
845 + i = -1;
846 + break;
847 + }
848 + udelay(10);
849 + }
850 + if (i != -1) {
851 + printk(KERN_ERR PFX "Error: Wait on DMA RX status timed out.\n");
852 + return -ENODEV;
853 + }
854 +
855 + return 0;
856 +}
857 +
858 +/* Reset the RX DMA channel */
859 +int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
860 + u16 mmio_base)
861 +{
862 + int i;
863 + u32 value;
864 +
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)
872 + break;
873 + udelay(10);
874 + }
875 + bcm43xx_write32(bcm,
876 + mmio_base + BCM43xx_DMA_TX_CONTROL,
877 + 0x00000000);
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) {
883 + i = -1;
884 + break;
885 + }
886 + udelay(10);
887 + }
888 + if (i != -1) {
889 + printk(KERN_ERR PFX "Error: Wait on DMA TX status timed out.\n");
890 + return -ENODEV;
891 + }
892 + /* ensure the reset is completed. */
893 + udelay(300);
894 +
895 + return 0;
896 +}
897 +
898 +static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
899 + struct bcm43xx_dmadesc *desc,
900 + struct bcm43xx_dmadesc_meta *meta,
901 + gfp_t gfp_flags)
902 +{
903 + struct bcm43xx_rxhdr *rxhdr;
904 + dma_addr_t dmaaddr;
905 + u32 desc_addr;
906 + u32 desc_ctl;
907 + const int slot = (int)(desc - ring->vbase);
908 + struct sk_buff *skb;
909 +
910 + assert(slot >= 0 && slot < ring->nr_slots);
911 + assert(!ring->tx);
912 +
913 + skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
914 + if (unlikely(!skb))
915 + return -ENOMEM;
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);
924 + return -ENOMEM;
925 + }
926 + meta->skb = skb;
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);
936 +
937 + rxhdr = (struct bcm43xx_rxhdr *)(skb->data);
938 + rxhdr->frame_length = 0;
939 + rxhdr->flags1 = 0;
940 +
941 + return 0;
942 +}
943 +
944 +/* Allocate the initial descbuffers.
945 + * This is used for an RX ring only.
946 + */
947 +static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring)
948 +{
949 + int i, err = -ENOMEM;
950 + struct bcm43xx_dmadesc *desc;
951 + struct bcm43xx_dmadesc_meta *meta;
952 +
953 + for (i = 0; i < ring->nr_slots; i++) {
954 + desc = ring->vbase + i;
955 + meta = ring->meta + i;
956 +
957 + err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
958 + if (err)
959 + goto err_unwind;
960 + }
961 + ring->used_slots = ring->nr_slots;
962 + err = 0;
963 +out:
964 + return err;
965 +
966 +err_unwind:
967 + for (i--; i >= 0; i--) {
968 + desc = ring->vbase + i;
969 + meta = ring->meta + i;
970 +
971 + unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
972 + dev_kfree_skb(meta->skb);
973 + }
974 + goto out;
975 +}
976 +
977 +/* Do initial setup of the DMA controller.
978 + * Reset the controller, write the ring busaddress
979 + * and switch the "enable" bit on.
980 + */
981 +static int dmacontroller_setup(struct bcm43xx_dmaring *ring)
982 +{
983 + int err = 0;
984 + u32 value;
985 +
986 + if (ring->tx) {
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);
993 + } else {
994 + err = alloc_initial_descbuffers(ring);
995 + if (err)
996 + goto out;
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);
1006 + }
1007 +
1008 +out:
1009 + return err;
1010 +}
1011 +
1012 +/* Shutdown the DMA controller. */
1013 +static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring)
1014 +{
1015 + if (ring->tx) {
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);
1019 + } else {
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);
1023 + }
1024 +}
1025 +
1026 +static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
1027 +{
1028 + struct bcm43xx_dmadesc *desc;
1029 + struct bcm43xx_dmadesc_meta *meta;
1030 + int i;
1031 +
1032 + if (!ring->used_slots)
1033 + return;
1034 + for (i = 0; i < ring->nr_slots; i++) {
1035 + desc = ring->vbase + i;
1036 + meta = ring->meta + i;
1037 +
1038 + if (!meta->skb) {
1039 + assert(ring->tx);
1040 + continue;
1041 + }
1042 + if (ring->tx) {
1043 + unmap_descbuffer(ring, meta->dmaaddr,
1044 + meta->skb->len, 1);
1045 + } else {
1046 + unmap_descbuffer(ring, meta->dmaaddr,
1047 + ring->rx_buffersize, 0);
1048 + }
1049 + free_descriptor_buffer(ring, desc, meta, 0);
1050 + }
1051 +}
1052 +
1053 +/* Main initialization function. */
1054 +static
1055 +struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
1056 + u16 dma_controller_base,
1057 + int nr_descriptor_slots,
1058 + int tx)
1059 +{
1060 + struct bcm43xx_dmaring *ring;
1061 + int err;
1062 +
1063 + ring = kzalloc(sizeof(*ring), GFP_KERNEL);
1064 + if (!ring)
1065 + goto out;
1066 +
1067 + ring->meta = kzalloc(sizeof(*ring->meta) * nr_descriptor_slots,
1068 + GFP_KERNEL);
1069 + if (!ring->meta)
1070 + goto err_kfree_ring;
1071 +
1072 + ring->memoffset = BCM43xx_DMA_DMABUSADDROFFSET;
1073 +#ifdef CONFIG_BCM947XX
1074 + if (bcm->pci_dev->bus->number == 0)
1075 + ring->memoffset = 0;
1076 +#endif
1077 +
1078 + ring->bcm = bcm;
1079 + ring->nr_slots = nr_descriptor_slots;
1080 + ring->mmio_base = dma_controller_base;
1081 + if (tx) {
1082 + ring->tx = 1;
1083 + ring->current_slot = -1;
1084 + } else {
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;
1089 + break;
1090 + case BCM43xx_MMIO_DMA4_BASE:
1091 + ring->rx_buffersize = BCM43xx_DMA4_RXBUFFERSIZE;
1092 + ring->frameoffset = BCM43xx_DMA4_RX_FRAMEOFFSET;
1093 + break;
1094 + default:
1095 + assert(0);
1096 + }
1097 + }
1098 +
1099 + err = alloc_ringmemory(ring);
1100 + if (err)
1101 + goto err_kfree_meta;
1102 + err = dmacontroller_setup(ring);
1103 + if (err)
1104 + goto err_free_ringmemory;
1105 +
1106 +out:
1107 + return ring;
1108 +
1109 +err_free_ringmemory:
1110 + free_ringmemory(ring);
1111 +err_kfree_meta:
1112 + kfree(ring->meta);
1113 +err_kfree_ring:
1114 + kfree(ring);
1115 + ring = NULL;
1116 + goto out;
1117 +}
1118 +
1119 +/* Main cleanup function. */
1120 +static void bcm43xx_destroy_dmaring(struct bcm43xx_dmaring *ring)
1121 +{
1122 + if (!ring)
1123 + return;
1124 +
1125 + dprintk(KERN_INFO PFX "DMA 0x%04x (%s) max used slots: %d/%d\n",
1126 + ring->mmio_base,
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.
1131 + */
1132 + dmacontroller_cleanup(ring);
1133 + free_all_descbuffers(ring);
1134 + free_ringmemory(ring);
1135 +
1136 + kfree(ring->meta);
1137 + kfree(ring);
1138 +}
1139 +
1140 +void bcm43xx_dma_free(struct bcm43xx_private *bcm)
1141 +{
1142 + struct bcm43xx_dma *dma;
1143 +
1144 + if (bcm43xx_using_pio(bcm))
1145 + return;
1146 + dma = bcm43xx_current_dma(bcm);
1147 +
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;
1160 +}
1161 +
1162 +int bcm43xx_dma_init(struct bcm43xx_private *bcm)
1163 +{
1164 + struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
1165 + struct bcm43xx_dmaring *ring;
1166 + int err = -ENOMEM;
1167 +
1168 + /* setup TX DMA channels. */
1169 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
1170 + BCM43xx_TXRING_SLOTS, 1);
1171 + if (!ring)
1172 + goto out;
1173 + dma->tx_ring0 = ring;
1174 +
1175 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA2_BASE,
1176 + BCM43xx_TXRING_SLOTS, 1);
1177 + if (!ring)
1178 + goto err_destroy_tx0;
1179 + dma->tx_ring1 = ring;
1180 +
1181 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA3_BASE,
1182 + BCM43xx_TXRING_SLOTS, 1);
1183 + if (!ring)
1184 + goto err_destroy_tx1;
1185 + dma->tx_ring2 = ring;
1186 +
1187 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
1188 + BCM43xx_TXRING_SLOTS, 1);
1189 + if (!ring)
1190 + goto err_destroy_tx2;
1191 + dma->tx_ring3 = ring;
1192 +
1193 + /* setup RX DMA channels. */
1194 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
1195 + BCM43xx_RXRING_SLOTS, 0);
1196 + if (!ring)
1197 + goto err_destroy_tx3;
1198 + dma->rx_ring0 = ring;
1199 +
1200 + if (bcm->current_core->rev < 5) {
1201 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
1202 + BCM43xx_RXRING_SLOTS, 0);
1203 + if (!ring)
1204 + goto err_destroy_rx0;
1205 + dma->rx_ring1 = ring;
1206 + }
1207 +
1208 + dprintk(KERN_INFO PFX "DMA initialized\n");
1209 + err = 0;
1210 +out:
1211 + return err;
1212 +
1213 +err_destroy_rx0:
1214 + bcm43xx_destroy_dmaring(dma->rx_ring0);
1215 + dma->rx_ring0 = NULL;
1216 +err_destroy_tx3:
1217 + bcm43xx_destroy_dmaring(dma->tx_ring3);
1218 + dma->tx_ring3 = NULL;
1219 +err_destroy_tx2:
1220 + bcm43xx_destroy_dmaring(dma->tx_ring2);
1221 + dma->tx_ring2 = NULL;
1222 +err_destroy_tx1:
1223 + bcm43xx_destroy_dmaring(dma->tx_ring1);
1224 + dma->tx_ring1 = NULL;
1225 +err_destroy_tx0:
1226 + bcm43xx_destroy_dmaring(dma->tx_ring0);
1227 + dma->tx_ring0 = NULL;
1228 + goto out;
1229 +}
1230 +
1231 +/* Generate a cookie for the TX header. */
1232 +static u16 generate_cookie(struct bcm43xx_dmaring *ring,
1233 + int slot)
1234 +{
1235 + u16 cookie = 0x0000;
1236 +
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
1240 + */
1241 + switch (ring->mmio_base) {
1242 + default:
1243 + assert(0);
1244 + case BCM43xx_MMIO_DMA1_BASE:
1245 + break;
1246 + case BCM43xx_MMIO_DMA2_BASE:
1247 + cookie = 0x1000;
1248 + break;
1249 + case BCM43xx_MMIO_DMA3_BASE:
1250 + cookie = 0x2000;
1251 + break;
1252 + case BCM43xx_MMIO_DMA4_BASE:
1253 + cookie = 0x3000;
1254 + break;
1255 + }
1256 + assert(((u16)slot & 0xF000) == 0x0000);
1257 + cookie |= (u16)slot;
1258 +
1259 + return cookie;
1260 +}
1261 +
1262 +/* Inspect a cookie and find out to which controller/slot it belongs. */
1263 +static
1264 +struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm,
1265 + u16 cookie, int *slot)
1266 +{
1267 + struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
1268 + struct bcm43xx_dmaring *ring = NULL;
1269 +
1270 + switch (cookie & 0xF000) {
1271 + case 0x0000:
1272 + ring = dma->tx_ring0;
1273 + break;
1274 + case 0x1000:
1275 + ring = dma->tx_ring1;
1276 + break;
1277 + case 0x2000:
1278 + ring = dma->tx_ring2;
1279 + break;
1280 + case 0x3000:
1281 + ring = dma->tx_ring3;
1282 + break;
1283 + default:
1284 + assert(0);
1285 + }
1286 + *slot = (cookie & 0x0FFF);
1287 + assert(*slot >= 0 && *slot < ring->nr_slots);
1288 +
1289 + return ring;
1290 +}
1291 +
1292 +static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
1293 + int slot)
1294 +{
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.
1299 + */
1300 + wmb();
1301 + slot = next_slot(ring, slot);
1302 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_INDEX,
1303 + (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
1304 +}
1305 +
1306 +static int dma_tx_fragment(struct bcm43xx_dmaring *ring,
1307 + struct sk_buff *skb,
1308 + struct ieee80211_tx_control *ctl)
1309 +{
1310 + struct sk_buff *hdr_skb;
1311 + int slot;
1312 + struct bcm43xx_dmadesc *desc;
1313 + struct bcm43xx_dmadesc_meta *meta;
1314 + u32 desc_ctl;
1315 + u32 desc_addr;
1316 +
1317 + assert(skb_shinfo(skb)->nr_frags == 0);
1318 +
1319 + hdr_skb = dev_alloc_skb(sizeof(struct bcm43xx_txhdr));
1320 + if (unlikely(!hdr_skb))
1321 + return -ENOMEM;
1322 + skb_put(hdr_skb, sizeof(struct bcm43xx_txhdr));
1323 +
1324 + slot = request_slot(ring);
1325 + desc = ring->vbase + slot;
1326 + meta = ring->meta + slot;
1327 +
1328 + bcm43xx_generate_txhdr(ring->bcm,
1329 + (struct bcm43xx_txhdr *)hdr_skb->data,
1330 + skb->data, skb->len,
1331 + 1,//FIXME
1332 + generate_cookie(ring, slot),
1333 + ctl);
1334 +
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);
1343 + return -ENOMEM;
1344 + }
1345 +
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);
1353 +
1354 + slot = request_slot(ring);
1355 + desc = ring->vbase + slot;
1356 + meta = ring->meta + slot;
1357 +
1358 + /* We inspect the txstatus on the FRAMESTART descriptor later
1359 + * on xmit-status IRQ.
1360 + */
1361 + meta->must_xmit_txstat = 1;
1362 + memset(&meta->txstat, 0, sizeof(meta->txstat));
1363 + memcpy(&meta->txstat.control, ctl, sizeof(*ctl));
1364 +
1365 + meta->skb = skb;
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);
1374 + return -ENOMEM;
1375 + }
1376 +
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;
1381 +
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);
1387 +
1388 + return 0;
1389 +}
1390 +
1391 +int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
1392 + struct sk_buff *skb,
1393 + struct ieee80211_tx_control *ctl)
1394 +{
1395 + struct bcm43xx_dmaring *ring = bcm43xx_current_dma(bcm)->tx_ring1;
1396 + int err;
1397 +
1398 + assert(ring->tx);
1399 +
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.
1405 + */
1406 + printk(KERN_ERR PFX "DMA queue overflow\n");
1407 + return -ENOMEM;
1408 + }
1409 +
1410 + err = dma_tx_fragment(ring, skb, ctl);
1411 + if (likely(!err))
1412 + ring->nr_tx_packets++;
1413 +
1414 + return err;
1415 +}
1416 +
1417 +void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
1418 + struct bcm43xx_xmitstatus *status)
1419 +{
1420 + struct bcm43xx_dmaring *ring;
1421 + struct bcm43xx_dmadesc *desc;
1422 + struct bcm43xx_dmadesc_meta *meta;
1423 + int is_last_fragment;
1424 + int slot;
1425 +
1426 + ring = parse_cookie(bcm, status->cookie, &slot);
1427 + assert(ring);
1428 + assert(ring->tx);
1429 + assert(get_desc_ctl(ring->vbase + slot) & BCM43xx_DMADTOR_FRAMESTART);
1430 + while (1) {
1431 + assert(slot >= 0 && slot < ring->nr_slots);
1432 + desc = ring->vbase + slot;
1433 + meta = ring->meta + slot;
1434 +
1435 + is_last_fragment = !!(get_desc_ctl(desc) & BCM43xx_DMADTOR_FRAMEEND);
1436 + unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
1437 +
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().
1443 + */
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));
1448 + meta->skb = NULL;
1449 + } else
1450 + free_descriptor_buffer(ring, desc, meta, 1);
1451 + /* Everything belonging to the slot is unmapped
1452 + * and freed, so we can return it.
1453 + */
1454 + return_slot(ring, slot);
1455 +
1456 + if (is_last_fragment)
1457 + break;
1458 + slot = next_slot(ring, slot);
1459 + }
1460 + bcm->stats.last_tx = jiffies;
1461 +}
1462 +
1463 +void bcm43xx_dma_get_tx_stats(struct bcm43xx_private *bcm,
1464 + struct ieee80211_tx_queue_stats *stats)
1465 +{
1466 + struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
1467 + struct bcm43xx_dmaring *ring;
1468 + struct ieee80211_tx_queue_stats_data *data;
1469 +
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;
1475 +}
1476 +
1477 +static void dma_rx(struct bcm43xx_dmaring *ring,
1478 + int *slot)
1479 +{
1480 + struct bcm43xx_dmadesc *desc;
1481 + struct bcm43xx_dmadesc_meta *meta;
1482 + struct bcm43xx_rxhdr *rxhdr;
1483 + struct sk_buff *skb;
1484 + u16 len;
1485 + int err;
1486 + dma_addr_t dmaaddr;
1487 +
1488 + desc = ring->vbase + *slot;
1489 + meta = ring->meta + *slot;
1490 +
1491 + sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
1492 + skb = meta->skb;
1493 +
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;
1498 +
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);
1505 +
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);
1510 +
1511 + return;
1512 + }
1513 + rxhdr = (struct bcm43xx_rxhdr *)skb->data;
1514 + len = le16_to_cpu(rxhdr->frame_length);
1515 + if (len == 0) {
1516 + int i = 0;
1517 +
1518 + do {
1519 + udelay(2);
1520 + barrier();
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);
1527 + goto drop;
1528 + }
1529 + }
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.
1535 + */
1536 + int cnt = 0;
1537 + s32 tmp = len;
1538 +
1539 + while (1) {
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);
1546 + cnt++;
1547 + tmp -= ring->rx_buffersize;
1548 + if (tmp <= 0)
1549 + break;
1550 + }
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);
1554 + goto drop;
1555 + }
1556 +
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);
1563 + goto drop;
1564 + }
1565 +
1566 + unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
1567 + skb_put(skb, len + ring->frameoffset);
1568 + skb_pull(skb, ring->frameoffset);
1569 +
1570 + bcm43xx_rx(ring->bcm, skb, rxhdr);
1571 +drop:
1572 + return;
1573 +}
1574 +
1575 +void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
1576 +{
1577 + u32 status;
1578 + u16 descptr;
1579 + int slot, current_slot;
1580 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
1581 + int used_slots = 0;
1582 +#endif
1583 +
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);
1589 +
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;
1596 +#endif
1597 + }
1598 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX,
1599 + (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
1600 + ring->current_slot = slot;
1601 +}
1602 +
1603 +void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring)
1604 +{
1605 + assert(ring->tx);
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);
1610 +}
1611 +
1612 +void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
1613 +{
1614 + assert(ring->tx);
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);
1619 +}
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
1623 @@ -0,0 +1,228 @@
1624 +#ifndef BCM43xx_DMA_H_
1625 +#define BCM43xx_DMA_H_
1626 +
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>
1632 +
1633 +#include "bcm43xx.h"
1634 +
1635 +
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)
1641 +
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
1651 +
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
1679 +
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)
1686 +
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
1693 +
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
1699 +
1700 +
1701 +
1702 +#ifdef CONFIG_BCM43XX_D80211_DMA
1703 +
1704 +
1705 +struct sk_buff;
1706 +struct bcm43xx_private;
1707 +struct bcm43xx_xmitstatus;
1708 +
1709 +
1710 +struct bcm43xx_dmadesc {
1711 + __le32 _control;
1712 + __le32 _address;
1713 +} __attribute__((__packed__));
1714 +
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)
1720 +
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;
1729 +};
1730 +
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. */
1742 + int nr_slots;
1743 + /* Number of used descriptor slots. */
1744 + int used_slots;
1745 + /* Currently used slot in the ring. */
1746 + int current_slot;
1747 + /* Total number of packets sent. Statistics only. */
1748 + unsigned int nr_tx_packets;
1749 + /* Frameoffset in octets. */
1750 + u32 frameoffset;
1751 + /* Descriptor buffer size. */
1752 + u16 rx_buffersize;
1753 + /* The MMIO base register of the DMA controller, this
1754 + * ring is posted to.
1755 + */
1756 + u16 mmio_base;
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*/
1763 +};
1764 +
1765 +
1766 +static inline
1767 +u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring,
1768 + u16 offset)
1769 +{
1770 + return bcm43xx_read32(ring->bcm, ring->mmio_base + offset);
1771 +}
1772 +
1773 +static inline
1774 +void bcm43xx_dma_write(struct bcm43xx_dmaring *ring,
1775 + u16 offset, u32 value)
1776 +{
1777 + bcm43xx_write32(ring->bcm, ring->mmio_base + offset, value);
1778 +}
1779 +
1780 +
1781 +int bcm43xx_dma_init(struct bcm43xx_private *bcm);
1782 +void bcm43xx_dma_free(struct bcm43xx_private *bcm);
1783 +
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);
1788 +
1789 +void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring);
1790 +void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring);
1791 +
1792 +void bcm43xx_dma_get_tx_stats(struct bcm43xx_private *bcm,
1793 + struct ieee80211_tx_queue_stats *stats);
1794 +
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);
1800 +
1801 +void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
1802 +
1803 +
1804 +#else /* CONFIG_BCM43XX_D80211_DMA */
1805 +
1806 +
1807 +static inline
1808 +int bcm43xx_dma_init(struct bcm43xx_private *bcm)
1809 +{
1810 + return 0;
1811 +}
1812 +static inline
1813 +void bcm43xx_dma_free(struct bcm43xx_private *bcm)
1814 +{
1815 +}
1816 +static inline
1817 +int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
1818 + u16 dmacontroller_mmio_base)
1819 +{
1820 + return 0;
1821 +}
1822 +static inline
1823 +int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
1824 + u16 dmacontroller_mmio_base)
1825 +{
1826 + return 0;
1827 +}
1828 +static inline
1829 +void bcm43xx_dma_get_tx_stats(struct bcm43xx_private *bcm,
1830 + struct ieee80211_tx_queue_stats *stats)
1831 +{
1832 +}
1833 +static inline
1834 +int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
1835 + struct sk_buff *skb,
1836 + struct ieee80211_tx_control *ctl)
1837 +{
1838 + return 0;
1839 +}
1840 +static inline
1841 +void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
1842 + struct bcm43xx_xmitstatus *status)
1843 +{
1844 +}
1845 +static inline
1846 +void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
1847 +{
1848 +}
1849 +
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
1855 @@ -0,0 +1,50 @@
1856 +/*
1857 +
1858 + Broadcom BCM43xx wireless driver
1859 +
1860 + ethtool support
1861 +
1862 + Copyright (c) 2006 Jason Lunz <lunz@falooley.org>
1863 +
1864 + Some code in this file is derived from the 8139too.c driver
1865 + Copyright (C) 2002 Jeff Garzik
1866 +
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.
1871 +
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.
1876 +
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.
1881 +
1882 +*/
1883 +
1884 +#include "bcm43xx.h"
1885 +#include "bcm43xx_ethtool.h"
1886 +
1887 +#include <linux/netdevice.h>
1888 +#include <linux/pci.h>
1889 +#include <linux/string.h>
1890 +#include <linux/version.h>
1891 +
1892 +
1893 +static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1894 +{
1895 + struct bcm43xx_private *bcm = bcm43xx_priv(dev);
1896 +
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);
1900 +}
1901 +
1902 +struct ethtool_ops bcm43xx_ethtool_ops = {
1903 + .get_drvinfo = bcm43xx_get_drvinfo,
1904 + .get_link = ethtool_op_get_link,
1905 +};
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
1909 @@ -0,0 +1,8 @@
1910 +#ifndef BCM43xx_ETHTOOL_H_
1911 +#define BCM43xx_ETHTOOL_H_
1912 +
1913 +#include <linux/ethtool.h>
1914 +
1915 +extern struct ethtool_ops bcm43xx_ethtool_ops;
1916 +
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
1921 @@ -0,0 +1,917 @@
1922 +#ifndef BCM43xx_H_
1923 +#define BCM43xx_H_
1924 +
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>
1934 +
1935 +#include <linux/wireless.h>
1936 +#include <net/d80211.h>
1937 +#include <net/d80211_mgmt.h>
1938 +#include <net/d80211_common.h>
1939 +
1940 +#include "bcm43xx_debugfs.h"
1941 +#include "bcm43xx_leds.h"
1942 +#include "bcm43xx_sysfs.h"
1943 +
1944 +
1945 +#define PFX KBUILD_MODNAME ": "
1946 +
1947 +#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50
1948 +#define BCM43xx_IRQWAIT_MAX_RETRIES 50
1949 +
1950 +#define BCM43xx_IO_SIZE 8192
1951 +
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
1958 +
1959 +/* MMIO offsets */
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
2011 +
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
2033 +
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 */
2051 +
2052 +/* GPIO register offset, in both ChipCommon and PCI core. */
2053 +#define BCM43xx_GPIO_CONTROL 0x6c
2054 +
2055 +/* SHM Routing */
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
2061 +
2062 +/* MacFilter offsets. */
2063 +#define BCM43xx_MACFILTER_SELF 0x0000
2064 +#define BCM43xx_MACFILTER_ASSOC 0x0003
2065 +
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
2072 +
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
2077 +
2078 +/* SBTOPCI2 values. */
2079 +#define BCM43xx_SBTOPCI2_PREFETCH 0x4
2080 +#define BCM43xx_SBTOPCI2_BURST 0x8
2081 +
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
2094 +
2095 +/* PowerControl */
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
2101 +
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
2106 +
2107 +#define BCM43xx_PCTL_FORCE_SLOW 0x0800
2108 +#define BCM43xx_PCTL_FORCE_PLL 0x1000
2109 +#define BCM43xx_PCTL_DYN_XTAL 0x2000
2110 +
2111 +/* COREIDs */
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
2130 +
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)
2140 +
2141 +/* Mask to get the Backplane Flag Number from SBTPSFLAG. */
2142 +#define BCM43xx_BACKPLANE_FLAG_NR_MASK 0x3f
2143 +
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
2151 +
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
2157 +
2158 +/* sbtmstatehigh state flags */
2159 +#define BCM43xx_SBTMSTATEHIGH_SERROR 0x1
2160 +#define BCM43xx_SBTMSTATEHIGH_BUSY 0x4
2161 +
2162 +/* sbimstate flags */
2163 +#define BCM43xx_SBIMSTATE_IB_ERROR 0x20000
2164 +#define BCM43xx_SBIMSTATE_TIMEOUT 0x40000
2165 +
2166 +/* PHYVersioning */
2167 +#define BCM43xx_PHYTYPE_A 0x00
2168 +#define BCM43xx_PHYTYPE_B 0x01
2169 +#define BCM43xx_PHYTYPE_G 0x02
2170 +
2171 +/* PHYRegisters */
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
2186 +
2187 +/* RadioRegisters */
2188 +#define BCM43xx_RADIOCTL_ID 0x01
2189 +
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*/
2208 +
2209 +/* MicrocodeFlagsBitfield (addr + lo-word values?)*/
2210 +#define BCM43xx_UCODEFLAGS_OFFSET 0x005E
2211 +
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
2218 +
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)
2231 +
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)
2241 +
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
2248 +
2249 +/* Rate values. */
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
2262 +
2263 +#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7
2264 +#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4
2265 +
2266 +/* Max size of a security key */
2267 +#define BCM43xx_SEC_KEYSIZE 16
2268 +/* Security algorithms. */
2269 +enum {
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,
2276 +};
2277 +
2278 +
2279 +#ifdef assert
2280 +# undef assert
2281 +#endif
2282 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2283 +#define assert(expr) \
2284 + do { \
2285 + if (unlikely(!(expr))) { \
2286 + printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", \
2287 + #expr, __FILE__, __LINE__, __FUNCTION__); \
2288 + } \
2289 + } while (0)
2290 +#else
2291 +#define assert(expr) do { /* nothing */ } while (0)
2292 +#endif
2293 +
2294 +/* rate limited printk(). */
2295 +#ifdef printkl
2296 +# undef printkl
2297 +#endif
2298 +#define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0)
2299 +/* rate limited printk() for debugging */
2300 +#ifdef dprintkl
2301 +# undef dprintkl
2302 +#endif
2303 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2304 +# define dprintkl printkl
2305 +#else
2306 +# define dprintkl(f, x...) do { /* nothing */ } while (0)
2307 +#endif
2308 +
2309 +/* debugging printk() */
2310 +#ifdef dprintk
2311 +# undef dprintk
2312 +#endif
2313 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2314 +# define dprintk(f, x...) do { printk(f ,##x); } while (0)
2315 +#else
2316 +# define dprintk(f, x...) do { /* nothing */ } while (0)
2317 +#endif
2318 +
2319 +
2320 +struct net_device;
2321 +struct pci_dev;
2322 +struct bcm43xx_dmaring;
2323 +struct bcm43xx_pioqueue;
2324 +
2325 +struct bcm43xx_initval {
2326 + u16 offset;
2327 + u16 size;
2328 + u32 value;
2329 +} __attribute__((__packed__));
2330 +
2331 +/* Values for bcm430x_sprominfo.locale */
2332 +enum {
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,
2345 +};
2346 +
2347 +#define BCM43xx_SPROM_SIZE 64 /* in 16-bit words. */
2348 +struct bcm43xx_sprominfo {
2349 + u16 boardflags2;
2350 + u8 il0macaddr[6];
2351 + u8 et0macaddr[6];
2352 + u8 et1macaddr[6];
2353 + u8 et0phyaddr:5;
2354 + u8 et1phyaddr:5;
2355 + u8 et0mdcport:1;
2356 + u8 et1mdcport:1;
2357 + u8 boardrev;
2358 + u8 locale:4;
2359 + u8 antennas_aphy:2;
2360 + u8 antennas_bgphy:2;
2361 + u16 pa0b0;
2362 + u16 pa0b1;
2363 + u16 pa0b2;
2364 + u8 wl0gpio0;
2365 + u8 wl0gpio1;
2366 + u8 wl0gpio2;
2367 + u8 wl0gpio3;
2368 + u8 maxpower_aphy;
2369 + u8 maxpower_bgphy;
2370 + u16 pa1b0;
2371 + u16 pa1b1;
2372 + u16 pa1b2;
2373 + u8 idle_tssi_tgt_aphy;
2374 + u8 idle_tssi_tgt_bgphy;
2375 + u16 boardflags;
2376 + u16 antennagain_aphy;
2377 + u16 antennagain_bgphy;
2378 +};
2379 +
2380 +/* Value pair to measure the LocalOscillator. */
2381 +struct bcm43xx_lopair {
2382 + s8 low;
2383 + s8 high;
2384 + u8 used:1;
2385 +};
2386 +#define BCM43xx_LO_COUNT (14*4)
2387 +
2388 +struct bcm43xx_phyinfo {
2389 + /* Hardware Data */
2390 + u8 version;
2391 + u8 type;
2392 + u8 rev;
2393 + u16 antenna_diversity;
2394 + u16 savedpctlreg;
2395 + u16 minlowsig[2];
2396 + u16 minlowsigpos[2];
2397 + u8 connected:1,
2398 + calibrated:1,
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.
2403 + */
2404 + struct bcm43xx_lopair *_lo_pairs;
2405 +
2406 + /* TSSI to dBm table in use */
2407 + const s8 *tssi2dbm;
2408 + /* idle TSSI value */
2409 + s8 idle_tssi;
2410 +
2411 + /* Values from bcm43xx_calc_loopback_gain() */
2412 + u16 loopback_gain[2];
2413 +
2414 + /* PHY lock for core.rev < 3
2415 + * This lock is only used by bcm43xx_phy_{un}lock()
2416 + */
2417 + spinlock_t lock;
2418 +};
2419 +
2420 +
2421 +struct bcm43xx_radioinfo {
2422 + u16 manufact;
2423 + u16 version;
2424 + u8 revision;
2425 +
2426 + /* Desired TX power level (in dBm).
2427 + * This is set by the user and adjusted in bcm43xx_phy_xmitpower(). */
2428 + u8 power_level;
2429 + /* TX Power control values. */
2430 + union {
2431 + /* B/G PHY */
2432 + struct {
2433 + u16 baseband_atten;
2434 + u16 radio_atten;
2435 + u16 txctl1;
2436 + u16 txctl2;
2437 + };
2438 + /* A PHY */
2439 + struct {
2440 + u16 txpwr_offset;
2441 + };
2442 + };
2443 +
2444 + /* Current Interference Mitigation mode */
2445 + int interfmode;
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
2452 + */
2453 +#define BCM43xx_INTERFSTACK_SIZE 26
2454 + u32 interfstack[BCM43xx_INTERFSTACK_SIZE];
2455 +
2456 + /* Saved values from the NRSSI Slope calculation */
2457 + s16 nrssi[2];
2458 + s32 nrssislope;
2459 + /* In memory nrssi lookup table. */
2460 + s8 nrssi_lt[64];
2461 +
2462 + /* current channel */
2463 + u8 channel;
2464 + u8 initial_channel;
2465 +
2466 + u16 lofcal;
2467 +
2468 + u16 initval;
2469 +
2470 + u8 enabled:1;
2471 + /* ACI (adjacent channel interference) flags. */
2472 + u8 aci_enable:1,
2473 + aci_wlan_automatic:1,
2474 + aci_hw_rssi:1;
2475 +};
2476 +
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 */
2485 +};
2486 +
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;
2493 +};
2494 +
2495 +#define BCM43xx_MAX_80211_CORES 2
2496 +
2497 +#ifdef CONFIG_BCM947XX
2498 +#define core_offset(bcm) (bcm)->current_core_offset
2499 +#else
2500 +#define core_offset(bcm) 0
2501 +#endif
2502 +
2503 +/* Generic information about a core. */
2504 +struct bcm43xx_coreinfo {
2505 + u8 available:1,
2506 + enabled:1,
2507 + initialized:1;
2508 + /** core_id ID number */
2509 + u16 id;
2510 + /** core_rev revision number */
2511 + u8 rev;
2512 + /** Index number for _switch_core() */
2513 + u8 index;
2514 +};
2515 +
2516 +/* Additional information for each 80211 core. */
2517 +struct bcm43xx_coreinfo_80211 {
2518 + /* PHY device. */
2519 + struct bcm43xx_phyinfo phy;
2520 + /* Radio device. */
2521 + struct bcm43xx_radioinfo radio;
2522 + union {
2523 + /* DMA context. */
2524 + struct bcm43xx_dma dma;
2525 + /* PIO context. */
2526 + struct bcm43xx_pio pio;
2527 + };
2528 +};
2529 +
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;
2535 + u8 nr_samples;
2536 + s8 samples[8][4];
2537 +};
2538 +
2539 +struct bcm43xx_stats {
2540 + u8 link_quality;
2541 + /* Store the last TX/RX times here for updating the leds. */
2542 + unsigned long last_tx;
2543 + unsigned long last_rx;
2544 +};
2545 +
2546 +struct bcm43xx_key {
2547 + u8 enabled:1;
2548 + u8 algorithm;
2549 +};
2550 +
2551 +struct bcm43xx_private {
2552 + struct bcm43xx_sysfs sysfs;
2553 +
2554 + struct ieee80211_hw *ieee;
2555 + struct ieee80211_low_level_stats ieee_stats;
2556 + int iw_mode;
2557 +
2558 + struct net_device *net_dev;
2559 + struct pci_dev *pci_dev;
2560 + unsigned int irq;
2561 +
2562 + void __iomem *mmio_addr;
2563 + unsigned int mmio_len;
2564 +
2565 + /* Do not use the lock directly. Use the bcm43xx_lock* helper
2566 + * functions, to be MMIO-safe. */
2567 + spinlock_t _lock;
2568 +
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. */
2580 +
2581 + struct bcm43xx_stats stats;
2582 +
2583 + /* Bus type we are connected to.
2584 + * This is currently always BCM43xx_BUSTYPE_PCI
2585 + */
2586 + u8 bustype;
2587 +
2588 + u16 board_vendor;
2589 + u16 board_type;
2590 + u16 board_revision;
2591 +
2592 + u16 chip_id;
2593 + u8 chip_rev;
2594 + u8 chip_package;
2595 +
2596 + struct bcm43xx_sprominfo sprom;
2597 +#define BCM43xx_NR_LEDS 4
2598 + struct bcm43xx_led leds[BCM43xx_NR_LEDS];
2599 +
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;
2605 +#endif
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.
2610 + */
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.
2618 + */
2619 + int current_80211_core_idx;
2620 + /* Number of available 80211 cores. */
2621 + int nr_80211_available;
2622 +
2623 + u32 chipcommon_capabilities;
2624 +
2625 + /* Reason code of the last interrupt. */
2626 + u32 irq_reason;
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;
2632 +
2633 + /* Interrupt Service Routine tasklet (bottom-half) */
2634 + struct tasklet_struct isr_tasklet;
2635 +
2636 + /* Periodic tasks */
2637 + struct timer_list periodic_tasks;
2638 + unsigned int periodic_state;
2639 +
2640 + struct work_struct restart_work;
2641 +
2642 + /* Informational stuff. */
2643 + char nick[IW_ESSID_MAX_SIZE + 1];
2644 + u8 bssid[ETH_ALEN];
2645 +
2646 + /* encryption/decryption */
2647 + u16 security_offset;
2648 + struct bcm43xx_key key[54];
2649 + u8 default_key_idx;
2650 +
2651 + /* Firmware. */
2652 + const struct firmware *ucode;
2653 + const struct firmware *pcm;
2654 + const struct firmware *initvals0;
2655 + const struct firmware *initvals1;
2656 +
2657 + /* Cached beacon template while uploading the template. */
2658 + struct sk_buff *cached_beacon;
2659 +
2660 + /* Debugging stuff follows. */
2661 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2662 + struct bcm43xx_dfsentry *dfsentry;
2663 +#endif
2664 +};
2665 +
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.
2671 + */
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.
2678 + */
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)
2681 +
2682 +static inline
2683 +struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
2684 +{
2685 + return ieee80211_dev_hw_data(dev);
2686 +}
2687 +
2688 +/* Helper function, which returns a boolean.
2689 + * TRUE, if PIO is used; FALSE, if DMA is used.
2690 + */
2691 +#if defined(CONFIG_BCM43XX_D80211_DMA) && defined(CONFIG_BCM43XX_D80211_PIO)
2692 +static inline
2693 +int bcm43xx_using_pio(struct bcm43xx_private *bcm)
2694 +{
2695 + return bcm->__using_pio;
2696 +}
2697 +#elif defined(CONFIG_BCM43XX_D80211_DMA)
2698 +static inline
2699 +int bcm43xx_using_pio(struct bcm43xx_private *bcm)
2700 +{
2701 + return 0;
2702 +}
2703 +#elif defined(CONFIG_BCM43XX_D80211_PIO)
2704 +static inline
2705 +int bcm43xx_using_pio(struct bcm43xx_private *bcm)
2706 +{
2707 + return 1;
2708 +}
2709 +#else
2710 +# error "Using neither DMA nor PIO? Confused..."
2711 +#endif
2712 +
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.
2716 + */
2717 +static inline
2718 +struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
2719 +{
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);
2724 +}
2725 +static inline
2726 +struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
2727 +{
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);
2732 +}
2733 +static inline
2734 +struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
2735 +{
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);
2739 +}
2740 +static inline
2741 +struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
2742 +{
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);
2746 +}
2747 +
2748 +/* Are we running in init_board() context? */
2749 +static inline
2750 +int bcm43xx_is_initializing(struct bcm43xx_private *bcm)
2751 +{
2752 + if (bcm->initialized)
2753 + return 0;
2754 + if (bcm->shutting_down)
2755 + return 0;
2756 + return 1;
2757 +}
2758 +
2759 +static inline
2760 +struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy,
2761 + u16 radio_attenuation,
2762 + u16 baseband_attenuation)
2763 +{
2764 + return phy->_lo_pairs + (radio_attenuation + 14 * (baseband_attenuation / 2));
2765 +}
2766 +
2767 +
2768 +static inline
2769 +u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset)
2770 +{
2771 + return ioread16(bcm->mmio_addr + core_offset(bcm) + offset);
2772 +}
2773 +
2774 +static inline
2775 +void bcm43xx_write16(struct bcm43xx_private *bcm, u16 offset, u16 value)
2776 +{
2777 + iowrite16(value, bcm->mmio_addr + core_offset(bcm) + offset);
2778 +}
2779 +
2780 +static inline
2781 +u32 bcm43xx_read32(struct bcm43xx_private *bcm, u16 offset)
2782 +{
2783 + return ioread32(bcm->mmio_addr + core_offset(bcm) + offset);
2784 +}
2785 +
2786 +static inline
2787 +void bcm43xx_write32(struct bcm43xx_private *bcm, u16 offset, u32 value)
2788 +{
2789 + iowrite32(value, bcm->mmio_addr + core_offset(bcm) + offset);
2790 +}
2791 +
2792 +static inline
2793 +int bcm43xx_pci_read_config16(struct bcm43xx_private *bcm, int offset, u16 *value)
2794 +{
2795 + return pci_read_config_word(bcm->pci_dev, offset, value);
2796 +}
2797 +
2798 +static inline
2799 +int bcm43xx_pci_read_config32(struct bcm43xx_private *bcm, int offset, u32 *value)
2800 +{
2801 + return pci_read_config_dword(bcm->pci_dev, offset, value);
2802 +}
2803 +
2804 +static inline
2805 +int bcm43xx_pci_write_config16(struct bcm43xx_private *bcm, int offset, u16 value)
2806 +{
2807 + return pci_write_config_word(bcm->pci_dev, offset, value);
2808 +}
2809 +
2810 +static inline
2811 +int bcm43xx_pci_write_config32(struct bcm43xx_private *bcm, int offset, u32 value)
2812 +{
2813 + return pci_write_config_dword(bcm->pci_dev, offset, value);
2814 +}
2815 +
2816 +/** Limit a value between two limits */
2817 +#ifdef limit_value
2818 +# undef limit_value
2819 +#endif
2820 +#define limit_value(value, min, max) \
2821 + ({ \
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; \
2829 + __value; \
2830 + })
2831 +
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]
2837 +
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
2842 @@ -0,0 +1,337 @@
2843 +/*
2844 +
2845 + Broadcom BCM43xx wireless driver
2846 +
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>
2852 +
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.
2857 +
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.
2862 +
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.
2867 +
2868 +*/
2869 +
2870 +#include "bcm43xx.h"
2871 +#include "bcm43xx_ilt.h"
2872 +#include "bcm43xx_phy.h"
2873 +
2874 +
2875 +/**** Initial Internal Lookup Tables ****/
2876 +
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,
2904 + 0x01473FFD,
2905 +};
2906 +
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,
2934 + 0x246DCB87,
2935 +};
2936 +
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,
3002 +};
3003 +
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,
3069 +};
3070 +
3071 +const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE] = {
3072 + 0x0001, 0x0001, 0x0001, 0xFFFE,
3073 + 0xFFFE, 0x3FFF, 0x1000, 0x0393,
3074 +};
3075 +
3076 +const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE] = {
3077 + 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
3078 + 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
3079 +};
3080 +
3081 +const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE] = {
3082 + 0x013C, 0x01F5, 0x031A, 0x0631,
3083 + 0x0001, 0x0001, 0x0001, 0x0001,
3084 +};
3085 +
3086 +const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE] = {
3087 + 0x5484, 0x3C40, 0x0000, 0x0000,
3088 + 0x0000, 0x0000, 0x0000, 0x0000,
3089 +};
3090 +
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,
3099 +};
3100 +
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,
3109 +};
3110 +
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,
3119 +};
3120 +
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 */
3135 + 0x007A,
3136 +};
3137 +
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 */
3152 + 0x00DE,
3153 +};
3154 +
3155 +/**** Helper functions to access the device Internal Lookup Tables ****/
3156 +
3157 +void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
3158 +{
3159 + if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
3160 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
3161 + mmiowb();
3162 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val);
3163 + } else {
3164 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
3165 + mmiowb();
3166 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val);
3167 + }
3168 +}
3169 +
3170 +u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset)
3171 +{
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);
3175 + } else {
3176 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
3177 + return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1);
3178 + }
3179 +}
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
3183 @@ -0,0 +1,32 @@
3184 +#ifndef BCM43xx_ILT_H_
3185 +#define BCM43xx_ILT_H_
3186 +
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];
3210 +
3211 +
3212 +void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
3213 +u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset);
3214 +
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
3219 @@ -0,0 +1,293 @@
3220 +/*
3221 +
3222 + Broadcom BCM43xx wireless driver
3223 +
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>
3229 +
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.
3234 +
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.
3239 +
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.
3244 +
3245 +*/
3246 +
3247 +#include "bcm43xx_leds.h"
3248 +#include "bcm43xx.h"
3249 +
3250 +#include <asm/bitops.h>
3251 +
3252 +
3253 +static void bcm43xx_led_changestate(struct bcm43xx_led *led)
3254 +{
3255 + struct bcm43xx_private *bcm = led->bcm;
3256 + const int index = bcm43xx_led_index(led);
3257 + const u16 mask = (1 << index);
3258 + u16 ledctl;
3259 +
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);
3265 +}
3266 +
3267 +static void bcm43xx_led_blink(unsigned long d)
3268 +{
3269 + struct bcm43xx_led *led = (struct bcm43xx_led *)d;
3270 + struct bcm43xx_private *bcm = led->bcm;
3271 + unsigned long flags;
3272 +
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);
3277 + }
3278 + bcm43xx_unlock_mmio(bcm, flags);
3279 +}
3280 +
3281 +static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
3282 + unsigned long interval)
3283 +{
3284 + if (led->blink_interval)
3285 + return;
3286 + led->blink_interval = interval;
3287 + bcm43xx_led_changestate(led);
3288 + led->blink_timer.expires = jiffies + interval;
3289 + add_timer(&led->blink_timer);
3290 +}
3291 +
3292 +static void bcm43xx_led_blink_stop(struct bcm43xx_led *led, int sync)
3293 +{
3294 + struct bcm43xx_private *bcm = led->bcm;
3295 + const int index = bcm43xx_led_index(led);
3296 + u16 ledctl;
3297 +
3298 + if (!led->blink_interval)
3299 + return;
3300 + if (unlikely(sync))
3301 + del_timer_sync(&led->blink_timer);
3302 + else
3303 + del_timer(&led->blink_timer);
3304 + led->blink_interval = 0;
3305 +
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);
3311 + else
3312 + ledctl &= ~(1 << index);
3313 + bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
3314 +}
3315 +
3316 +static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm,
3317 + struct bcm43xx_led *led,
3318 + int led_index)
3319 +{
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.
3325 + */
3326 +
3327 + switch (led_index) {
3328 + case 0:
3329 + led->behaviour = BCM43xx_LED_ACTIVITY;
3330 + if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
3331 + led->behaviour = BCM43xx_LED_RADIO_ALL;
3332 + break;
3333 + case 1:
3334 + led->behaviour = BCM43xx_LED_RADIO_B;
3335 + if (bcm->board_vendor == PCI_VENDOR_ID_ASUSTEK)
3336 + led->behaviour = BCM43xx_LED_ASSOC;
3337 + break;
3338 + case 2:
3339 + led->behaviour = BCM43xx_LED_RADIO_A;
3340 + break;
3341 + case 3:
3342 + led->behaviour = BCM43xx_LED_OFF;
3343 + break;
3344 + default:
3345 + assert(0);
3346 + }
3347 +}
3348 +
3349 +int bcm43xx_leds_init(struct bcm43xx_private *bcm)