remove ethernet bonding updates
[openwrt/svn-archive/archive.git] / openwrt / target / linux / brcm-2.6 / patches / 005-bcm43xx-dscape-060328.patch
1 diff -Nur linux-2.6.16/Documentation/networking/bcm43xx-d80211-HOWTO.txt linux-2.6.16-bcm43xx/Documentation/networking/bcm43xx-d80211-HOWTO.txt
2 --- linux-2.6.16/Documentation/networking/bcm43xx-d80211-HOWTO.txt 1970-01-01 01:00:00.000000000 +0100
3 +++ linux-2.6.16-bcm43xx/Documentation/networking/bcm43xx-d80211-HOWTO.txt 2006-03-28 22:16:14.000000000 +0200
4 @@ -0,0 +1,67 @@
5 +**** ****
6 +**** HOWTO get bcm43xx-dscape running ****
7 +**** ****
8 +
9 +This is a port of the bcm43xx driver for the devicescape ieee802.11
10 +stack. The devicescape ieee802.11 stack is an advanced out-of-mainline
11 +802.11 protocol module.
12 +I will call the "devicescape ieee802.11 stack" simply "dscape" in the
13 +following text.
14 +
15 +
16 +*** Setting up the bcm43xx driver with dscape is currently non-trivial,
17 +*** as several modifications to the kernel and the userland
18 +*** wpa_supplicant tool are required. We are working on it...
19 +
20 +
21 +1) You need to patch the kernel with the ieee80211-devicescape stack
22 + and the bcm43xx-dscape port.
23 + Both are available in one cummulative at:
24 + ftp://ftp.bu3sch.de/bcm43xx-snapshots/all-in-one/bcm43xx-dscape/
25 + Read the instructions on http://bcm43xx.berlios.de/ for how to apply
26 + this patch.
27 +
28 + Patch the kernel, compile and install it.
29 + When configuring, enable
30 + "Networking/Generic IEEE 802.11 Networking Stack (dscape)"
31 + and
32 + "Device Drivers/Network device support/Wireless LAN (non-hamradio)/Broadcom BCM43xx wireless support (DeviceScape stack)"
33 + Reboot.
34 +
35 +2) Set up a wpa_supplicant config file in /etc/wpa_supplicant.conf
36 + Here is an example for an AES WPA encrypted network:
37 +
38 + # WPA AES encryption
39 + ctrl_interface=/var/run/wpa_supplicant
40 + network={
41 + ssid="ACCESSPOINT_SSID"
42 + key_mgmt=WPA-PSK
43 + proto=WPA
44 + pairwise=CCMP TKIP
45 + group=CCMP TKIP
46 + psk="MY PASSPHRASE"
47 + priority=3
48 + }
49 +
50 +3) Take a bottle of your favourite beer, open it and take a swallow.
51 +
52 +4) Now it's time to bring the driver up.
53 + Do modprobe bcm43xx-d80211 to load the driver.
54 + There is an ugly bash script to bring the driver up after insmod.
55 + It is found in the "scripts" subdirectory of the patched kernel
56 + tree and is called "bcm43xx-d80211-sta_up.sh".
57 + Call scripts/bcm43xx-d80211-sta_up.sh --help to get some usage information.
58 + It may suffice to call scripts/bcm43xx-d80211-sta_up.sh without any parameters. See
59 + the help. Default parameters, which are used when called without parameters,
60 + are explained there.
61 +
62 +5) If you want to access the internet, make sure your default route
63 + is correctly set up with your gateway's IP:
64 + route add default gw 192.168.xxx.xxx
65 +
66 +6) Take another swallow from your bottle of beer and test if it works:
67 + ping www.kernel.org
68 +
69 +7) If it works, drink the rest of your beer. Otherwise read this HOWTO again,
70 + and again and again. Complain to bcm43xx-dev@lists.berlios.de, if it still
71 + does not work.
72 diff -Nur linux-2.6.16/Documentation/networking/bcm43xx-d80211.txt linux-2.6.16-bcm43xx/Documentation/networking/bcm43xx-d80211.txt
73 --- linux-2.6.16/Documentation/networking/bcm43xx-d80211.txt 1970-01-01 01:00:00.000000000 +0100
74 +++ linux-2.6.16-bcm43xx/Documentation/networking/bcm43xx-d80211.txt 2006-03-28 22:16:14.000000000 +0200
75 @@ -0,0 +1,31 @@
76 +
77 + BCM43xx Linux Driver Project
78 + ============================
79 +
80 +About this software
81 +-------------------
82 +
83 +The goal of this project is to develop a linux driver for Broadcom
84 +BCM43xx chips, based on the specification at
85 +http://bcm-specs.sipsolutions.net/
86 +
87 +The project page is http://bcm43xx.berlios.de/
88 +
89 +This is a port of the bcm43xx driver for the devicescape ieee802.11
90 +stack.
91 +
92 +Requirements
93 +------------
94 +
95 +1) Linux Kernel 2.6.16 or later
96 + http://www.kernel.org/
97 +
98 + See Documentation/networking/bcm43xx-d80211-HOWTO.txt for further
99 + instructions.
100 +
101 +2) Firmware Files
102 +
103 + Please try bcm43xx-fwcutter. It can extract the firmware from various
104 + binary driver files and supports driver files from Windows, MacOS and
105 + Linux. You can get bcm43xx-fwcutter from http://bcm43xx.berlios.de/.
106 + Also, bcm43xx-fwcutter comes with a README file for further instructions.
107 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
108 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.c 1970-01-01 01:00:00.000000000 +0100
109 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.c 2006-03-28 22:16:14.000000000 +0200
110 @@ -0,0 +1,499 @@
111 +/*
112 +
113 + Broadcom BCM43xx wireless driver
114 +
115 + debugfs driver debugging code
116 +
117 + Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
118 +
119 + This program is free software; you can redistribute it and/or modify
120 + it under the terms of the GNU General Public License as published by
121 + the Free Software Foundation; either version 2 of the License, or
122 + (at your option) any later version.
123 +
124 + This program is distributed in the hope that it will be useful,
125 + but WITHOUT ANY WARRANTY; without even the implied warranty of
126 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
127 + GNU General Public License for more details.
128 +
129 + You should have received a copy of the GNU General Public License
130 + along with this program; see the file COPYING. If not, write to
131 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
132 + Boston, MA 02110-1301, USA.
133 +
134 +*/
135 +
136 +
137 +
138 +#include <linux/fs.h>
139 +#include <linux/debugfs.h>
140 +#include <linux/slab.h>
141 +#include <linux/netdevice.h>
142 +#include <linux/pci.h>
143 +#include <asm/io.h>
144 +
145 +#include "bcm43xx.h"
146 +#include "bcm43xx_main.h"
147 +#include "bcm43xx_debugfs.h"
148 +#include "bcm43xx_dma.h"
149 +#include "bcm43xx_pio.h"
150 +#include "bcm43xx_xmit.h"
151 +
152 +#define REALLY_BIG_BUFFER_SIZE (1024*256)
153 +
154 +static struct bcm43xx_debugfs fs;
155 +static char really_big_buffer[REALLY_BIG_BUFFER_SIZE];
156 +static DECLARE_MUTEX(big_buffer_sem);
157 +
158 +
159 +static ssize_t write_file_dummy(struct file *file, const char __user *buf,
160 + size_t count, loff_t *ppos)
161 +{
162 + return count;
163 +}
164 +
165 +static int open_file_generic(struct inode *inode, struct file *file)
166 +{
167 + file->private_data = inode->u.generic_ip;
168 + return 0;
169 +}
170 +
171 +#define fappend(fmt, x...) pos += snprintf(buf + pos, len - pos, fmt , ##x)
172 +
173 +static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
174 + size_t count, loff_t *ppos)
175 +{
176 + const size_t len = REALLY_BIG_BUFFER_SIZE;
177 +
178 + struct bcm43xx_private *bcm = file->private_data;
179 + char *buf = really_big_buffer;
180 + size_t pos = 0;
181 + ssize_t res;
182 + struct net_device *net_dev;
183 + struct pci_dev *pci_dev;
184 + unsigned long flags;
185 + u16 tmp16;
186 + int i;
187 +
188 + down(&big_buffer_sem);
189 +
190 + bcm43xx_lock_mmio(bcm, flags);
191 + if (!bcm->initialized) {
192 + fappend("Board not initialized.\n");
193 + goto out;
194 + }
195 + net_dev = bcm->net_dev;
196 + pci_dev = bcm->pci_dev;
197 +
198 + /* This is where the information is written to the "devinfo" file */
199 + fappend("*** %s devinfo ***\n", net_dev->name);
200 + fappend("vendor: 0x%04x device: 0x%04x\n",
201 + pci_dev->vendor, pci_dev->device);
202 + fappend("subsystem_vendor: 0x%04x subsystem_device: 0x%04x\n",
203 + pci_dev->subsystem_vendor, pci_dev->subsystem_device);
204 + fappend("IRQ: %d\n", bcm->irq);
205 + fappend("mmio_addr: 0x%p mmio_len: %u\n", bcm->mmio_addr, bcm->mmio_len);
206 + fappend("chip_id: 0x%04x chip_rev: 0x%02x\n", bcm->chip_id, bcm->chip_rev);
207 + if ((bcm->core_80211[0].rev >= 3) && (bcm43xx_read32(bcm, 0x0158) & (1 << 16)))
208 + fappend("Radio disabled by hardware!\n");
209 + if ((bcm->core_80211[0].rev < 3) && !(bcm43xx_read16(bcm, 0x049A) & (1 << 4)))
210 + fappend("Radio disabled by hardware!\n");
211 + fappend("board_vendor: 0x%04x board_type: 0x%04x\n", bcm->board_vendor,
212 + bcm->board_type);
213 +
214 + fappend("\nCores:\n");
215 +#define fappend_core(name, info) fappend("core \"" name "\" %s, %s, id: 0x%04x, " \
216 + "rev: 0x%02x, index: 0x%02x\n", \
217 + (info).available \
218 + ? "available" : "nonavailable", \
219 + (info).enabled \
220 + ? "enabled" : "disabled", \
221 + (info).id, (info).rev, (info).index)
222 + fappend_core("CHIPCOMMON", bcm->core_chipcommon);
223 + fappend_core("PCI", bcm->core_pci);
224 + fappend_core("first 80211", bcm->core_80211[0]);
225 + fappend_core("second 80211", bcm->core_80211[1]);
226 +#undef fappend_core
227 + tmp16 = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
228 + fappend("LEDs: ");
229 + for (i = 0; i < BCM43xx_NR_LEDS; i++)
230 + fappend("%d ", !!(tmp16 & (1 << i)));
231 + fappend("\n");
232 +
233 +out:
234 + bcm43xx_unlock_mmio(bcm, flags);
235 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
236 + up(&big_buffer_sem);
237 + return res;
238 +}
239 +
240 +static ssize_t drvinfo_read_file(struct file *file, char __user *userbuf,
241 + size_t count, loff_t *ppos)
242 +{
243 + const size_t len = REALLY_BIG_BUFFER_SIZE;
244 +
245 + char *buf = really_big_buffer;
246 + size_t pos = 0;
247 + ssize_t res;
248 +
249 + down(&big_buffer_sem);
250 +
251 + /* This is where the information is written to the "driver" file */
252 + fappend(KBUILD_MODNAME " driver\n");
253 + fappend("Compiled at: %s %s\n", __DATE__, __TIME__);
254 +
255 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
256 + up(&big_buffer_sem);
257 + return res;
258 +}
259 +
260 +static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
261 + size_t count, loff_t *ppos)
262 +{
263 + const size_t len = REALLY_BIG_BUFFER_SIZE;
264 +
265 + struct bcm43xx_private *bcm = file->private_data;
266 + char *buf = really_big_buffer;
267 + size_t pos = 0;
268 + ssize_t res;
269 + unsigned long flags;
270 +
271 + down(&big_buffer_sem);
272 + bcm43xx_lock_mmio(bcm, flags);
273 + if (!bcm->initialized) {
274 + fappend("Board not initialized.\n");
275 + goto out;
276 + }
277 +
278 + /* This is where the information is written to the "sprom_dump" file */
279 + fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
280 +
281 +out:
282 + bcm43xx_unlock_mmio(bcm, flags);
283 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
284 + up(&big_buffer_sem);
285 + return res;
286 +}
287 +
288 +static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
289 + size_t count, loff_t *ppos)
290 +{
291 + const size_t len = REALLY_BIG_BUFFER_SIZE;
292 +
293 + struct bcm43xx_private *bcm = file->private_data;
294 + char *buf = really_big_buffer;
295 + size_t pos = 0;
296 + ssize_t res;
297 + unsigned long flags;
298 + u64 tsf;
299 +
300 + down(&big_buffer_sem);
301 + bcm43xx_lock_mmio(bcm, flags);
302 + if (!bcm->initialized) {
303 + fappend("Board not initialized.\n");
304 + goto out;
305 + }
306 + bcm43xx_tsf_read(bcm, &tsf);
307 + fappend("0x%08x%08x\n",
308 + (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
309 + (unsigned int)(tsf & 0xFFFFFFFFULL));
310 +
311 +out:
312 + bcm43xx_unlock_mmio(bcm, flags);
313 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
314 + up(&big_buffer_sem);
315 + return res;
316 +}
317 +
318 +static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
319 + size_t count, loff_t *ppos)
320 +{
321 + struct bcm43xx_private *bcm = file->private_data;
322 + char *buf = really_big_buffer;
323 + ssize_t buf_size;
324 + ssize_t res;
325 + unsigned long flags;
326 + u64 tsf;
327 +
328 + buf_size = min(count, sizeof (really_big_buffer) - 1);
329 + down(&big_buffer_sem);
330 + if (copy_from_user(buf, user_buf, buf_size)) {
331 + res = -EFAULT;
332 + goto out_up;
333 + }
334 + bcm43xx_lock_mmio(bcm, flags);
335 + if (!bcm->initialized) {
336 + printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
337 + res = -EFAULT;
338 + goto out_unlock;
339 + }
340 + if (sscanf(buf, "%lli", &tsf) != 1) {
341 + printk(KERN_INFO PFX "debugfs: invalid values for \"tsf\"\n");
342 + res = -EINVAL;
343 + goto out_unlock;
344 + }
345 + bcm43xx_tsf_write(bcm, tsf);
346 + res = buf_size;
347 +
348 +out_unlock:
349 + bcm43xx_unlock_mmio(bcm, flags);
350 +out_up:
351 + up(&big_buffer_sem);
352 + return res;
353 +}
354 +
355 +static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
356 + size_t count, loff_t *ppos)
357 +{
358 + const size_t len = REALLY_BIG_BUFFER_SIZE;
359 +
360 + struct bcm43xx_private *bcm = file->private_data;
361 + char *buf = really_big_buffer;
362 + size_t pos = 0;
363 + ssize_t res;
364 + unsigned long flags;
365 + struct bcm43xx_dfsentry *e;
366 + struct bcm43xx_xmitstatus *status;
367 + int i, cnt, j = 0;
368 +
369 + down(&big_buffer_sem);
370 + bcm43xx_lock(bcm, flags);
371 +
372 + fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
373 + BCM43xx_NR_LOGGED_XMITSTATUS);
374 + e = bcm->dfsentry;
375 + if (e->xmitstatus_printing == 0) {
376 + /* At the beginning, make a copy of all data to avoid
377 + * concurrency, as this function is called multiple
378 + * times for big logs. Without copying, the data might
379 + * change between reads. This would result in total trash.
380 + */
381 + e->xmitstatus_printing = 1;
382 + e->saved_xmitstatus_ptr = e->xmitstatus_ptr;
383 + e->saved_xmitstatus_cnt = e->xmitstatus_cnt;
384 + memcpy(e->xmitstatus_print_buffer, e->xmitstatus_buffer,
385 + BCM43xx_NR_LOGGED_XMITSTATUS * sizeof(*(e->xmitstatus_buffer)));
386 + }
387 + i = e->saved_xmitstatus_ptr - 1;
388 + if (i < 0)
389 + i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
390 + cnt = e->saved_xmitstatus_cnt;
391 + while (cnt) {
392 + status = e->xmitstatus_print_buffer + i;
393 + fappend("0x%02x: cookie: 0x%04x, flags: 0x%02x, "
394 + "cnt1: 0x%02x, cnt2: 0x%02x, seq: 0x%04x, "
395 + "unk: 0x%04x\n", j,
396 + status->cookie, status->flags,
397 + status->cnt1, status->cnt2, status->seq,
398 + status->unknown);
399 + j++;
400 + cnt--;
401 + i--;
402 + if (i < 0)
403 + i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
404 + }
405 +
406 + bcm43xx_unlock(bcm, flags);
407 + res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
408 + bcm43xx_lock(bcm, flags);
409 + if (*ppos == pos) {
410 + /* Done. Drop the copied data. */
411 + e->xmitstatus_printing = 0;
412 + }
413 + bcm43xx_unlock(bcm, flags);
414 + up(&big_buffer_sem);
415 + return res;
416 +}
417 +
418 +#undef fappend
419 +
420 +
421 +static struct file_operations devinfo_fops = {
422 + .read = devinfo_read_file,
423 + .write = write_file_dummy,
424 + .open = open_file_generic,
425 +};
426 +
427 +static struct file_operations spromdump_fops = {
428 + .read = spromdump_read_file,
429 + .write = write_file_dummy,
430 + .open = open_file_generic,
431 +};
432 +
433 +static struct file_operations drvinfo_fops = {
434 + .read = drvinfo_read_file,
435 + .write = write_file_dummy,
436 + .open = open_file_generic,
437 +};
438 +
439 +static struct file_operations tsf_fops = {
440 + .read = tsf_read_file,
441 + .write = tsf_write_file,
442 + .open = open_file_generic,
443 +};
444 +
445 +static struct file_operations txstat_fops = {
446 + .read = txstat_read_file,
447 + .write = write_file_dummy,
448 + .open = open_file_generic,
449 +};
450 +
451 +
452 +void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
453 +{
454 + struct bcm43xx_dfsentry *e;
455 + char devdir[IFNAMSIZ];
456 +
457 + assert(bcm);
458 + e = kzalloc(sizeof(*e), GFP_KERNEL);
459 + if (!e) {
460 + printk(KERN_ERR PFX "out of memory\n");
461 + return;
462 + }
463 + e->bcm = bcm;
464 + e->xmitstatus_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
465 + * sizeof(*(e->xmitstatus_buffer)),
466 + GFP_KERNEL);
467 + if (!e->xmitstatus_buffer) {
468 + printk(KERN_ERR PFX "out of memory\n");
469 + kfree(e);
470 + return;
471 + }
472 + e->xmitstatus_print_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
473 + * sizeof(*(e->xmitstatus_buffer)),
474 + GFP_KERNEL);
475 + if (!e->xmitstatus_print_buffer) {
476 + printk(KERN_ERR PFX "out of memory\n");
477 + kfree(e);
478 + return;
479 + }
480 +
481 +
482 + bcm->dfsentry = e;
483 +
484 + strncpy(devdir, bcm->net_dev->name, ARRAY_SIZE(devdir));
485 + e->subdir = debugfs_create_dir(devdir, fs.root);
486 + e->dentry_devinfo = debugfs_create_file("devinfo", 0444, e->subdir,
487 + bcm, &devinfo_fops);
488 + if (!e->dentry_devinfo)
489 + printk(KERN_ERR PFX "debugfs: creating \"devinfo\" for \"%s\" failed!\n", devdir);
490 + e->dentry_spromdump = debugfs_create_file("sprom_dump", 0444, e->subdir,
491 + bcm, &spromdump_fops);
492 + if (!e->dentry_spromdump)
493 + printk(KERN_ERR PFX "debugfs: creating \"sprom_dump\" for \"%s\" failed!\n", devdir);
494 + e->dentry_tsf = debugfs_create_file("tsf", 0666, e->subdir,
495 + bcm, &tsf_fops);
496 + if (!e->dentry_tsf)
497 + printk(KERN_ERR PFX "debugfs: creating \"tsf\" for \"%s\" failed!\n", devdir);
498 + e->dentry_txstat = debugfs_create_file("tx_status", 0444, e->subdir,
499 + bcm, &txstat_fops);
500 + if (!e->dentry_txstat)
501 + printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir);
502 +}
503 +
504 +void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
505 +{
506 + struct bcm43xx_dfsentry *e;
507 +
508 + if (!bcm)
509 + return;
510 +
511 + e = bcm->dfsentry;
512 + assert(e);
513 + debugfs_remove(e->dentry_spromdump);
514 + debugfs_remove(e->dentry_devinfo);
515 + debugfs_remove(e->dentry_tsf);
516 + debugfs_remove(e->dentry_txstat);
517 + debugfs_remove(e->subdir);
518 + kfree(e->xmitstatus_buffer);
519 + kfree(e->xmitstatus_print_buffer);
520 + kfree(e);
521 +}
522 +
523 +void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
524 + struct bcm43xx_xmitstatus *status)
525 +{
526 + struct bcm43xx_dfsentry *e;
527 + struct bcm43xx_xmitstatus *savedstatus;
528 +
529 + /* This is protected by bcm->_lock */
530 + e = bcm->dfsentry;
531 + assert(e);
532 + savedstatus = e->xmitstatus_buffer + e->xmitstatus_ptr;
533 + memcpy(savedstatus, status, sizeof(*status));
534 + e->xmitstatus_ptr++;
535 + if (e->xmitstatus_ptr >= BCM43xx_NR_LOGGED_XMITSTATUS)
536 + e->xmitstatus_ptr = 0;
537 + if (e->xmitstatus_cnt < BCM43xx_NR_LOGGED_XMITSTATUS)
538 + e->xmitstatus_cnt++;
539 +}
540 +
541 +void bcm43xx_debugfs_init(void)
542 +{
543 + memset(&fs, 0, sizeof(fs));
544 + fs.root = debugfs_create_dir(KBUILD_MODNAME, NULL);
545 + if (!fs.root)
546 + printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "\" subdir failed!\n");
547 + fs.dentry_driverinfo = debugfs_create_file("driver", 0444, fs.root, NULL, &drvinfo_fops);
548 + if (!fs.dentry_driverinfo)
549 + printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "/driver\" failed!\n");
550 +}
551 +
552 +void bcm43xx_debugfs_exit(void)
553 +{
554 + debugfs_remove(fs.dentry_driverinfo);
555 + debugfs_remove(fs.root);
556 +}
557 +
558 +void bcm43xx_printk_dump(const char *data,
559 + size_t size,
560 + const char *description)
561 +{
562 + size_t i;
563 + char c;
564 +
565 + printk(KERN_INFO PFX "Data dump (%s, %u bytes):",
566 + description, size);
567 + for (i = 0; i < size; i++) {
568 + c = data[i];
569 + if (i % 8 == 0)
570 + printk("\n" KERN_INFO PFX "0x%08x: 0x%02x, ", i, c & 0xff);
571 + else
572 + printk("0x%02x, ", c & 0xff);
573 + }
574 + printk("\n");
575 +}
576 +
577 +void bcm43xx_printk_bitdump(const unsigned char *data,
578 + size_t bytes, int msb_to_lsb,
579 + const char *description)
580 +{
581 + size_t i;
582 + int j;
583 + const unsigned char *d;
584 +
585 + printk(KERN_INFO PFX "*** Bitdump (%s, %u bytes, %s) ***",
586 + description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB");
587 + for (i = 0; i < bytes; i++) {
588 + d = data + i;
589 + if (i % 8 == 0)
590 + printk("\n" KERN_INFO PFX "0x%08x: ", i);
591 + if (msb_to_lsb) {
592 + for (j = 7; j >= 0; j--) {
593 + if (*d & (1 << j))
594 + printk("1");
595 + else
596 + printk("0");
597 + }
598 + } else {
599 + for (j = 0; j < 8; j++) {
600 + if (*d & (1 << j))
601 + printk("1");
602 + else
603 + printk("0");
604 + }
605 + }
606 + printk(" ");
607 + }
608 + printk("\n");
609 +}
610 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
611 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.h 1970-01-01 01:00:00.000000000 +0100
612 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.h 2006-03-28 22:16:14.000000000 +0200
613 @@ -0,0 +1,117 @@
614 +#ifndef BCM43xx_DEBUGFS_H_
615 +#define BCM43xx_DEBUGFS_H_
616 +
617 +struct bcm43xx_private;
618 +struct bcm43xx_xmitstatus;
619 +
620 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
621 +
622 +#include <linux/list.h>
623 +#include <asm/semaphore.h>
624 +
625 +struct dentry;
626 +
627 +/* limited by the size of the "really_big_buffer" */
628 +#define BCM43xx_NR_LOGGED_XMITSTATUS 100
629 +
630 +struct bcm43xx_dfsentry {
631 + struct dentry *subdir;
632 + struct dentry *dentry_devinfo;
633 + struct dentry *dentry_spromdump;
634 + struct dentry *dentry_tsf;
635 + struct dentry *dentry_txstat;
636 +
637 + struct bcm43xx_private *bcm;
638 +
639 + /* saved xmitstatus. */
640 + struct bcm43xx_xmitstatus *xmitstatus_buffer;
641 + int xmitstatus_ptr;
642 + int xmitstatus_cnt;
643 + /* We need a seperate buffer while printing to avoid
644 + * concurrency issues. (New xmitstatus can arrive
645 + * while we are printing).
646 + */
647 + struct bcm43xx_xmitstatus *xmitstatus_print_buffer;
648 + int saved_xmitstatus_ptr;
649 + int saved_xmitstatus_cnt;
650 + int xmitstatus_printing;
651 +};
652 +
653 +struct bcm43xx_debugfs {
654 + struct dentry *root;
655 + struct dentry *dentry_driverinfo;
656 +};
657 +
658 +void bcm43xx_debugfs_init(void);
659 +void bcm43xx_debugfs_exit(void);
660 +void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm);
661 +void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm);
662 +void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
663 + struct bcm43xx_xmitstatus *status);
664 +
665 +/* Debug helper: Dump binary data through printk. */
666 +void bcm43xx_printk_dump(const char *data,
667 + size_t size,
668 + const char *description);
669 +/* Debug helper: Dump bitwise binary data through printk. */
670 +void bcm43xx_printk_bitdump(const unsigned char *data,
671 + size_t bytes, int msb_to_lsb,
672 + const char *description);
673 +#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) \
674 + do { \
675 + bcm43xx_printk_bitdump((const unsigned char *)(pointer), \
676 + sizeof(*(pointer)), \
677 + (msb_to_lsb), \
678 + (description)); \
679 + } while (0)
680 +
681 +#else /* CONFIG_BCM43XX_D80211_DEBUG*/
682 +
683 +static inline
684 +void bcm43xx_debugfs_init(void) { }
685 +static inline
686 +void bcm43xx_debugfs_exit(void) { }
687 +static inline
688 +void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) { }
689 +static inline
690 +void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) { }
691 +static inline
692 +void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
693 + struct bcm43xx_xmitstatus *status) { }
694 +
695 +static inline
696 +void bcm43xx_printk_dump(const char *data,
697 + size_t size,
698 + const char *description)
699 +{
700 +}
701 +static inline
702 +void bcm43xx_printk_bitdump(const unsigned char *data,
703 + size_t bytes, int msb_to_lsb,
704 + const char *description)
705 +{
706 +}
707 +#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) do { /* nothing */ } while (0)
708 +
709 +#endif /* CONFIG_BCM43XX_D80211_DEBUG*/
710 +
711 +/* Ugly helper macros to make incomplete code more verbose on runtime */
712 +#ifdef TODO
713 +# undef TODO
714 +#endif
715 +#define TODO() \
716 + do { \
717 + printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n", \
718 + __FUNCTION__, __FILE__, __LINE__); \
719 + } while (0)
720 +
721 +#ifdef FIXME
722 +# undef FIXME
723 +#endif
724 +#define FIXME() \
725 + do { \
726 + printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n", \
727 + __FUNCTION__, __FILE__, __LINE__); \
728 + } while (0)
729 +
730 +#endif /* BCM43xx_DEBUGFS_H_ */
731 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
732 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.c 1970-01-01 01:00:00.000000000 +0100
733 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.c 2006-03-28 22:16:14.000000000 +0200
734 @@ -0,0 +1,991 @@
735 +/*
736 +
737 + Broadcom BCM43xx wireless driver
738 +
739 + DMA ringbuffer and descriptor allocation/management
740 +
741 + Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
742 +
743 + Some code in this file is derived from the b44.c driver
744 + Copyright (C) 2002 David S. Miller
745 + Copyright (C) Pekka Pietikainen
746 +
747 + This program is free software; you can redistribute it and/or modify
748 + it under the terms of the GNU General Public License as published by
749 + the Free Software Foundation; either version 2 of the License, or
750 + (at your option) any later version.
751 +
752 + This program is distributed in the hope that it will be useful,
753 + but WITHOUT ANY WARRANTY; without even the implied warranty of
754 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
755 + GNU General Public License for more details.
756 +
757 + You should have received a copy of the GNU General Public License
758 + along with this program; see the file COPYING. If not, write to
759 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
760 + Boston, MA 02110-1301, USA.
761 +
762 +*/
763 +
764 +#include "bcm43xx.h"
765 +#include "bcm43xx_dma.h"
766 +#include "bcm43xx_main.h"
767 +#include "bcm43xx_debugfs.h"
768 +#include "bcm43xx_power.h"
769 +#include "bcm43xx_xmit.h"
770 +
771 +#include <linux/dma-mapping.h>
772 +#include <linux/pci.h>
773 +#include <linux/delay.h>
774 +#include <linux/skbuff.h>
775 +
776 +
777 +static inline int free_slots(struct bcm43xx_dmaring *ring)
778 +{
779 + return (ring->nr_slots - ring->used_slots);
780 +}
781 +
782 +static inline int next_slot(struct bcm43xx_dmaring *ring, int slot)
783 +{
784 + assert(slot >= -1 && slot <= ring->nr_slots - 1);
785 + if (slot == ring->nr_slots - 1)
786 + return 0;
787 + return slot + 1;
788 +}
789 +
790 +static inline int prev_slot(struct bcm43xx_dmaring *ring, int slot)
791 +{
792 + assert(slot >= 0 && slot <= ring->nr_slots - 1);
793 + if (slot == 0)
794 + return ring->nr_slots - 1;
795 + return slot - 1;
796 +}
797 +
798 +/* Request a slot for usage. */
799 +static inline
800 +int request_slot(struct bcm43xx_dmaring *ring)
801 +{
802 + int slot;
803 +
804 + assert(ring->tx);
805 + assert(!ring->suspended);
806 + assert(free_slots(ring) != 0);
807 +
808 + slot = next_slot(ring, ring->current_slot);
809 + ring->current_slot = slot;
810 + ring->used_slots++;
811 +
812 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
813 + if (ring->used_slots > ring->max_used_slots)
814 + ring->max_used_slots = ring->used_slots;
815 +#endif /* CONFIG_BCM43XX_D80211_DEBUG*/
816 +
817 + return slot;
818 +}
819 +
820 +/* Return a slot to the free slots. */
821 +static inline
822 +void return_slot(struct bcm43xx_dmaring *ring, int slot)
823 +{
824 + assert(ring->tx);
825 +
826 + ring->used_slots--;
827 +}
828 +
829 +static inline
830 +dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
831 + unsigned char *buf,
832 + size_t len,
833 + int tx)
834 +{
835 + dma_addr_t dmaaddr;
836 +
837 + if (tx) {
838 + dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
839 + buf, len,
840 + DMA_TO_DEVICE);
841 + } else {
842 + dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
843 + buf, len,
844 + DMA_FROM_DEVICE);
845 + }
846 +
847 + return dmaaddr;
848 +}
849 +
850 +static inline
851 +void unmap_descbuffer(struct bcm43xx_dmaring *ring,
852 + dma_addr_t addr,
853 + size_t len,
854 + int tx)
855 +{
856 + if (tx) {
857 + dma_unmap_single(&ring->bcm->pci_dev->dev,
858 + addr, len,
859 + DMA_TO_DEVICE);
860 + } else {
861 + dma_unmap_single(&ring->bcm->pci_dev->dev,
862 + addr, len,
863 + DMA_FROM_DEVICE);
864 + }
865 +}
866 +
867 +static inline
868 +void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,
869 + dma_addr_t addr,
870 + size_t len)
871 +{
872 + assert(!ring->tx);
873 +
874 + dma_sync_single_for_cpu(&ring->bcm->pci_dev->dev,
875 + addr, len, DMA_FROM_DEVICE);
876 +}
877 +
878 +static inline
879 +void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,
880 + dma_addr_t addr,
881 + size_t len)
882 +{
883 + assert(!ring->tx);
884 +
885 + dma_sync_single_for_device(&ring->bcm->pci_dev->dev,
886 + addr, len, DMA_FROM_DEVICE);
887 +}
888 +
889 +/* Unmap and free a descriptor buffer. */
890 +static inline
891 +void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
892 + struct bcm43xx_dmadesc *desc,
893 + struct bcm43xx_dmadesc_meta *meta,
894 + int irq_context)
895 +{
896 + assert(meta->skb);
897 + if (irq_context)
898 + dev_kfree_skb_irq(meta->skb);
899 + else
900 + dev_kfree_skb(meta->skb);
901 + meta->skb = NULL;
902 +}
903 +
904 +static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
905 +{
906 + struct device *dev = &(ring->bcm->pci_dev->dev);
907 +
908 + ring->vbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
909 + &(ring->dmabase), GFP_KERNEL);
910 + if (!ring->vbase) {
911 + printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
912 + return -ENOMEM;
913 + }
914 + if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) {
915 + printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G "
916 + "(0x%08x, len: %lu)\n",
917 + ring->dmabase, BCM43xx_DMA_RINGMEMSIZE);
918 + dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
919 + ring->vbase, ring->dmabase);
920 + return -ENOMEM;
921 + }
922 + assert(!(ring->dmabase & 0x000003FF));
923 + memset(ring->vbase, 0, BCM43xx_DMA_RINGMEMSIZE);
924 +
925 + return 0;
926 +}
927 +
928 +static void free_ringmemory(struct bcm43xx_dmaring *ring)
929 +{
930 + struct device *dev = &(ring->bcm->pci_dev->dev);
931 +
932 + dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
933 + ring->vbase, ring->dmabase);
934 +}
935 +
936 +/* Reset the RX DMA channel */
937 +int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
938 + u16 mmio_base)
939 +{
940 + int i;
941 + u32 value;
942 +
943 + bcm43xx_write32(bcm,
944 + mmio_base + BCM43xx_DMA_RX_CONTROL,
945 + 0x00000000);
946 + for (i = 0; i < 1000; i++) {
947 + value = bcm43xx_read32(bcm,
948 + mmio_base + BCM43xx_DMA_RX_STATUS);
949 + value &= BCM43xx_DMA_RXSTAT_STAT_MASK;
950 + if (value == BCM43xx_DMA_RXSTAT_STAT_DISABLED) {
951 + i = -1;
952 + break;
953 + }
954 + udelay(10);
955 + }
956 + if (i != -1) {
957 + printk(KERN_ERR PFX "Error: Wait on DMA RX status timed out.\n");
958 + return -ENODEV;
959 + }
960 +
961 + return 0;
962 +}
963 +
964 +/* Reset the RX DMA channel */
965 +int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
966 + u16 mmio_base)
967 +{
968 + int i;
969 + u32 value;
970 +
971 + for (i = 0; i < 1000; i++) {
972 + value = bcm43xx_read32(bcm,
973 + mmio_base + BCM43xx_DMA_TX_STATUS);
974 + value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
975 + if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED ||
976 + value == BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT ||
977 + value == BCM43xx_DMA_TXSTAT_STAT_STOPPED)
978 + break;
979 + udelay(10);
980 + }
981 + bcm43xx_write32(bcm,
982 + mmio_base + BCM43xx_DMA_TX_CONTROL,
983 + 0x00000000);
984 + for (i = 0; i < 1000; i++) {
985 + value = bcm43xx_read32(bcm,
986 + mmio_base + BCM43xx_DMA_TX_STATUS);
987 + value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
988 + if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED) {
989 + i = -1;
990 + break;
991 + }
992 + udelay(10);
993 + }
994 + if (i != -1) {
995 + printk(KERN_ERR PFX "Error: Wait on DMA TX status timed out.\n");
996 + return -ENODEV;
997 + }
998 + /* ensure the reset is completed. */
999 + udelay(300);
1000 +
1001 + return 0;
1002 +}
1003 +
1004 +static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
1005 + struct bcm43xx_dmadesc *desc,
1006 + struct bcm43xx_dmadesc_meta *meta,
1007 + gfp_t gfp_flags)
1008 +{
1009 + struct bcm43xx_rxhdr *rxhdr;
1010 + dma_addr_t dmaaddr;
1011 + u32 desc_addr;
1012 + u32 desc_ctl;
1013 + const int slot = (int)(desc - ring->vbase);
1014 + struct sk_buff *skb;
1015 +
1016 + assert(slot >= 0 && slot < ring->nr_slots);
1017 + assert(!ring->tx);
1018 +
1019 + skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
1020 + if (unlikely(!skb))
1021 + return -ENOMEM;
1022 + dmaaddr = map_descbuffer(ring, skb->data,
1023 + ring->rx_buffersize, 0);
1024 + if (unlikely(dmaaddr + ring->rx_buffersize > BCM43xx_DMA_BUSADDRMAX)) {
1025 + unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
1026 + dev_kfree_skb_any(skb);
1027 + printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G "
1028 + "(0x%08x, len: %u)\n",
1029 + dmaaddr, ring->rx_buffersize);
1030 + return -ENOMEM;
1031 + }
1032 + meta->skb = skb;
1033 + meta->dmaaddr = dmaaddr;
1034 + skb->dev = ring->bcm->net_dev;
1035 + desc_addr = (u32)(dmaaddr + ring->memoffset);
1036 + desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK &
1037 + (u32)(ring->rx_buffersize - ring->frameoffset));
1038 + if (slot == ring->nr_slots - 1)
1039 + desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
1040 + set_desc_addr(desc, desc_addr);
1041 + set_desc_ctl(desc, desc_ctl);
1042 +
1043 + rxhdr = (struct bcm43xx_rxhdr *)(skb->data);
1044 + rxhdr->frame_length = 0;
1045 + rxhdr->flags1 = 0;
1046 +
1047 + return 0;
1048 +}
1049 +
1050 +/* Allocate the initial descbuffers.
1051 + * This is used for an RX ring only.
1052 + */
1053 +static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring)
1054 +{
1055 + int i, err = -ENOMEM;
1056 + struct bcm43xx_dmadesc *desc;
1057 + struct bcm43xx_dmadesc_meta *meta;
1058 +
1059 + for (i = 0; i < ring->nr_slots; i++) {
1060 + desc = ring->vbase + i;
1061 + meta = ring->meta + i;
1062 +
1063 + err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
1064 + if (err)
1065 + goto err_unwind;
1066 + }
1067 + ring->used_slots = ring->nr_slots;
1068 + err = 0;
1069 +out:
1070 + return err;
1071 +
1072 +err_unwind:
1073 + for (i--; i >= 0; i--) {
1074 + desc = ring->vbase + i;
1075 + meta = ring->meta + i;
1076 +
1077 + unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
1078 + dev_kfree_skb(meta->skb);
1079 + }
1080 + goto out;
1081 +}
1082 +
1083 +/* Do initial setup of the DMA controller.
1084 + * Reset the controller, write the ring busaddress
1085 + * and switch the "enable" bit on.
1086 + */
1087 +static int dmacontroller_setup(struct bcm43xx_dmaring *ring)
1088 +{
1089 + int err = 0;
1090 + u32 value;
1091 +
1092 + if (ring->tx) {
1093 + /* Set Transmit Control register to "transmit enable" */
1094 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
1095 + BCM43xx_DMA_TXCTRL_ENABLE);
1096 + /* Set Transmit Descriptor ring address. */
1097 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING,
1098 + ring->dmabase + ring->memoffset);
1099 + } else {
1100 + err = alloc_initial_descbuffers(ring);
1101 + if (err)
1102 + goto out;
1103 + /* Set Receive Control "receive enable" and frame offset */
1104 + value = (ring->frameoffset << BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT);
1105 + value |= BCM43xx_DMA_RXCTRL_ENABLE;
1106 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_CONTROL, value);
1107 + /* Set Receive Descriptor ring address. */
1108 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING,
1109 + ring->dmabase + ring->memoffset);
1110 + /* Init the descriptor pointer. */
1111 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, 200);
1112 + }
1113 +
1114 +out:
1115 + return err;
1116 +}
1117 +
1118 +/* Shutdown the DMA controller. */
1119 +static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring)
1120 +{
1121 + if (ring->tx) {
1122 + bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base);
1123 + /* Zero out Transmit Descriptor ring address. */
1124 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, 0);
1125 + } else {
1126 + bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base);
1127 + /* Zero out Receive Descriptor ring address. */
1128 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, 0);
1129 + }
1130 +}
1131 +
1132 +static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
1133 +{
1134 + struct bcm43xx_dmadesc *desc;
1135 + struct bcm43xx_dmadesc_meta *meta;
1136 + int i;
1137 +
1138 + if (!ring->used_slots)
1139 + return;
1140 + for (i = 0; i < ring->nr_slots; i++) {
1141 + desc = ring->vbase + i;
1142 + meta = ring->meta + i;
1143 +
1144 + if (!meta->skb) {
1145 + assert(ring->tx);
1146 + continue;
1147 + }
1148 + if (ring->tx) {
1149 + unmap_descbuffer(ring, meta->dmaaddr,
1150 + meta->skb->len, 1);
1151 + } else {
1152 + unmap_descbuffer(ring, meta->dmaaddr,
1153 + ring->rx_buffersize, 0);
1154 + }
1155 + free_descriptor_buffer(ring, desc, meta, 0);
1156 + }
1157 +}
1158 +
1159 +/* Main initialization function. */
1160 +static
1161 +struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
1162 + u16 dma_controller_base,
1163 + int nr_descriptor_slots,
1164 + int tx)
1165 +{
1166 + struct bcm43xx_dmaring *ring;
1167 + int err;
1168 +
1169 + ring = kzalloc(sizeof(*ring), GFP_KERNEL);
1170 + if (!ring)
1171 + goto out;
1172 +
1173 + ring->meta = kzalloc(sizeof(*ring->meta) * nr_descriptor_slots,
1174 + GFP_KERNEL);
1175 + if (!ring->meta)
1176 + goto err_kfree_ring;
1177 +
1178 + ring->memoffset = BCM43xx_DMA_DMABUSADDROFFSET;
1179 +#ifdef CONFIG_BCM947XX
1180 + if (bcm->pci_dev->bus->number == 0)
1181 + ring->memoffset = 0;
1182 +#endif
1183 +
1184 + ring->bcm = bcm;
1185 + ring->nr_slots = nr_descriptor_slots;
1186 + ring->mmio_base = dma_controller_base;
1187 + if (tx) {
1188 + ring->tx = 1;
1189 + ring->current_slot = -1;
1190 + } else {
1191 + switch (dma_controller_base) {
1192 + case BCM43xx_MMIO_DMA1_BASE:
1193 + ring->rx_buffersize = BCM43xx_DMA1_RXBUFFERSIZE;
1194 + ring->frameoffset = BCM43xx_DMA1_RX_FRAMEOFFSET;
1195 + break;
1196 + case BCM43xx_MMIO_DMA4_BASE:
1197 + ring->rx_buffersize = BCM43xx_DMA4_RXBUFFERSIZE;
1198 + ring->frameoffset = BCM43xx_DMA4_RX_FRAMEOFFSET;
1199 + break;
1200 + default:
1201 + assert(0);
1202 + }
1203 + }
1204 +
1205 + err = alloc_ringmemory(ring);
1206 + if (err)
1207 + goto err_kfree_meta;
1208 + err = dmacontroller_setup(ring);
1209 + if (err)
1210 + goto err_free_ringmemory;
1211 +
1212 +out:
1213 + return ring;
1214 +
1215 +err_free_ringmemory:
1216 + free_ringmemory(ring);
1217 +err_kfree_meta:
1218 + kfree(ring->meta);
1219 +err_kfree_ring:
1220 + kfree(ring);
1221 + ring = NULL;
1222 + goto out;
1223 +}
1224 +
1225 +/* Main cleanup function. */
1226 +static void bcm43xx_destroy_dmaring(struct bcm43xx_dmaring *ring)
1227 +{
1228 + if (!ring)
1229 + return;
1230 +
1231 + dprintk(KERN_INFO PFX "DMA 0x%04x (%s) max used slots: %d/%d\n",
1232 + ring->mmio_base,
1233 + (ring->tx) ? "TX" : "RX",
1234 + ring->max_used_slots, ring->nr_slots);
1235 + /* Device IRQs are disabled prior entering this function,
1236 + * so no need to take care of concurrency with rx handler stuff.
1237 + */
1238 + dmacontroller_cleanup(ring);
1239 + free_all_descbuffers(ring);
1240 + free_ringmemory(ring);
1241 +
1242 + kfree(ring->meta);
1243 + kfree(ring);
1244 +}
1245 +
1246 +void bcm43xx_dma_free(struct bcm43xx_private *bcm)
1247 +{
1248 + struct bcm43xx_dma *dma;
1249 +
1250 + if (bcm43xx_using_pio(bcm))
1251 + return;
1252 + dma = bcm43xx_current_dma(bcm);
1253 +
1254 + bcm43xx_destroy_dmaring(dma->rx_ring1);
1255 + dma->rx_ring1 = NULL;
1256 + bcm43xx_destroy_dmaring(dma->rx_ring0);
1257 + dma->rx_ring0 = NULL;
1258 + bcm43xx_destroy_dmaring(dma->tx_ring3);
1259 + dma->tx_ring3 = NULL;
1260 + bcm43xx_destroy_dmaring(dma->tx_ring2);
1261 + dma->tx_ring2 = NULL;
1262 + bcm43xx_destroy_dmaring(dma->tx_ring1);
1263 + dma->tx_ring1 = NULL;
1264 + bcm43xx_destroy_dmaring(dma->tx_ring0);
1265 + dma->tx_ring0 = NULL;
1266 +}
1267 +
1268 +int bcm43xx_dma_init(struct bcm43xx_private *bcm)
1269 +{
1270 + struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
1271 + struct bcm43xx_dmaring *ring;
1272 + int err = -ENOMEM;
1273 +
1274 + /* setup TX DMA channels. */
1275 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
1276 + BCM43xx_TXRING_SLOTS, 1);
1277 + if (!ring)
1278 + goto out;
1279 + dma->tx_ring0 = ring;
1280 +
1281 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA2_BASE,
1282 + BCM43xx_TXRING_SLOTS, 1);
1283 + if (!ring)
1284 + goto err_destroy_tx0;
1285 + dma->tx_ring1 = ring;
1286 +
1287 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA3_BASE,
1288 + BCM43xx_TXRING_SLOTS, 1);
1289 + if (!ring)
1290 + goto err_destroy_tx1;
1291 + dma->tx_ring2 = ring;
1292 +
1293 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
1294 + BCM43xx_TXRING_SLOTS, 1);
1295 + if (!ring)
1296 + goto err_destroy_tx2;
1297 + dma->tx_ring3 = ring;
1298 +
1299 + /* setup RX DMA channels. */
1300 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
1301 + BCM43xx_RXRING_SLOTS, 0);
1302 + if (!ring)
1303 + goto err_destroy_tx3;
1304 + dma->rx_ring0 = ring;
1305 +
1306 + if (bcm->current_core->rev < 5) {
1307 + ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
1308 + BCM43xx_RXRING_SLOTS, 0);
1309 + if (!ring)
1310 + goto err_destroy_rx0;
1311 + dma->rx_ring1 = ring;
1312 + }
1313 +
1314 + dprintk(KERN_INFO PFX "DMA initialized\n");
1315 + err = 0;
1316 +out:
1317 + return err;
1318 +
1319 +err_destroy_rx0:
1320 + bcm43xx_destroy_dmaring(dma->rx_ring0);
1321 + dma->rx_ring0 = NULL;
1322 +err_destroy_tx3:
1323 + bcm43xx_destroy_dmaring(dma->tx_ring3);
1324 + dma->tx_ring3 = NULL;
1325 +err_destroy_tx2:
1326 + bcm43xx_destroy_dmaring(dma->tx_ring2);
1327 + dma->tx_ring2 = NULL;
1328 +err_destroy_tx1:
1329 + bcm43xx_destroy_dmaring(dma->tx_ring1);
1330 + dma->tx_ring1 = NULL;
1331 +err_destroy_tx0:
1332 + bcm43xx_destroy_dmaring(dma->tx_ring0);
1333 + dma->tx_ring0 = NULL;
1334 + goto out;
1335 +}
1336 +
1337 +/* Generate a cookie for the TX header. */
1338 +static u16 generate_cookie(struct bcm43xx_dmaring *ring,
1339 + int slot)
1340 +{
1341 + u16 cookie = 0x0000;
1342 +
1343 + /* Use the upper 4 bits of the cookie as
1344 + * DMA controller ID and store the slot number
1345 + * in the lower 12 bits
1346 + */
1347 + switch (ring->mmio_base) {
1348 + default:
1349 + assert(0);
1350 + case BCM43xx_MMIO_DMA1_BASE:
1351 + break;
1352 + case BCM43xx_MMIO_DMA2_BASE:
1353 + cookie = 0x1000;
1354 + break;
1355 + case BCM43xx_MMIO_DMA3_BASE:
1356 + cookie = 0x2000;
1357 + break;
1358 + case BCM43xx_MMIO_DMA4_BASE:
1359 + cookie = 0x3000;
1360 + break;
1361 + }
1362 + assert(((u16)slot & 0xF000) == 0x0000);
1363 + cookie |= (u16)slot;
1364 +
1365 + return cookie;
1366 +}
1367 +
1368 +/* Inspect a cookie and find out to which controller/slot it belongs. */
1369 +static
1370 +struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm,
1371 + u16 cookie, int *slot)
1372 +{
1373 + struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
1374 + struct bcm43xx_dmaring *ring = NULL;
1375 +
1376 + switch (cookie & 0xF000) {
1377 + case 0x0000:
1378 + ring = dma->tx_ring0;
1379 + break;
1380 + case 0x1000:
1381 + ring = dma->tx_ring1;
1382 + break;
1383 + case 0x2000:
1384 + ring = dma->tx_ring2;
1385 + break;
1386 + case 0x3000:
1387 + ring = dma->tx_ring3;
1388 + break;
1389 + default:
1390 + assert(0);
1391 + }
1392 + *slot = (cookie & 0x0FFF);
1393 + assert(*slot >= 0 && *slot < ring->nr_slots);
1394 +
1395 + return ring;
1396 +}
1397 +
1398 +static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
1399 + int slot)
1400 +{
1401 + /* Everything is ready to start. Buffers are DMA mapped and
1402 + * associated with slots.
1403 + * "slot" is the last slot of the new frame we want to transmit.
1404 + * Close your seat belts now, please.
1405 + */
1406 + wmb();
1407 + slot = next_slot(ring, slot);
1408 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_INDEX,
1409 + (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
1410 +}
1411 +
1412 +static int dma_tx_fragment(struct bcm43xx_dmaring *ring,
1413 + struct sk_buff *skb,
1414 + struct ieee80211_tx_control *ctl)
1415 +{
1416 + struct sk_buff *hdr_skb;
1417 + int slot;
1418 + struct bcm43xx_dmadesc *desc;
1419 + struct bcm43xx_dmadesc_meta *meta;
1420 + u32 desc_ctl;
1421 + u32 desc_addr;
1422 +
1423 + assert(skb_shinfo(skb)->nr_frags == 0);
1424 +
1425 + hdr_skb = dev_alloc_skb(sizeof(struct bcm43xx_txhdr));
1426 + if (unlikely(!hdr_skb))
1427 + return -ENOMEM;
1428 + skb_put(hdr_skb, sizeof(struct bcm43xx_txhdr));
1429 +
1430 + slot = request_slot(ring);
1431 + desc = ring->vbase + slot;
1432 + meta = ring->meta + slot;
1433 +
1434 + bcm43xx_generate_txhdr(ring->bcm,
1435 + (struct bcm43xx_txhdr *)hdr_skb->data,
1436 + skb->data, skb->len,
1437 + 1,//FIXME
1438 + generate_cookie(ring, slot),
1439 + ctl);
1440 +
1441 + meta->skb = hdr_skb;
1442 + meta->dmaaddr = map_descbuffer(ring, hdr_skb->data, hdr_skb->len, 1);
1443 + if (unlikely(meta->dmaaddr + hdr_skb->len > BCM43xx_DMA_BUSADDRMAX)) {
1444 + return_slot(ring, slot);
1445 + dev_kfree_skb_irq(hdr_skb);
1446 + printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G "
1447 + "(0x%08x, len: %u)\n",
1448 + meta->dmaaddr, hdr_skb->len);
1449 + return -ENOMEM;
1450 + }
1451 +
1452 + desc_addr = (u32)(meta->dmaaddr + ring->memoffset);
1453 + desc_ctl = BCM43xx_DMADTOR_FRAMESTART |
1454 + (BCM43xx_DMADTOR_BYTECNT_MASK & (u32)(hdr_skb->len));
1455 + if (slot == ring->nr_slots - 1)
1456 + desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
1457 + set_desc_ctl(desc, desc_ctl);
1458 + set_desc_addr(desc, desc_addr);
1459 +
1460 + slot = request_slot(ring);
1461 + desc = ring->vbase + slot;
1462 + meta = ring->meta + slot;
1463 +
1464 + /* We inspect the txstatus on the FRAMESTART descriptor later
1465 + * on xmit-status IRQ.
1466 + */
1467 + meta->must_xmit_txstat = 1;
1468 + memset(&meta->txstat, 0, sizeof(meta->txstat));
1469 + memcpy(&meta->txstat.control, ctl, sizeof(*ctl));
1470 +
1471 + meta->skb = skb;
1472 + meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
1473 + if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) {
1474 + return_slot(ring, prev_slot(ring, slot));
1475 + return_slot(ring, slot);
1476 + dev_kfree_skb_irq(hdr_skb);
1477 + printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G "
1478 + "(0x%08x, len: %u)\n",
1479 + meta->dmaaddr, skb->len);
1480 + return -ENOMEM;
1481 + }
1482 +
1483 + desc_addr = (u32)(meta->dmaaddr + ring->memoffset);
1484 + desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK & (u32)(skb->len));
1485 + if (slot == ring->nr_slots - 1)
1486 + desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
1487 +
1488 + desc_ctl |= BCM43xx_DMADTOR_FRAMEEND | BCM43xx_DMADTOR_COMPIRQ;
1489 + set_desc_ctl(desc, desc_ctl);
1490 + set_desc_addr(desc, desc_addr);
1491 + /* Now transfer the whole frame. */
1492 + dmacontroller_poke_tx(ring, slot);
1493 +
1494 + return 0;
1495 +}
1496 +
1497 +int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
1498 + struct sk_buff *skb,
1499 + struct ieee80211_tx_control *ctl)
1500 +{
1501 + struct bcm43xx_dmaring *ring = bcm43xx_current_dma(bcm)->tx_ring1;
1502 + int err;
1503 +
1504 + assert(ring->tx);
1505 +
1506 +#define SLOTS_PER_PACKET 2
1507 + if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
1508 + /* This should never trigger, as the ieee80211 stack
1509 + * recognizes if the device queue is full and does
1510 + * not send data anymore.
1511 + */
1512 + printk(KERN_ERR PFX "DMA queue overflow\n");
1513 + return -ENOMEM;
1514 + }
1515 +
1516 + err = dma_tx_fragment(ring, skb, ctl);
1517 + if (likely(!err))
1518 + ring->nr_tx_packets++;
1519 +
1520 + return err;
1521 +}
1522 +
1523 +void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
1524 + struct bcm43xx_xmitstatus *status)
1525 +{
1526 + struct bcm43xx_dmaring *ring;
1527 + struct bcm43xx_dmadesc *desc;
1528 + struct bcm43xx_dmadesc_meta *meta;
1529 + int is_last_fragment;
1530 + int slot;
1531 +
1532 + ring = parse_cookie(bcm, status->cookie, &slot);
1533 + assert(ring);
1534 + assert(ring->tx);
1535 + assert(get_desc_ctl(ring->vbase + slot) & BCM43xx_DMADTOR_FRAMESTART);
1536 + while (1) {
1537 + assert(slot >= 0 && slot < ring->nr_slots);
1538 + desc = ring->vbase + slot;
1539 + meta = ring->meta + slot;
1540 +
1541 + is_last_fragment = !!(get_desc_ctl(desc) & BCM43xx_DMADTOR_FRAMEEND);
1542 + unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
1543 +
1544 + if (meta->must_xmit_txstat) {
1545 + meta->must_xmit_txstat = 0;
1546 + /* Call back to inform the ieee80211 subsystem about the
1547 + * status of the transmission.
1548 + * Some fields of txstat are already filled in dma_tx().
1549 + */
1550 + meta->txstat.ack = !!(status->flags & BCM43xx_TXSTAT_FLAG_ACK);
1551 + meta->txstat.retry_count = status->cnt2 - 1;
1552 + //FIXME: Fill in more information?
1553 + ieee80211_tx_status_irqsafe(bcm->net_dev, meta->skb, &(meta->txstat));
1554 + meta->skb = NULL;
1555 + } else
1556 + free_descriptor_buffer(ring, desc, meta, 1);
1557 + /* Everything belonging to the slot is unmapped
1558 + * and freed, so we can return it.
1559 + */
1560 + return_slot(ring, slot);
1561 +
1562 + if (is_last_fragment)
1563 + break;
1564 + slot = next_slot(ring, slot);
1565 + }
1566 + bcm->stats.last_tx = jiffies;
1567 +}
1568 +
1569 +void bcm43xx_dma_get_tx_stats(struct bcm43xx_private *bcm,
1570 + struct ieee80211_tx_queue_stats *stats)
1571 +{
1572 + struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
1573 + struct bcm43xx_dmaring *ring;
1574 + struct ieee80211_tx_queue_stats_data *data;
1575 +
1576 + ring = dma->tx_ring1;
1577 + data = &(stats->data[0]);
1578 + data->len = ring->used_slots / SLOTS_PER_PACKET;
1579 + data->limit = ring->nr_slots / SLOTS_PER_PACKET;
1580 + data->count = ring->nr_tx_packets;
1581 +}
1582 +
1583 +static void dma_rx(struct bcm43xx_dmaring *ring,
1584 + int *slot)
1585 +{
1586 + struct bcm43xx_dmadesc *desc;
1587 + struct bcm43xx_dmadesc_meta *meta;
1588 + struct bcm43xx_rxhdr *rxhdr;
1589 + struct sk_buff *skb;
1590 + u16 len;
1591 + int err;
1592 + dma_addr_t dmaaddr;
1593 +
1594 + desc = ring->vbase + *slot;
1595 + meta = ring->meta + *slot;
1596 +
1597 + sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
1598 + skb = meta->skb;
1599 +
1600 + if (ring->mmio_base == BCM43xx_MMIO_DMA4_BASE) {
1601 + /* We received an xmit status. */
1602 + struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data;
1603 + struct bcm43xx_xmitstatus stat;
1604 +
1605 + stat.cookie = le16_to_cpu(hw->cookie);
1606 + stat.flags = hw->flags;
1607 + stat.cnt1 = hw->cnt1;
1608 + stat.cnt2 = hw->cnt2;
1609 + stat.seq = le16_to_cpu(hw->seq);
1610 + stat.unknown = le16_to_cpu(hw->unknown);
1611 +
1612 + bcm43xx_debugfs_log_txstat(ring->bcm, &stat);
1613 + bcm43xx_dma_handle_xmitstatus(ring->bcm, &stat);
1614 + /* recycle the descriptor buffer. */
1615 + sync_descbuffer_for_device(ring, meta->dmaaddr, ring->rx_buffersize);
1616 +
1617 + return;
1618 + }
1619 + rxhdr = (struct bcm43xx_rxhdr *)skb->data;
1620 + len = le16_to_cpu(rxhdr->frame_length);
1621 + if (len == 0) {
1622 + int i = 0;
1623 +
1624 + do {
1625 + udelay(2);
1626 + barrier();
1627 + len = le16_to_cpu(rxhdr->frame_length);
1628 + } while (len == 0 && i++ < 5);
1629 + if (unlikely(len == 0)) {
1630 + /* recycle the descriptor buffer. */
1631 + sync_descbuffer_for_device(ring, meta->dmaaddr,
1632 + ring->rx_buffersize);
1633 + goto drop;
1634 + }
1635 + }
1636 + if (unlikely(len > ring->rx_buffersize)) {
1637 + /* The data did not fit into one descriptor buffer
1638 + * and is split over multiple buffers.
1639 + * This should never happen, as we try to allocate buffers
1640 + * big enough. So simply ignore this packet.
1641 + */
1642 + int cnt = 0;
1643 + s32 tmp = len;
1644 +
1645 + while (1) {
1646 + desc = ring->vbase + *slot;
1647 + meta = ring->meta + *slot;
1648 + /* recycle the descriptor buffer. */
1649 + sync_descbuffer_for_device(ring, meta->dmaaddr,
1650 + ring->rx_buffersize);
1651 + *slot = next_slot(ring, *slot);
1652 + cnt++;
1653 + tmp -= ring->rx_buffersize;
1654 + if (tmp <= 0)
1655 + break;
1656 + }
1657 + printkl(KERN_ERR PFX "DMA RX buffer too small "
1658 + "(len: %u, buffer: %u, nr-dropped: %d)\n",
1659 + len, ring->rx_buffersize, cnt);
1660 + goto drop;
1661 + }
1662 +
1663 + dmaaddr = meta->dmaaddr;
1664 + err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
1665 + if (unlikely(err)) {
1666 + dprintkl(KERN_ERR PFX "DMA RX: setup_rx_descbuffer() failed\n");
1667 + sync_descbuffer_for_device(ring, dmaaddr,
1668 + ring->rx_buffersize);
1669 + goto drop;
1670 + }
1671 +
1672 + unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
1673 + skb_put(skb, len + ring->frameoffset);
1674 + skb_pull(skb, ring->frameoffset);
1675 +
1676 + bcm43xx_rx(ring->bcm, skb, rxhdr);
1677 +drop:
1678 + return;
1679 +}
1680 +
1681 +void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
1682 +{
1683 + u32 status;
1684 + u16 descptr;
1685 + int slot, current_slot;
1686 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
1687 + int used_slots = 0;
1688 +#endif
1689 +
1690 + assert(!ring->tx);
1691 + status = bcm43xx_dma_read(ring, BCM43xx_DMA_RX_STATUS);
1692 + descptr = (status & BCM43xx_DMA_RXSTAT_DPTR_MASK);
1693 + current_slot = descptr / sizeof(struct bcm43xx_dmadesc);
1694 + assert(current_slot >= 0 && current_slot < ring->nr_slots);
1695 +
1696 + slot = ring->current_slot;
1697 + for ( ; slot != current_slot; slot = next_slot(ring, slot)) {
1698 + dma_rx(ring, &slot);
1699 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
1700 + if (++used_slots > ring->max_used_slots)
1701 + ring->max_used_slots = used_slots;
1702 +#endif
1703 + }
1704 + bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX,
1705 + (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
1706 + ring->current_slot = slot;
1707 +}
1708 +
1709 +void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring)
1710 +{
1711 + assert(ring->tx);
1712 + bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1);
1713 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
1714 + bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
1715 + | BCM43xx_DMA_TXCTRL_SUSPEND);
1716 +}
1717 +
1718 +void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
1719 +{
1720 + assert(ring->tx);
1721 + bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
1722 + bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
1723 + & ~BCM43xx_DMA_TXCTRL_SUSPEND);
1724 + bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1);
1725 +}
1726 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
1727 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.h 1970-01-01 01:00:00.000000000 +0100
1728 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_dma.h 2006-03-28 22:16:14.000000000 +0200
1729 @@ -0,0 +1,228 @@
1730 +#ifndef BCM43xx_DMA_H_
1731 +#define BCM43xx_DMA_H_
1732 +
1733 +#include <linux/list.h>
1734 +#include <linux/spinlock.h>
1735 +#include <linux/workqueue.h>
1736 +#include <linux/linkage.h>
1737 +#include <asm/atomic.h>
1738 +
1739 +#include "bcm43xx.h"
1740 +
1741 +
1742 +/* DMA-Interrupt reasons. */
1743 +#define BCM43xx_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \
1744 + | (1 << 14) | (1 << 15))
1745 +#define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13)
1746 +#define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
1747 +
1748 +/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */
1749 +#define BCM43xx_DMA_TX_CONTROL 0x00
1750 +#define BCM43xx_DMA_TX_DESC_RING 0x04
1751 +#define BCM43xx_DMA_TX_DESC_INDEX 0x08
1752 +#define BCM43xx_DMA_TX_STATUS 0x0c
1753 +#define BCM43xx_DMA_RX_CONTROL 0x10
1754 +#define BCM43xx_DMA_RX_DESC_RING 0x14
1755 +#define BCM43xx_DMA_RX_DESC_INDEX 0x18
1756 +#define BCM43xx_DMA_RX_STATUS 0x1c
1757 +
1758 +/* DMA controller channel control word values. */
1759 +#define BCM43xx_DMA_TXCTRL_ENABLE (1 << 0)
1760 +#define BCM43xx_DMA_TXCTRL_SUSPEND (1 << 1)
1761 +#define BCM43xx_DMA_TXCTRL_LOOPBACK (1 << 2)
1762 +#define BCM43xx_DMA_TXCTRL_FLUSH (1 << 4)
1763 +#define BCM43xx_DMA_RXCTRL_ENABLE (1 << 0)
1764 +#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK 0x000000fe
1765 +#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT 1
1766 +#define BCM43xx_DMA_RXCTRL_PIO (1 << 8)
1767 +/* DMA controller channel status word values. */
1768 +#define BCM43xx_DMA_TXSTAT_DPTR_MASK 0x00000fff
1769 +#define BCM43xx_DMA_TXSTAT_STAT_MASK 0x0000f000
1770 +#define BCM43xx_DMA_TXSTAT_STAT_DISABLED 0x00000000
1771 +#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE 0x00001000
1772 +#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT 0x00002000
1773 +#define BCM43xx_DMA_TXSTAT_STAT_STOPPED 0x00003000
1774 +#define BCM43xx_DMA_TXSTAT_STAT_SUSP 0x00004000
1775 +#define BCM43xx_DMA_TXSTAT_ERROR_MASK 0x000f0000
1776 +#define BCM43xx_DMA_TXSTAT_FLUSHED (1 << 20)
1777 +#define BCM43xx_DMA_RXSTAT_DPTR_MASK 0x00000fff
1778 +#define BCM43xx_DMA_RXSTAT_STAT_MASK 0x0000f000
1779 +#define BCM43xx_DMA_RXSTAT_STAT_DISABLED 0x00000000
1780 +#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE 0x00001000
1781 +#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT 0x00002000
1782 +#define BCM43xx_DMA_RXSTAT_STAT_RESERVED 0x00003000
1783 +#define BCM43xx_DMA_RXSTAT_STAT_ERRORS 0x00004000
1784 +#define BCM43xx_DMA_RXSTAT_ERROR_MASK 0x000f0000
1785 +
1786 +/* DMA descriptor control field values. */
1787 +#define BCM43xx_DMADTOR_BYTECNT_MASK 0x00001fff
1788 +#define BCM43xx_DMADTOR_DTABLEEND (1 << 28) /* End of descriptor table */
1789 +#define BCM43xx_DMADTOR_COMPIRQ (1 << 29) /* IRQ on completion request */
1790 +#define BCM43xx_DMADTOR_FRAMEEND (1 << 30)
1791 +#define BCM43xx_DMADTOR_FRAMESTART (1 << 31)
1792 +
1793 +/* Misc DMA constants */
1794 +#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE
1795 +#define BCM43xx_DMA_BUSADDRMAX 0x3FFFFFFF
1796 +#define BCM43xx_DMA_DMABUSADDROFFSET (1 << 30)
1797 +#define BCM43xx_DMA1_RX_FRAMEOFFSET 30
1798 +#define BCM43xx_DMA4_RX_FRAMEOFFSET 0
1799 +
1800 +/* DMA engine tuning knobs */
1801 +#define BCM43xx_TXRING_SLOTS 512
1802 +#define BCM43xx_RXRING_SLOTS 64
1803 +#define BCM43xx_DMA1_RXBUFFERSIZE (2304 + 100)
1804 +#define BCM43xx_DMA4_RXBUFFERSIZE 16
1805 +
1806 +
1807 +
1808 +#ifdef CONFIG_BCM43XX_D80211_DMA
1809 +
1810 +
1811 +struct sk_buff;
1812 +struct bcm43xx_private;
1813 +struct bcm43xx_xmitstatus;
1814 +
1815 +
1816 +struct bcm43xx_dmadesc {
1817 + __le32 _control;
1818 + __le32 _address;
1819 +} __attribute__((__packed__));
1820 +
1821 +/* Macros to access the bcm43xx_dmadesc struct */
1822 +#define get_desc_ctl(desc) le32_to_cpu((desc)->_control)
1823 +#define set_desc_ctl(desc, ctl) do { (desc)->_control = cpu_to_le32(ctl); } while (0)
1824 +#define get_desc_addr(desc) le32_to_cpu((desc)->_address)
1825 +#define set_desc_addr(desc, addr) do { (desc)->_address = cpu_to_le32(addr); } while (0)
1826 +
1827 +struct bcm43xx_dmadesc_meta {
1828 + /* The kernel DMA-able buffer. */
1829 + struct sk_buff *skb;
1830 + /* DMA base bus-address of the descriptor buffer. */
1831 + dma_addr_t dmaaddr;
1832 + /* ieee80211 TX status. Only used once per 802.11 frag. */
1833 + u8 must_xmit_txstat:1;
1834 + struct ieee80211_tx_status txstat;
1835 +};
1836 +
1837 +struct bcm43xx_dmaring {
1838 + struct bcm43xx_private *bcm;
1839 + /* Kernel virtual base address of the ring memory. */
1840 + struct bcm43xx_dmadesc *vbase;
1841 + /* DMA memory offset */
1842 + dma_addr_t memoffset;
1843 + /* (Unadjusted) DMA base bus-address of the ring memory. */
1844 + dma_addr_t dmabase;
1845 + /* Meta data about all descriptors. */
1846 + struct bcm43xx_dmadesc_meta *meta;
1847 + /* Number of descriptor slots in the ring. */
1848 + int nr_slots;
1849 + /* Number of used descriptor slots. */
1850 + int used_slots;
1851 + /* Currently used slot in the ring. */
1852 + int current_slot;
1853 + /* Total number of packets sent. Statistics only. */
1854 + unsigned int nr_tx_packets;
1855 + /* Frameoffset in octets. */
1856 + u32 frameoffset;
1857 + /* Descriptor buffer size. */
1858 + u16 rx_buffersize;
1859 + /* The MMIO base register of the DMA controller, this
1860 + * ring is posted to.
1861 + */
1862 + u16 mmio_base;
1863 + u8 tx:1, /* TRUE, if this is a TX ring. */
1864 + suspended:1; /* TRUE, if transfers are suspended on this ring. */
1865 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
1866 + /* Maximum number of used slots. */
1867 + int max_used_slots;
1868 +#endif /* CONFIG_BCM43XX_D80211_DEBUG*/
1869 +};
1870 +
1871 +
1872 +static inline
1873 +u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring,
1874 + u16 offset)
1875 +{
1876 + return bcm43xx_read32(ring->bcm, ring->mmio_base + offset);
1877 +}
1878 +
1879 +static inline
1880 +void bcm43xx_dma_write(struct bcm43xx_dmaring *ring,
1881 + u16 offset, u32 value)
1882 +{
1883 + bcm43xx_write32(ring->bcm, ring->mmio_base + offset, value);
1884 +}
1885 +
1886 +
1887 +int bcm43xx_dma_init(struct bcm43xx_private *bcm);
1888 +void bcm43xx_dma_free(struct bcm43xx_private *bcm);
1889 +
1890 +int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
1891 + u16 dmacontroller_mmio_base);
1892 +int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
1893 + u16 dmacontroller_mmio_base);
1894 +
1895 +void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring);
1896 +void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring);
1897 +
1898 +void bcm43xx_dma_get_tx_stats(struct bcm43xx_private *bcm,
1899 + struct ieee80211_tx_queue_stats *stats);
1900 +
1901 +int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
1902 + struct sk_buff *skb,
1903 + struct ieee80211_tx_control *ctl);
1904 +void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
1905 + struct bcm43xx_xmitstatus *status);
1906 +
1907 +void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
1908 +
1909 +
1910 +#else /* CONFIG_BCM43XX_D80211_DMA */
1911 +
1912 +
1913 +static inline
1914 +int bcm43xx_dma_init(struct bcm43xx_private *bcm)
1915 +{
1916 + return 0;
1917 +}
1918 +static inline
1919 +void bcm43xx_dma_free(struct bcm43xx_private *bcm)
1920 +{
1921 +}
1922 +static inline
1923 +int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
1924 + u16 dmacontroller_mmio_base)
1925 +{
1926 + return 0;
1927 +}
1928 +static inline
1929 +int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
1930 + u16 dmacontroller_mmio_base)
1931 +{
1932 + return 0;
1933 +}
1934 +static inline
1935 +void bcm43xx_dma_get_tx_stats(struct bcm43xx_private *bcm,
1936 + struct ieee80211_tx_queue_stats *stats)
1937 +{
1938 +}
1939 +static inline
1940 +int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
1941 + struct sk_buff *skb,
1942 + struct ieee80211_tx_control *ctl)
1943 +{
1944 + return 0;
1945 +}
1946 +static inline
1947 +void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
1948 + struct bcm43xx_xmitstatus *status)
1949 +{
1950 +}
1951 +static inline
1952 +void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
1953 +{
1954 +}
1955 +
1956 +#endif /* CONFIG_BCM43XX_D80211_DMA */
1957 +#endif /* BCM43xx_DMA_H_ */
1958 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
1959 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.c 1970-01-01 01:00:00.000000000 +0100
1960 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.c 2006-03-28 22:16:14.000000000 +0200
1961 @@ -0,0 +1,50 @@
1962 +/*
1963 +
1964 + Broadcom BCM43xx wireless driver
1965 +
1966 + ethtool support
1967 +
1968 + Copyright (c) 2006 Jason Lunz <lunz@falooley.org>
1969 +
1970 + Some code in this file is derived from the 8139too.c driver
1971 + Copyright (C) 2002 Jeff Garzik
1972 +
1973 + This program is free software; you can redistribute it and/or modify
1974 + it under the terms of the GNU General Public License as published by
1975 + the Free Software Foundation; either version 2 of the License, or
1976 + (at your option) any later version.
1977 +
1978 + This program is distributed in the hope that it will be useful,
1979 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1980 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1981 + GNU General Public License for more details.
1982 +
1983 + You should have received a copy of the GNU General Public License
1984 + along with this program; see the file COPYING. If not, write to
1985 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
1986 + Boston, MA 02110-1301, USA.
1987 +
1988 +*/
1989 +
1990 +#include "bcm43xx.h"
1991 +#include "bcm43xx_ethtool.h"
1992 +
1993 +#include <linux/netdevice.h>
1994 +#include <linux/pci.h>
1995 +#include <linux/string.h>
1996 +#include <linux/version.h>
1997 +
1998 +
1999 +static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
2000 +{
2001 + struct bcm43xx_private *bcm = bcm43xx_priv(dev);
2002 +
2003 + strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
2004 + strncpy(info->version, UTS_RELEASE, sizeof(info->version));
2005 + strncpy(info->bus_info, pci_name(bcm->pci_dev), ETHTOOL_BUSINFO_LEN);
2006 +}
2007 +
2008 +struct ethtool_ops bcm43xx_ethtool_ops = {
2009 + .get_drvinfo = bcm43xx_get_drvinfo,
2010 + .get_link = ethtool_op_get_link,
2011 +};
2012 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
2013 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.h 1970-01-01 01:00:00.000000000 +0100
2014 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ethtool.h 2006-03-28 22:16:14.000000000 +0200
2015 @@ -0,0 +1,8 @@
2016 +#ifndef BCM43xx_ETHTOOL_H_
2017 +#define BCM43xx_ETHTOOL_H_
2018 +
2019 +#include <linux/ethtool.h>
2020 +
2021 +extern struct ethtool_ops bcm43xx_ethtool_ops;
2022 +
2023 +#endif /* BCM43xx_ETHTOOL_H_ */
2024 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
2025 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h 1970-01-01 01:00:00.000000000 +0100
2026 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h 2006-03-28 22:16:14.000000000 +0200
2027 @@ -0,0 +1,917 @@
2028 +#ifndef BCM43xx_H_
2029 +#define BCM43xx_H_
2030 +
2031 +#include <linux/version.h>
2032 +#include <linux/kernel.h>
2033 +#include <linux/spinlock.h>
2034 +#include <linux/interrupt.h>
2035 +#include <linux/stringify.h>
2036 +#include <linux/netdevice.h>
2037 +#include <linux/pci.h>
2038 +#include <asm/atomic.h>
2039 +#include <asm/io.h>
2040 +
2041 +#include <linux/wireless.h>
2042 +#include <net/d80211.h>
2043 +#include <net/d80211_mgmt.h>
2044 +#include <net/d80211_common.h>
2045 +
2046 +#include "bcm43xx_debugfs.h"
2047 +#include "bcm43xx_leds.h"
2048 +#include "bcm43xx_sysfs.h"
2049 +
2050 +
2051 +#define PFX KBUILD_MODNAME ": "
2052 +
2053 +#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50
2054 +#define BCM43xx_IRQWAIT_MAX_RETRIES 50
2055 +
2056 +#define BCM43xx_IO_SIZE 8192
2057 +
2058 +/* Active Core PCI Configuration Register. */
2059 +#define BCM43xx_PCICFG_ACTIVE_CORE 0x80
2060 +/* SPROM control register. */
2061 +#define BCM43xx_PCICFG_SPROMCTL 0x88
2062 +/* Interrupt Control PCI Configuration Register. (Only on PCI cores with rev >= 6) */
2063 +#define BCM43xx_PCICFG_ICR 0x94
2064 +
2065 +/* MMIO offsets */
2066 +#define BCM43xx_MMIO_DMA1_REASON 0x20
2067 +#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x24
2068 +#define BCM43xx_MMIO_DMA2_REASON 0x28
2069 +#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x2C
2070 +#define BCM43xx_MMIO_DMA3_REASON 0x30
2071 +#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x34
2072 +#define BCM43xx_MMIO_DMA4_REASON 0x38
2073 +#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x3C
2074 +#define BCM43xx_MMIO_STATUS_BITFIELD 0x120
2075 +#define BCM43xx_MMIO_STATUS2_BITFIELD 0x124
2076 +#define BCM43xx_MMIO_GEN_IRQ_REASON 0x128
2077 +#define BCM43xx_MMIO_GEN_IRQ_MASK 0x12C
2078 +#define BCM43xx_MMIO_RAM_CONTROL 0x130
2079 +#define BCM43xx_MMIO_RAM_DATA 0x134
2080 +#define BCM43xx_MMIO_PS_STATUS 0x140
2081 +#define BCM43xx_MMIO_RADIO_HWENABLED_HI 0x158
2082 +#define BCM43xx_MMIO_SHM_CONTROL 0x160
2083 +#define BCM43xx_MMIO_SHM_DATA 0x164
2084 +#define BCM43xx_MMIO_SHM_DATA_UNALIGNED 0x166
2085 +#define BCM43xx_MMIO_XMITSTAT_0 0x170
2086 +#define BCM43xx_MMIO_XMITSTAT_1 0x174
2087 +#define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */
2088 +#define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
2089 +#define BCM43xx_MMIO_DMA1_BASE 0x200
2090 +#define BCM43xx_MMIO_DMA2_BASE 0x220
2091 +#define BCM43xx_MMIO_DMA3_BASE 0x240
2092 +#define BCM43xx_MMIO_DMA4_BASE 0x260
2093 +#define BCM43xx_MMIO_PIO1_BASE 0x300
2094 +#define BCM43xx_MMIO_PIO2_BASE 0x310
2095 +#define BCM43xx_MMIO_PIO3_BASE 0x320
2096 +#define BCM43xx_MMIO_PIO4_BASE 0x330
2097 +#define BCM43xx_MMIO_PHY_VER 0x3E0
2098 +#define BCM43xx_MMIO_PHY_RADIO 0x3E2
2099 +#define BCM43xx_MMIO_ANTENNA 0x3E8
2100 +#define BCM43xx_MMIO_CHANNEL 0x3F0
2101 +#define BCM43xx_MMIO_CHANNEL_EXT 0x3F4
2102 +#define BCM43xx_MMIO_RADIO_CONTROL 0x3F6
2103 +#define BCM43xx_MMIO_RADIO_DATA_HIGH 0x3F8
2104 +#define BCM43xx_MMIO_RADIO_DATA_LOW 0x3FA
2105 +#define BCM43xx_MMIO_PHY_CONTROL 0x3FC
2106 +#define BCM43xx_MMIO_PHY_DATA 0x3FE
2107 +#define BCM43xx_MMIO_MACFILTER_CONTROL 0x420
2108 +#define BCM43xx_MMIO_MACFILTER_DATA 0x422
2109 +#define BCM43xx_MMIO_RADIO_HWENABLED_LO 0x49A
2110 +#define BCM43xx_MMIO_GPIO_CONTROL 0x49C
2111 +#define BCM43xx_MMIO_GPIO_MASK 0x49E
2112 +#define BCM43xx_MMIO_TSF_0 0x632 /* core rev < 3 only */
2113 +#define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */
2114 +#define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */
2115 +#define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */
2116 +#define BCM43xx_MMIO_POWERUP_DELAY 0x6A8
2117 +
2118 +/* SPROM offsets. */
2119 +#define BCM43xx_SPROM_BASE 0x1000
2120 +#define BCM43xx_SPROM_BOARDFLAGS2 0x1c
2121 +#define BCM43xx_SPROM_IL0MACADDR 0x24
2122 +#define BCM43xx_SPROM_ET0MACADDR 0x27
2123 +#define BCM43xx_SPROM_ET1MACADDR 0x2a
2124 +#define BCM43xx_SPROM_ETHPHY 0x2d
2125 +#define BCM43xx_SPROM_BOARDREV 0x2e
2126 +#define BCM43xx_SPROM_PA0B0 0x2f
2127 +#define BCM43xx_SPROM_PA0B1 0x30
2128 +#define BCM43xx_SPROM_PA0B2 0x31
2129 +#define BCM43xx_SPROM_WL0GPIO0 0x32
2130 +#define BCM43xx_SPROM_WL0GPIO2 0x33
2131 +#define BCM43xx_SPROM_MAXPWR 0x34
2132 +#define BCM43xx_SPROM_PA1B0 0x35
2133 +#define BCM43xx_SPROM_PA1B1 0x36
2134 +#define BCM43xx_SPROM_PA1B2 0x37
2135 +#define BCM43xx_SPROM_IDL_TSSI_TGT 0x38
2136 +#define BCM43xx_SPROM_BOARDFLAGS 0x39
2137 +#define BCM43xx_SPROM_ANTENNA_GAIN 0x3a
2138 +#define BCM43xx_SPROM_VERSION 0x3f
2139 +
2140 +/* BCM43xx_SPROM_BOARDFLAGS values */
2141 +#define BCM43xx_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
2142 +#define BCM43xx_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */
2143 +#define BCM43xx_BFL_AIRLINEMODE 0x0004 /* implements GPIO 13 radio disable indication */
2144 +#define BCM43xx_BFL_RSSI 0x0008 /* software calculates nrssi slope. */
2145 +#define BCM43xx_BFL_ENETSPI 0x0010 /* has ephy roboswitch spi */
2146 +#define BCM43xx_BFL_XTAL_NOSLOW 0x0020 /* no slow clock available */
2147 +#define BCM43xx_BFL_CCKHIPWR 0x0040 /* can do high power CCK transmission */
2148 +#define BCM43xx_BFL_ENETADM 0x0080 /* has ADMtek switch */
2149 +#define BCM43xx_BFL_ENETVLAN 0x0100 /* can do vlan */
2150 +#define BCM43xx_BFL_AFTERBURNER 0x0200 /* supports Afterburner mode */
2151 +#define BCM43xx_BFL_NOPCI 0x0400 /* leaves PCI floating */
2152 +#define BCM43xx_BFL_FEM 0x0800 /* supports the Front End Module */
2153 +#define BCM43xx_BFL_EXTLNA 0x1000 /* has an external LNA */
2154 +#define BCM43xx_BFL_HGPA 0x2000 /* had high gain PA */
2155 +#define BCM43xx_BFL_BTCMOD 0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */
2156 +#define BCM43xx_BFL_ALTIQ 0x8000 /* alternate I/Q settings */
2157 +
2158 +/* GPIO register offset, in both ChipCommon and PCI core. */
2159 +#define BCM43xx_GPIO_CONTROL 0x6c
2160 +
2161 +/* SHM Routing */
2162 +#define BCM43xx_SHM_SHARED 0x0001
2163 +#define BCM43xx_SHM_WIRELESS 0x0002
2164 +#define BCM43xx_SHM_PCM 0x0003
2165 +#define BCM43xx_SHM_HWMAC 0x0004
2166 +#define BCM43xx_SHM_UCODE 0x0300
2167 +
2168 +/* MacFilter offsets. */
2169 +#define BCM43xx_MACFILTER_SELF 0x0000
2170 +#define BCM43xx_MACFILTER_ASSOC 0x0003
2171 +
2172 +/* Chipcommon registers. */
2173 +#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04
2174 +#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0
2175 +#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4
2176 +#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8
2177 +#define BCM43xx_CHIPCOMMON_SYSCLKCTL 0xC0
2178 +
2179 +/* PCI core specific registers. */
2180 +#define BCM43xx_PCICORE_BCAST_ADDR 0x50
2181 +#define BCM43xx_PCICORE_BCAST_DATA 0x54
2182 +#define BCM43xx_PCICORE_SBTOPCI2 0x108
2183 +
2184 +/* SBTOPCI2 values. */
2185 +#define BCM43xx_SBTOPCI2_PREFETCH 0x4
2186 +#define BCM43xx_SBTOPCI2_BURST 0x8
2187 +
2188 +/* Chipcommon capabilities. */
2189 +#define BCM43xx_CAPABILITIES_PCTL 0x00040000
2190 +#define BCM43xx_CAPABILITIES_PLLMASK 0x00030000
2191 +#define BCM43xx_CAPABILITIES_PLLSHIFT 16
2192 +#define BCM43xx_CAPABILITIES_FLASHMASK 0x00000700
2193 +#define BCM43xx_CAPABILITIES_FLASHSHIFT 8
2194 +#define BCM43xx_CAPABILITIES_EXTBUSPRESENT 0x00000040
2195 +#define BCM43xx_CAPABILITIES_UARTGPIO 0x00000020
2196 +#define BCM43xx_CAPABILITIES_UARTCLOCKMASK 0x00000018
2197 +#define BCM43xx_CAPABILITIES_UARTCLOCKSHIFT 3
2198 +#define BCM43xx_CAPABILITIES_MIPSBIGENDIAN 0x00000004
2199 +#define BCM43xx_CAPABILITIES_NRUARTSMASK 0x00000003
2200 +
2201 +/* PowerControl */
2202 +#define BCM43xx_PCTL_IN 0xB0
2203 +#define BCM43xx_PCTL_OUT 0xB4
2204 +#define BCM43xx_PCTL_OUTENABLE 0xB8
2205 +#define BCM43xx_PCTL_XTAL_POWERUP 0x40
2206 +#define BCM43xx_PCTL_PLL_POWERDOWN 0x80
2207 +
2208 +/* PowerControl Clock Modes */
2209 +#define BCM43xx_PCTL_CLK_FAST 0x00
2210 +#define BCM43xx_PCTL_CLK_SLOW 0x01
2211 +#define BCM43xx_PCTL_CLK_DYNAMIC 0x02
2212 +
2213 +#define BCM43xx_PCTL_FORCE_SLOW 0x0800
2214 +#define BCM43xx_PCTL_FORCE_PLL 0x1000
2215 +#define BCM43xx_PCTL_DYN_XTAL 0x2000
2216 +
2217 +/* COREIDs */
2218 +#define BCM43xx_COREID_CHIPCOMMON 0x800
2219 +#define BCM43xx_COREID_ILINE20 0x801
2220 +#define BCM43xx_COREID_SDRAM 0x803
2221 +#define BCM43xx_COREID_PCI 0x804
2222 +#define BCM43xx_COREID_MIPS 0x805
2223 +#define BCM43xx_COREID_ETHERNET 0x806
2224 +#define BCM43xx_COREID_V90 0x807
2225 +#define BCM43xx_COREID_USB11_HOSTDEV 0x80a
2226 +#define BCM43xx_COREID_IPSEC 0x80b
2227 +#define BCM43xx_COREID_PCMCIA 0x80d
2228 +#define BCM43xx_COREID_EXT_IF 0x80f
2229 +#define BCM43xx_COREID_80211 0x812
2230 +#define BCM43xx_COREID_MIPS_3302 0x816
2231 +#define BCM43xx_COREID_USB11_HOST 0x817
2232 +#define BCM43xx_COREID_USB11_DEV 0x818
2233 +#define BCM43xx_COREID_USB20_HOST 0x819
2234 +#define BCM43xx_COREID_USB20_DEV 0x81a
2235 +#define BCM43xx_COREID_SDIO_HOST 0x81b
2236 +
2237 +/* Core Information Registers */
2238 +#define BCM43xx_CIR_BASE 0xf00
2239 +#define BCM43xx_CIR_SBTPSFLAG (BCM43xx_CIR_BASE + 0x18)
2240 +#define BCM43xx_CIR_SBIMSTATE (BCM43xx_CIR_BASE + 0x90)
2241 +#define BCM43xx_CIR_SBINTVEC (BCM43xx_CIR_BASE + 0x94)
2242 +#define BCM43xx_CIR_SBTMSTATELOW (BCM43xx_CIR_BASE + 0x98)
2243 +#define BCM43xx_CIR_SBTMSTATEHIGH (BCM43xx_CIR_BASE + 0x9c)
2244 +#define BCM43xx_CIR_SBIMCONFIGLOW (BCM43xx_CIR_BASE + 0xa8)
2245 +#define BCM43xx_CIR_SB_ID_HI (BCM43xx_CIR_BASE + 0xfc)
2246 +
2247 +/* Mask to get the Backplane Flag Number from SBTPSFLAG. */
2248 +#define BCM43xx_BACKPLANE_FLAG_NR_MASK 0x3f
2249 +
2250 +/* SBIMCONFIGLOW values/masks. */
2251 +#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK 0x00000007
2252 +#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT 0
2253 +#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK 0x00000070
2254 +#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT 4
2255 +#define BCM43xx_SBIMCONFIGLOW_CONNID_MASK 0x00ff0000
2256 +#define BCM43xx_SBIMCONFIGLOW_CONNID_SHIFT 16
2257 +
2258 +/* sbtmstatelow state flags */
2259 +#define BCM43xx_SBTMSTATELOW_RESET 0x01
2260 +#define BCM43xx_SBTMSTATELOW_REJECT 0x02
2261 +#define BCM43xx_SBTMSTATELOW_CLOCK 0x10000
2262 +#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000
2263 +
2264 +/* sbtmstatehigh state flags */
2265 +#define BCM43xx_SBTMSTATEHIGH_SERROR 0x1
2266 +#define BCM43xx_SBTMSTATEHIGH_BUSY 0x4
2267 +
2268 +/* sbimstate flags */
2269 +#define BCM43xx_SBIMSTATE_IB_ERROR 0x20000
2270 +#define BCM43xx_SBIMSTATE_TIMEOUT 0x40000
2271 +
2272 +/* PHYVersioning */
2273 +#define BCM43xx_PHYTYPE_A 0x00
2274 +#define BCM43xx_PHYTYPE_B 0x01
2275 +#define BCM43xx_PHYTYPE_G 0x02
2276 +
2277 +/* PHYRegisters */
2278 +#define BCM43xx_PHY_ILT_A_CTRL 0x0072
2279 +#define BCM43xx_PHY_ILT_A_DATA1 0x0073
2280 +#define BCM43xx_PHY_ILT_A_DATA2 0x0074
2281 +#define BCM43xx_PHY_G_LO_CONTROL 0x0810
2282 +#define BCM43xx_PHY_ILT_G_CTRL 0x0472
2283 +#define BCM43xx_PHY_ILT_G_DATA1 0x0473
2284 +#define BCM43xx_PHY_ILT_G_DATA2 0x0474
2285 +#define BCM43xx_PHY_A_PCTL 0x007B
2286 +#define BCM43xx_PHY_G_PCTL 0x0029
2287 +#define BCM43xx_PHY_A_CRS 0x0029
2288 +#define BCM43xx_PHY_RADIO_BITFIELD 0x0401
2289 +#define BCM43xx_PHY_G_CRS 0x0429
2290 +#define BCM43xx_PHY_NRSSILT_CTRL 0x0803
2291 +#define BCM43xx_PHY_NRSSILT_DATA 0x0804
2292 +
2293 +/* RadioRegisters */
2294 +#define BCM43xx_RADIOCTL_ID 0x01
2295 +
2296 +/* StatusBitField */
2297 +#define BCM43xx_SBF_MAC_ENABLED 0x00000001
2298 +#define BCM43xx_SBF_2 0x00000002 /*FIXME: fix name*/
2299 +#define BCM43xx_SBF_CORE_READY 0x00000004
2300 +#define BCM43xx_SBF_400 0x00000400 /*FIXME: fix name*/
2301 +#define BCM43xx_SBF_4000 0x00004000 /*FIXME: fix name*/
2302 +#define BCM43xx_SBF_8000 0x00008000 /*FIXME: fix name*/
2303 +#define BCM43xx_SBF_XFER_REG_BYTESWAP 0x00010000
2304 +#define BCM43xx_SBF_MODE_NOTADHOC 0x00020000
2305 +#define BCM43xx_SBF_MODE_AP 0x00040000
2306 +#define BCM43xx_SBF_RADIOREG_LOCK 0x00080000
2307 +#define BCM43xx_SBF_MODE_MONITOR 0x00400000
2308 +#define BCM43xx_SBF_MODE_PROMISC 0x01000000
2309 +#define BCM43xx_SBF_PS1 0x02000000
2310 +#define BCM43xx_SBF_PS2 0x04000000
2311 +#define BCM43xx_SBF_NO_SSID_BCAST 0x08000000
2312 +#define BCM43xx_SBF_TIME_UPDATE 0x10000000
2313 +#define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/
2314 +
2315 +/* MicrocodeFlagsBitfield (addr + lo-word values?)*/
2316 +#define BCM43xx_UCODEFLAGS_OFFSET 0x005E
2317 +
2318 +#define BCM43xx_UCODEFLAG_AUTODIV 0x0001
2319 +#define BCM43xx_UCODEFLAG_UNKBGPHY 0x0002
2320 +#define BCM43xx_UCODEFLAG_UNKBPHY 0x0004
2321 +#define BCM43xx_UCODEFLAG_UNKGPHY 0x0020
2322 +#define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040
2323 +#define BCM43xx_UCODEFLAG_JAPAN 0x0080
2324 +
2325 +/* Generic-Interrupt reasons. */
2326 +#define BCM43xx_IRQ_READY (1 << 0)
2327 +#define BCM43xx_IRQ_BEACON (1 << 1)
2328 +#define BCM43xx_IRQ_PS (1 << 2)
2329 +#define BCM43xx_IRQ_REG124 (1 << 5)
2330 +#define BCM43xx_IRQ_PMQ (1 << 6)
2331 +#define BCM43xx_IRQ_PIO_WORKAROUND (1 << 8)
2332 +#define BCM43xx_IRQ_XMIT_ERROR (1 << 11)
2333 +#define BCM43xx_IRQ_RX (1 << 15)
2334 +#define BCM43xx_IRQ_SCAN (1 << 16)
2335 +#define BCM43xx_IRQ_NOISE (1 << 18)
2336 +#define BCM43xx_IRQ_XMIT_STATUS (1 << 29)
2337 +
2338 +#define BCM43xx_IRQ_ALL 0xffffffff
2339 +#define BCM43xx_IRQ_INITIAL (BCM43xx_IRQ_PS | \
2340 + BCM43xx_IRQ_REG124 | \
2341 + BCM43xx_IRQ_PMQ | \
2342 + BCM43xx_IRQ_XMIT_ERROR | \
2343 + BCM43xx_IRQ_RX | \
2344 + BCM43xx_IRQ_SCAN | \
2345 + BCM43xx_IRQ_NOISE | \
2346 + BCM43xx_IRQ_XMIT_STATUS)
2347 +
2348 +/* Bus type PCI. */
2349 +#define BCM43xx_BUSTYPE_PCI 0
2350 +/* Bus type Silicone Backplane Bus. */
2351 +#define BCM43xx_BUSTYPE_SB 1
2352 +/* Bus type PCMCIA. */
2353 +#define BCM43xx_BUSTYPE_PCMCIA 2
2354 +
2355 +/* Rate values. */
2356 +#define BCM43xx_CCK_RATE_1MB 0x02
2357 +#define BCM43xx_CCK_RATE_2MB 0x04
2358 +#define BCM43xx_CCK_RATE_5MB 0x0B
2359 +#define BCM43xx_CCK_RATE_11MB 0x16
2360 +#define BCM43xx_OFDM_RATE_6MB 0x0C
2361 +#define BCM43xx_OFDM_RATE_9MB 0x12
2362 +#define BCM43xx_OFDM_RATE_12MB 0x18
2363 +#define BCM43xx_OFDM_RATE_18MB 0x24
2364 +#define BCM43xx_OFDM_RATE_24MB 0x30
2365 +#define BCM43xx_OFDM_RATE_36MB 0x48
2366 +#define BCM43xx_OFDM_RATE_48MB 0x60
2367 +#define BCM43xx_OFDM_RATE_54MB 0x6C
2368 +
2369 +#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7
2370 +#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4
2371 +
2372 +/* Max size of a security key */
2373 +#define BCM43xx_SEC_KEYSIZE 16
2374 +/* Security algorithms. */
2375 +enum {
2376 + BCM43xx_SEC_ALGO_NONE = 0, /* unencrypted, as of TX header. */
2377 + BCM43xx_SEC_ALGO_WEP,
2378 + BCM43xx_SEC_ALGO_UNKNOWN,
2379 + BCM43xx_SEC_ALGO_AES,
2380 + BCM43xx_SEC_ALGO_WEP104,
2381 + BCM43xx_SEC_ALGO_TKIP,
2382 +};
2383 +
2384 +
2385 +#ifdef assert
2386 +# undef assert
2387 +#endif
2388 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2389 +#define assert(expr) \
2390 + do { \
2391 + if (unlikely(!(expr))) { \
2392 + printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", \
2393 + #expr, __FILE__, __LINE__, __FUNCTION__); \
2394 + } \
2395 + } while (0)
2396 +#else
2397 +#define assert(expr) do { /* nothing */ } while (0)
2398 +#endif
2399 +
2400 +/* rate limited printk(). */
2401 +#ifdef printkl
2402 +# undef printkl
2403 +#endif
2404 +#define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0)
2405 +/* rate limited printk() for debugging */
2406 +#ifdef dprintkl
2407 +# undef dprintkl
2408 +#endif
2409 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2410 +# define dprintkl printkl
2411 +#else
2412 +# define dprintkl(f, x...) do { /* nothing */ } while (0)
2413 +#endif
2414 +
2415 +/* debugging printk() */
2416 +#ifdef dprintk
2417 +# undef dprintk
2418 +#endif
2419 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2420 +# define dprintk(f, x...) do { printk(f ,##x); } while (0)
2421 +#else
2422 +# define dprintk(f, x...) do { /* nothing */ } while (0)
2423 +#endif
2424 +
2425 +
2426 +struct net_device;
2427 +struct pci_dev;
2428 +struct bcm43xx_dmaring;
2429 +struct bcm43xx_pioqueue;
2430 +
2431 +struct bcm43xx_initval {
2432 + u16 offset;
2433 + u16 size;
2434 + u32 value;
2435 +} __attribute__((__packed__));
2436 +
2437 +/* Values for bcm430x_sprominfo.locale */
2438 +enum {
2439 + BCM43xx_LOCALE_WORLD = 0,
2440 + BCM43xx_LOCALE_THAILAND,
2441 + BCM43xx_LOCALE_ISRAEL,
2442 + BCM43xx_LOCALE_JORDAN,
2443 + BCM43xx_LOCALE_CHINA,
2444 + BCM43xx_LOCALE_JAPAN,
2445 + BCM43xx_LOCALE_USA_CANADA_ANZ,
2446 + BCM43xx_LOCALE_EUROPE,
2447 + BCM43xx_LOCALE_USA_LOW,
2448 + BCM43xx_LOCALE_JAPAN_HIGH,
2449 + BCM43xx_LOCALE_ALL,
2450 + BCM43xx_LOCALE_NONE,
2451 +};
2452 +
2453 +#define BCM43xx_SPROM_SIZE 64 /* in 16-bit words. */
2454 +struct bcm43xx_sprominfo {
2455 + u16 boardflags2;
2456 + u8 il0macaddr[6];
2457 + u8 et0macaddr[6];
2458 + u8 et1macaddr[6];
2459 + u8 et0phyaddr:5;
2460 + u8 et1phyaddr:5;
2461 + u8 et0mdcport:1;
2462 + u8 et1mdcport:1;
2463 + u8 boardrev;
2464 + u8 locale:4;
2465 + u8 antennas_aphy:2;
2466 + u8 antennas_bgphy:2;
2467 + u16 pa0b0;
2468 + u16 pa0b1;
2469 + u16 pa0b2;
2470 + u8 wl0gpio0;
2471 + u8 wl0gpio1;
2472 + u8 wl0gpio2;
2473 + u8 wl0gpio3;
2474 + u8 maxpower_aphy;
2475 + u8 maxpower_bgphy;
2476 + u16 pa1b0;
2477 + u16 pa1b1;
2478 + u16 pa1b2;
2479 + u8 idle_tssi_tgt_aphy;
2480 + u8 idle_tssi_tgt_bgphy;
2481 + u16 boardflags;
2482 + u16 antennagain_aphy;
2483 + u16 antennagain_bgphy;
2484 +};
2485 +
2486 +/* Value pair to measure the LocalOscillator. */
2487 +struct bcm43xx_lopair {
2488 + s8 low;
2489 + s8 high;
2490 + u8 used:1;
2491 +};
2492 +#define BCM43xx_LO_COUNT (14*4)
2493 +
2494 +struct bcm43xx_phyinfo {
2495 + /* Hardware Data */
2496 + u8 version;
2497 + u8 type;
2498 + u8 rev;
2499 + u16 antenna_diversity;
2500 + u16 savedpctlreg;
2501 + u16 minlowsig[2];
2502 + u16 minlowsigpos[2];
2503 + u8 connected:1,
2504 + calibrated:1,
2505 + is_locked:1, /* used in bcm43xx_phy_{un}lock() */
2506 + dyn_tssi_tbl:1; /* used in bcm43xx_phy_init_tssi2dbm_table() */
2507 + /* LO Measurement Data.
2508 + * Use bcm43xx_get_lopair() to get a value.
2509 + */
2510 + struct bcm43xx_lopair *_lo_pairs;
2511 +
2512 + /* TSSI to dBm table in use */
2513 + const s8 *tssi2dbm;
2514 + /* idle TSSI value */
2515 + s8 idle_tssi;
2516 +
2517 + /* Values from bcm43xx_calc_loopback_gain() */
2518 + u16 loopback_gain[2];
2519 +
2520 + /* PHY lock for core.rev < 3
2521 + * This lock is only used by bcm43xx_phy_{un}lock()
2522 + */
2523 + spinlock_t lock;
2524 +};
2525 +
2526 +
2527 +struct bcm43xx_radioinfo {
2528 + u16 manufact;
2529 + u16 version;
2530 + u8 revision;
2531 +
2532 + /* Desired TX power level (in dBm).
2533 + * This is set by the user and adjusted in bcm43xx_phy_xmitpower(). */
2534 + u8 power_level;
2535 + /* TX Power control values. */
2536 + union {
2537 + /* B/G PHY */
2538 + struct {
2539 + u16 baseband_atten;
2540 + u16 radio_atten;
2541 + u16 txctl1;
2542 + u16 txctl2;
2543 + };
2544 + /* A PHY */
2545 + struct {
2546 + u16 txpwr_offset;
2547 + };
2548 + };
2549 +
2550 + /* Current Interference Mitigation mode */
2551 + int interfmode;
2552 + /* Stack of saved values from the Interference Mitigation code.
2553 + * Each value in the stack is layed out as follows:
2554 + * bit 0-11: offset
2555 + * bit 12-15: register ID
2556 + * bit 16-32: value
2557 + * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT
2558 + */
2559 +#define BCM43xx_INTERFSTACK_SIZE 26
2560 + u32 interfstack[BCM43xx_INTERFSTACK_SIZE];
2561 +
2562 + /* Saved values from the NRSSI Slope calculation */
2563 + s16 nrssi[2];
2564 + s32 nrssislope;
2565 + /* In memory nrssi lookup table. */
2566 + s8 nrssi_lt[64];
2567 +
2568 + /* current channel */
2569 + u8 channel;
2570 + u8 initial_channel;
2571 +
2572 + u16 lofcal;
2573 +
2574 + u16 initval;
2575 +
2576 + u8 enabled:1;
2577 + /* ACI (adjacent channel interference) flags. */
2578 + u8 aci_enable:1,
2579 + aci_wlan_automatic:1,
2580 + aci_hw_rssi:1;
2581 +};
2582 +
2583 +/* Data structures for DMA transmission, per 80211 core. */
2584 +struct bcm43xx_dma {
2585 + struct bcm43xx_dmaring *tx_ring0;
2586 + struct bcm43xx_dmaring *tx_ring1;
2587 + struct bcm43xx_dmaring *tx_ring2;
2588 + struct bcm43xx_dmaring *tx_ring3;
2589 + struct bcm43xx_dmaring *rx_ring0;
2590 + struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */
2591 +};
2592 +
2593 +/* Data structures for PIO transmission, per 80211 core. */
2594 +struct bcm43xx_pio {
2595 + struct bcm43xx_pioqueue *queue0;
2596 + struct bcm43xx_pioqueue *queue1;
2597 + struct bcm43xx_pioqueue *queue2;
2598 + struct bcm43xx_pioqueue *queue3;
2599 +};
2600 +
2601 +#define BCM43xx_MAX_80211_CORES 2
2602 +
2603 +#ifdef CONFIG_BCM947XX
2604 +#define core_offset(bcm) (bcm)->current_core_offset
2605 +#else
2606 +#define core_offset(bcm) 0
2607 +#endif
2608 +
2609 +/* Generic information about a core. */
2610 +struct bcm43xx_coreinfo {
2611 + u8 available:1,
2612 + enabled:1,
2613 + initialized:1;
2614 + /** core_id ID number */
2615 + u16 id;
2616 + /** core_rev revision number */
2617 + u8 rev;
2618 + /** Index number for _switch_core() */
2619 + u8 index;
2620 +};
2621 +
2622 +/* Additional information for each 80211 core. */
2623 +struct bcm43xx_coreinfo_80211 {
2624 + /* PHY device. */
2625 + struct bcm43xx_phyinfo phy;
2626 + /* Radio device. */
2627 + struct bcm43xx_radioinfo radio;
2628 + union {
2629 + /* DMA context. */
2630 + struct bcm43xx_dma dma;
2631 + /* PIO context. */
2632 + struct bcm43xx_pio pio;
2633 + };
2634 +};
2635 +
2636 +/* Context information for a noise calculation (Link Quality). */
2637 +struct bcm43xx_noise_calculation {
2638 + struct bcm43xx_coreinfo *core_at_start;
2639 + u8 channel_at_start;
2640 + u8 calculation_running:1;
2641 + u8 nr_samples;
2642 + s8 samples[8][4];
2643 +};
2644 +
2645 +struct bcm43xx_stats {
2646 + u8 link_quality;
2647 + /* Store the last TX/RX times here for updating the leds. */
2648 + unsigned long last_tx;
2649 + unsigned long last_rx;
2650 +};
2651 +
2652 +struct bcm43xx_key {
2653 + u8 enabled:1;
2654 + u8 algorithm;
2655 +};
2656 +
2657 +struct bcm43xx_private {
2658 + struct bcm43xx_sysfs sysfs;
2659 +
2660 + struct ieee80211_hw *ieee;
2661 + struct ieee80211_low_level_stats ieee_stats;
2662 + int iw_mode;
2663 +
2664 + struct net_device *net_dev;
2665 + struct pci_dev *pci_dev;
2666 + unsigned int irq;
2667 +
2668 + void __iomem *mmio_addr;
2669 + unsigned int mmio_len;
2670 +
2671 + /* Do not use the lock directly. Use the bcm43xx_lock* helper
2672 + * functions, to be MMIO-safe. */
2673 + spinlock_t _lock;
2674 +
2675 + /* Driver status flags. */
2676 + u32 initialized:1, /* init_board() succeed */
2677 + was_initialized:1, /* for PCI suspend/resume. */
2678 + shutting_down:1, /* free_board() in progress */
2679 + __using_pio:1, /* Internal, use bcm43xx_using_pio(). */
2680 + bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */
2681 + reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */
2682 + powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */
2683 + short_preamble:1, /* TRUE, if short preamble is enabled. */
2684 + short_slot:1, /* TRUE, if short slot timing is enabled. */
2685 + firmware_norelease:1; /* Do not release the firmware. Used on suspend. */
2686 +
2687 + struct bcm43xx_stats stats;
2688 +
2689 + /* Bus type we are connected to.
2690 + * This is currently always BCM43xx_BUSTYPE_PCI
2691 + */
2692 + u8 bustype;
2693 +
2694 + u16 board_vendor;
2695 + u16 board_type;
2696 + u16 board_revision;
2697 +
2698 + u16 chip_id;
2699 + u8 chip_rev;
2700 + u8 chip_package;
2701 +
2702 + struct bcm43xx_sprominfo sprom;
2703 +#define BCM43xx_NR_LEDS 4
2704 + struct bcm43xx_led leds[BCM43xx_NR_LEDS];
2705 +
2706 + /* The currently active core. */
2707 + struct bcm43xx_coreinfo *current_core;
2708 +#ifdef CONFIG_BCM947XX
2709 + /** current core memory offset */
2710 + u32 current_core_offset;
2711 +#endif
2712 + struct bcm43xx_coreinfo *active_80211_core;
2713 + /* coreinfo structs for all possible cores follow.
2714 + * Note that a core might not exist.
2715 + * So check the coreinfo flags before using it.
2716 + */
2717 + struct bcm43xx_coreinfo core_chipcommon;
2718 + struct bcm43xx_coreinfo core_pci;
2719 + struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
2720 + /* Additional information, specific to the 80211 cores. */
2721 + struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
2722 + /* Index of the current 80211 core. If current_core is not
2723 + * an 80211 core, this is -1.
2724 + */
2725 + int current_80211_core_idx;
2726 + /* Number of available 80211 cores. */
2727 + int nr_80211_available;
2728 +
2729 + u32 chipcommon_capabilities;
2730 +
2731 + /* Reason code of the last interrupt. */
2732 + u32 irq_reason;
2733 + u32 dma_reason[4];
2734 + /* saved irq enable/disable state bitfield. */
2735 + u32 irq_savedstate;
2736 + /* Link Quality calculation context. */
2737 + struct bcm43xx_noise_calculation noisecalc;
2738 +
2739 + /* Interrupt Service Routine tasklet (bottom-half) */
2740 + struct tasklet_struct isr_tasklet;
2741 +
2742 + /* Periodic tasks */
2743 + struct timer_list periodic_tasks;
2744 + unsigned int periodic_state;
2745 +
2746 + struct work_struct restart_work;
2747 +
2748 + /* Informational stuff. */
2749 + char nick[IW_ESSID_MAX_SIZE + 1];
2750 + u8 bssid[ETH_ALEN];
2751 +
2752 + /* encryption/decryption */
2753 + u16 security_offset;
2754 + struct bcm43xx_key key[54];
2755 + u8 default_key_idx;
2756 +
2757 + /* Firmware. */
2758 + const struct firmware *ucode;
2759 + const struct firmware *pcm;
2760 + const struct firmware *initvals0;
2761 + const struct firmware *initvals1;
2762 +
2763 + /* Cached beacon template while uploading the template. */
2764 + struct sk_buff *cached_beacon;
2765 +
2766 + /* Debugging stuff follows. */
2767 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
2768 + struct bcm43xx_dfsentry *dfsentry;
2769 +#endif
2770 +};
2771 +
2772 +/* bcm43xx_(un)lock() protect struct bcm43xx_private.
2773 + * Note that _NO_ MMIO writes are allowed. If you want to
2774 + * write to the device through MMIO in the critical section, use
2775 + * the *_mmio lock functions.
2776 + * MMIO read-access is allowed, though.
2777 + */
2778 +#define bcm43xx_lock(bcm, flags) spin_lock_irqsave(&(bcm)->_lock, flags)
2779 +#define bcm43xx_unlock(bcm, flags) spin_unlock_irqrestore(&(bcm)->_lock, flags)
2780 +/* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO.
2781 + * MMIO write-access to the device is allowed.
2782 + * All MMIO writes are flushed on unlock, so it is guaranteed to not
2783 + * interfere with other threads writing MMIO registers.
2784 + */
2785 +#define bcm43xx_lock_mmio(bcm, flags) bcm43xx_lock(bcm, flags)
2786 +#define bcm43xx_unlock_mmio(bcm, flags) do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0)
2787 +
2788 +static inline
2789 +struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
2790 +{
2791 + return ieee80211_dev_hw_data(dev);
2792 +}
2793 +
2794 +/* Helper function, which returns a boolean.
2795 + * TRUE, if PIO is used; FALSE, if DMA is used.
2796 + */
2797 +#if defined(CONFIG_BCM43XX_D80211_DMA) && defined(CONFIG_BCM43XX_D80211_PIO)
2798 +static inline
2799 +int bcm43xx_using_pio(struct bcm43xx_private *bcm)
2800 +{
2801 + return bcm->__using_pio;
2802 +}
2803 +#elif defined(CONFIG_BCM43XX_D80211_DMA)
2804 +static inline
2805 +int bcm43xx_using_pio(struct bcm43xx_private *bcm)
2806 +{
2807 + return 0;
2808 +}
2809 +#elif defined(CONFIG_BCM43XX_D80211_PIO)
2810 +static inline
2811 +int bcm43xx_using_pio(struct bcm43xx_private *bcm)
2812 +{
2813 + return 1;
2814 +}
2815 +#else
2816 +# error "Using neither DMA nor PIO? Confused..."
2817 +#endif
2818 +
2819 +/* Helper functions to access data structures private to the 80211 cores.
2820 + * Note that we _must_ have an 80211 core mapped when calling
2821 + * any of these functions.
2822 + */
2823 +static inline
2824 +struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
2825 +{
2826 + assert(bcm43xx_using_pio(bcm));
2827 + assert(bcm->current_80211_core_idx >= 0);
2828 + assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
2829 + return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio);
2830 +}
2831 +static inline
2832 +struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
2833 +{
2834 + assert(!bcm43xx_using_pio(bcm));
2835 + assert(bcm->current_80211_core_idx >= 0);
2836 + assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
2837 + return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma);
2838 +}
2839 +static inline
2840 +struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
2841 +{
2842 + assert(bcm->current_80211_core_idx >= 0);
2843 + assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
2844 + return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy);
2845 +}
2846 +static inline
2847 +struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
2848 +{
2849 + assert(bcm->current_80211_core_idx >= 0);
2850 + assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
2851 + return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio);
2852 +}
2853 +
2854 +/* Are we running in init_board() context? */
2855 +static inline
2856 +int bcm43xx_is_initializing(struct bcm43xx_private *bcm)
2857 +{
2858 + if (bcm->initialized)
2859 + return 0;
2860 + if (bcm->shutting_down)
2861 + return 0;
2862 + return 1;
2863 +}
2864 +
2865 +static inline
2866 +struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy,
2867 + u16 radio_attenuation,
2868 + u16 baseband_attenuation)
2869 +{
2870 + return phy->_lo_pairs + (radio_attenuation + 14 * (baseband_attenuation / 2));
2871 +}
2872 +
2873 +
2874 +static inline
2875 +u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset)
2876 +{
2877 + return ioread16(bcm->mmio_addr + core_offset(bcm) + offset);
2878 +}
2879 +
2880 +static inline
2881 +void bcm43xx_write16(struct bcm43xx_private *bcm, u16 offset, u16 value)
2882 +{
2883 + iowrite16(value, bcm->mmio_addr + core_offset(bcm) + offset);
2884 +}
2885 +
2886 +static inline
2887 +u32 bcm43xx_read32(struct bcm43xx_private *bcm, u16 offset)
2888 +{
2889 + return ioread32(bcm->mmio_addr + core_offset(bcm) + offset);
2890 +}
2891 +
2892 +static inline
2893 +void bcm43xx_write32(struct bcm43xx_private *bcm, u16 offset, u32 value)
2894 +{
2895 + iowrite32(value, bcm->mmio_addr + core_offset(bcm) + offset);
2896 +}
2897 +
2898 +static inline
2899 +int bcm43xx_pci_read_config16(struct bcm43xx_private *bcm, int offset, u16 *value)
2900 +{
2901 + return pci_read_config_word(bcm->pci_dev, offset, value);
2902 +}
2903 +
2904 +static inline
2905 +int bcm43xx_pci_read_config32(struct bcm43xx_private *bcm, int offset, u32 *value)
2906 +{
2907 + return pci_read_config_dword(bcm->pci_dev, offset, value);
2908 +}
2909 +
2910 +static inline
2911 +int bcm43xx_pci_write_config16(struct bcm43xx_private *bcm, int offset, u16 value)
2912 +{
2913 + return pci_write_config_word(bcm->pci_dev, offset, value);
2914 +}
2915 +
2916 +static inline
2917 +int bcm43xx_pci_write_config32(struct bcm43xx_private *bcm, int offset, u32 value)
2918 +{
2919 + return pci_write_config_dword(bcm->pci_dev, offset, value);
2920 +}
2921 +
2922 +/** Limit a value between two limits */
2923 +#ifdef limit_value
2924 +# undef limit_value
2925 +#endif
2926 +#define limit_value(value, min, max) \
2927 + ({ \
2928 + typeof(value) __value = (value); \
2929 + typeof(value) __min = (min); \
2930 + typeof(value) __max = (max); \
2931 + if (__value < __min) \
2932 + __value = __min; \
2933 + else if (__value > __max) \
2934 + __value = __max; \
2935 + __value; \
2936 + })
2937 +
2938 +/** Helpers to print MAC addresses. */
2939 +#define BCM43xx_MACFMT "%02x:%02x:%02x:%02x:%02x:%02x"
2940 +#define BCM43xx_MACARG(x) ((u8*)(x))[0], ((u8*)(x))[1], \
2941 + ((u8*)(x))[2], ((u8*)(x))[3], \
2942 + ((u8*)(x))[4], ((u8*)(x))[5]
2943 +
2944 +#endif /* BCM43xx_H_ */
2945 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
2946 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.c 1970-01-01 01:00:00.000000000 +0100
2947 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.c 2006-03-28 22:16:14.000000000 +0200
2948 @@ -0,0 +1,337 @@
2949 +/*
2950 +
2951 + Broadcom BCM43xx wireless driver
2952 +
2953 + Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
2954 + Stefano Brivio <st3@riseup.net>
2955 + Michael Buesch <mbuesch@freenet.de>
2956 + Danny van Dyk <kugelfang@gentoo.org>
2957 + Andreas Jaggi <andreas.jaggi@waterwave.ch>
2958 +
2959 + This program is free software; you can redistribute it and/or modify
2960 + it under the terms of the GNU General Public License as published by
2961 + the Free Software Foundation; either version 2 of the License, or
2962 + (at your option) any later version.
2963 +
2964 + This program is distributed in the hope that it will be useful,
2965 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2966 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2967 + GNU General Public License for more details.
2968 +
2969 + You should have received a copy of the GNU General Public License
2970 + along with this program; see the file COPYING. If not, write to
2971 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
2972 + Boston, MA 02110-1301, USA.
2973 +
2974 +*/
2975 +
2976 +#include "bcm43xx.h"
2977 +#include "bcm43xx_ilt.h"
2978 +#include "bcm43xx_phy.h"
2979 +
2980 +
2981 +/**** Initial Internal Lookup Tables ****/
2982 +
2983 +const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE] = {
2984 + 0xFEB93FFD, 0xFEC63FFD, /* 0 */
2985 + 0xFED23FFD, 0xFEDF3FFD,
2986 + 0xFEEC3FFE, 0xFEF83FFE,
2987 + 0xFF053FFE, 0xFF113FFE,
2988 + 0xFF1E3FFE, 0xFF2A3FFF, /* 8 */
2989 + 0xFF373FFF, 0xFF443FFF,
2990 + 0xFF503FFF, 0xFF5D3FFF,
2991 + 0xFF693FFF, 0xFF763FFF,
2992 + 0xFF824000, 0xFF8F4000, /* 16 */
2993 + 0xFF9B4000, 0xFFA84000,
2994 + 0xFFB54000, 0xFFC14000,
2995 + 0xFFCE4000, 0xFFDA4000,
2996 + 0xFFE74000, 0xFFF34000, /* 24 */
2997 + 0x00004000, 0x000D4000,
2998 + 0x00194000, 0x00264000,
2999 + 0x00324000, 0x003F4000,
3000 + 0x004B4000, 0x00584000, /* 32 */
3001 + 0x00654000, 0x00714000,
3002 + 0x007E4000, 0x008A3FFF,
3003 + 0x00973FFF, 0x00A33FFF,
3004 + 0x00B03FFF, 0x00BC3FFF, /* 40 */
3005 + 0x00C93FFF, 0x00D63FFF,
3006 + 0x00E23FFE, 0x00EF3FFE,
3007 + 0x00FB3FFE, 0x01083FFE,
3008 + 0x01143FFE, 0x01213FFD, /* 48 */
3009 + 0x012E3FFD, 0x013A3FFD,
3010 + 0x01473FFD,
3011 +};
3012 +
3013 +const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE] = {
3014 + 0xDB93CB87, 0xD666CF64, /* 0 */
3015 + 0xD1FDD358, 0xCDA6D826,
3016 + 0xCA38DD9F, 0xC729E2B4,
3017 + 0xC469E88E, 0xC26AEE2B,
3018 + 0xC0DEF46C, 0xC073FA62, /* 8 */
3019 + 0xC01D00D5, 0xC0760743,
3020 + 0xC1560D1E, 0xC2E51369,
3021 + 0xC4ED18FF, 0xC7AC1ED7,
3022 + 0xCB2823B2, 0xCEFA28D9, /* 16 */
3023 + 0xD2F62D3F, 0xD7BB3197,
3024 + 0xDCE53568, 0xE1FE3875,
3025 + 0xE7D13B35, 0xED663D35,
3026 + 0xF39B3EC4, 0xF98E3FA7, /* 24 */
3027 + 0x00004000, 0x06723FA7,
3028 + 0x0C653EC4, 0x129A3D35,
3029 + 0x182F3B35, 0x1E023875,
3030 + 0x231B3568, 0x28453197, /* 32 */
3031 + 0x2D0A2D3F, 0x310628D9,
3032 + 0x34D823B2, 0x38541ED7,
3033 + 0x3B1318FF, 0x3D1B1369,
3034 + 0x3EAA0D1E, 0x3F8A0743, /* 40 */
3035 + 0x3FE300D5, 0x3F8DFA62,
3036 + 0x3F22F46C, 0x3D96EE2B,
3037 + 0x3B97E88E, 0x38D7E2B4,
3038 + 0x35C8DD9F, 0x325AD826, /* 48 */
3039 + 0x2E03D358, 0x299ACF64,
3040 + 0x246DCB87,
3041 +};
3042 +
3043 +const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE] = {
3044 + 0x0082, 0x0082, 0x0102, 0x0182, /* 0 */
3045 + 0x0202, 0x0282, 0x0302, 0x0382,
3046 + 0x0402, 0x0482, 0x0502, 0x0582,
3047 + 0x05E2, 0x0662, 0x06E2, 0x0762,
3048 + 0x07E2, 0x0842, 0x08C2, 0x0942, /* 16 */
3049 + 0x09C2, 0x0A22, 0x0AA2, 0x0B02,
3050 + 0x0B82, 0x0BE2, 0x0C62, 0x0CC2,
3051 + 0x0D42, 0x0DA2, 0x0E02, 0x0E62,
3052 + 0x0EE2, 0x0F42, 0x0FA2, 0x1002, /* 32 */
3053 + 0x1062, 0x10C2, 0x1122, 0x1182,
3054 + 0x11E2, 0x1242, 0x12A2, 0x12E2,
3055 + 0x1342, 0x13A2, 0x1402, 0x1442,
3056 + 0x14A2, 0x14E2, 0x1542, 0x1582, /* 48 */
3057 + 0x15E2, 0x1622, 0x1662, 0x16C1,
3058 + 0x1701, 0x1741, 0x1781, 0x17E1,
3059 + 0x1821, 0x1861, 0x18A1, 0x18E1,
3060 + 0x1921, 0x1961, 0x19A1, 0x19E1, /* 64 */
3061 + 0x1A21, 0x1A61, 0x1AA1, 0x1AC1,
3062 + 0x1B01, 0x1B41, 0x1B81, 0x1BA1,
3063 + 0x1BE1, 0x1C21, 0x1C41, 0x1C81,
3064 + 0x1CA1, 0x1CE1, 0x1D01, 0x1D41, /* 80 */
3065 + 0x1D61, 0x1DA1, 0x1DC1, 0x1E01,
3066 + 0x1E21, 0x1E61, 0x1E81, 0x1EA1,
3067 + 0x1EE1, 0x1F01, 0x1F21, 0x1F41,
3068 + 0x1F81, 0x1FA1, 0x1FC1, 0x1FE1, /* 96 */
3069 + 0x2001, 0x2041, 0x2061, 0x2081,
3070 + 0x20A1, 0x20C1, 0x20E1, 0x2101,
3071 + 0x2121, 0x2141, 0x2161, 0x2181,
3072 + 0x21A1, 0x21C1, 0x21E1, 0x2201, /* 112 */
3073 + 0x2221, 0x2241, 0x2261, 0x2281,
3074 + 0x22A1, 0x22C1, 0x22C1, 0x22E1,
3075 + 0x2301, 0x2321, 0x2341, 0x2361,
3076 + 0x2361, 0x2381, 0x23A1, 0x23C1, /* 128 */
3077 + 0x23E1, 0x23E1, 0x2401, 0x2421,
3078 + 0x2441, 0x2441, 0x2461, 0x2481,
3079 + 0x2481, 0x24A1, 0x24C1, 0x24C1,
3080 + 0x24E1, 0x2501, 0x2501, 0x2521, /* 144 */
3081 + 0x2541, 0x2541, 0x2561, 0x2561,
3082 + 0x2581, 0x25A1, 0x25A1, 0x25C1,
3083 + 0x25C1, 0x25E1, 0x2601, 0x2601,
3084 + 0x2621, 0x2621, 0x2641, 0x2641, /* 160 */
3085 + 0x2661, 0x2661, 0x2681, 0x2681,
3086 + 0x26A1, 0x26A1, 0x26C1, 0x26C1,
3087 + 0x26E1, 0x26E1, 0x2701, 0x2701,
3088 + 0x2721, 0x2721, 0x2740, 0x2740, /* 176 */
3089 + 0x2760, 0x2760, 0x2780, 0x2780,
3090 + 0x2780, 0x27A0, 0x27A0, 0x27C0,
3091 + 0x27C0, 0x27E0, 0x27E0, 0x27E0,
3092 + 0x2800, 0x2800, 0x2820, 0x2820, /* 192 */
3093 + 0x2820, 0x2840, 0x2840, 0x2840,
3094 + 0x2860, 0x2860, 0x2880, 0x2880,
3095 + 0x2880, 0x28A0, 0x28A0, 0x28A0,
3096 + 0x28C0, 0x28C0, 0x28C0, 0x28E0, /* 208 */
3097 + 0x28E0, 0x28E0, 0x2900, 0x2900,
3098 + 0x2900, 0x2920, 0x2920, 0x2920,
3099 + 0x2940, 0x2940, 0x2940, 0x2960,
3100 + 0x2960, 0x2960, 0x2960, 0x2980, /* 224 */
3101 + 0x2980, 0x2980, 0x29A0, 0x29A0,
3102 + 0x29A0, 0x29A0, 0x29C0, 0x29C0,
3103 + 0x29C0, 0x29E0, 0x29E0, 0x29E0,
3104 + 0x29E0, 0x2A00, 0x2A00, 0x2A00, /* 240 */
3105 + 0x2A00, 0x2A20, 0x2A20, 0x2A20,
3106 + 0x2A20, 0x2A40, 0x2A40, 0x2A40,
3107 + 0x2A40, 0x2A60, 0x2A60, 0x2A60,
3108 +};
3109 +
3110 +const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE] = {
3111 + 0x0089, 0x02E9, 0x0409, 0x04E9, /* 0 */
3112 + 0x05A9, 0x0669, 0x0709, 0x0789,
3113 + 0x0829, 0x08A9, 0x0929, 0x0989,
3114 + 0x0A09, 0x0A69, 0x0AC9, 0x0B29,
3115 + 0x0BA9, 0x0BE9, 0x0C49, 0x0CA9, /* 16 */
3116 + 0x0D09, 0x0D69, 0x0DA9, 0x0E09,
3117 + 0x0E69, 0x0EA9, 0x0F09, 0x0F49,
3118 + 0x0FA9, 0x0FE9, 0x1029, 0x1089,
3119 + 0x10C9, 0x1109, 0x1169, 0x11A9, /* 32 */
3120 + 0x11E9, 0x1229, 0x1289, 0x12C9,
3121 + 0x1309, 0x1349, 0x1389, 0x13C9,
3122 + 0x1409, 0x1449, 0x14A9, 0x14E9,
3123 + 0x1529, 0x1569, 0x15A9, 0x15E9, /* 48 */
3124 + 0x1629, 0x1669, 0x16A9, 0x16E8,
3125 + 0x1728, 0x1768, 0x17A8, 0x17E8,
3126 + 0x1828, 0x1868, 0x18A8, 0x18E8,
3127 + 0x1928, 0x1968, 0x19A8, 0x19E8, /* 64 */
3128 + 0x1A28, 0x1A68, 0x1AA8, 0x1AE8,
3129 + 0x1B28, 0x1B68, 0x1BA8, 0x1BE8,
3130 + 0x1C28, 0x1C68, 0x1CA8, 0x1CE8,
3131 + 0x1D28, 0x1D68, 0x1DC8, 0x1E08, /* 80 */
3132 + 0x1E48, 0x1E88, 0x1EC8, 0x1F08,
3133 + 0x1F48, 0x1F88, 0x1FE8, 0x2028,
3134 + 0x2068, 0x20A8, 0x2108, 0x2148,
3135 + 0x2188, 0x21C8, 0x2228, 0x2268, /* 96 */
3136 + 0x22C8, 0x2308, 0x2348, 0x23A8,
3137 + 0x23E8, 0x2448, 0x24A8, 0x24E8,
3138 + 0x2548, 0x25A8, 0x2608, 0x2668,
3139 + 0x26C8, 0x2728, 0x2787, 0x27E7, /* 112 */
3140 + 0x2847, 0x28C7, 0x2947, 0x29A7,
3141 + 0x2A27, 0x2AC7, 0x2B47, 0x2BE7,
3142 + 0x2CA7, 0x2D67, 0x2E47, 0x2F67,
3143 + 0x3247, 0x3526, 0x3646, 0x3726, /* 128 */
3144 + 0x3806, 0x38A6, 0x3946, 0x39E6,
3145 + 0x3A66, 0x3AE6, 0x3B66, 0x3BC6,
3146 + 0x3C45, 0x3CA5, 0x3D05, 0x3D85,
3147 + 0x3DE5, 0x3E45, 0x3EA5, 0x3EE5, /* 144 */
3148 + 0x3F45, 0x3FA5, 0x4005, 0x4045,
3149 + 0x40A5, 0x40E5, 0x4145, 0x4185,
3150 + 0x41E5, 0x4225, 0x4265, 0x42C5,
3151 + 0x4305, 0x4345, 0x43A5, 0x43E5, /* 160 */
3152 + 0x4424, 0x4464, 0x44C4, 0x4504,
3153 + 0x4544, 0x4584, 0x45C4, 0x4604,
3154 + 0x4644, 0x46A4, 0x46E4, 0x4724,
3155 + 0x4764, 0x47A4, 0x47E4, 0x4824, /* 176 */
3156 + 0x4864, 0x48A4, 0x48E4, 0x4924,
3157 + 0x4964, 0x49A4, 0x49E4, 0x4A24,
3158 + 0x4A64, 0x4AA4, 0x4AE4, 0x4B23,
3159 + 0x4B63, 0x4BA3, 0x4BE3, 0x4C23, /* 192 */
3160 + 0x4C63, 0x4CA3, 0x4CE3, 0x4D23,
3161 + 0x4D63, 0x4DA3, 0x4DE3, 0x4E23,
3162 + 0x4E63, 0x4EA3, 0x4EE3, 0x4F23,
3163 + 0x4F63, 0x4FC3, 0x5003, 0x5043, /* 208 */
3164 + 0x5083, 0x50C3, 0x5103, 0x5143,
3165 + 0x5183, 0x51E2, 0x5222, 0x5262,
3166 + 0x52A2, 0x52E2, 0x5342, 0x5382,
3167 + 0x53C2, 0x5402, 0x5462, 0x54A2, /* 224 */
3168 + 0x5502, 0x5542, 0x55A2, 0x55E2,
3169 + 0x5642, 0x5682, 0x56E2, 0x5722,
3170 + 0x5782, 0x57E1, 0x5841, 0x58A1,
3171 + 0x5901, 0x5961, 0x59C1, 0x5A21, /* 240 */
3172 + 0x5AA1, 0x5B01, 0x5B81, 0x5BE1,
3173 + 0x5C61, 0x5D01, 0x5D80, 0x5E20,
3174 + 0x5EE0, 0x5FA0, 0x6080, 0x61C0,
3175 +};
3176 +
3177 +const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE] = {
3178 + 0x0001, 0x0001, 0x0001, 0xFFFE,
3179 + 0xFFFE, 0x3FFF, 0x1000, 0x0393,
3180 +};
3181 +
3182 +const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE] = {
3183 + 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
3184 + 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
3185 +};
3186 +
3187 +const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE] = {
3188 + 0x013C, 0x01F5, 0x031A, 0x0631,
3189 + 0x0001, 0x0001, 0x0001, 0x0001,
3190 +};
3191 +
3192 +const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE] = {
3193 + 0x5484, 0x3C40, 0x0000, 0x0000,
3194 + 0x0000, 0x0000, 0x0000, 0x0000,
3195 +};
3196 +
3197 +const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE] = {
3198 + 0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */
3199 + 0x2F2D, 0x2A2A, 0x2527, 0x1F21,
3200 + 0x1A1D, 0x1719, 0x1616, 0x1414,
3201 + 0x1414, 0x1400, 0x1414, 0x1614,
3202 + 0x1716, 0x1A19, 0x1F1D, 0x2521, /* 16 */
3203 + 0x2A27, 0x2F2A, 0x332D, 0x3B35,
3204 + 0x5140, 0x6C62, 0x0077,
3205 +};
3206 +
3207 +const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE] = {
3208 + 0xD8DD, 0xCBD4, 0xBCC0, 0XB6B7, /* 0 */
3209 + 0xB2B0, 0xADAD, 0xA7A9, 0x9FA1,
3210 + 0x969B, 0x9195, 0x8F8F, 0x8A8A,
3211 + 0x8A8A, 0x8A00, 0x8A8A, 0x8F8A,
3212 + 0x918F, 0x9695, 0x9F9B, 0xA7A1, /* 16 */
3213 + 0xADA9, 0xB2AD, 0xB6B0, 0xBCB7,
3214 + 0xCBC0, 0xD8D4, 0x00DD,
3215 +};
3216 +
3217 +const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE] = {
3218 + 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 0 */
3219 + 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
3220 + 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
3221 + 0xA4A4, 0xA400, 0xA4A4, 0xA4A4,
3222 + 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 16 */
3223 + 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
3224 + 0xA4A4, 0xA4A4, 0x00A4,
3225 +};
3226 +
3227 +const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE] = {
3228 + 0x007A, 0x0075, 0x0071, 0x006C, /* 0 */
3229 + 0x0067, 0x0063, 0x005E, 0x0059,
3230 + 0x0054, 0x0050, 0x004B, 0x0046,
3231 + 0x0042, 0x003D, 0x003D, 0x003D,
3232 + 0x003D, 0x003D, 0x003D, 0x003D, /* 16 */
3233 + 0x003D, 0x003D, 0x003D, 0x003D,
3234 + 0x003D, 0x003D, 0x0000, 0x003D,
3235 + 0x003D, 0x003D, 0x003D, 0x003D,
3236 + 0x003D, 0x003D, 0x003D, 0x003D, /* 32 */
3237 + 0x003D, 0x003D, 0x003D, 0x003D,
3238 + 0x0042, 0x0046, 0x004B, 0x0050,
3239 + 0x0054, 0x0059, 0x005E, 0x0063,
3240 + 0x0067, 0x006C, 0x0071, 0x0075, /* 48 */
3241 + 0x007A,
3242 +};
3243 +
3244 +const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE] = {
3245 + 0x00DE, 0x00DC, 0x00DA, 0x00D8, /* 0 */
3246 + 0x00D6, 0x00D4, 0x00D2, 0x00CF,
3247 + 0x00CD, 0x00CA, 0x00C7, 0x00C4,
3248 + 0x00C1, 0x00BE, 0x00BE, 0x00BE,
3249 + 0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 16 */
3250 + 0x00BE, 0x00BE, 0x00BE, 0x00BE,
3251 + 0x00BE, 0x00BE, 0x0000, 0x00BE,
3252 + 0x00BE, 0x00BE, 0x00BE, 0x00BE,
3253 + 0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 32 */
3254 + 0x00BE, 0x00BE, 0x00BE, 0x00BE,
3255 + 0x00C1, 0x00C4, 0x00C7, 0x00CA,
3256 + 0x00CD, 0x00CF, 0x00D2, 0x00D4,
3257 + 0x00D6, 0x00D8, 0x00DA, 0x00DC, /* 48 */
3258 + 0x00DE,
3259 +};
3260 +
3261 +/**** Helper functions to access the device Internal Lookup Tables ****/
3262 +
3263 +void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
3264 +{
3265 + if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
3266 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
3267 + mmiowb();
3268 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val);
3269 + } else {
3270 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
3271 + mmiowb();
3272 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val);
3273 + }
3274 +}
3275 +
3276 +u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset)
3277 +{
3278 + if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
3279 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
3280 + return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1);
3281 + } else {
3282 + bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
3283 + return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1);
3284 + }
3285 +}
3286 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
3287 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.h 1970-01-01 01:00:00.000000000 +0100
3288 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_ilt.h 2006-03-28 22:16:14.000000000 +0200
3289 @@ -0,0 +1,32 @@
3290 +#ifndef BCM43xx_ILT_H_
3291 +#define BCM43xx_ILT_H_
3292 +
3293 +#define BCM43xx_ILT_ROTOR_SIZE 53
3294 +extern const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE];
3295 +#define BCM43xx_ILT_RETARD_SIZE 53
3296 +extern const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE];
3297 +#define BCM43xx_ILT_FINEFREQA_SIZE 256
3298 +extern const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE];
3299 +#define BCM43xx_ILT_FINEFREQG_SIZE 256
3300 +extern const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE];
3301 +#define BCM43xx_ILT_NOISEA2_SIZE 8
3302 +extern const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE];
3303 +#define BCM43xx_ILT_NOISEA3_SIZE 8
3304 +extern const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE];
3305 +#define BCM43xx_ILT_NOISEG1_SIZE 8
3306 +extern const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE];
3307 +#define BCM43xx_ILT_NOISEG2_SIZE 8
3308 +extern const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE];
3309 +#define BCM43xx_ILT_NOISESCALEG_SIZE 27
3310 +extern const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE];
3311 +extern const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE];
3312 +extern const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE];
3313 +#define BCM43xx_ILT_SIGMASQR_SIZE 53
3314 +extern const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE];
3315 +extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE];
3316 +
3317 +
3318 +void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
3319 +u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset);
3320 +
3321 +#endif /* BCM43xx_ILT_H_ */
3322 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
3323 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_leds.c 1970-01-01 01:00:00.000000000 +0100
3324 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_leds.c 2006-03-28 22:16:14.000000000 +0200
3325 @@ -0,0 +1,293 @@
3326 +/*
3327 +
3328 + Broadcom BCM43xx wireless driver
3329 +
3330 + Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
3331 + Stefano Brivio <st3@riseup.net>
3332 + Michael Buesch <mbuesch@freenet.de>
3333 + Danny van Dyk <kugelfang@gentoo.org>
3334 + Andreas Jaggi <andreas.jaggi@waterwave.ch>
3335 +
3336 + This program is free software; you can redistribute it and/or modify
3337 + it under the terms of the GNU General Public License as published by
3338 + the Free Software Foundation; either version 2 of the License, or
3339 + (at your option) any later version.
3340 +
3341 + This program is distributed in the hope that it will be useful,
3342 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3343 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3344 + GNU General Public License for more details.
3345 +
3346 + You should have received a copy of the GNU General Public License
3347 + along with this program; see the file COPYING. If not, write to
3348 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
3349 + Boston, MA 02110-1301, USA.
3350 +
3351 +*/
3352 +
3353 +#include "bcm43xx_leds.h"
3354 +#include "bcm43xx.h"
3355 +
3356 +#include <asm/bitops.h>
3357 +
3358 +
3359 +static void bcm43xx_led_changestate(struct bcm43xx_led *led)
3360 +{
3361 + struct bcm43xx_private *bcm = led->bcm;
3362 + const int index = bcm43xx_led_index(led);
3363 + const u16 mask = (1 << index);
3364 + u16 ledctl;
3365 +
3366 + assert(index >= 0 && index < BCM43xx_NR_LEDS);
3367 + assert(led->blink_interval);
3368 + ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
3369 + ledctl = (ledctl & mask) ? (ledctl & ~mask) : (ledctl | mask);
3370 + bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
3371 +}
3372 +
3373 +static void bcm43xx_led_blink(unsigned long d)
3374 +{
3375 + struct bcm43xx_led *led = (struct bcm43xx_led *)d;
3376 + struct bcm43xx_private *bcm = led->bcm;
3377 + unsigned long flags;
3378 +
3379 + bcm43xx_lock_mmio(bcm, flags);
3380 + if (led->blink_interval) {
3381 + bcm43xx_led_changestate(led);
3382 + mod_timer(&led->blink_timer, jiffies + led->blink_interval);
3383 + }
3384 + bcm43xx_unlock_mmio(bcm, flags);
3385 +}
3386 +
3387 +static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
3388 + unsigned long interval)
3389 +{
3390 + if (led->blink_interval)
3391 + return;
3392 + led->blink_interval = interval;
3393 + bcm43xx_led_changestate(led);
3394 + led->blink_timer.expires = jiffies + interval;
3395 + add_timer(&led->blink_timer);
3396 +}
3397 +
3398 +static void bcm43xx_led_blink_stop(struct bcm43xx_led *led, int sync)
3399 +{
3400 + struct bcm43xx_private *bcm = led->bcm;
3401 + const int index = bcm43xx_led_index(led);
3402 + u16 ledctl;
3403 +
3404 + if (!led->blink_interval)
3405 + return;
3406 + if (unlikely(sync))
3407 + del_timer_sync(&led->blink_timer);
3408 + else
3409 + del_timer(&led->blink_timer);
3410 + led->blink_interval = 0;
3411 +
3412 + /* Make sure the LED is turned off. */
3413 + assert(index >= 0 && index < BCM43xx_NR_LEDS);
3414 + ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
3415 + if (led->activelow)
3416 + ledctl |= (1 << index);
3417 + else
3418 + ledctl &= ~(1 << index);
3419 + bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
3420 +}
3421 +
3422 +static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm,
3423 + struct bcm43xx_led *led,
3424 + int led_index)
3425 +{
3426 + /* This function is called, if the behaviour (and activelow)
3427 + * information for a LED is missing in the SPROM.
3428 + * We hardcode the behaviour values for various devices here.
3429 + * Note that the BCM43xx_LED_TEST_XXX behaviour values can
3430 + * be used to figure out which led is mapped to which index.
3431 + */
3432 +
3433 + switch (led_index) {
3434 + case 0:
3435 + led->behaviour = BCM43xx_LED_ACTIVITY;
3436 + if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
3437 + led->behaviour = BCM43xx_LED_RADIO_ALL;
3438 + break;
3439 + case 1:
3440 + led->behaviour = BCM43xx_LED_RADIO_B;
3441 + if (bcm->board_vendor == PCI_VENDOR_ID_ASUSTEK)
3442 + led->behaviour = BCM43xx_LED_ASSOC;
3443 + break;
3444 + case 2:
3445 + led->behaviour = BCM43xx_LED_RADIO_A;
3446 + break;
3447 + case 3:
3448 + led->behaviour = BCM43xx_LED_OFF;
3449 + break;
3450 + default:
3451 + assert(0);
3452 + }
3453 +}
3454 +
3455 +int bcm43xx_leds_init(struct bcm43xx_private *bcm)
3456 +{
3457 + struct bcm43xx_led *led;
3458 + u8 sprom[4];
3459 + int i;
3460 +
3461 + sprom[0] = bcm->sprom.wl0gpio0;
3462 + sprom[1] = bcm->sprom.wl0gpio1;
3463 + sprom[2] = bcm->sprom.wl0gpio2;
3464 + sprom[3] = bcm->sprom.wl0gpio3;
3465 +
3466 + for (i = 0; i < BCM43xx_NR_LEDS; i++) {
3467 + led = &(bcm->leds[i]);
3468 + led->bcm = bcm;
3469 + setup_timer(&led->blink_timer,
3470 + bcm43xx_led_blink,
3471 + (unsigned long)led);
3472 +
3473 + if (sprom[i] == 0xFF) {
3474 + bcm43xx_led_init_hardcoded(bcm, led, i);
3475 + } else {
3476 + led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR;
3477 + led->activelow = !!(sprom[i] & BCM43xx_LED_ACTIVELOW);
3478 + }
3479 + }
3480 +
3481 + return 0;
3482 +}
3483 +
3484 +void bcm43xx_leds_exit(struct bcm43xx_private *bcm)
3485 +{
3486 + struct bcm43xx_led *led;
3487 + int i;
3488 +
3489 + for (i = 0; i < BCM43xx_NR_LEDS; i++) {
3490 + led = &(bcm->leds[i]);
3491 + bcm43xx_led_blink_stop(led, 1);
3492 + }
3493 + bcm43xx_leds_switch_all(bcm, 0);
3494 +}
3495 +
3496 +void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
3497 +{
3498 + struct bcm43xx_led *led;
3499 + struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
3500 + struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3501 + const int transferring = (jiffies - bcm->stats.last_tx) < BCM43xx_LED_XFER_THRES;
3502 + int i, turn_on;
3503 + unsigned long interval = 0;
3504 + u16 ledctl;
3505 +
3506 + ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
3507 + for (i = 0; i < BCM43xx_NR_LEDS; i++) {
3508 + led = &(bcm->leds[i]);
3509 +
3510 + turn_on = 0;
3511 + switch (led->behaviour) {
3512 + case BCM43xx_LED_INACTIVE:
3513 + continue;
3514 + case BCM43xx_LED_OFF:
3515 + break;
3516 + case BCM43xx_LED_ON:
3517 + turn_on = 1;
3518 + break;
3519 + case BCM43xx_LED_ACTIVITY:
3520 + turn_on = activity;
3521 + break;
3522 + case BCM43xx_LED_RADIO_ALL:
3523 + turn_on = radio->enabled;
3524 + break;
3525 + case BCM43xx_LED_RADIO_A:
3526 + turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A);
3527 + break;
3528 + case BCM43xx_LED_RADIO_B:
3529 + turn_on = (radio->enabled &&
3530 + (phy->type == BCM43xx_PHYTYPE_B ||
3531 + phy->type == BCM43xx_PHYTYPE_G));
3532 + break;
3533 + case BCM43xx_LED_MODE_BG:
3534 + if (phy->type == BCM43xx_PHYTYPE_G &&
3535 + 1/*FIXME: using G rates.*/)
3536 + turn_on = 1;
3537 + break;
3538 + case BCM43xx_LED_TRANSFER:
3539 + if (transferring)
3540 + bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM);
3541 + else
3542 + bcm43xx_led_blink_stop(led, 0);
3543 + continue;
3544 + case BCM43xx_LED_APTRANSFER:
3545 + if (bcm->iw_mode == IW_MODE_MASTER) {
3546 + if (transferring) {
3547 + interval = BCM43xx_LEDBLINK_FAST;
3548 + turn_on = 1;
3549 + }
3550 + } else {
3551 + turn_on = 1;
3552 + if (0/*TODO: not assoc*/)
3553 + interval = BCM43xx_LEDBLINK_SLOW;
3554 + else if (transferring)
3555 + interval = BCM43xx_LEDBLINK_FAST;
3556 + else
3557 + turn_on = 0;
3558 + }
3559 + if (turn_on)
3560 + bcm43xx_led_blink_start(led, interval);
3561 + else
3562 + bcm43xx_led_blink_stop(led, 0);
3563 + continue;
3564 + case BCM43xx_LED_WEIRD:
3565 + //TODO
3566 + break;
3567 + case BCM43xx_LED_ASSOC:
3568 + if (1/*bcm->softmac->associated*/)
3569 + turn_on = 1;
3570 + break;
3571 +#ifdef CONFIG_BCM43XX_DEBUG
3572 + case BCM43xx_LED_TEST_BLINKSLOW:
3573 + bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_SLOW);
3574 + continue;
3575 + case BCM43xx_LED_TEST_BLINKMEDIUM:
3576 + bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM);
3577 + continue;
3578 + case BCM43xx_LED_TEST_BLINKFAST:
3579 + bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_FAST);
3580 + continue;
3581 +#endif /* CONFIG_BCM43XX_DEBUG */
3582 + default:
3583 + assert(0);
3584 + };
3585 +
3586 + if (led->activelow)
3587 + turn_on = !turn_on;
3588 + if (turn_on)
3589 + ledctl |= (1 << i);
3590 + else
3591 + ledctl &= ~(1 << i);
3592 + }
3593 + bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
3594 +}
3595 +
3596 +void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
3597 +{
3598 + struct bcm43xx_led *led;
3599 + u16 ledctl;
3600 + int i;
3601 + int bit_on;
3602 +
3603 + ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
3604 + for (i = 0; i < BCM43xx_NR_LEDS; i++) {
3605 + led = &(bcm->leds[i]);
3606 + if (led->behaviour == BCM43xx_LED_INACTIVE)
3607 + continue;
3608 + if (on)
3609 + bit_on = led->activelow ? 0 : 1;
3610 + else
3611 + bit_on = led->activelow ? 1 : 0;
3612 + if (bit_on)
3613 + ledctl |= (1 << i);
3614 + else
3615 + ledctl &= ~(1 << i);
3616 + }
3617 + bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
3618 +}
3619 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_leds.h linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_leds.h
3620 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_leds.h 1970-01-01 01:00:00.000000000 +0100
3621 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_leds.h 2006-03-28 22:16:14.000000000 +0200
3622 @@ -0,0 +1,56 @@
3623 +#ifndef BCM43xx_LEDS_H_
3624 +#define BCM43xx_LEDS_H_
3625 +
3626 +#include <linux/types.h>
3627 +#include <linux/timer.h>
3628 +
3629 +
3630 +struct bcm43xx_led {
3631 + u8 behaviour:7;
3632 + u8 activelow:1;
3633 +
3634 + struct bcm43xx_private *bcm;
3635 + struct timer_list blink_timer;
3636 + unsigned long blink_interval;
3637 +};
3638 +#define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds))
3639 +
3640 +/* Delay between state changes when blinking in jiffies */
3641 +#define BCM43xx_LEDBLINK_SLOW (HZ / 1)
3642 +#define BCM43xx_LEDBLINK_MEDIUM (HZ / 4)
3643 +#define BCM43xx_LEDBLINK_FAST (HZ / 8)
3644 +
3645 +#define BCM43xx_LED_XFER_THRES (HZ / 100)
3646 +
3647 +#define BCM43xx_LED_BEHAVIOUR 0x7F
3648 +#define BCM43xx_LED_ACTIVELOW 0x80
3649 +enum { /* LED behaviour values */
3650 + BCM43xx_LED_OFF,
3651 + BCM43xx_LED_ON,
3652 + BCM43xx_LED_ACTIVITY,
3653 + BCM43xx_LED_RADIO_ALL,
3654 + BCM43xx_LED_RADIO_A,
3655 + BCM43xx_LED_RADIO_B,
3656 + BCM43xx_LED_MODE_BG,
3657 + BCM43xx_LED_TRANSFER,
3658 + BCM43xx_LED_APTRANSFER,
3659 + BCM43xx_LED_WEIRD,//FIXME
3660 + BCM43xx_LED_ASSOC,
3661 + BCM43xx_LED_INACTIVE,
3662 +
3663 + /* Behaviour values for testing.
3664 + * With these values it is easier to figure out
3665 + * the real behaviour of leds, in case the SPROM
3666 + * is missing information.
3667 + */
3668 + BCM43xx_LED_TEST_BLINKSLOW,
3669 + BCM43xx_LED_TEST_BLINKMEDIUM,
3670 + BCM43xx_LED_TEST_BLINKFAST,
3671 +};
3672 +
3673 +int bcm43xx_leds_init(struct bcm43xx_private *bcm);
3674 +void bcm43xx_leds_exit(struct bcm43xx_private *bcm);
3675 +void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity);
3676 +void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on);
3677 +
3678 +#endif /* BCM43xx_LEDS_H_ */
3679 diff -Nur linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c
3680 --- linux-2.6.16/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c 1970-01-01 01:00:00.000000000 +0100
3681 +++ linux-2.6.16-bcm43xx/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c 2006-03-28 22:16:14.000000000 +0200
3682 @@ -0,0 +1,4491 @@
3683 +/*
3684 +
3685 + Broadcom BCM43xx wireless driver
3686 +
3687 + Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
3688 + Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
3689 + Copyright (c) 2005, 2006 Michael Buesch <mbuesch@freenet.de>
3690 + Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
3691 + Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
3692 +
3693 + Some parts of the code in this file are derived from the ipw2200
3694 + driver Copyright(c) 2003 - 2004 Intel Corporation.
3695 +
3696 + This program is free software; you can redistribute it and/or modify
3697 + it under the terms of the GNU General Public License as published by
3698 + the Free Software Foundation; either version 2 of the License, or
3699 + (at your option) any later version.
3700 +
3701 + This program is distributed in the hope that it will be useful,
3702 + but WITHOUT ANY WARRANTY; without even the implied warranty of
3703 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3704 + GNU General Public License for more details.
3705 +
3706 + You should have received a copy of the GNU General Public License
3707 + along with this program; see the file COPYING. If not, write to
3708 + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
3709 + Boston, MA 02110-1301, USA.
3710 +
3711 +*/
3712 +
3713 +#include <linux/delay.h>
3714 +#include <linux/init.h>
3715 +#include <linux/moduleparam.h>
3716 +#include <linux/if_arp.h>
3717 +#include <linux/etherdevice.h>
3718 +#include <linux/version.h>
3719 +#include <linux/firmware.h>
3720 +#include <linux/wireless.h>
3721 +#include <linux/workqueue.h>
3722 +#include <linux/skbuff.h>
3723 +#include <linux/dma-mapping.h>
3724 +#include <net/iw_handler.h>
3725 +
3726 +#include "bcm43xx.h"
3727 +#include "bcm43xx_main.h"
3728 +#include "bcm43xx_debugfs.h"
3729 +#include "bcm43xx_radio.h"
3730 +#include "bcm43xx_phy.h"
3731 +#include "bcm43xx_dma.h"
3732 +#include "bcm43xx_pio.h"
3733 +#include "bcm43xx_power.h"
3734 +#include "bcm43xx_sysfs.h"
3735 +#include "bcm43xx_ethtool.h"
3736 +#include "bcm43xx_xmit.h"
3737 +
3738 +
3739 +MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver");
3740 +MODULE_AUTHOR("Martin Langer");
3741 +MODULE_AUTHOR("Stefano Brivio");
3742 +MODULE_AUTHOR("Michael Buesch");
3743 +MODULE_LICENSE("GPL");
3744 +
3745 +#ifdef CONFIG_BCM947XX
3746 +extern char *nvram_get(char *name);
3747 +#endif
3748 +
3749 +#if defined(CONFIG_BCM43XX_D80211_DMA) && defined(CONFIG_BCM43XX_D80211_PIO)
3750 +static int modparam_pio;
3751 +module_param_named(pio, modparam_pio, int, 0444);
3752 +MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
3753 +#elif defined(CONFIG_BCM43XX_D80211_DMA)
3754 +# define modparam_pio 0
3755 +#elif defined(CONFIG_BCM43XX_D80211_PIO)
3756 +# define modparam_pio 1
3757 +#endif
3758 +
3759 +static int modparam_bad_frames_preempt;
3760 +module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
3761 +MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames Preemption");
3762 +
3763 +static int modparam_short_retry = BCM43xx_DEFAULT_SHORT_RETRY_LIMIT;
3764 +module_param_named(short_retry, modparam_short_retry, int, 0444);
3765 +MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)");
3766 +
3767 +static int modparam_long_retry = BCM43xx_DEFAULT_LONG_RETRY_LIMIT;
3768 +module_param_named(long_retry, modparam_long_retry, int, 0444);
3769 +MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)");
3770 +
3771 +static int modparam_noleds;
3772 +module_param_named(noleds, modparam_noleds, int, 0444);
3773 +MODULE_PARM_DESC(noleds, "Turn off all LED activity");
3774 +
3775 +#ifdef CONFIG_BCM43XX_D80211_DEBUG
3776 +static char modparam_fwpostfix[64];
3777 +module_param_string(fwpostfix, modparam_fwpostfix, 64, 0444);
3778 +MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging.");
3779 +#else
3780 +# define modparam_fwpostfix ""
3781 +#endif /* CONFIG_BCM43XX_D80211_DEBUG*/
3782 +
3783 +
3784 +/* If you want to debug with just a single device, enable this,
3785 + * where the string is the pci device ID (as given by the kernel's
3786 + * pci_name function) of the device to be used.
3787 + */
3788 +//#define DEBUG_SINGLE_DEVICE_ONLY "0001:11:00.0"
3789 +
3790 +/* If you want to enable printing of each MMIO access, enable this. */
3791 +//#define DEBUG_ENABLE_MMIO_PRINT
3792 +
3793 +/* If you want to enable printing of MMIO access within
3794 + * ucode/pcm upload, initvals write, enable this.
3795 + */
3796 +//#define DEBUG_ENABLE_UCODE_MMIO_PRINT
3797 +
3798 +/* If you want to enable printing of PCI Config Space access, enable this */
3799 +//#define DEBUG_ENABLE_PCILOG
3800 +
3801 +
3802 +/* Detailed list maintained at:
3803 + * http://openfacts.berlios.de/index-en.phtml?title=Bcm43xxDevices
3804 + */
3805 +static struct pci_device_id bcm43xx_pci_tbl[] = {
3806 + /* Broadcom 4303 802.11b */
3807 + { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
3808 + /* Broadcom 4307 802.11b */
3809 + { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
3810 + /* Broadcom 4318 802.11b/g */
3811 + { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
3812 + /* Broadcom 4306 802.11b/g */
3813 + { PCI_VENDOR_ID_BROADCOM, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
3814 + /* Broadcom 4306 802.11a */
3815 +// { PCI_VENDOR_ID_BROADCOM, 0x4321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
3816 + /* Broadcom 4309 802.11a/b/g */
3817 + { PCI_VENDOR_ID_BROADCOM, 0x4324, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
3818 + /* Broadcom 43XG 802.11b/g */
3819 + { PCI_VENDOR_ID_BROADCOM, 0x4325, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
3820 +#ifdef CONFIG_BCM947XX
3821 + /* SB bus on BCM947xx */
3822 + { PCI_VENDOR_ID_BROADCOM, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
3823 +#endif
3824 + { 0 },
3825 +};
3826 +MODULE_DEVICE_TABLE(pci, bcm43xx_pci_tbl);
3827 +
3828 +
3829 +static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val)
3830 +{
3831 + u32 status;
3832 +
3833 + status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
3834 + if (!(status & BCM43xx_SBF_XFER_REG_BYTESWAP))
3835 + val = swab32(val);
3836 +
3837 + bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset);
3838 + mmiowb();
3839 + bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val);
3840 +}
3841 +
3842 +static inline
3843 +void bcm43xx_shm_control_word(struct bcm43xx_private *bcm,
3844 + u16 routing, u16 offset)
3845 +{
3846 + u32 control;
3847 +
3848 + /* "offset" is the WORD offset. */
3849 +
3850 + control = routing;
3851 + control <<= 16;
3852 + control |= offset;
3853 + bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_CONTROL, control);
3854 +}
3855 +
3856 +u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm,
3857 + u16 routing, u16 offset)
3858 +{
3859 + u32 ret;
3860 +
3861 + if (routing == BCM43xx_SHM_SHARED) {
3862 + if (offset & 0x0003) {
3863 + /* Unaligned access */
3864 + bcm43xx_shm_control_word(bcm, routing, offset >> 2);
3865 + ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
3866 + ret <<= 16;
3867 + bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
3868 + ret |= bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
3869 +
3870 + return ret;
3871 + }
3872 + offset >>= 2;
3873 + }
3874 + bcm43xx_shm_control_word(bcm, routing, offset);
3875 + ret = bcm43xx_read32(bcm, BCM43xx_MMIO_SHM_DATA