提交 2079fcdc 编写于 作者: A Adrian Bunk 提交者: John W. Linville

the scheduled bcm43xx removal

Signed-off-by: NAdrian Bunk <bunk@kernel.org>
Cc: <Larry.Finger@lwfinger.net>
Cc: <stefano.brivio@polimi.it>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 affe0a02
...@@ -230,15 +230,6 @@ Who: Jean Delvare <khali@linux-fr.org> ...@@ -230,15 +230,6 @@ Who: Jean Delvare <khali@linux-fr.org>
--------------------------- ---------------------------
What: bcm43xx wireless network driver
When: 2.6.26
Files: drivers/net/wireless/bcm43xx
Why: This driver's functionality has been replaced by the
mac80211-based b43 and b43legacy drivers.
Who: John W. Linville <linville@tuxdriver.com>
---------------------------
What: ieee80211 softmac wireless networking component What: ieee80211 softmac wireless networking component
When: 2.6.26 (or after removal of bcm43xx and port of zd1211rw to mac80211) When: 2.6.26 (or after removal of bcm43xx and port of zd1211rw to mac80211)
Files: net/ieee80211/softmac Files: net/ieee80211/softmac
......
...@@ -80,7 +80,7 @@ once you enable the radio, will depend on your hardware and driver combination. ...@@ -80,7 +80,7 @@ once you enable the radio, will depend on your hardware and driver combination.
e.g. With the BCM4318 on the Acer Aspire 5020 series: e.g. With the BCM4318 on the Acer Aspire 5020 series:
ndiswrapper: Light blinks on when transmitting ndiswrapper: Light blinks on when transmitting
bcm43xx/b43: Solid light, blinks off when transmitting b43: Solid light, blinks off when transmitting
Wireless radio control is unconditionally enabled - all Acer laptops that support Wireless radio control is unconditionally enabled - all Acer laptops that support
acer-wmi come with built-in wireless. However, should you feel so inclined to acer-wmi come with built-in wireless. However, should you feel so inclined to
......
BCM43xx Linux Driver Project
============================
Introduction
------------
Many of the wireless devices found in modern notebook computers are
based on the wireless chips produced by Broadcom. These devices have
been a problem for Linux users as there is no open-source driver
available. In addition, Broadcom has not released specifications
for the device, and driver availability has been limited to the
binary-only form used in the GPL versions of AP hardware such as the
Linksys WRT54G, and the Windows and OS X drivers. Before this project
began, the only way to use these devices were to use the Windows or
OS X drivers with either the Linuxant or ndiswrapper modules. There
is a strong penalty if this method is used as loading the binary-only
module "taints" the kernel, and no kernel developer will help diagnose
any kernel problems.
Development
-----------
This driver has been developed using
a clean-room technique that is described at
http://bcm-specs.sipsolutions.net/ReverseEngineeringProcess. For legal
reasons, none of the clean-room crew works on the on the Linux driver,
and none of the Linux developers sees anything but the specifications,
which are the ultimate product of the reverse-engineering group.
Software
--------
Since the release of the 2.6.17 kernel, the bcm43xx driver has been
distributed with the kernel source, and is prebuilt in most, if not
all, distributions. There is, however, additional software that is
required. The firmware used by the chip is the intellectual property
of Broadcom and they have not given the bcm43xx team redistribution
rights to this firmware. Since we cannot legally redistribute
the firmware we cannot include it with the driver. Furthermore, it
cannot be placed in the downloadable archives of any distributing
organization; therefore, the user is responsible for obtaining the
firmware and placing it in the appropriate location so that the driver
can find it when initializing.
To help with this process, the bcm43xx developers provide a separate
program named bcm43xx-fwcutter to "cut" the firmware out of a
Windows or OS X driver and write the extracted files to the proper
location. This program is usually provided with the distribution;
however, it may be downloaded from
http://developer.berlios.de/project/showfiles.php?group_id=4547
The firmware is available in two versions. V3 firmware is used with
the in-kernel bcm43xx driver that uses a software MAC layer called
SoftMAC, and will have a microcode revision of 0x127 or smaller. The
V4 firmware is used by an out-of-kernel driver employing a variation of
the Devicescape MAC layer known as d80211. Once bcm43xx-d80211 reaches
a satisfactory level of development, it will replace bcm43xx-softmac
in the kernel as it is much more flexible and powerful.
A source for the latest V3 firmware is
http://downloads.openwrt.org/sources/wl_apsta-3.130.20.0.o
Once this file is downloaded, the command
'bcm43xx-fwcutter -w <dir> <filename>'
will extract the microcode and write it to directory
<dir>. The correct directory will depend on your distribution;
however, most use '/lib/firmware'. Once this step is completed,
the bcm3xx driver should load when the system is booted. To see
any messages relating to the driver, issue the command 'dmesg |
grep bcm43xx' from a terminal window. If there are any problems,
please send that output to Bcm43xx-dev@lists.berlios.de.
Although the driver has been in-kernel since 2.6.17, the earliest
version is quite limited in its capability. Patches that include
all features of later versions are available for the stable kernel
versions from 2.6.18. These will be needed if you use a BCM4318,
or a PCI Express version (BCM4311 and BCM4312). In addition, if you
have an early BCM4306 and more than 1 GB RAM, your kernel will need
to be patched. These patches, which are being updated regularly,
are available at ftp://lwfinger.dynalias.org/patches. Look for
combined_2.6.YY.patch. Of course you will need kernel source downloaded
from kernel.org, or the source from your distribution.
If you build your own kernel, please enable CONFIG_BCM43XX_DEBUG
and CONFIG_IEEE80211_SOFTMAC_DEBUG. The log information provided is
essential for solving any problems.
...@@ -825,15 +825,6 @@ L: linux-wireless@vger.kernel.org ...@@ -825,15 +825,6 @@ L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/en/users/Drivers/b43 W: http://linuxwireless.org/en/users/Drivers/b43
S: Maintained S: Maintained
BCM43XX WIRELESS DRIVER (SOFTMAC BASED VERSION)
P: Larry Finger
M: Larry.Finger@lwfinger.net
P: Stefano Brivio
M: stefano.brivio@polimi.it
L: linux-wireless@vger.kernel.org
W: http://bcm43xx.berlios.de/
S: Obsolete
BEFS FILE SYSTEM BEFS FILE SYSTEM
P: Sergey S. Kostyliov P: Sergey S. Kostyliov
M: rathamahata@php4.ru M: rathamahata@php4.ru
......
...@@ -741,7 +741,6 @@ config P54_PCI ...@@ -741,7 +741,6 @@ config P54_PCI
source "drivers/net/wireless/ath5k/Kconfig" source "drivers/net/wireless/ath5k/Kconfig"
source "drivers/net/wireless/iwlwifi/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig"
source "drivers/net/wireless/hostap/Kconfig" source "drivers/net/wireless/hostap/Kconfig"
source "drivers/net/wireless/bcm43xx/Kconfig"
source "drivers/net/wireless/b43/Kconfig" source "drivers/net/wireless/b43/Kconfig"
source "drivers/net/wireless/b43legacy/Kconfig" source "drivers/net/wireless/b43legacy/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig" source "drivers/net/wireless/zd1211rw/Kconfig"
......
...@@ -35,7 +35,6 @@ obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o ...@@ -35,7 +35,6 @@ obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o
obj-$(CONFIG_PRISM54) += prism54/ obj-$(CONFIG_PRISM54) += prism54/
obj-$(CONFIG_HOSTAP) += hostap/ obj-$(CONFIG_HOSTAP) += hostap/
obj-$(CONFIG_BCM43XX) += bcm43xx/
obj-$(CONFIG_B43) += b43/ obj-$(CONFIG_B43) += b43/
obj-$(CONFIG_B43LEGACY) += b43legacy/ obj-$(CONFIG_B43LEGACY) += b43legacy/
obj-$(CONFIG_ZD1211RW) += zd1211rw/ obj-$(CONFIG_ZD1211RW) += zd1211rw/
......
config BCM43XX
tristate "Broadcom BCM43xx wireless support (DEPRECATED)"
depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && (!SSB_B43_PCI_BRIDGE || SSB != y) && EXPERIMENTAL
select WIRELESS_EXT
select FW_LOADER
select HW_RANDOM
---help---
This is an experimental driver for the Broadcom 43xx wireless
chip, found in the Apple Airport Extreme and various other
devices. This driver is deprecated and will be removed
from the kernel in the near future. It has been replaced
by the b43 and b43legacy drivers.
config BCM43XX_DEBUG
bool "Broadcom BCM43xx debugging (RECOMMENDED)"
depends on BCM43XX
default y
---help---
Broadcom 43xx debugging messages.
Say Y, because the driver is still very experimental and
this will help you get it running.
config BCM43XX_DMA
bool
depends on BCM43XX
config BCM43XX_PIO
bool
depends on BCM43XX
choice
prompt "BCM43xx data transfer mode"
depends on BCM43XX
default BCM43XX_DMA_AND_PIO_MODE
config BCM43XX_DMA_AND_PIO_MODE
bool "DMA + PIO"
select BCM43XX_DMA
select BCM43XX_PIO
---help---
Include both, Direct Memory Access (DMA) and Programmed I/O (PIO)
data transfer modes.
The actually used mode is selectable through the module
parameter "pio". If the module parameter is pio=0, DMA is used.
Otherwise PIO is used. DMA is default.
If unsure, choose this option.
config BCM43XX_DMA_MODE
bool "DMA (Direct Memory Access) only"
select BCM43XX_DMA
---help---
Only include Direct Memory Access (DMA).
This reduces the size of the driver module, by omitting the PIO code.
config BCM43XX_PIO_MODE
bool "PIO (Programmed I/O) only"
select BCM43XX_PIO
---help---
Only include Programmed I/O (PIO).
This reduces the size of the driver module, by omitting the DMA code.
Please note that PIO transfers are slow (compared to DMA).
Also note that not all devices of the 43xx series support PIO.
The 4306 (Apple Airport Extreme and others) supports PIO, while
the 4318 is known to _not_ support PIO.
Only use PIO, if DMA does not work for you.
endchoice
obj-$(CONFIG_BCM43XX) += bcm43xx.o
bcm43xx-obj-$(CONFIG_BCM43XX_DEBUG) += bcm43xx_debugfs.o
bcm43xx-obj-$(CONFIG_BCM43XX_DMA) += bcm43xx_dma.o
bcm43xx-obj-$(CONFIG_BCM43XX_PIO) += bcm43xx_pio.o
bcm43xx-objs := bcm43xx_main.o bcm43xx_ilt.o \
bcm43xx_radio.o bcm43xx_phy.o \
bcm43xx_power.o bcm43xx_wx.o \
bcm43xx_leds.o bcm43xx_ethtool.o \
bcm43xx_xmit.o bcm43xx_sysfs.o \
$(bcm43xx-obj-y)
此差异已折叠。
/*
Broadcom BCM43xx wireless driver
debugfs driver debugging code
Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <linux/fs.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <asm/io.h>
#include "bcm43xx.h"
#include "bcm43xx_main.h"
#include "bcm43xx_debugfs.h"
#include "bcm43xx_dma.h"
#include "bcm43xx_pio.h"
#include "bcm43xx_xmit.h"
#define REALLY_BIG_BUFFER_SIZE (1024*256)
static struct bcm43xx_debugfs fs;
static char really_big_buffer[REALLY_BIG_BUFFER_SIZE];
static DECLARE_MUTEX(big_buffer_sem);
static ssize_t write_file_dummy(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return count;
}
static int open_file_generic(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return 0;
}
#define fappend(fmt, x...) pos += snprintf(buf + pos, len - pos, fmt , ##x)
static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
const size_t len = REALLY_BIG_BUFFER_SIZE;
struct bcm43xx_private *bcm = file->private_data;
char *buf = really_big_buffer;
size_t pos = 0;
ssize_t res;
struct net_device *net_dev;
struct pci_dev *pci_dev;
unsigned long flags;
u16 tmp16;
int i;
down(&big_buffer_sem);
mutex_lock(&bcm->mutex);
spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
fappend("Board not initialized.\n");
goto out;
}
net_dev = bcm->net_dev;
pci_dev = bcm->pci_dev;
/* This is where the information is written to the "devinfo" file */
fappend("*** %s devinfo ***\n", net_dev->name);
fappend("vendor: 0x%04x device: 0x%04x\n",
pci_dev->vendor, pci_dev->device);
fappend("subsystem_vendor: 0x%04x subsystem_device: 0x%04x\n",
pci_dev->subsystem_vendor, pci_dev->subsystem_device);
fappend("IRQ: %d\n", bcm->irq);
fappend("mmio_addr: 0x%p\n", bcm->mmio_addr);
fappend("chip_id: 0x%04x chip_rev: 0x%02x\n", bcm->chip_id, bcm->chip_rev);
if ((bcm->core_80211[0].rev >= 3) && (bcm43xx_read32(bcm, 0x0158) & (1 << 16)))
fappend("Radio disabled by hardware!\n");
if ((bcm->core_80211[0].rev < 3) && !(bcm43xx_read16(bcm, 0x049A) & (1 << 4)))
fappend("Radio disabled by hardware!\n");
fappend("board_vendor: 0x%04x board_type: 0x%04x\n", bcm->board_vendor,
bcm->board_type);
fappend("\nCores:\n");
#define fappend_core(name, info) fappend("core \"" name "\" %s, %s, id: 0x%04x, " \
"rev: 0x%02x, index: 0x%02x\n", \
(info).available \
? "available" : "nonavailable", \
(info).enabled \
? "enabled" : "disabled", \
(info).id, (info).rev, (info).index)
fappend_core("CHIPCOMMON", bcm->core_chipcommon);
fappend_core("PCI", bcm->core_pci);
fappend_core("first 80211", bcm->core_80211[0]);
fappend_core("second 80211", bcm->core_80211[1]);
#undef fappend_core
tmp16 = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
fappend("LEDs: ");
for (i = 0; i < BCM43xx_NR_LEDS; i++)
fappend("%d ", !!(tmp16 & (1 << i)));
fappend("\n");
out:
spin_unlock_irqrestore(&bcm->irq_lock, flags);
mutex_unlock(&bcm->mutex);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
up(&big_buffer_sem);
return res;
}
static ssize_t drvinfo_read_file(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
const size_t len = REALLY_BIG_BUFFER_SIZE;
char *buf = really_big_buffer;
size_t pos = 0;
ssize_t res;
down(&big_buffer_sem);
/* This is where the information is written to the "driver" file */
fappend(KBUILD_MODNAME " driver\n");
fappend("Compiled at: %s %s\n", __DATE__, __TIME__);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
up(&big_buffer_sem);
return res;
}
static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
const size_t len = REALLY_BIG_BUFFER_SIZE;
struct bcm43xx_private *bcm = file->private_data;
char *buf = really_big_buffer;
size_t pos = 0;
ssize_t res;
unsigned long flags;
down(&big_buffer_sem);
mutex_lock(&bcm->mutex);
spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
fappend("Board not initialized.\n");
goto out;
}
/* This is where the information is written to the "sprom_dump" file */
fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
out:
spin_unlock_irqrestore(&bcm->irq_lock, flags);
mutex_unlock(&bcm->mutex);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
up(&big_buffer_sem);
return res;
}
static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
const size_t len = REALLY_BIG_BUFFER_SIZE;
struct bcm43xx_private *bcm = file->private_data;
char *buf = really_big_buffer;
size_t pos = 0;
ssize_t res;
unsigned long flags;
u64 tsf;
down(&big_buffer_sem);
mutex_lock(&bcm->mutex);
spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
fappend("Board not initialized.\n");
goto out;
}
bcm43xx_tsf_read(bcm, &tsf);
fappend("0x%08x%08x\n",
(unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
(unsigned int)(tsf & 0xFFFFFFFFULL));
out:
spin_unlock_irqrestore(&bcm->irq_lock, flags);
mutex_unlock(&bcm->mutex);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
up(&big_buffer_sem);
return res;
}
static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct bcm43xx_private *bcm = file->private_data;
char *buf = really_big_buffer;
ssize_t buf_size;
ssize_t res;
unsigned long flags;
unsigned long long tsf;
buf_size = min(count, sizeof (really_big_buffer) - 1);
down(&big_buffer_sem);
if (copy_from_user(buf, user_buf, buf_size)) {
res = -EFAULT;
goto out_up;
}
mutex_lock(&bcm->mutex);
spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
res = -EFAULT;
goto out_unlock;
}
if (sscanf(buf, "%lli", &tsf) != 1) {
printk(KERN_INFO PFX "debugfs: invalid values for \"tsf\"\n");
res = -EINVAL;
goto out_unlock;
}
bcm43xx_tsf_write(bcm, tsf);
mmiowb();
res = buf_size;
out_unlock:
spin_unlock_irqrestore(&bcm->irq_lock, flags);
mutex_unlock(&bcm->mutex);
out_up:
up(&big_buffer_sem);
return res;
}
static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
const size_t len = REALLY_BIG_BUFFER_SIZE;
struct bcm43xx_private *bcm = file->private_data;
char *buf = really_big_buffer;
size_t pos = 0;
ssize_t res;
unsigned long flags;
struct bcm43xx_dfsentry *e;
struct bcm43xx_xmitstatus *status;
int i, cnt, j = 0;
down(&big_buffer_sem);
mutex_lock(&bcm->mutex);
spin_lock_irqsave(&bcm->irq_lock, flags);
fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
BCM43xx_NR_LOGGED_XMITSTATUS);
e = bcm->dfsentry;
if (e->xmitstatus_printing == 0) {
/* At the beginning, make a copy of all data to avoid
* concurrency, as this function is called multiple
* times for big logs. Without copying, the data might
* change between reads. This would result in total trash.
*/
e->xmitstatus_printing = 1;
e->saved_xmitstatus_ptr = e->xmitstatus_ptr;
e->saved_xmitstatus_cnt = e->xmitstatus_cnt;
memcpy(e->xmitstatus_print_buffer, e->xmitstatus_buffer,
BCM43xx_NR_LOGGED_XMITSTATUS * sizeof(*(e->xmitstatus_buffer)));
}
i = e->saved_xmitstatus_ptr - 1;
if (i < 0)
i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
cnt = e->saved_xmitstatus_cnt;
while (cnt) {
status = e->xmitstatus_print_buffer + i;
fappend("0x%02x: cookie: 0x%04x, flags: 0x%02x, "
"cnt1: 0x%02x, cnt2: 0x%02x, seq: 0x%04x, "
"unk: 0x%04x\n", j,
status->cookie, status->flags,
status->cnt1, status->cnt2, status->seq,
status->unknown);
j++;
cnt--;
i--;
if (i < 0)
i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
}
spin_unlock_irqrestore(&bcm->irq_lock, flags);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
spin_lock_irqsave(&bcm->irq_lock, flags);
if (*ppos == pos) {
/* Done. Drop the copied data. */
e->xmitstatus_printing = 0;
}
spin_unlock_irqrestore(&bcm->irq_lock, flags);
mutex_unlock(&bcm->mutex);
up(&big_buffer_sem);
return res;
}
static ssize_t restart_write_file(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct bcm43xx_private *bcm = file->private_data;
char *buf = really_big_buffer;
ssize_t buf_size;
ssize_t res;
unsigned long flags;
buf_size = min(count, sizeof (really_big_buffer) - 1);
down(&big_buffer_sem);
if (copy_from_user(buf, user_buf, buf_size)) {
res = -EFAULT;
goto out_up;
}
mutex_lock(&(bcm)->mutex);
spin_lock_irqsave(&(bcm)->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
res = -EFAULT;
goto out_unlock;
}
if (count > 0 && buf[0] == '1') {
bcm43xx_controller_restart(bcm, "manually restarted");
res = count;
} else
res = -EINVAL;
out_unlock:
spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
mutex_unlock(&(bcm)->mutex);
out_up:
up(&big_buffer_sem);
return res;
}
#undef fappend
static const struct file_operations devinfo_fops = {
.read = devinfo_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
static const struct file_operations spromdump_fops = {
.read = spromdump_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
static const struct file_operations drvinfo_fops = {
.read = drvinfo_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
static const struct file_operations tsf_fops = {
.read = tsf_read_file,
.write = tsf_write_file,
.open = open_file_generic,
};
static const struct file_operations txstat_fops = {
.read = txstat_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
static const struct file_operations restart_fops = {
.write = restart_write_file,
.open = open_file_generic,
};
void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
{
struct bcm43xx_dfsentry *e;
char devdir[IFNAMSIZ];
assert(bcm);
e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e) {
printk(KERN_ERR PFX "out of memory\n");
return;
}
e->bcm = bcm;
e->xmitstatus_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
* sizeof(*(e->xmitstatus_buffer)),
GFP_KERNEL);
if (!e->xmitstatus_buffer) {
printk(KERN_ERR PFX "out of memory\n");
kfree(e);
return;
}
e->xmitstatus_print_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
* sizeof(*(e->xmitstatus_buffer)),
GFP_KERNEL);
if (!e->xmitstatus_print_buffer) {
printk(KERN_ERR PFX "out of memory\n");
kfree(e);
return;
}
bcm->dfsentry = e;
strncpy(devdir, bcm->net_dev->name, ARRAY_SIZE(devdir));
e->subdir = debugfs_create_dir(devdir, fs.root);
e->dentry_devinfo = debugfs_create_file("devinfo", 0444, e->subdir,
bcm, &devinfo_fops);
if (!e->dentry_devinfo)
printk(KERN_ERR PFX "debugfs: creating \"devinfo\" for \"%s\" failed!\n", devdir);
e->dentry_spromdump = debugfs_create_file("sprom_dump", 0444, e->subdir,
bcm, &spromdump_fops);
if (!e->dentry_spromdump)
printk(KERN_ERR PFX "debugfs: creating \"sprom_dump\" for \"%s\" failed!\n", devdir);
e->dentry_tsf = debugfs_create_file("tsf", 0666, e->subdir,
bcm, &tsf_fops);
if (!e->dentry_tsf)
printk(KERN_ERR PFX "debugfs: creating \"tsf\" for \"%s\" failed!\n", devdir);
e->dentry_txstat = debugfs_create_file("tx_status", 0444, e->subdir,
bcm, &txstat_fops);
if (!e->dentry_txstat)
printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir);
e->dentry_restart = debugfs_create_file("restart", 0222, e->subdir,
bcm, &restart_fops);
if (!e->dentry_restart)
printk(KERN_ERR PFX "debugfs: creating \"restart\" for \"%s\" failed!\n", devdir);
}
void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
{
struct bcm43xx_dfsentry *e;
if (!bcm)
return;
e = bcm->dfsentry;
assert(e);
debugfs_remove(e->dentry_spromdump);
debugfs_remove(e->dentry_devinfo);
debugfs_remove(e->dentry_tsf);
debugfs_remove(e->dentry_txstat);
debugfs_remove(e->dentry_restart);
debugfs_remove(e->subdir);
kfree(e->xmitstatus_buffer);
kfree(e->xmitstatus_print_buffer);
kfree(e);
}
void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status)
{
struct bcm43xx_dfsentry *e;
struct bcm43xx_xmitstatus *savedstatus;
/* This is protected by bcm->_lock */
e = bcm->dfsentry;
assert(e);
savedstatus = e->xmitstatus_buffer + e->xmitstatus_ptr;
memcpy(savedstatus, status, sizeof(*status));
e->xmitstatus_ptr++;
if (e->xmitstatus_ptr >= BCM43xx_NR_LOGGED_XMITSTATUS)
e->xmitstatus_ptr = 0;
if (e->xmitstatus_cnt < BCM43xx_NR_LOGGED_XMITSTATUS)
e->xmitstatus_cnt++;
}
void bcm43xx_debugfs_init(void)
{
memset(&fs, 0, sizeof(fs));
fs.root = debugfs_create_dir(KBUILD_MODNAME, NULL);
if (!fs.root)
printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "\" subdir failed!\n");
fs.dentry_driverinfo = debugfs_create_file("driver", 0444, fs.root, NULL, &drvinfo_fops);
if (!fs.dentry_driverinfo)
printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "/driver\" failed!\n");
}
void bcm43xx_debugfs_exit(void)
{
debugfs_remove(fs.dentry_driverinfo);
debugfs_remove(fs.root);
}
void bcm43xx_printk_dump(const char *data,
size_t size,
const char *description)
{
size_t i;
char c;
printk(KERN_INFO PFX "Data dump (%s, %zd bytes):",
description, size);
for (i = 0; i < size; i++) {
c = data[i];
if (i % 8 == 0)
printk("\n" KERN_INFO PFX "0x%08zx: 0x%02x, ", i, c & 0xff);
else
printk("0x%02x, ", c & 0xff);
}
printk("\n");
}
void bcm43xx_printk_bitdump(const unsigned char *data,
size_t bytes, int msb_to_lsb,
const char *description)
{
size_t i;
int j;
const unsigned char *d;
printk(KERN_INFO PFX "*** Bitdump (%s, %zd bytes, %s) ***",
description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB");
for (i = 0; i < bytes; i++) {
d = data + i;
if (i % 8 == 0)
printk("\n" KERN_INFO PFX "0x%08zx: ", i);
if (msb_to_lsb) {
for (j = 7; j >= 0; j--) {
if (*d & (1 << j))
printk("1");
else
printk("0");
}
} else {
for (j = 0; j < 8; j++) {
if (*d & (1 << j))
printk("1");
else
printk("0");
}
}
printk(" ");
}
printk("\n");
}
#ifndef BCM43xx_DEBUGFS_H_
#define BCM43xx_DEBUGFS_H_
struct bcm43xx_private;
struct bcm43xx_xmitstatus;
#ifdef CONFIG_BCM43XX_DEBUG
#include <linux/list.h>
#include <asm/semaphore.h>
struct dentry;
/* limited by the size of the "really_big_buffer" */
#define BCM43xx_NR_LOGGED_XMITSTATUS 100
struct bcm43xx_dfsentry {
struct dentry *subdir;
struct dentry *dentry_devinfo;
struct dentry *dentry_spromdump;
struct dentry *dentry_tsf;
struct dentry *dentry_txstat;
struct dentry *dentry_restart;
struct bcm43xx_private *bcm;
/* saved xmitstatus. */
struct bcm43xx_xmitstatus *xmitstatus_buffer;
int xmitstatus_ptr;
int xmitstatus_cnt;
/* We need a seperate buffer while printing to avoid
* concurrency issues. (New xmitstatus can arrive
* while we are printing).
*/
struct bcm43xx_xmitstatus *xmitstatus_print_buffer;
int saved_xmitstatus_ptr;
int saved_xmitstatus_cnt;
int xmitstatus_printing;
};
struct bcm43xx_debugfs {
struct dentry *root;
struct dentry *dentry_driverinfo;
};
void bcm43xx_debugfs_init(void);
void bcm43xx_debugfs_exit(void);
void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm);
void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm);
void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status);
/* Debug helper: Dump binary data through printk. */
void bcm43xx_printk_dump(const char *data,
size_t size,
const char *description);
/* Debug helper: Dump bitwise binary data through printk. */
void bcm43xx_printk_bitdump(const unsigned char *data,
size_t bytes, int msb_to_lsb,
const char *description);
#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) \
do { \
bcm43xx_printk_bitdump((const unsigned char *)(pointer), \
sizeof(*(pointer)), \
(msb_to_lsb), \
(description)); \
} while (0)
#else /* CONFIG_BCM43XX_DEBUG*/
static inline
void bcm43xx_debugfs_init(void) { }
static inline
void bcm43xx_debugfs_exit(void) { }
static inline
void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) { }
static inline
void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) { }
static inline
void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status) { }
static inline
void bcm43xx_printk_dump(const char *data,
size_t size,
const char *description)
{
}
static inline
void bcm43xx_printk_bitdump(const unsigned char *data,
size_t bytes, int msb_to_lsb,
const char *description)
{
}
#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) do { /* nothing */ } while (0)
#endif /* CONFIG_BCM43XX_DEBUG*/
/* Ugly helper macros to make incomplete code more verbose on runtime */
#ifdef TODO
# undef TODO
#endif
#define TODO() \
do { \
printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n", \
__FUNCTION__, __FILE__, __LINE__); \
} while (0)
#ifdef FIXME
# undef FIXME
#endif
#define FIXME() \
do { \
printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n", \
__FUNCTION__, __FILE__, __LINE__); \
} while (0)
#endif /* BCM43xx_DEBUGFS_H_ */
此差异已折叠。
#ifndef BCM43xx_DMA_H_
#define BCM43xx_DMA_H_
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/dma-mapping.h>
#include <linux/linkage.h>
#include <asm/atomic.h>
/* DMA-Interrupt reasons. */
#define BCM43xx_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \
| (1 << 14) | (1 << 15))
#define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13)
#define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
/*** 32-bit DMA Engine. ***/
/* 32-bit DMA controller registers. */
#define BCM43xx_DMA32_TXCTL 0x00
#define BCM43xx_DMA32_TXENABLE 0x00000001
#define BCM43xx_DMA32_TXSUSPEND 0x00000002
#define BCM43xx_DMA32_TXLOOPBACK 0x00000004
#define BCM43xx_DMA32_TXFLUSH 0x00000010
#define BCM43xx_DMA32_TXADDREXT_MASK 0x00030000
#define BCM43xx_DMA32_TXADDREXT_SHIFT 16
#define BCM43xx_DMA32_TXRING 0x04
#define BCM43xx_DMA32_TXINDEX 0x08
#define BCM43xx_DMA32_TXSTATUS 0x0C
#define BCM43xx_DMA32_TXDPTR 0x00000FFF
#define BCM43xx_DMA32_TXSTATE 0x0000F000
#define BCM43xx_DMA32_TXSTAT_DISABLED 0x00000000
#define BCM43xx_DMA32_TXSTAT_ACTIVE 0x00001000
#define BCM43xx_DMA32_TXSTAT_IDLEWAIT 0x00002000
#define BCM43xx_DMA32_TXSTAT_STOPPED 0x00003000
#define BCM43xx_DMA32_TXSTAT_SUSP 0x00004000
#define BCM43xx_DMA32_TXERROR 0x000F0000
#define BCM43xx_DMA32_TXERR_NOERR 0x00000000
#define BCM43xx_DMA32_TXERR_PROT 0x00010000
#define BCM43xx_DMA32_TXERR_UNDERRUN 0x00020000
#define BCM43xx_DMA32_TXERR_BUFREAD 0x00030000
#define BCM43xx_DMA32_TXERR_DESCREAD 0x00040000
#define BCM43xx_DMA32_TXACTIVE 0xFFF00000
#define BCM43xx_DMA32_RXCTL 0x10
#define BCM43xx_DMA32_RXENABLE 0x00000001
#define BCM43xx_DMA32_RXFROFF_MASK 0x000000FE
#define BCM43xx_DMA32_RXFROFF_SHIFT 1
#define BCM43xx_DMA32_RXDIRECTFIFO 0x00000100
#define BCM43xx_DMA32_RXADDREXT_MASK 0x00030000
#define BCM43xx_DMA32_RXADDREXT_SHIFT 16
#define BCM43xx_DMA32_RXRING 0x14
#define BCM43xx_DMA32_RXINDEX 0x18
#define BCM43xx_DMA32_RXSTATUS 0x1C
#define BCM43xx_DMA32_RXDPTR 0x00000FFF
#define BCM43xx_DMA32_RXSTATE 0x0000F000
#define BCM43xx_DMA32_RXSTAT_DISABLED 0x00000000
#define BCM43xx_DMA32_RXSTAT_ACTIVE 0x00001000
#define BCM43xx_DMA32_RXSTAT_IDLEWAIT 0x00002000
#define BCM43xx_DMA32_RXSTAT_STOPPED 0x00003000
#define BCM43xx_DMA32_RXERROR 0x000F0000
#define BCM43xx_DMA32_RXERR_NOERR 0x00000000
#define BCM43xx_DMA32_RXERR_PROT 0x00010000
#define BCM43xx_DMA32_RXERR_OVERFLOW 0x00020000
#define BCM43xx_DMA32_RXERR_BUFWRITE 0x00030000
#define BCM43xx_DMA32_RXERR_DESCREAD 0x00040000
#define BCM43xx_DMA32_RXACTIVE 0xFFF00000
/* 32-bit DMA descriptor. */
struct bcm43xx_dmadesc32 {
__le32 control;
__le32 address;
} __attribute__((__packed__));
#define BCM43xx_DMA32_DCTL_BYTECNT 0x00001FFF
#define BCM43xx_DMA32_DCTL_ADDREXT_MASK 0x00030000
#define BCM43xx_DMA32_DCTL_ADDREXT_SHIFT 16
#define BCM43xx_DMA32_DCTL_DTABLEEND 0x10000000
#define BCM43xx_DMA32_DCTL_IRQ 0x20000000
#define BCM43xx_DMA32_DCTL_FRAMEEND 0x40000000
#define BCM43xx_DMA32_DCTL_FRAMESTART 0x80000000
/* Address field Routing value. */
#define BCM43xx_DMA32_ROUTING 0xC0000000
#define BCM43xx_DMA32_ROUTING_SHIFT 30
#define BCM43xx_DMA32_NOTRANS 0x00000000
#define BCM43xx_DMA32_CLIENTTRANS 0x40000000
/*** 64-bit DMA Engine. ***/
/* 64-bit DMA controller registers. */
#define BCM43xx_DMA64_TXCTL 0x00
#define BCM43xx_DMA64_TXENABLE 0x00000001
#define BCM43xx_DMA64_TXSUSPEND 0x00000002
#define BCM43xx_DMA64_TXLOOPBACK 0x00000004
#define BCM43xx_DMA64_TXFLUSH 0x00000010
#define BCM43xx_DMA64_TXADDREXT_MASK 0x00030000
#define BCM43xx_DMA64_TXADDREXT_SHIFT 16
#define BCM43xx_DMA64_TXINDEX 0x04
#define BCM43xx_DMA64_TXRINGLO 0x08
#define BCM43xx_DMA64_TXRINGHI 0x0C
#define BCM43xx_DMA64_TXSTATUS 0x10
#define BCM43xx_DMA64_TXSTATDPTR 0x00001FFF
#define BCM43xx_DMA64_TXSTAT 0xF0000000
#define BCM43xx_DMA64_TXSTAT_DISABLED 0x00000000
#define BCM43xx_DMA64_TXSTAT_ACTIVE 0x10000000
#define BCM43xx_DMA64_TXSTAT_IDLEWAIT 0x20000000
#define BCM43xx_DMA64_TXSTAT_STOPPED 0x30000000
#define BCM43xx_DMA64_TXSTAT_SUSP 0x40000000
#define BCM43xx_DMA64_TXERROR 0x14
#define BCM43xx_DMA64_TXERRDPTR 0x0001FFFF
#define BCM43xx_DMA64_TXERR 0xF0000000
#define BCM43xx_DMA64_TXERR_NOERR 0x00000000
#define BCM43xx_DMA64_TXERR_PROT 0x10000000
#define BCM43xx_DMA64_TXERR_UNDERRUN 0x20000000
#define BCM43xx_DMA64_TXERR_TRANSFER 0x30000000
#define BCM43xx_DMA64_TXERR_DESCREAD 0x40000000
#define BCM43xx_DMA64_TXERR_CORE 0x50000000
#define BCM43xx_DMA64_RXCTL 0x20
#define BCM43xx_DMA64_RXENABLE 0x00000001
#define BCM43xx_DMA64_RXFROFF_MASK 0x000000FE
#define BCM43xx_DMA64_RXFROFF_SHIFT 1
#define BCM43xx_DMA64_RXDIRECTFIFO 0x00000100
#define BCM43xx_DMA64_RXADDREXT_MASK 0x00030000
#define BCM43xx_DMA64_RXADDREXT_SHIFT 16
#define BCM43xx_DMA64_RXINDEX 0x24
#define BCM43xx_DMA64_RXRINGLO 0x28
#define BCM43xx_DMA64_RXRINGHI 0x2C
#define BCM43xx_DMA64_RXSTATUS 0x30
#define BCM43xx_DMA64_RXSTATDPTR 0x00001FFF
#define BCM43xx_DMA64_RXSTAT 0xF0000000
#define BCM43xx_DMA64_RXSTAT_DISABLED 0x00000000
#define BCM43xx_DMA64_RXSTAT_ACTIVE 0x10000000
#define BCM43xx_DMA64_RXSTAT_IDLEWAIT 0x20000000
#define BCM43xx_DMA64_RXSTAT_STOPPED 0x30000000
#define BCM43xx_DMA64_RXSTAT_SUSP 0x40000000
#define BCM43xx_DMA64_RXERROR 0x34
#define BCM43xx_DMA64_RXERRDPTR 0x0001FFFF
#define BCM43xx_DMA64_RXERR 0xF0000000
#define BCM43xx_DMA64_RXERR_NOERR 0x00000000
#define BCM43xx_DMA64_RXERR_PROT 0x10000000
#define BCM43xx_DMA64_RXERR_UNDERRUN 0x20000000
#define BCM43xx_DMA64_RXERR_TRANSFER 0x30000000
#define BCM43xx_DMA64_RXERR_DESCREAD 0x40000000
#define BCM43xx_DMA64_RXERR_CORE 0x50000000
/* 64-bit DMA descriptor. */
struct bcm43xx_dmadesc64 {
__le32 control0;
__le32 control1;
__le32 address_low;
__le32 address_high;
} __attribute__((__packed__));
#define BCM43xx_DMA64_DCTL0_DTABLEEND 0x10000000
#define BCM43xx_DMA64_DCTL0_IRQ 0x20000000
#define BCM43xx_DMA64_DCTL0_FRAMEEND 0x40000000
#define BCM43xx_DMA64_DCTL0_FRAMESTART 0x80000000
#define BCM43xx_DMA64_DCTL1_BYTECNT 0x00001FFF
#define BCM43xx_DMA64_DCTL1_ADDREXT_MASK 0x00030000
#define BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT 16
/* Address field Routing value. */
#define BCM43xx_DMA64_ROUTING 0xC0000000
#define BCM43xx_DMA64_ROUTING_SHIFT 30
#define BCM43xx_DMA64_NOTRANS 0x00000000
#define BCM43xx_DMA64_CLIENTTRANS 0x80000000
struct bcm43xx_dmadesc_generic {
union {
struct bcm43xx_dmadesc32 dma32;
struct bcm43xx_dmadesc64 dma64;
} __attribute__((__packed__));
} __attribute__((__packed__));
/* Misc DMA constants */
#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE
#define BCM43xx_DMA0_RX_FRAMEOFFSET 30
#define BCM43xx_DMA3_RX_FRAMEOFFSET 0
/* DMA engine tuning knobs */
#define BCM43xx_TXRING_SLOTS 512
#define BCM43xx_RXRING_SLOTS 64
#define BCM43xx_DMA0_RX_BUFFERSIZE (2304 + 100)
#define BCM43xx_DMA3_RX_BUFFERSIZE 16
/* Suspend the tx queue, if less than this percent slots are free. */
#define BCM43xx_TXSUSPEND_PERCENT 20
/* Resume the tx queue, if more than this percent slots are free. */
#define BCM43xx_TXRESUME_PERCENT 50
#ifdef CONFIG_BCM43XX_DMA
struct sk_buff;
struct bcm43xx_private;
struct bcm43xx_xmitstatus;
struct bcm43xx_dmadesc_meta {
/* The kernel DMA-able buffer. */
struct sk_buff *skb;
/* DMA base bus-address of the descriptor buffer. */
dma_addr_t dmaaddr;
};
struct bcm43xx_dmaring {
/* Kernel virtual base address of the ring memory. */
void *descbase;
/* Meta data about all descriptors. */
struct bcm43xx_dmadesc_meta *meta;
/* DMA Routing value. */
u32 routing;
/* (Unadjusted) DMA base bus-address of the ring memory. */
dma_addr_t dmabase;
/* Number of descriptor slots in the ring. */
int nr_slots;
/* Number of used descriptor slots. */
int used_slots;
/* Currently used slot in the ring. */
int current_slot;
/* Marks to suspend/resume the queue. */
int suspend_mark;
int resume_mark;
/* Frameoffset in octets. */
u32 frameoffset;
/* Descriptor buffer size. */
u16 rx_buffersize;
/* The MMIO base register of the DMA controller. */
u16 mmio_base;
/* DMA controller index number (0-5). */
int index;
/* Boolean. Is this a TX ring? */
u8 tx;
/* Boolean. 64bit DMA if true, 32bit DMA otherwise. */
u8 dma64;
/* Boolean. Are transfers suspended on this ring? */
u8 suspended;
struct bcm43xx_private *bcm;
#ifdef CONFIG_BCM43XX_DEBUG
/* Maximum number of used slots. */
int max_used_slots;
#endif /* CONFIG_BCM43XX_DEBUG*/
};
static inline
int bcm43xx_dma_desc2idx(struct bcm43xx_dmaring *ring,
struct bcm43xx_dmadesc_generic *desc)
{
if (ring->dma64) {
struct bcm43xx_dmadesc64 *dd64 = ring->descbase;
return (int)(&(desc->dma64) - dd64);
} else {
struct bcm43xx_dmadesc32 *dd32 = ring->descbase;
return (int)(&(desc->dma32) - dd32);
}
}
static inline
struct bcm43xx_dmadesc_generic * bcm43xx_dma_idx2desc(struct bcm43xx_dmaring *ring,
int slot,
struct bcm43xx_dmadesc_meta **meta)
{
*meta = &(ring->meta[slot]);
if (ring->dma64) {
struct bcm43xx_dmadesc64 *dd64 = ring->descbase;
return (struct bcm43xx_dmadesc_generic *)(&(dd64[slot]));
} else {
struct bcm43xx_dmadesc32 *dd32 = ring->descbase;
return (struct bcm43xx_dmadesc_generic *)(&(dd32[slot]));
}
}
static inline
u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring,
u16 offset)
{
return bcm43xx_read32(ring->bcm, ring->mmio_base + offset);
}
static inline
void bcm43xx_dma_write(struct bcm43xx_dmaring *ring,
u16 offset, u32 value)
{
bcm43xx_write32(ring->bcm, ring->mmio_base + offset, value);
}
int bcm43xx_dma_init(struct bcm43xx_private *bcm);
void bcm43xx_dma_free(struct bcm43xx_private *bcm);
int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
u16 dmacontroller_mmio_base,
int dma64);
int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
u16 dmacontroller_mmio_base,
int dma64);
u16 bcm43xx_dmacontroller_base(int dma64bit, int dmacontroller_idx);
void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring);
void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring);
void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status);
int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
struct ieee80211_txb *txb);
void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
/* Helper function that returns the dma mask for this device. */
static inline
u64 bcm43xx_get_supported_dma_mask(struct bcm43xx_private *bcm)
{
int dma64 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH) &
BCM43xx_SBTMSTATEHIGH_DMA64BIT;
u16 mmio_base = bcm43xx_dmacontroller_base(dma64, 0);
u32 mask = BCM43xx_DMA32_TXADDREXT_MASK;
if (dma64)
return DMA_64BIT_MASK;
bcm43xx_write32(bcm, mmio_base + BCM43xx_DMA32_TXCTL, mask);
if (bcm43xx_read32(bcm, mmio_base + BCM43xx_DMA32_TXCTL) & mask)
return DMA_32BIT_MASK;
return DMA_30BIT_MASK;
}
#else /* CONFIG_BCM43XX_DMA */
static inline
int bcm43xx_dma_init(struct bcm43xx_private *bcm)
{
return 0;
}
static inline
void bcm43xx_dma_free(struct bcm43xx_private *bcm)
{
}
static inline
int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
u16 dmacontroller_mmio_base,
int dma64)
{
return 0;
}
static inline
int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
u16 dmacontroller_mmio_base,
int dma64)
{
return 0;
}
static inline
int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
struct ieee80211_txb *txb)
{
return 0;
}
static inline
void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status)
{
}
static inline
void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
{
}
static inline
void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring)
{
}
static inline
void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
{
}
#endif /* CONFIG_BCM43XX_DMA */
#endif /* BCM43xx_DMA_H_ */
/*
Broadcom BCM43xx wireless driver
ethtool support
Copyright (c) 2006 Jason Lunz <lunz@falooley.org>
Some code in this file is derived from the 8139too.c driver
Copyright (C) 2002 Jeff Garzik
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "bcm43xx.h"
#include "bcm43xx_ethtool.h"
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/utsname.h>
static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct bcm43xx_private *bcm = bcm43xx_priv(dev);
strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
strncpy(info->version, utsname()->release, sizeof(info->version));
strncpy(info->bus_info, pci_name(bcm->pci_dev), ETHTOOL_BUSINFO_LEN);
}
const struct ethtool_ops bcm43xx_ethtool_ops = {
.get_drvinfo = bcm43xx_get_drvinfo,
.get_link = ethtool_op_get_link,
};
#ifndef BCM43xx_ETHTOOL_H_
#define BCM43xx_ETHTOOL_H_
#include <linux/ethtool.h>
extern const struct ethtool_ops bcm43xx_ethtool_ops;
#endif /* BCM43xx_ETHTOOL_H_ */
/*
Broadcom BCM43xx wireless driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Stefano Brivio <st3@riseup.net>
Michael Buesch <mbuesch@freenet.de>
Danny van Dyk <kugelfang@gentoo.org>
Andreas Jaggi <andreas.jaggi@waterwave.ch>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "bcm43xx.h"
#include "bcm43xx_ilt.h"
#include "bcm43xx_phy.h"
/**** Initial Internal Lookup Tables ****/
const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE] = {
0xFEB93FFD, 0xFEC63FFD, /* 0 */
0xFED23FFD, 0xFEDF3FFD,
0xFEEC3FFE, 0xFEF83FFE,
0xFF053FFE, 0xFF113FFE,
0xFF1E3FFE, 0xFF2A3FFF, /* 8 */
0xFF373FFF, 0xFF443FFF,
0xFF503FFF, 0xFF5D3FFF,
0xFF693FFF, 0xFF763FFF,
0xFF824000, 0xFF8F4000, /* 16 */
0xFF9B4000, 0xFFA84000,
0xFFB54000, 0xFFC14000,
0xFFCE4000, 0xFFDA4000,
0xFFE74000, 0xFFF34000, /* 24 */
0x00004000, 0x000D4000,
0x00194000, 0x00264000,
0x00324000, 0x003F4000,
0x004B4000, 0x00584000, /* 32 */
0x00654000, 0x00714000,
0x007E4000, 0x008A3FFF,
0x00973FFF, 0x00A33FFF,
0x00B03FFF, 0x00BC3FFF, /* 40 */
0x00C93FFF, 0x00D63FFF,
0x00E23FFE, 0x00EF3FFE,
0x00FB3FFE, 0x01083FFE,
0x01143FFE, 0x01213FFD, /* 48 */
0x012E3FFD, 0x013A3FFD,
0x01473FFD,
};
const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE] = {
0xDB93CB87, 0xD666CF64, /* 0 */
0xD1FDD358, 0xCDA6D826,
0xCA38DD9F, 0xC729E2B4,
0xC469E88E, 0xC26AEE2B,
0xC0DEF46C, 0xC073FA62, /* 8 */
0xC01D00D5, 0xC0760743,
0xC1560D1E, 0xC2E51369,
0xC4ED18FF, 0xC7AC1ED7,
0xCB2823B2, 0xCEFA28D9, /* 16 */
0xD2F62D3F, 0xD7BB3197,
0xDCE53568, 0xE1FE3875,
0xE7D13B35, 0xED663D35,
0xF39B3EC4, 0xF98E3FA7, /* 24 */
0x00004000, 0x06723FA7,
0x0C653EC4, 0x129A3D35,
0x182F3B35, 0x1E023875,
0x231B3568, 0x28453197, /* 32 */
0x2D0A2D3F, 0x310628D9,
0x34D823B2, 0x38541ED7,
0x3B1318FF, 0x3D1B1369,
0x3EAA0D1E, 0x3F8A0743, /* 40 */
0x3FE300D5, 0x3F8DFA62,
0x3F22F46C, 0x3D96EE2B,
0x3B97E88E, 0x38D7E2B4,
0x35C8DD9F, 0x325AD826, /* 48 */
0x2E03D358, 0x299ACF64,
0x246DCB87,
};
const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE] = {
0x0082, 0x0082, 0x0102, 0x0182, /* 0 */
0x0202, 0x0282, 0x0302, 0x0382,
0x0402, 0x0482, 0x0502, 0x0582,
0x05E2, 0x0662, 0x06E2, 0x0762,
0x07E2, 0x0842, 0x08C2, 0x0942, /* 16 */
0x09C2, 0x0A22, 0x0AA2, 0x0B02,
0x0B82, 0x0BE2, 0x0C62, 0x0CC2,
0x0D42, 0x0DA2, 0x0E02, 0x0E62,
0x0EE2, 0x0F42, 0x0FA2, 0x1002, /* 32 */
0x1062, 0x10C2, 0x1122, 0x1182,
0x11E2, 0x1242, 0x12A2, 0x12E2,
0x1342, 0x13A2, 0x1402, 0x1442,
0x14A2, 0x14E2, 0x1542, 0x1582, /* 48 */
0x15E2, 0x1622, 0x1662, 0x16C1,
0x1701, 0x1741, 0x1781, 0x17E1,
0x1821, 0x1861, 0x18A1, 0x18E1,
0x1921, 0x1961, 0x19A1, 0x19E1, /* 64 */
0x1A21, 0x1A61, 0x1AA1, 0x1AC1,
0x1B01, 0x1B41, 0x1B81, 0x1BA1,
0x1BE1, 0x1C21, 0x1C41, 0x1C81,
0x1CA1, 0x1CE1, 0x1D01, 0x1D41, /* 80 */
0x1D61, 0x1DA1, 0x1DC1, 0x1E01,
0x1E21, 0x1E61, 0x1E81, 0x1EA1,
0x1EE1, 0x1F01, 0x1F21, 0x1F41,
0x1F81, 0x1FA1, 0x1FC1, 0x1FE1, /* 96 */
0x2001, 0x2041, 0x2061, 0x2081,
0x20A1, 0x20C1, 0x20E1, 0x2101,
0x2121, 0x2141, 0x2161, 0x2181,
0x21A1, 0x21C1, 0x21E1, 0x2201, /* 112 */
0x2221, 0x2241, 0x2261, 0x2281,
0x22A1, 0x22C1, 0x22C1, 0x22E1,
0x2301, 0x2321, 0x2341, 0x2361,
0x2361, 0x2381, 0x23A1, 0x23C1, /* 128 */
0x23E1, 0x23E1, 0x2401, 0x2421,
0x2441, 0x2441, 0x2461, 0x2481,
0x2481, 0x24A1, 0x24C1, 0x24C1,
0x24E1, 0x2501, 0x2501, 0x2521, /* 144 */
0x2541, 0x2541, 0x2561, 0x2561,
0x2581, 0x25A1, 0x25A1, 0x25C1,
0x25C1, 0x25E1, 0x2601, 0x2601,
0x2621, 0x2621, 0x2641, 0x2641, /* 160 */
0x2661, 0x2661, 0x2681, 0x2681,
0x26A1, 0x26A1, 0x26C1, 0x26C1,
0x26E1, 0x26E1, 0x2701, 0x2701,
0x2721, 0x2721, 0x2740, 0x2740, /* 176 */
0x2760, 0x2760, 0x2780, 0x2780,
0x2780, 0x27A0, 0x27A0, 0x27C0,
0x27C0, 0x27E0, 0x27E0, 0x27E0,
0x2800, 0x2800, 0x2820, 0x2820, /* 192 */
0x2820, 0x2840, 0x2840, 0x2840,
0x2860, 0x2860, 0x2880, 0x2880,
0x2880, 0x28A0, 0x28A0, 0x28A0,
0x28C0, 0x28C0, 0x28C0, 0x28E0, /* 208 */
0x28E0, 0x28E0, 0x2900, 0x2900,
0x2900, 0x2920, 0x2920, 0x2920,
0x2940, 0x2940, 0x2940, 0x2960,
0x2960, 0x2960, 0x2960, 0x2980, /* 224 */
0x2980, 0x2980, 0x29A0, 0x29A0,
0x29A0, 0x29A0, 0x29C0, 0x29C0,
0x29C0, 0x29E0, 0x29E0, 0x29E0,
0x29E0, 0x2A00, 0x2A00, 0x2A00, /* 240 */
0x2A00, 0x2A20, 0x2A20, 0x2A20,
0x2A20, 0x2A40, 0x2A40, 0x2A40,
0x2A40, 0x2A60, 0x2A60, 0x2A60,
};
const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE] = {
0x0089, 0x02E9, 0x0409, 0x04E9, /* 0 */
0x05A9, 0x0669, 0x0709, 0x0789,
0x0829, 0x08A9, 0x0929, 0x0989,
0x0A09, 0x0A69, 0x0AC9, 0x0B29,
0x0BA9, 0x0BE9, 0x0C49, 0x0CA9, /* 16 */
0x0D09, 0x0D69, 0x0DA9, 0x0E09,
0x0E69, 0x0EA9, 0x0F09, 0x0F49,
0x0FA9, 0x0FE9, 0x1029, 0x1089,
0x10C9, 0x1109, 0x1169, 0x11A9, /* 32 */
0x11E9, 0x1229, 0x1289, 0x12C9,
0x1309, 0x1349, 0x1389, 0x13C9,
0x1409, 0x1449, 0x14A9, 0x14E9,
0x1529, 0x1569, 0x15A9, 0x15E9, /* 48 */
0x1629, 0x1669, 0x16A9, 0x16E8,
0x1728, 0x1768, 0x17A8, 0x17E8,
0x1828, 0x1868, 0x18A8, 0x18E8,
0x1928, 0x1968, 0x19A8, 0x19E8, /* 64 */
0x1A28, 0x1A68, 0x1AA8, 0x1AE8,
0x1B28, 0x1B68, 0x1BA8, 0x1BE8,
0x1C28, 0x1C68, 0x1CA8, 0x1CE8,
0x1D28, 0x1D68, 0x1DC8, 0x1E08, /* 80 */
0x1E48, 0x1E88, 0x1EC8, 0x1F08,
0x1F48, 0x1F88, 0x1FE8, 0x2028,
0x2068, 0x20A8, 0x2108, 0x2148,
0x2188, 0x21C8, 0x2228, 0x2268, /* 96 */
0x22C8, 0x2308, 0x2348, 0x23A8,
0x23E8, 0x2448, 0x24A8, 0x24E8,
0x2548, 0x25A8, 0x2608, 0x2668,
0x26C8, 0x2728, 0x2787, 0x27E7, /* 112 */
0x2847, 0x28C7, 0x2947, 0x29A7,
0x2A27, 0x2AC7, 0x2B47, 0x2BE7,
0x2CA7, 0x2D67, 0x2E47, 0x2F67,
0x3247, 0x3526, 0x3646, 0x3726, /* 128 */
0x3806, 0x38A6, 0x3946, 0x39E6,
0x3A66, 0x3AE6, 0x3B66, 0x3BC6,
0x3C45, 0x3CA5, 0x3D05, 0x3D85,
0x3DE5, 0x3E45, 0x3EA5, 0x3EE5, /* 144 */
0x3F45, 0x3FA5, 0x4005, 0x4045,
0x40A5, 0x40E5, 0x4145, 0x4185,
0x41E5, 0x4225, 0x4265, 0x42C5,
0x4305, 0x4345, 0x43A5, 0x43E5, /* 160 */
0x4424, 0x4464, 0x44C4, 0x4504,
0x4544, 0x4584, 0x45C4, 0x4604,
0x4644, 0x46A4, 0x46E4, 0x4724,
0x4764, 0x47A4, 0x47E4, 0x4824, /* 176 */
0x4864, 0x48A4, 0x48E4, 0x4924,
0x4964, 0x49A4, 0x49E4, 0x4A24,
0x4A64, 0x4AA4, 0x4AE4, 0x4B23,
0x4B63, 0x4BA3, 0x4BE3, 0x4C23, /* 192 */
0x4C63, 0x4CA3, 0x4CE3, 0x4D23,
0x4D63, 0x4DA3, 0x4DE3, 0x4E23,
0x4E63, 0x4EA3, 0x4EE3, 0x4F23,
0x4F63, 0x4FC3, 0x5003, 0x5043, /* 208 */
0x5083, 0x50C3, 0x5103, 0x5143,
0x5183, 0x51E2, 0x5222, 0x5262,
0x52A2, 0x52E2, 0x5342, 0x5382,
0x53C2, 0x5402, 0x5462, 0x54A2, /* 224 */
0x5502, 0x5542, 0x55A2, 0x55E2,
0x5642, 0x5682, 0x56E2, 0x5722,
0x5782, 0x57E1, 0x5841, 0x58A1,
0x5901, 0x5961, 0x59C1, 0x5A21, /* 240 */
0x5AA1, 0x5B01, 0x5B81, 0x5BE1,
0x5C61, 0x5D01, 0x5D80, 0x5E20,
0x5EE0, 0x5FA0, 0x6080, 0x61C0,
};
const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE] = {
0x0001, 0x0001, 0x0001, 0xFFFE,
0xFFFE, 0x3FFF, 0x1000, 0x0393,
};
const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE] = {
0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
};
const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE] = {
0x013C, 0x01F5, 0x031A, 0x0631,
0x0001, 0x0001, 0x0001, 0x0001,
};
const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE] = {
0x5484, 0x3C40, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000,
};
const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE] = {
0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */
0x2F2D, 0x2A2A, 0x2527, 0x1F21,
0x1A1D, 0x1719, 0x1616, 0x1414,
0x1414, 0x1400, 0x1414, 0x1614,
0x1716, 0x1A19, 0x1F1D, 0x2521, /* 16 */
0x2A27, 0x2F2A, 0x332D, 0x3B35,
0x5140, 0x6C62, 0x0077,
};
const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE] = {
0xD8DD, 0xCBD4, 0xBCC0, 0XB6B7, /* 0 */
0xB2B0, 0xADAD, 0xA7A9, 0x9FA1,
0x969B, 0x9195, 0x8F8F, 0x8A8A,
0x8A8A, 0x8A00, 0x8A8A, 0x8F8A,
0x918F, 0x9695, 0x9F9B, 0xA7A1, /* 16 */
0xADA9, 0xB2AD, 0xB6B0, 0xBCB7,
0xCBC0, 0xD8D4, 0x00DD,
};
const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE] = {
0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 0 */
0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
0xA4A4, 0xA400, 0xA4A4, 0xA4A4,
0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 16 */
0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
0xA4A4, 0xA4A4, 0x00A4,
};
const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE] = {
0x007A, 0x0075, 0x0071, 0x006C, /* 0 */
0x0067, 0x0063, 0x005E, 0x0059,
0x0054, 0x0050, 0x004B, 0x0046,
0x0042, 0x003D, 0x003D, 0x003D,
0x003D, 0x003D, 0x003D, 0x003D, /* 16 */
0x003D, 0x003D, 0x003D, 0x003D,
0x003D, 0x003D, 0x0000, 0x003D,
0x003D, 0x003D, 0x003D, 0x003D,
0x003D, 0x003D, 0x003D, 0x003D, /* 32 */
0x003D, 0x003D, 0x003D, 0x003D,
0x0042, 0x0046, 0x004B, 0x0050,
0x0054, 0x0059, 0x005E, 0x0063,
0x0067, 0x006C, 0x0071, 0x0075, /* 48 */
0x007A,
};
const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE] = {
0x00DE, 0x00DC, 0x00DA, 0x00D8, /* 0 */
0x00D6, 0x00D4, 0x00D2, 0x00CF,
0x00CD, 0x00CA, 0x00C7, 0x00C4,
0x00C1, 0x00BE, 0x00BE, 0x00BE,
0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 16 */
0x00BE, 0x00BE, 0x00BE, 0x00BE,
0x00BE, 0x00BE, 0x0000, 0x00BE,
0x00BE, 0x00BE, 0x00BE, 0x00BE,
0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 32 */
0x00BE, 0x00BE, 0x00BE, 0x00BE,
0x00C1, 0x00C4, 0x00C7, 0x00CA,
0x00CD, 0x00CF, 0x00D2, 0x00D4,
0x00D6, 0x00D8, 0x00DA, 0x00DC, /* 48 */
0x00DE,
};
/**** Helper functions to access the device Internal Lookup Tables ****/
void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
{
if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
mmiowb();
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val);
} else {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
mmiowb();
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val);
}
}
void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val)
{
if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
mmiowb();
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA2, (val & 0xFFFF0000) >> 16);
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val & 0x0000FFFF);
} else {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
mmiowb();
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA2, (val & 0xFFFF0000) >> 16);
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val & 0x0000FFFF);
}
}
u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset)
{
if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1);
} else {
bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1);
}
}
#ifndef BCM43xx_ILT_H_
#define BCM43xx_ILT_H_
#define BCM43xx_ILT_ROTOR_SIZE 53
extern const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE];
#define BCM43xx_ILT_RETARD_SIZE 53
extern const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE];
#define BCM43xx_ILT_FINEFREQA_SIZE 256
extern const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE];
#define BCM43xx_ILT_FINEFREQG_SIZE 256
extern const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE];
#define BCM43xx_ILT_NOISEA2_SIZE 8
extern const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE];
#define BCM43xx_ILT_NOISEA3_SIZE 8
extern const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE];
#define BCM43xx_ILT_NOISEG1_SIZE 8
extern const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE];
#define BCM43xx_ILT_NOISEG2_SIZE 8
extern const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE];
#define BCM43xx_ILT_NOISESCALEG_SIZE 27
extern const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE];
extern const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE];
extern const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE];
#define BCM43xx_ILT_SIGMASQR_SIZE 53
extern const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE];
extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE];
void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val);
u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset);
#endif /* BCM43xx_ILT_H_ */
/*
Broadcom BCM43xx wireless driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Stefano Brivio <st3@riseup.net>
Michael Buesch <mbuesch@freenet.de>
Danny van Dyk <kugelfang@gentoo.org>
Andreas Jaggi <andreas.jaggi@waterwave.ch>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "bcm43xx_leds.h"
#include "bcm43xx_radio.h"
#include "bcm43xx.h"
#include <linux/bitops.h>
static void bcm43xx_led_changestate(struct bcm43xx_led *led)
{
struct bcm43xx_private *bcm = led->bcm;
const int index = bcm43xx_led_index(led);
const u16 mask = (1 << index);
u16 ledctl;
assert(index >= 0 && index < BCM43xx_NR_LEDS);
assert(led->blink_interval);
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
ledctl = (ledctl & mask) ? (ledctl & ~mask) : (ledctl | mask);
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
}
static void bcm43xx_led_blink(unsigned long d)
{
struct bcm43xx_led *led = (struct bcm43xx_led *)d;
struct bcm43xx_private *bcm = led->bcm;
unsigned long flags;
spin_lock_irqsave(&bcm->leds_lock, flags);
if (led->blink_interval) {
bcm43xx_led_changestate(led);
mod_timer(&led->blink_timer, jiffies + led->blink_interval);
}
spin_unlock_irqrestore(&bcm->leds_lock, flags);
}
static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
unsigned long interval)
{
if (led->blink_interval)
return;
led->blink_interval = interval;
bcm43xx_led_changestate(led);
led->blink_timer.expires = jiffies + interval;
add_timer(&led->blink_timer);
}
static void bcm43xx_led_blink_stop(struct bcm43xx_led *led, int sync)
{
struct bcm43xx_private *bcm = led->bcm;
const int index = bcm43xx_led_index(led);
u16 ledctl;
if (!led->blink_interval)
return;
if (unlikely(sync))
del_timer_sync(&led->blink_timer);
else
del_timer(&led->blink_timer);
led->blink_interval = 0;
/* Make sure the LED is turned off. */
assert(index >= 0 && index < BCM43xx_NR_LEDS);
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
if (led->activelow)
ledctl |= (1 << index);
else
ledctl &= ~(1 << index);
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
}
static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm,
struct bcm43xx_led *led,
int led_index)
{
/* This function is called, if the behaviour (and activelow)
* information for a LED is missing in the SPROM.
* We hardcode the behaviour values for various devices here.
* Note that the BCM43xx_LED_TEST_XXX behaviour values can
* be used to figure out which led is mapped to which index.
*/
switch (led_index) {
case 0:
led->behaviour = BCM43xx_LED_ACTIVITY;
led->activelow = 1;
if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
led->behaviour = BCM43xx_LED_RADIO_ALL;
break;
case 1:
led->behaviour = BCM43xx_LED_RADIO_B;
if (bcm->board_vendor == PCI_VENDOR_ID_ASUSTEK)
led->behaviour = BCM43xx_LED_ASSOC;
break;
case 2:
led->behaviour = BCM43xx_LED_RADIO_A;
break;
case 3:
led->behaviour = BCM43xx_LED_OFF;
break;
default:
assert(0);
}
}
int bcm43xx_leds_init(struct bcm43xx_private *bcm)
{
struct bcm43xx_led *led;
u8 sprom[4];
int i;
sprom[0] = bcm->sprom.wl0gpio0;
sprom[1] = bcm->sprom.wl0gpio1;
sprom[2] = bcm->sprom.wl0gpio2;
sprom[3] = bcm->sprom.wl0gpio3;
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
led->bcm = bcm;
setup_timer(&led->blink_timer,
bcm43xx_led_blink,
(unsigned long)led);
if (sprom[i] == 0xFF) {
bcm43xx_led_init_hardcoded(bcm, led, i);
} else {
led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR;
led->activelow = !!(sprom[i] & BCM43xx_LED_ACTIVELOW);
}
}
return 0;
}
void bcm43xx_leds_exit(struct bcm43xx_private *bcm)
{
struct bcm43xx_led *led;
int i;
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
bcm43xx_led_blink_stop(led, 1);
}
bcm43xx_leds_switch_all(bcm, 0);
}
void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
{
struct bcm43xx_led *led;
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
const int transferring = (jiffies - bcm->stats.last_tx) < BCM43xx_LED_XFER_THRES;
int i, turn_on;
unsigned long interval = 0;
u16 ledctl;
unsigned long flags;
spin_lock_irqsave(&bcm->leds_lock, flags);
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
turn_on = 0;
switch (led->behaviour) {
case BCM43xx_LED_INACTIVE:
continue;
case BCM43xx_LED_OFF:
case BCM43xx_LED_BCM4303_3:
break;
case BCM43xx_LED_ON:
turn_on = 1;
break;
case BCM43xx_LED_ACTIVITY:
case BCM43xx_LED_BCM4303_0:
turn_on = activity;
break;
case BCM43xx_LED_RADIO_ALL:
turn_on = radio->enabled && bcm43xx_is_hw_radio_enabled(bcm);
break;
case BCM43xx_LED_RADIO_A:
case BCM43xx_LED_BCM4303_2:
turn_on = (radio->enabled && bcm43xx_is_hw_radio_enabled(bcm) &&
phy->type == BCM43xx_PHYTYPE_A);
break;
case BCM43xx_LED_RADIO_B:
case BCM43xx_LED_BCM4303_1:
turn_on = (radio->enabled && bcm43xx_is_hw_radio_enabled(bcm) &&
(phy->type == BCM43xx_PHYTYPE_B ||
phy->type == BCM43xx_PHYTYPE_G));
break;
case BCM43xx_LED_MODE_BG:
if (phy->type == BCM43xx_PHYTYPE_G && bcm43xx_is_hw_radio_enabled(bcm) &&
1/*FIXME: using G rates.*/)
turn_on = 1;
break;
case BCM43xx_LED_TRANSFER:
if (transferring)
bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM);
else
bcm43xx_led_blink_stop(led, 0);
continue;
case BCM43xx_LED_APTRANSFER:
if (bcm->ieee->iw_mode == IW_MODE_MASTER) {
if (transferring) {
interval = BCM43xx_LEDBLINK_FAST;
turn_on = 1;
}
} else {
turn_on = 1;
if (0/*TODO: not assoc*/)
interval = BCM43xx_LEDBLINK_SLOW;
else if (transferring)
interval = BCM43xx_LEDBLINK_FAST;
else
turn_on = 0;
}
if (turn_on)
bcm43xx_led_blink_start(led, interval);
else
bcm43xx_led_blink_stop(led, 0);
continue;
case BCM43xx_LED_WEIRD:
//TODO
break;
case BCM43xx_LED_ASSOC:
if (bcm->softmac->associnfo.associated)
turn_on = 1;
break;
#ifdef CONFIG_BCM43XX_DEBUG
case BCM43xx_LED_TEST_BLINKSLOW:
bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_SLOW);
continue;
case BCM43xx_LED_TEST_BLINKMEDIUM:
bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM);
continue;
case BCM43xx_LED_TEST_BLINKFAST:
bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_FAST);
continue;
#endif /* CONFIG_BCM43XX_DEBUG */
default:
dprintkl(KERN_INFO PFX "Bad value in leds_update,"
" led->behaviour: 0x%x\n", led->behaviour);
};
if (led->activelow)
turn_on = !turn_on;
if (turn_on)
ledctl |= (1 << i);
else
ledctl &= ~(1 << i);
}
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
spin_unlock_irqrestore(&bcm->leds_lock, flags);
}
void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
{
struct bcm43xx_led *led;
u16 ledctl;
int i;
int bit_on;
unsigned long flags;
spin_lock_irqsave(&bcm->leds_lock, flags);
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
if (led->behaviour == BCM43xx_LED_INACTIVE)
continue;
if (on)
bit_on = led->activelow ? 0 : 1;
else
bit_on = led->activelow ? 1 : 0;
if (bit_on)
ledctl |= (1 << i);
else
ledctl &= ~(1 << i);
}
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
spin_unlock_irqrestore(&bcm->leds_lock, flags);
}
#ifndef BCM43xx_LEDS_H_
#define BCM43xx_LEDS_H_
#include <linux/types.h>
#include <linux/timer.h>
struct bcm43xx_led {
u8 behaviour:7;
u8 activelow:1;
struct bcm43xx_private *bcm;
struct timer_list blink_timer;
unsigned long blink_interval;
};
#define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds))
/* Delay between state changes when blinking in jiffies */
#define BCM43xx_LEDBLINK_SLOW (HZ / 1)
#define BCM43xx_LEDBLINK_MEDIUM (HZ / 4)
#define BCM43xx_LEDBLINK_FAST (HZ / 8)
#define BCM43xx_LED_XFER_THRES (HZ / 100)
#define BCM43xx_LED_BEHAVIOUR 0x7F
#define BCM43xx_LED_ACTIVELOW 0x80
enum { /* LED behaviour values */
BCM43xx_LED_OFF,
BCM43xx_LED_ON,
BCM43xx_LED_ACTIVITY,
BCM43xx_LED_RADIO_ALL,
BCM43xx_LED_RADIO_A,
BCM43xx_LED_RADIO_B,
BCM43xx_LED_MODE_BG,
BCM43xx_LED_TRANSFER,
BCM43xx_LED_APTRANSFER,
BCM43xx_LED_WEIRD,//FIXME
BCM43xx_LED_ASSOC,
BCM43xx_LED_INACTIVE,
/* Behaviour values for testing.
* With these values it is easier to figure out
* the real behaviour of leds, in case the SPROM
* is missing information.
*/
BCM43xx_LED_TEST_BLINKSLOW,
BCM43xx_LED_TEST_BLINKMEDIUM,
BCM43xx_LED_TEST_BLINKFAST,
/* Misc values for BCM4303 */
BCM43xx_LED_BCM4303_0 = 0x2B,
BCM43xx_LED_BCM4303_1 = 0x78,
BCM43xx_LED_BCM4303_2 = 0x2E,
BCM43xx_LED_BCM4303_3 = 0x19,
};
int bcm43xx_leds_init(struct bcm43xx_private *bcm);
void bcm43xx_leds_exit(struct bcm43xx_private *bcm);
void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity);
void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on);
#endif /* BCM43xx_LEDS_H_ */
此差异已折叠。
/*
Broadcom BCM43xx wireless driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Stefano Brivio <st3@riseup.net>
Michael Buesch <mbuesch@freenet.de>
Danny van Dyk <kugelfang@gentoo.org>
Andreas Jaggi <andreas.jaggi@waterwave.ch>
Some parts of the code in this file are derived from the ipw2200
driver Copyright(c) 2003 - 2004 Intel Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef BCM43xx_MAIN_H_
#define BCM43xx_MAIN_H_
#include "bcm43xx.h"
#define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes]
#define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes)
/* Magic helper macro to pad structures. Ignore those above. It's magic. */
#define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes))
/* Lightweight function to convert a frequency (in Mhz) to a channel number. */
static inline
u8 bcm43xx_freq_to_channel_a(int freq)
{
return ((freq - 5000) / 5);
}
static inline
u8 bcm43xx_freq_to_channel_bg(int freq)
{
u8 channel;
if (freq == 2484)
channel = 14;
else
channel = (freq - 2407) / 5;
return channel;
}
static inline
u8 bcm43xx_freq_to_channel(struct bcm43xx_private *bcm,
int freq)
{
if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
return bcm43xx_freq_to_channel_a(freq);
return bcm43xx_freq_to_channel_bg(freq);
}
/* Lightweight function to convert a channel number to a frequency (in Mhz). */
static inline
int bcm43xx_channel_to_freq_a(u8 channel)
{
return (5000 + (5 * channel));
}
static inline
int bcm43xx_channel_to_freq_bg(u8 channel)
{
int freq;
if (channel == 14)
freq = 2484;
else
freq = 2407 + (5 * channel);
return freq;
}
static inline
int bcm43xx_channel_to_freq(struct bcm43xx_private *bcm,
u8 channel)
{
if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
return bcm43xx_channel_to_freq_a(channel);
return bcm43xx_channel_to_freq_bg(channel);
}
void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf);
void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf);
void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
int iw_mode);
u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm,
u16 routing, u16 offset);
u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm,
u16 routing, u16 offset);
void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
u16 routing, u16 offset,
u32 value);
void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
u16 routing, u16 offset,
u16 value);
void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm);
int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core);
int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
int phytype);
void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy);
void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
void bcm43xx_mac_enable(struct bcm43xx_private *bcm);
void bcm43xx_cancel_work(struct bcm43xx_private *bcm);
void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm);
void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason);
int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom);
int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom);
#endif /* BCM43xx_MAIN_H_ */
此差异已折叠。
/*
Broadcom BCM43xx wireless driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Stefano Brivio <st3@riseup.net>
Michael Buesch <mbuesch@freenet.de>
Danny van Dyk <kugelfang@gentoo.org>
Andreas Jaggi <andreas.jaggi@waterwave.ch>
Some parts of the code in this file are derived from the ipw2200
driver Copyright(c) 2003 - 2004 Intel Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef BCM43xx_PHY_H_
#define BCM43xx_PHY_H_
#include <linux/types.h>
struct bcm43xx_private;
void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm);
#define bcm43xx_phy_lock(bcm, flags) \
do { \
local_irq_save(flags); \
bcm43xx_raw_phy_lock(bcm); \
} while (0)
void bcm43xx_raw_phy_unlock(struct bcm43xx_private *bcm);
#define bcm43xx_phy_unlock(bcm, flags) \
do { \
bcm43xx_raw_phy_unlock(bcm); \
local_irq_restore(flags); \
} while (0)
/* Card uses the loopback gain stuff */
#define has_loopback_gain(phy) \
(((phy)->rev > 1) || ((phy)->connected))
u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset);
void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm);
int bcm43xx_phy_init(struct bcm43xx_private *bcm);
void bcm43xx_phy_set_antenna_diversity(struct bcm43xx_private *bcm);
void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm);
int bcm43xx_phy_connect(struct bcm43xx_private *bcm, int connect);
void bcm43xx_phy_lo_b_measure(struct bcm43xx_private *bcm);
void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm);
void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm);
/* Adjust the LocalOscillator to the saved values.
* "fixed" is only set to 1 once in initialization. Set to 0 otherwise.
*/
void bcm43xx_phy_lo_adjust(struct bcm43xx_private *bcm, int fixed);
void bcm43xx_phy_lo_mark_all_unused(struct bcm43xx_private *bcm);
void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
u16 baseband_attenuation);
#endif /* BCM43xx_PHY_H_ */
此差异已折叠。
#ifndef BCM43xx_PIO_H_
#define BCM43xx_PIO_H_
#include "bcm43xx.h"
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/skbuff.h>
#define BCM43xx_PIO_TXCTL 0x00
#define BCM43xx_PIO_TXDATA 0x02
#define BCM43xx_PIO_TXQBUFSIZE 0x04
#define BCM43xx_PIO_RXCTL 0x08
#define BCM43xx_PIO_RXDATA 0x0A
#define BCM43xx_PIO_TXCTL_WRITELO (1 << 0)
#define BCM43xx_PIO_TXCTL_WRITEHI (1 << 1)
#define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2)
#define BCM43xx_PIO_TXCTL_INIT (1 << 3)
#define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7)
#define BCM43xx_PIO_RXCTL_DATAAVAILABLE (1 << 0)
#define BCM43xx_PIO_RXCTL_READY (1 << 1)
/* PIO constants */
#define BCM43xx_PIO_MAXTXDEVQPACKETS 31
#define BCM43xx_PIO_TXQADJUST 80
/* PIO tuning knobs */
#define BCM43xx_PIO_MAXTXPACKETS 256
#ifdef CONFIG_BCM43XX_PIO
struct bcm43xx_pioqueue;
struct bcm43xx_xmitstatus;
struct bcm43xx_pio_txpacket {
struct bcm43xx_pioqueue *queue;
struct ieee80211_txb *txb;
struct list_head list;
u8 xmitted_frags;
u16 xmitted_octets;
};
#define pio_txpacket_getindex(packet) ((int)((packet) - (packet)->queue->tx_packets_cache))
struct bcm43xx_pioqueue {
struct bcm43xx_private *bcm;
u16 mmio_base;
u8 tx_suspended:1,
tx_frozen:1,
need_workarounds:1; /* Workarounds needed for core.rev < 3 */
/* Adjusted size of the device internal TX buffer. */
u16 tx_devq_size;
/* Used octets of the device internal TX buffer. */
u16 tx_devq_used;
/* Used packet slots in the device internal TX buffer. */
u8 tx_devq_packets;
/* Packets from the txfree list can
* be taken on incoming TX requests.
*/
struct list_head txfree;
unsigned int nr_txfree;
/* Packets on the txqueue are queued,
* but not completely written to the chip, yet.
*/
struct list_head txqueue;
/* Packets on the txrunning queue are completely
* posted to the device. We are waiting for the txstatus.
*/
struct list_head txrunning;
/* Total number or packets sent.
* (This counter can obviously wrap).
*/
unsigned int nr_tx_packets;
struct tasklet_struct txtask;
struct bcm43xx_pio_txpacket tx_packets_cache[BCM43xx_PIO_MAXTXPACKETS];
};
static inline
u16 bcm43xx_pio_read(struct bcm43xx_pioqueue *queue,
u16 offset)
{
return bcm43xx_read16(queue->bcm, queue->mmio_base + offset);
}
static inline
void bcm43xx_pio_write(struct bcm43xx_pioqueue *queue,
u16 offset, u16 value)
{
bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value);
mmiowb();
}
int bcm43xx_pio_init(struct bcm43xx_private *bcm);
void bcm43xx_pio_free(struct bcm43xx_private *bcm);
int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
struct ieee80211_txb *txb);
void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status);
void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue);
/* Suspend a TX queue on hardware level. */
void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue);
void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue);
/* Suspend (freeze) the TX tasklet (software level). */
void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm);
void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm);
#else /* CONFIG_BCM43XX_PIO */
static inline
int bcm43xx_pio_init(struct bcm43xx_private *bcm)
{
return 0;
}
static inline
void bcm43xx_pio_free(struct bcm43xx_private *bcm)
{
}
static inline
int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
struct ieee80211_txb *txb)
{
return 0;
}
static inline
void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
struct bcm43xx_xmitstatus *status)
{
}
static inline
void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue)
{
}
static inline
void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue)
{
}
static inline
void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue)
{
}
static inline
void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm)
{
}
static inline
void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm)
{
}
#endif /* CONFIG_BCM43XX_PIO */
#endif /* BCM43xx_PIO_H_ */
此差异已折叠。
/*
Broadcom BCM43xx wireless driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Stefano Brivio <st3@riseup.net>
Michael Buesch <mbuesch@freenet.de>
Danny van Dyk <kugelfang@gentoo.org>
Andreas Jaggi <andreas.jaggi@waterwave.ch>
Some parts of the code in this file are derived from the ipw2200
driver Copyright(c) 2003 - 2004 Intel Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef BCM43xx_POWER_H_
#define BCM43xx_POWER_H_
#include <linux/types.h>
/* Clock sources */
enum {
/* PCI clock */
BCM43xx_PCTL_CLKSRC_PCI,
/* Crystal slow clock oscillator */
BCM43xx_PCTL_CLKSRC_XTALOS,
/* Low power oscillator */
BCM43xx_PCTL_CLKSRC_LOPWROS,
};
struct bcm43xx_private;
int bcm43xx_pctl_init(struct bcm43xx_private *bcm);
int bcm43xx_pctl_set_clock(struct bcm43xx_private *bcm, u16 mode);
int bcm43xx_pctl_set_crystal(struct bcm43xx_private *bcm, int on);
u16 bcm43xx_pctl_powerup_delay(struct bcm43xx_private *bcm);
void bcm43xx_power_saving_ctl_bits(struct bcm43xx_private *bcm,
int bit25, int bit26);
#endif /* BCM43xx_POWER_H_ */
此差异已折叠。
/*
Broadcom BCM43xx wireless driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Stefano Brivio <st3@riseup.net>
Michael Buesch <mbuesch@freenet.de>
Danny van Dyk <kugelfang@gentoo.org>
Andreas Jaggi <andreas.jaggi@waterwave.ch>
Some parts of the code in this file are derived from the ipw2200
driver Copyright(c) 2003 - 2004 Intel Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef BCM43xx_RADIO_H_
#define BCM43xx_RADIO_H_
#include "bcm43xx.h"
#define BCM43xx_RADIO_DEFAULT_CHANNEL_A 36
#define BCM43xx_RADIO_DEFAULT_CHANNEL_BG 6
/* Force antenna 0. */
#define BCM43xx_RADIO_TXANTENNA_0 0
/* Force antenna 1. */
#define BCM43xx_RADIO_TXANTENNA_1 1
/* Use the RX antenna, that was selected for the most recently
* received good PLCP header.
*/
#define BCM43xx_RADIO_TXANTENNA_LASTPLCP 3
#define BCM43xx_RADIO_TXANTENNA_DEFAULT BCM43xx_RADIO_TXANTENNA_LASTPLCP
#define BCM43xx_RADIO_INTERFMODE_NONE 0
#define BCM43xx_RADIO_INTERFMODE_NONWLAN 1
#define BCM43xx_RADIO_INTERFMODE_MANUALWLAN 2
#define BCM43xx_RADIO_INTERFMODE_AUTOWLAN 3
void bcm43xx_radio_lock(struct bcm43xx_private *bcm);
void bcm43xx_radio_unlock(struct bcm43xx_private *bcm);
u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset);
void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val);
u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm);
void bcm43xx_radio_init2060(struct bcm43xx_private *bcm);
void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm);
void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm);
static inline
int bcm43xx_is_hw_radio_enabled(struct bcm43xx_private *bcm)
{
/* function to return state of hardware enable of radio
* returns 0 if radio disabled, 1 if radio enabled
*/
if (bcm->current_core->rev >= 3)
return ((bcm43xx_read32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI)
& BCM43xx_MMIO_RADIO_HWENABLED_HI_MASK)
== 0) ? 1 : 0;
else
return ((bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO)
& BCM43xx_MMIO_RADIO_HWENABLED_LO_MASK)
== 0) ? 0 : 1;
}
int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm, u8 channel,
int synthetic_pu_workaround);
void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower);
void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm,
u16 baseband_attenuation, u16 attenuation,
u16 txpower);
u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm);
u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm);
u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm);
void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val);
void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm);
u8 bcm43xx_radio_aci_detect(struct bcm43xx_private *bcm, u8 channel);
u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm);
int bcm43xx_radio_set_interference_mitigation(struct bcm43xx_private *bcm, int mode);
void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm);
void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm);
s16 bcm43xx_nrssi_hw_read(struct bcm43xx_private *bcm, u16 offset);
void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val);
void bcm43xx_nrssi_hw_update(struct bcm43xx_private *bcm, u16 val);
void bcm43xx_nrssi_mem_update(struct bcm43xx_private *bcm);
void bcm43xx_radio_set_tx_iq(struct bcm43xx_private *bcm);
u16 bcm43xx_radio_calibrationvalue(struct bcm43xx_private *bcm);
#endif /* BCM43xx_RADIO_H_ */
此差异已折叠。
#ifndef BCM43xx_SYSFS_H_
#define BCM43xx_SYSFS_H_
struct bcm43xx_private;
int bcm43xx_sysfs_register(struct bcm43xx_private *bcm);
void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm);
#endif /* BCM43xx_SYSFS_H_ */
此差异已折叠。
/*
Broadcom BCM43xx wireless driver
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
Stefano Brivio <st3@riseup.net>
Michael Buesch <mbuesch@freenet.de>
Danny van Dyk <kugelfang@gentoo.org>
Andreas Jaggi <andreas.jaggi@waterwave.ch>
Some parts of the code in this file are derived from the ipw2200
driver Copyright(c) 2003 - 2004 Intel Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef BCM43xx_WX_H_
#define BCM43xx_WX_H_
extern const struct iw_handler_def bcm43xx_wx_handlers_def;
#endif /* BCM43xx_WX_H_ */
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册