summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2008-03-17 16:57:35 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2008-03-17 16:57:35 +1100
commit0ff2d19d39f29acf6a8c86f9e5bb8aaf4fe4d95e (patch)
tree0f833d94252d7eda983da632917b104616e16037
parent8757b299262f0e87f62480657f64d954967b1630 (diff)
parent26c0f03f6b77c513cb7bc37b73a06819bdbb791b (diff)
Merge commit 'wireless/master'
Conflicts: MAINTAINERS
-rw-r--r--Documentation/feature-removal-schedule.txt27
-rw-r--r--Documentation/laptops/acer-wmi.txt2
-rw-r--r--Documentation/networking/bcm43xx.txt89
-rw-r--r--MAINTAINERS15
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/ath5k/hw.c36
-rw-r--r--drivers/net/wireless/ath5k/phy.c10
-rw-r--r--drivers/net/wireless/b43/main.c4
-rw-r--r--drivers/net/wireless/b43/main.h3
-rw-r--r--drivers/net/wireless/b43/wa.c45
-rw-r--r--drivers/net/wireless/bcm43xx/Kconfig70
-rw-r--r--drivers/net/wireless/bcm43xx/Makefile12
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h997
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c556
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h118
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.c1263
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.h386
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c50
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h8
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ilt.c352
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ilt.h33
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.c307
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.h62
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c4281
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.h133
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c2346
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.h78
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_pio.c674
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_pio.h163
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_power.c393
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_power.h56
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.c2170
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.h115
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c471
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h9
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c1035
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.h36
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.c565
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.h150
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-commands.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-commands.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h314
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c55
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c112
-rw-r--r--drivers/net/wireless/libertas/assoc.c4
-rw-r--r--drivers/net/wireless/libertas/debugfs.c169
-rw-r--r--drivers/net/wireless/libertas/dev.h2
-rw-r--r--drivers/net/wireless/libertas/scan.c145
-rw-r--r--drivers/net/wireless/libertas/scan.h69
-rw-r--r--drivers/net/wireless/libertas/wext.c3
-rw-r--r--drivers/net/wireless/rndis_wlan.c451
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c70
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c71
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c97
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h27
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c62
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c58
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c34
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h25
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c17
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c19
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c100
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c126
-rw-r--r--drivers/ssb/Kconfig6
-rw-r--r--drivers/ssb/Makefile1
-rw-r--r--drivers/ssb/main.c23
-rw-r--r--drivers/ssb/pci.c113
-rw-r--r--drivers/ssb/pcmcia.c518
-rw-r--r--drivers/ssb/sprom.c133
-rw-r--r--drivers/ssb/ssb_private.h17
-rw-r--r--include/linux/ssb/ssb.h4
-rw-r--r--include/net/ieee80211.h1
-rw-r--r--include/net/ieee80211softmac.h373
-rw-r--r--include/net/ieee80211softmac_wx.h99
-rw-r--r--net/ieee80211/Kconfig1
-rw-r--r--net/ieee80211/Makefile1
-rw-r--r--net/ieee80211/softmac/Kconfig12
-rw-r--r--net/ieee80211/softmac/Makefile9
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c489
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_auth.c413
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_event.c189
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_io.c488
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c568
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_priv.h244
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_scan.c254
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c508
-rw-r--r--net/mac80211/Kconfig19
-rw-r--r--net/mac80211/Makefile2
-rw-r--r--net/mac80211/ieee80211.c9
-rw-r--r--net/mac80211/ieee80211_rate.h15
-rw-r--r--net/mac80211/rc80211_simple.c394
119 files changed, 1493 insertions, 22703 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 4e083b2e21d0..3d47d1c052ab 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -240,33 +240,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
-When: 2.6.26 (or after removal of bcm43xx and port of zd1211rw to mac80211)
-Files: net/ieee80211/softmac
-Why: No in-kernel drivers will depend on it any longer.
-Who: John W. Linville <linville@tuxdriver.com>
-
----------------------------
-
-What: rc80211-simple rate control algorithm for mac80211
-When: 2.6.26
-Files: net/mac80211/rc80211-simple.c
-Why: This algorithm was provided for reference but always exhibited bad
- responsiveness and performance and has some serious flaws. It has been
- replaced by rc80211-pid.
-Who: Stefano Brivio <stefano.brivio@polimi.it>
-
----------------------------
-
What (Why):
- include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files
(superseded by xt_TOS/xt_tos target & match)
diff --git a/Documentation/laptops/acer-wmi.txt b/Documentation/laptops/acer-wmi.txt
index 23df051dbf69..79b7dbd22141 100644
--- a/Documentation/laptops/acer-wmi.txt
+++ b/Documentation/laptops/acer-wmi.txt
@@ -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:
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
acer-wmi come with built-in wireless. However, should you feel so inclined to
diff --git a/Documentation/networking/bcm43xx.txt b/Documentation/networking/bcm43xx.txt
deleted file mode 100644
index d602c8d6ff3e..000000000000
--- a/Documentation/networking/bcm43xx.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-
- 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.
diff --git a/MAINTAINERS b/MAINTAINERS
index 451a7dcedb69..39884635ef66 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -834,15 +834,6 @@ L: linux-wireless@vger.kernel.org
W: http://linuxwireless.org/en/users/Drivers/b43
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
P: Sergey S. Kostyliov
M: rathamahata@php4.ru
@@ -3597,12 +3588,6 @@ P: Ben Nizette
M: bn@niasdigital.com
S: Maintained
-SOFTMAC LAYER (IEEE 802.11)
-P: Daniel Drake
-M: dsd@gentoo.org
-L: linux-wireless@vger.kernel.org
-S: Obsolete
-
SOFTWARE RAID (Multiple Disks) SUPPORT
P: Ingo Molnar
M: mingo@redhat.com
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 3c3ef966c95b..f4ca6fd4a29f 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -741,7 +741,6 @@ config P54_PCI
source "drivers/net/wireless/ath5k/Kconfig"
source "drivers/net/wireless/iwlwifi/Kconfig"
source "drivers/net/wireless/hostap/Kconfig"
-source "drivers/net/wireless/bcm43xx/Kconfig"
source "drivers/net/wireless/b43/Kconfig"
source "drivers/net/wireless/b43legacy/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 091dfe2e574e..dd3899747b5c 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -35,7 +35,6 @@ obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o
obj-$(CONFIG_PRISM54) += prism54/
obj-$(CONFIG_HOSTAP) += hostap/
-obj-$(CONFIG_BCM43XX) += bcm43xx/
obj-$(CONFIG_B43) += b43/
obj-$(CONFIG_B43LEGACY) += b43legacy/
obj-$(CONFIG_ZD1211RW) += zd1211rw/
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index a4e312d4226e..677600b302d9 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -1,4 +1,4 @@
- /*
+/*
* Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
* Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
* Copyright (c) 2007 Matthew W. S. Bell <mentor@madwifi.org>
@@ -85,12 +85,12 @@ static int ath5k_hw_disable_pspoll(struct ath5k_hw *);
static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
{
- return turbo == true ? (usec * 80) : (usec * 40);
+ return turbo ? (usec * 80) : (usec * 40);
}
static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
{
- return turbo == true ? (clock / 80) : (clock / 40);
+ return turbo ? (clock / 80) : (clock / 40);
}
/*
@@ -104,7 +104,7 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
data = ath5k_hw_reg_read(ah, reg);
- if ((is_set == true) && (data & flag))
+ if (is_set && (data & flag))
break;
else if ((data & flag) == val)
break;
@@ -617,7 +617,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
*/
/*DCU/Antenna selection not available on 5210*/
if (ah->ah_version != AR5K_AR5210) {
- if (change_channel == true) {
+ if (change_channel) {
/* Seq number for queue 0 -do this for all queues ? */
s_seq = ath5k_hw_reg_read(ah,
AR5K_QUEUE_DFS_SEQNUM(0));
@@ -631,7 +631,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
- if (change_channel == true && ah->ah_rf_banks != NULL)
+ if (change_channel && ah->ah_rf_banks != NULL)
ath5k_hw_get_rf_gain(ah);
@@ -1122,7 +1122,7 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
/* fallthrough */
case AR5K_PM_NETWORK_SLEEP:
- if (set_chip == true)
+ if (set_chip)
ath5k_hw_reg_write(ah,
AR5K_SLEEP_CTL_SLE | sleep_duration,
AR5K_SLEEP_CTL);
@@ -1131,7 +1131,7 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
break;
case AR5K_PM_FULL_SLEEP:
- if (set_chip == true)
+ if (set_chip)
ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
AR5K_SLEEP_CTL);
@@ -1139,7 +1139,7 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
break;
case AR5K_PM_AWAKE:
- if (set_chip == false)
+ if (!set_chip)
goto commit;
ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
@@ -1446,7 +1446,7 @@ int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
AR5K_TXCFG_TXFULL);
- if (increase == false) {
+ if (!increase) {
if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
goto done;
} else
@@ -3205,19 +3205,19 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
return 0;
/* Set Slot time */
- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
AR5K_SLOT_TIME);
/* Set ACK_CTS timeout */
- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
/* Set Transmit Latency */
- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
AR5K_INIT_TRANSMIT_LATENCY_TURBO :
AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
/* Set IFS0 */
- if (ah->ah_turbo == true)
+ if (ah->ah_turbo)
ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
(ah->ah_aifs + tq->tqi_aifs) *
AR5K_INIT_SLOT_TIME_TURBO) <<
@@ -3230,16 +3230,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_INIT_SIFS, AR5K_IFS0);
/* Set IFS1 */
- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
/* Set PHY register 0x9844 (??) */
- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
(ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x38 :
(ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x1C,
AR5K_PHY(17));
/* Set Frame Control Register */
- ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
+ ath5k_hw_reg_write(ah, ah->ah_turbo ?
(AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
AR5K_PHY_TURBO_SHORT | 0x2020) :
(AR5K_PHY_FRAME_CTL_INI | 0x1020),
@@ -3278,7 +3278,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
/*
* Calculate and set retry limits
*/
- if (ah->ah_software_retry == true) {
+ if (ah->ah_software_retry) {
/* XXX Need to test this */
retry_lg = ah->ah_limit_tx_retries;
retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index ee1dc0fc6ea2..890ecce8bedc 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -981,14 +981,14 @@ static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits,
entry = ((first - 1) / 8) + offset;
position = (first - 1) % 8;
- if (set == true)
+ if (set)
data = ath5k_hw_bitswap(reg, bits);
for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
last = (position + left > 8) ? 8 : position + left;
mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8);
- if (set == true) {
+ if (set) {
rf[entry] &= ~mask;
rf[entry] |= ((data << position) << (col * 8)) & mask;
data >>= (8 - position);
@@ -1001,7 +1001,7 @@ static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits,
left -= 8 - position;
}
- data = set == true ? 1 : ath5k_hw_bitswap(data, bits);
+ data = set ? 1 : ath5k_hw_bitswap(data, bits);
return data;
}
@@ -1986,7 +1986,7 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
ATH5K_TRACE(ah->ah_sc);
- if (ah->ah_calibration == false ||
+ if (!ah->ah_calibration ||
ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
goto done;
@@ -2218,7 +2218,7 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
- if (ah->ah_txpower.txp_tpc == true)
+ if (ah->ah_txpower.txp_tpc)
ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
else
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 694e29570e5d..6c58f8b5dcf5 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2154,7 +2154,7 @@ static void b43_gpio_cleanup(struct b43_wldev *dev)
}
/* http://bcm-specs.sipsolutions.net/EnableMac */
-void b43_mac_enable(struct b43_wldev *dev)
+static void b43_mac_enable(struct b43_wldev *dev)
{
dev->mac_suspended--;
B43_WARN_ON(dev->mac_suspended < 0);
@@ -2178,7 +2178,7 @@ void b43_mac_enable(struct b43_wldev *dev)
}
/* http://bcm-specs.sipsolutions.net/SuspendMAC */
-void b43_mac_suspend(struct b43_wldev *dev)
+static void b43_mac_suspend(struct b43_wldev *dev)
{
int i;
u32 tmp;
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 1197975f9207..5230aeca78bf 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -106,9 +106,6 @@ void b43_dummy_transmission(struct b43_wldev *dev);
void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags);
-void b43_mac_suspend(struct b43_wldev *dev);
-void b43_mac_enable(struct b43_wldev *dev);
-
void b43_controller_restart(struct b43_wldev *dev, const char *reason);
#define B43_PS_ENABLED (1 << 0) /* Force enable hardware power saving */
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index e632125cb772..daa94211f838 100644
--- a/drivers/net/wireless/b43/wa.c
+++ b/drivers/net/wireless/b43/wa.c
@@ -204,42 +204,43 @@ static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */
b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]);
}
+static void b43_write_null_nst(struct b43_wldev *dev)
+{
+ int i;
+
+ for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
+ b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, i, 0);
+}
+
+static void b43_write_nst(struct b43_wldev *dev, const u16 *nst)
+{
+ int i;
+
+ for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
+ b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, i, nst[i]);
+}
+
static void b43_wa_nst(struct b43_wldev *dev) /* Noise scale table */
{
struct b43_phy *phy = &dev->phy;
- int i;
if (phy->type == B43_PHYTYPE_A) {
if (phy->rev <= 1)
- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
- i, 0);
+ b43_write_null_nst(dev);
else if (phy->rev == 2)
- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
- i, b43_tab_noisescalea2[i]);
+ b43_write_nst(dev, b43_tab_noisescalea2);
else if (phy->rev == 3)
- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
- i, b43_tab_noisescalea3[i]);
+ b43_write_nst(dev, b43_tab_noisescalea3);
else
- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
- i, b43_tab_noisescaleg3[i]);
+ b43_write_nst(dev, b43_tab_noisescaleg3);
} else {
if (phy->rev >= 6) {
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
- i, b43_tab_noisescaleg3[i]);
+ b43_write_nst(dev, b43_tab_noisescaleg3);
else
- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
- i, b43_tab_noisescaleg2[i]);
+ b43_write_nst(dev, b43_tab_noisescaleg2);
} else {
- for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
- b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
- i, b43_tab_noisescaleg1[i]);
+ b43_write_nst(dev, b43_tab_noisescaleg1);
}
}
}
diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig
deleted file mode 100644
index afb8f4305c24..000000000000
--- a/drivers/net/wireless/bcm43xx/Kconfig
+++ /dev/null
@@ -1,70 +0,0 @@
-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
diff --git a/drivers/net/wireless/bcm43xx/Makefile b/drivers/net/wireless/bcm43xx/Makefile
deleted file mode 100644
index bb5220c629d2..000000000000
--- a/drivers/net/wireless/bcm43xx/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-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)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
deleted file mode 100644
index 2ebd2edf5862..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ /dev/null
@@ -1,997 +0,0 @@
-#ifndef BCM43xx_H_
-#define BCM43xx_H_
-
-#include <linux/hw_random.h>
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/stringify.h>
-#include <linux/pci.h>
-#include <net/ieee80211.h>
-#include <net/ieee80211softmac.h>
-#include <asm/atomic.h>
-#include <asm/io.h>
-
-
-#include "bcm43xx_debugfs.h"
-#include "bcm43xx_leds.h"
-
-
-#define PFX KBUILD_MODNAME ": "
-
-#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50
-#define BCM43xx_IRQWAIT_MAX_RETRIES 100
-
-#define BCM43xx_IO_SIZE 8192
-
-/* Active Core PCI Configuration Register. */
-#define BCM43xx_PCICFG_ACTIVE_CORE 0x80
-/* SPROM control register. */
-#define BCM43xx_PCICFG_SPROMCTL 0x88
-/* Interrupt Control PCI Configuration Register. (Only on PCI cores with rev >= 6) */
-#define BCM43xx_PCICFG_ICR 0x94
-
-/* MMIO offsets */
-#define BCM43xx_MMIO_DMA0_REASON 0x20
-#define BCM43xx_MMIO_DMA0_IRQ_MASK 0x24
-#define BCM43xx_MMIO_DMA1_REASON 0x28
-#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x2C
-#define BCM43xx_MMIO_DMA2_REASON 0x30
-#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x34
-#define BCM43xx_MMIO_DMA3_REASON 0x38
-#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x3C
-#define BCM43xx_MMIO_DMA4_REASON 0x40
-#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x44
-#define BCM43xx_MMIO_DMA5_REASON 0x48
-#define BCM43xx_MMIO_DMA5_IRQ_MASK 0x4C
-#define BCM43xx_MMIO_STATUS_BITFIELD 0x120
-#define BCM43xx_MMIO_STATUS2_BITFIELD 0x124
-#define BCM43xx_MMIO_GEN_IRQ_REASON 0x128
-#define BCM43xx_MMIO_GEN_IRQ_MASK 0x12C
-#define BCM43xx_MMIO_RAM_CONTROL 0x130
-#define BCM43xx_MMIO_RAM_DATA 0x134
-#define BCM43xx_MMIO_PS_STATUS 0x140
-#define BCM43xx_MMIO_RADIO_HWENABLED_HI 0x158
-#define BCM43xx_MMIO_SHM_CONTROL 0x160
-#define BCM43xx_MMIO_SHM_DATA 0x164
-#define BCM43xx_MMIO_SHM_DATA_UNALIGNED 0x166
-#define BCM43xx_MMIO_XMITSTAT_0 0x170
-#define BCM43xx_MMIO_XMITSTAT_1 0x174
-#define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */
-#define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
-
-/* 32-bit DMA */
-#define BCM43xx_MMIO_DMA32_BASE0 0x200
-#define BCM43xx_MMIO_DMA32_BASE1 0x220
-#define BCM43xx_MMIO_DMA32_BASE2 0x240
-#define BCM43xx_MMIO_DMA32_BASE3 0x260
-#define BCM43xx_MMIO_DMA32_BASE4 0x280
-#define BCM43xx_MMIO_DMA32_BASE5 0x2A0
-/* 64-bit DMA */
-#define BCM43xx_MMIO_DMA64_BASE0 0x200
-#define BCM43xx_MMIO_DMA64_BASE1 0x240
-#define BCM43xx_MMIO_DMA64_BASE2 0x280
-#define BCM43xx_MMIO_DMA64_BASE3 0x2C0
-#define BCM43xx_MMIO_DMA64_BASE4 0x300
-#define BCM43xx_MMIO_DMA64_BASE5 0x340
-/* PIO */
-#define BCM43xx_MMIO_PIO1_BASE 0x300
-#define BCM43xx_MMIO_PIO2_BASE 0x310
-#define BCM43xx_MMIO_PIO3_BASE 0x320
-#define BCM43xx_MMIO_PIO4_BASE 0x330
-
-#define BCM43xx_MMIO_PHY_VER 0x3E0
-#define BCM43xx_MMIO_PHY_RADIO 0x3E2
-#define BCM43xx_MMIO_ANTENNA 0x3E8
-#define BCM43xx_MMIO_CHANNEL 0x3F0
-#define BCM43xx_MMIO_CHANNEL_EXT 0x3F4
-#define BCM43xx_MMIO_RADIO_CONTROL 0x3F6
-#define BCM43xx_MMIO_RADIO_DATA_HIGH 0x3F8
-#define BCM43xx_MMIO_RADIO_DATA_LOW 0x3FA
-#define BCM43xx_MMIO_PHY_CONTROL 0x3FC
-#define BCM43xx_MMIO_PHY_DATA 0x3FE
-#define BCM43xx_MMIO_MACFILTER_CONTROL 0x420
-#define BCM43xx_MMIO_MACFILTER_DATA 0x422
-#define BCM43xx_MMIO_RADIO_HWENABLED_LO 0x49A
-#define BCM43xx_MMIO_GPIO_CONTROL 0x49C
-#define BCM43xx_MMIO_GPIO_MASK 0x49E
-#define BCM43xx_MMIO_TSF_0 0x632 /* core rev < 3 only */
-#define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */
-#define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */
-#define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */
-#define BCM43xx_MMIO_RNG 0x65A
-#define BCM43xx_MMIO_POWERUP_DELAY 0x6A8
-
-/* SPROM offsets. */
-#define BCM43xx_SPROM_BASE 0x1000
-#define BCM43xx_SPROM_BOARDFLAGS2 0x1c
-#define BCM43xx_SPROM_IL0MACADDR 0x24
-#define BCM43xx_SPROM_ET0MACADDR 0x27
-#define BCM43xx_SPROM_ET1MACADDR 0x2a
-#define BCM43xx_SPROM_ETHPHY 0x2d
-#define BCM43xx_SPROM_BOARDREV 0x2e
-#define BCM43xx_SPROM_PA0B0 0x2f
-#define BCM43xx_SPROM_PA0B1 0x30
-#define BCM43xx_SPROM_PA0B2 0x31
-#define BCM43xx_SPROM_WL0GPIO0 0x32
-#define BCM43xx_SPROM_WL0GPIO2 0x33
-#define BCM43xx_SPROM_MAXPWR 0x34
-#define BCM43xx_SPROM_PA1B0 0x35
-#define BCM43xx_SPROM_PA1B1 0x36
-#define BCM43xx_SPROM_PA1B2 0x37
-#define BCM43xx_SPROM_IDL_TSSI_TGT 0x38
-#define BCM43xx_SPROM_BOARDFLAGS 0x39
-#define BCM43xx_SPROM_ANTENNA_GAIN 0x3a
-#define BCM43xx_SPROM_VERSION 0x3f
-
-/* BCM43xx_SPROM_BOARDFLAGS values */
-#define BCM43xx_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
-#define BCM43xx_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */
-#define BCM43xx_BFL_AIRLINEMODE 0x0004 /* implements GPIO 13 radio disable indication */
-#define BCM43xx_BFL_RSSI 0x0008 /* software calculates nrssi slope. */
-#define BCM43xx_BFL_ENETSPI 0x0010 /* has ephy roboswitch spi */
-#define BCM43xx_BFL_XTAL_NOSLOW 0x0020 /* no slow clock available */
-#define BCM43xx_BFL_CCKHIPWR 0x0040 /* can do high power CCK transmission */
-#define BCM43xx_BFL_ENETADM 0x0080 /* has ADMtek switch */
-#define BCM43xx_BFL_ENETVLAN 0x0100 /* can do vlan */
-#define BCM43xx_BFL_AFTERBURNER 0x0200 /* supports Afterburner mode */
-#define BCM43xx_BFL_NOPCI 0x0400 /* leaves PCI floating */
-#define BCM43xx_BFL_FEM 0x0800 /* supports the Front End Module */
-#define BCM43xx_BFL_EXTLNA 0x1000 /* has an external LNA */
-#define BCM43xx_BFL_HGPA 0x2000 /* had high gain PA */
-#define BCM43xx_BFL_BTCMOD 0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */
-#define BCM43xx_BFL_ALTIQ 0x8000 /* alternate I/Q settings */
-
-/* GPIO register offset, in both ChipCommon and PCI core. */
-#define BCM43xx_GPIO_CONTROL 0x6c
-
-/* SHM Routing */
-#define BCM43xx_SHM_SHARED 0x0001
-#define BCM43xx_SHM_WIRELESS 0x0002
-#define BCM43xx_SHM_PCM 0x0003
-#define BCM43xx_SHM_HWMAC 0x0004
-#define BCM43xx_SHM_UCODE 0x0300
-
-/* MacFilter offsets. */
-#define BCM43xx_MACFILTER_SELF 0x0000
-#define BCM43xx_MACFILTER_ASSOC 0x0003
-
-/* Chipcommon registers. */
-#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04
-#define BCM43xx_CHIPCOMMON_CTL 0x28
-#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0
-#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4
-#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8
-#define BCM43xx_CHIPCOMMON_SYSCLKCTL 0xC0
-
-/* PCI core specific registers. */
-#define BCM43xx_PCICORE_BCAST_ADDR 0x50
-#define BCM43xx_PCICORE_BCAST_DATA 0x54
-#define BCM43xx_PCICORE_SBTOPCI2 0x108
-
-/* SBTOPCI2 values. */
-#define BCM43xx_SBTOPCI2_PREFETCH 0x4
-#define BCM43xx_SBTOPCI2_BURST 0x8
-#define BCM43xx_SBTOPCI2_MEMREAD_MULTI 0x20
-
-/* PCI-E core registers. */
-#define BCM43xx_PCIECORE_REG_ADDR 0x0130
-#define BCM43xx_PCIECORE_REG_DATA 0x0134
-#define BCM43xx_PCIECORE_MDIO_CTL 0x0128
-#define BCM43xx_PCIECORE_MDIO_DATA 0x012C
-
-/* PCI-E registers. */
-#define BCM43xx_PCIE_TLP_WORKAROUND 0x0004
-#define BCM43xx_PCIE_DLLP_LINKCTL 0x0100
-
-/* PCI-E MDIO bits. */
-#define BCM43xx_PCIE_MDIO_ST 0x40000000
-#define BCM43xx_PCIE_MDIO_WT 0x10000000
-#define BCM43xx_PCIE_MDIO_DEV 22
-#define BCM43xx_PCIE_MDIO_REG 18
-#define BCM43xx_PCIE_MDIO_TA 0x00020000
-#define BCM43xx_PCIE_MDIO_TC 0x0100
-
-/* MDIO devices. */
-#define BCM43xx_MDIO_SERDES_RX 0x1F
-
-/* SERDES RX registers. */
-#define BCM43xx_SERDES_RXTIMER 0x2
-#define BCM43xx_SERDES_CDR 0x6
-#define BCM43xx_SERDES_CDR_BW 0x7
-
-/* Chipcommon capabilities. */
-#define BCM43xx_CAPABILITIES_PCTL 0x00040000
-#define BCM43xx_CAPABILITIES_PLLMASK 0x00030000
-#define BCM43xx_CAPABILITIES_PLLSHIFT 16
-#define BCM43xx_CAPABILITIES_FLASHMASK 0x00000700
-#define BCM43xx_CAPABILITIES_FLASHSHIFT 8
-#define BCM43xx_CAPABILITIES_EXTBUSPRESENT 0x00000040
-#define BCM43xx_CAPABILITIES_UARTGPIO 0x00000020
-#define BCM43xx_CAPABILITIES_UARTCLOCKMASK 0x00000018
-#define BCM43xx_CAPABILITIES_UARTCLOCKSHIFT 3
-#define BCM43xx_CAPABILITIES_MIPSBIGENDIAN 0x00000004
-#define BCM43xx_CAPABILITIES_NRUARTSMASK 0x00000003
-
-/* PowerControl */
-#define BCM43xx_PCTL_IN 0xB0
-#define BCM43xx_PCTL_OUT 0xB4
-#define BCM43xx_PCTL_OUTENABLE 0xB8
-#define BCM43xx_PCTL_XTAL_POWERUP 0x40
-#define BCM43xx_PCTL_PLL_POWERDOWN 0x80
-
-/* PowerControl Clock Modes */
-#define BCM43xx_PCTL_CLK_FAST 0x00
-#define BCM43xx_PCTL_CLK_SLOW 0x01
-#define BCM43xx_PCTL_CLK_DYNAMIC 0x02
-
-#define BCM43xx_PCTL_FORCE_SLOW 0x0800
-#define BCM43xx_PCTL_FORCE_PLL 0x1000
-#define BCM43xx_PCTL_DYN_XTAL 0x2000
-
-/* COREIDs */
-#define BCM43xx_COREID_CHIPCOMMON 0x800
-#define BCM43xx_COREID_ILINE20 0x801
-#define BCM43xx_COREID_SDRAM 0x803
-#define BCM43xx_COREID_PCI 0x804
-#define BCM43xx_COREID_MIPS 0x805
-#define BCM43xx_COREID_ETHERNET 0x806
-#define BCM43xx_COREID_V90 0x807
-#define BCM43xx_COREID_USB11_HOSTDEV 0x80a
-#define BCM43xx_COREID_IPSEC 0x80b
-#define BCM43xx_COREID_PCMCIA 0x80d
-#define BCM43xx_COREID_EXT_IF 0x80f
-#define BCM43xx_COREID_80211 0x812
-#define BCM43xx_COREID_MIPS_3302 0x816
-#define BCM43xx_COREID_USB11_HOST 0x817
-#define BCM43xx_COREID_USB11_DEV 0x818
-#define BCM43xx_COREID_USB20_HOST 0x819
-#define BCM43xx_COREID_USB20_DEV 0x81a
-#define BCM43xx_COREID_SDIO_HOST 0x81b
-#define BCM43xx_COREID_PCIE 0x820
-
-/* Core Information Registers */
-#define BCM43xx_CIR_BASE 0xf00
-#define BCM43xx_CIR_SBTPSFLAG (BCM43xx_CIR_BASE + 0x18)
-#define BCM43xx_CIR_SBIMSTATE (BCM43xx_CIR_BASE + 0x90)
-#define BCM43xx_CIR_SBINTVEC (BCM43xx_CIR_BASE + 0x94)
-#define BCM43xx_CIR_SBTMSTATELOW (BCM43xx_CIR_BASE + 0x98)
-#define BCM43xx_CIR_SBTMSTATEHIGH (BCM43xx_CIR_BASE + 0x9c)
-#define BCM43xx_CIR_SBIMCONFIGLOW (BCM43xx_CIR_BASE + 0xa8)
-#define BCM43xx_CIR_SB_ID_HI (BCM43xx_CIR_BASE + 0xfc)
-
-/* Mask to get the Backplane Flag Number from SBTPSFLAG. */
-#define BCM43xx_BACKPLANE_FLAG_NR_MASK 0x3f
-
-/* SBIMCONFIGLOW values/masks. */
-#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK 0x00000007
-#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT 0
-#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK 0x00000070
-#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT 4
-#define BCM43xx_SBIMCONFIGLOW_CONNID_MASK 0x00ff0000
-#define BCM43xx_SBIMCONFIGLOW_CONNID_SHIFT 16
-
-/* sbtmstatelow state flags */
-#define BCM43xx_SBTMSTATELOW_RESET 0x01
-#define BCM43xx_SBTMSTATELOW_REJECT 0x02
-#define BCM43xx_SBTMSTATELOW_CLOCK 0x10000
-#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000
-#define BCM43xx_SBTMSTATELOW_G_MODE_ENABLE 0x20000000
-
-/* sbtmstatehigh state flags */
-#define BCM43xx_SBTMSTATEHIGH_SERROR 0x00000001
-#define BCM43xx_SBTMSTATEHIGH_BUSY 0x00000004
-#define BCM43xx_SBTMSTATEHIGH_TIMEOUT 0x00000020
-#define BCM43xx_SBTMSTATEHIGH_G_PHY_AVAIL 0x00010000
-#define BCM43xx_SBTMSTATEHIGH_A_PHY_AVAIL 0x00020000
-#define BCM43xx_SBTMSTATEHIGH_COREFLAGS 0x1FFF0000
-#define BCM43xx_SBTMSTATEHIGH_DMA64BIT 0x10000000
-#define BCM43xx_SBTMSTATEHIGH_GATEDCLK 0x20000000
-#define BCM43xx_SBTMSTATEHIGH_BISTFAILED 0x40000000
-#define BCM43xx_SBTMSTATEHIGH_BISTCOMPLETE 0x80000000
-
-/* sbimstate flags */
-#define BCM43xx_SBIMSTATE_IB_ERROR 0x20000
-#define BCM43xx_SBIMSTATE_TIMEOUT 0x40000
-
-/* PHYVersioning */
-#define BCM43xx_PHYTYPE_A 0x00
-#define BCM43xx_PHYTYPE_B 0x01
-#define BCM43xx_PHYTYPE_G 0x02
-
-/* PHYRegisters */
-#define BCM43xx_PHY_ILT_A_CTRL 0x0072
-#define BCM43xx_PHY_ILT_A_DATA1 0x0073
-#define BCM43xx_PHY_ILT_A_DATA2 0x0074
-#define BCM43xx_PHY_G_LO_CONTROL 0x0810
-#define BCM43xx_PHY_ILT_G_CTRL 0x0472
-#define BCM43xx_PHY_ILT_G_DATA1 0x0473
-#define BCM43xx_PHY_ILT_G_DATA2 0x0474
-#define BCM43xx_PHY_A_PCTL 0x007B
-#define BCM43xx_PHY_G_PCTL 0x0029
-#define BCM43xx_PHY_A_CRS 0x0029
-#define BCM43xx_PHY_RADIO_BITFIELD 0x0401
-#define BCM43xx_PHY_G_CRS 0x0429
-#define BCM43xx_PHY_NRSSILT_CTRL 0x0803
-#define BCM43xx_PHY_NRSSILT_DATA 0x0804
-
-/* RadioRegisters */
-#define BCM43xx_RADIOCTL_ID 0x01
-
-/* StatusBitField */
-#define BCM43xx_SBF_MAC_ENABLED 0x00000001
-#define BCM43xx_SBF_2 0x00000002 /*FIXME: fix name*/
-#define BCM43xx_SBF_CORE_READY 0x00000004
-#define BCM43xx_SBF_400 0x00000400 /*FIXME: fix name*/
-#define BCM43xx_SBF_4000 0x00004000 /*FIXME: fix name*/
-#define BCM43xx_SBF_8000 0x00008000 /*FIXME: fix name*/
-#define BCM43xx_SBF_XFER_REG_BYTESWAP 0x00010000
-#define BCM43xx_SBF_MODE_NOTADHOC 0x00020000
-#define BCM43xx_SBF_MODE_AP 0x00040000
-#define BCM43xx_SBF_RADIOREG_LOCK 0x00080000
-#define BCM43xx_SBF_MODE_MONITOR 0x00400000
-#define BCM43xx_SBF_MODE_PROMISC 0x01000000
-#define BCM43xx_SBF_PS1 0x02000000
-#define BCM43xx_SBF_PS2 0x04000000
-#define BCM43xx_SBF_NO_SSID_BCAST 0x08000000
-#define BCM43xx_SBF_TIME_UPDATE 0x10000000
-#define BCM43xx_SBF_MODE_G 0x80000000
-
-/* Microcode */
-#define BCM43xx_UCODE_REVISION 0x0000
-#define BCM43xx_UCODE_PATCHLEVEL 0x0002
-#define BCM43xx_UCODE_DATE 0x0004
-#define BCM43xx_UCODE_TIME 0x0006
-#define BCM43xx_UCODE_STATUS 0x0040
-
-/* MicrocodeFlagsBitfield (addr + lo-word values?)*/
-#define BCM43xx_UCODEFLAGS_OFFSET 0x005E
-
-#define BCM43xx_UCODEFLAG_AUTODIV 0x0001
-#define BCM43xx_UCODEFLAG_UNKBGPHY 0x0002
-#define BCM43xx_UCODEFLAG_UNKBPHY 0x0004
-#define BCM43xx_UCODEFLAG_UNKGPHY 0x0020
-#define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040
-#define BCM43xx_UCODEFLAG_JAPAN 0x0080
-
-/* Hardware Radio Enable masks */
-#define BCM43xx_MMIO_RADIO_HWENABLED_HI_MASK (1 << 16)
-#define BCM43xx_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4)
-
-/* Generic-Interrupt reasons. */
-#define BCM43xx_IRQ_READY (1 << 0)
-#define BCM43xx_IRQ_BEACON (1 << 1)
-#define BCM43xx_IRQ_PS (1 << 2)
-#define BCM43xx_IRQ_REG124 (1 << 5)
-#define BCM43xx_IRQ_PMQ (1 << 6)
-#define BCM43xx_IRQ_PIO_WORKAROUND (1 << 8)
-#define BCM43xx_IRQ_XMIT_ERROR (1 << 11)
-#define BCM43xx_IRQ_RX (1 << 15)
-#define BCM43xx_IRQ_SCAN (1 << 16)
-#define BCM43xx_IRQ_NOISE (1 << 18)
-#define BCM43xx_IRQ_XMIT_STATUS (1 << 29)
-
-#define BCM43xx_IRQ_ALL 0xffffffff
-#define BCM43xx_IRQ_INITIAL (BCM43xx_IRQ_PS | \
- BCM43xx_IRQ_REG124 | \
- BCM43xx_IRQ_PMQ | \
- BCM43xx_IRQ_XMIT_ERROR | \
- BCM43xx_IRQ_RX | \
- BCM43xx_IRQ_SCAN | \
- BCM43xx_IRQ_NOISE | \
- BCM43xx_IRQ_XMIT_STATUS)
-
-
-/* Initial default iw_mode */
-#define BCM43xx_INITIAL_IWMODE IW_MODE_INFRA
-
-/* Bus type PCI. */
-#define BCM43xx_BUSTYPE_PCI 0
-/* Bus type Silicone Backplane Bus. */
-#define BCM43xx_BUSTYPE_SB 1
-/* Bus type PCMCIA. */
-#define BCM43xx_BUSTYPE_PCMCIA 2
-
-/* Threshold values. */
-#define BCM43xx_MIN_RTS_THRESHOLD 1U
-#define BCM43xx_MAX_RTS_THRESHOLD 2304U
-#define BCM43xx_DEFAULT_RTS_THRESHOLD BCM43xx_MAX_RTS_THRESHOLD
-
-#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7
-#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4
-
-/* FIXME: the next line is a guess as to what the maximum RSSI value might be */
-#define RX_RSSI_MAX 60
-
-/* Max size of a security key */
-#define BCM43xx_SEC_KEYSIZE 16
-/* Security algorithms. */
-enum {
- BCM43xx_SEC_ALGO_NONE = 0, /* unencrypted, as of TX header. */
- BCM43xx_SEC_ALGO_WEP,
- BCM43xx_SEC_ALGO_UNKNOWN,
- BCM43xx_SEC_ALGO_AES,
- BCM43xx_SEC_ALGO_WEP104,
- BCM43xx_SEC_ALGO_TKIP,
-};
-
-#ifdef assert
-# undef assert
-#endif
-#ifdef CONFIG_BCM43XX_DEBUG
-#define assert(expr) \
- do { \
- if (unlikely(!(expr))) { \
- printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", \
- #expr, __FILE__, __LINE__, __FUNCTION__); \
- } \
- } while (0)
-#else
-#define assert(expr) do { /* nothing */ } while (0)
-#endif
-
-/* rate limited printk(). */
-#ifdef printkl
-# undef printkl
-#endif
-#define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0)
-/* rate limited printk() for debugging */
-#ifdef dprintkl
-# undef dprintkl
-#endif
-#ifdef CONFIG_BCM43XX_DEBUG
-# define dprintkl printkl
-#else
-# define dprintkl(f, x...) do { /* nothing */ } while (0)
-#endif
-
-/* Helper macro for if branches.
- * An if branch marked with this macro is only taken in DEBUG mode.
- * Example:
- * if (DEBUG_ONLY(foo == bar)) {
- * do something
- * }
- * In DEBUG mode, the branch will be taken if (foo == bar).
- * In non-DEBUG mode, the branch will never be taken.
- */
-#ifdef DEBUG_ONLY
-# undef DEBUG_ONLY
-#endif
-#ifdef CONFIG_BCM43XX_DEBUG
-# define DEBUG_ONLY(x) (x)
-#else
-# define DEBUG_ONLY(x) 0
-#endif
-
-/* debugging printk() */
-#ifdef dprintk
-# undef dprintk
-#endif
-#ifdef CONFIG_BCM43XX_DEBUG
-# define dprintk(f, x...) do { printk(f ,##x); } while (0)
-#else
-# define dprintk(f, x...) do { /* nothing */ } while (0)
-#endif
-
-
-struct net_device;
-struct pci_dev;
-struct bcm43xx_dmaring;
-struct bcm43xx_pioqueue;
-
-struct bcm43xx_initval {
- __be16 offset;
- __be16 size;
- __be32 value;
-} __attribute__((__packed__));
-
-/* Values for bcm430x_sprominfo.locale */
-enum {
- BCM43xx_LOCALE_WORLD = 0,
- BCM43xx_LOCALE_THAILAND,
- BCM43xx_LOCALE_ISRAEL,
- BCM43xx_LOCALE_JORDAN,
- BCM43xx_LOCALE_CHINA,
- BCM43xx_LOCALE_JAPAN,
- BCM43xx_LOCALE_USA_CANADA_ANZ,
- BCM43xx_LOCALE_EUROPE,
- BCM43xx_LOCALE_USA_LOW,
- BCM43xx_LOCALE_JAPAN_HIGH,
- BCM43xx_LOCALE_ALL,
- BCM43xx_LOCALE_NONE,
-};
-
-#define BCM43xx_SPROM_SIZE 64 /* in 16-bit words. */
-struct bcm43xx_sprominfo {
- u16 boardflags2;
- u8 il0macaddr[6];
- u8 et0macaddr[6];
- u8 et1macaddr[6];
- u8 et0phyaddr:5;
- u8 et1phyaddr:5;
- u8 boardrev;
- u8 locale:4;
- u8 antennas_aphy:2;
- u8 antennas_bgphy:2;
- u16 pa0b0;
- u16 pa0b1;
- u16 pa0b2;
- u8 wl0gpio0;
- u8 wl0gpio1;
- u8 wl0gpio2;
- u8 wl0gpio3;
- u8 maxpower_aphy;
- u8 maxpower_bgphy;
- u16 pa1b0;
- u16 pa1b1;
- u16 pa1b2;
- u8 idle_tssi_tgt_aphy;
- u8 idle_tssi_tgt_bgphy;
- u16 boardflags;
- u16 antennagain_aphy;
- u16 antennagain_bgphy;
-};
-
-/* Value pair to measure the LocalOscillator. */
-struct bcm43xx_lopair {
- s8 low;
- s8 high;
- u8 used:1;
-};
-#define BCM43xx_LO_COUNT (14*4)
-
-struct bcm43xx_phyinfo {
- /* Hardware Data */
- u8 analog;
- u8 type;
- u8 rev;
- u16 antenna_diversity;
- u16 savedpctlreg;
- u16 minlowsig[2];
- u16 minlowsigpos[2];
- u8 connected:1,
- calibrated:1,
- is_locked:1, /* used in bcm43xx_phy_{un}lock() */
- dyn_tssi_tbl:1; /* used in bcm43xx_phy_init_tssi2dbm_table() */
- /* LO Measurement Data.
- * Use bcm43xx_get_lopair() to get a value.
- */
- struct bcm43xx_lopair *_lo_pairs;
-
- /* TSSI to dBm table in use */
- const s8 *tssi2dbm;
- /* idle TSSI value */
- s8 idle_tssi;
-
- /* Values from bcm43xx_calc_loopback_gain() */
- u16 loopback_gain[2];
-
- /* PHY lock for core.rev < 3
- * This lock is only used by bcm43xx_phy_{un}lock()
- */
- spinlock_t lock;
-
- /* Firmware. */
- const struct firmware *ucode;
- const struct firmware *pcm;
- const struct firmware *initvals0;
- const struct firmware *initvals1;
-};
-
-
-struct bcm43xx_radioinfo {
- u16 manufact;
- u16 version;
- u8 revision;
-
- /* Desired TX power in dBm Q5.2 */
- u16 txpower_desired;
- /* TX Power control values. */
- union {
- /* B/G PHY */
- struct {
- u16 baseband_atten;
- u16 radio_atten;
- u16 txctl1;
- u16 txctl2;
- };
- /* A PHY */
- struct {
- u16 txpwr_offset;
- };
- };
-
- /* Current Interference Mitigation mode */
- int interfmode;
- /* Stack of saved values from the Interference Mitigation code.
- * Each value in the stack is layed out as follows:
- * bit 0-11: offset
- * bit 12-15: register ID
- * bit 16-32: value
- * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT
- */
-#define BCM43xx_INTERFSTACK_SIZE 26
- u32 interfstack[BCM43xx_INTERFSTACK_SIZE];
-
- /* Saved values from the NRSSI Slope calculation */
- s16 nrssi[2];
- s32 nrssislope;
- /* In memory nrssi lookup table. */
- s8 nrssi_lt[64];
-
- /* current channel */
- u8 channel;
- u8 initial_channel;
-
- u16 lofcal;
-
- u16 initval;
-
- u8 enabled:1;
- /* ACI (adjacent channel interference) flags. */
- u8 aci_enable:1,
- aci_wlan_automatic:1,
- aci_hw_rssi:1;
-};
-
-/* Data structures for DMA transmission, per 80211 core. */
-struct bcm43xx_dma {
- struct bcm43xx_dmaring *tx_ring0;
- struct bcm43xx_dmaring *tx_ring1;
- struct bcm43xx_dmaring *tx_ring2;
- struct bcm43xx_dmaring *tx_ring3;
- struct bcm43xx_dmaring *tx_ring4;
- struct bcm43xx_dmaring *tx_ring5;
-
- struct bcm43xx_dmaring *rx_ring0;
- struct bcm43xx_dmaring *rx_ring3; /* only available on core.rev < 5 */
-};
-
-/* Data structures for PIO transmission, per 80211 core. */
-struct bcm43xx_pio {
- struct bcm43xx_pioqueue *queue0;
- struct bcm43xx_pioqueue *queue1;
- struct bcm43xx_pioqueue *queue2;
- struct bcm43xx_pioqueue *queue3;
-};
-
-#define BCM43xx_MAX_80211_CORES 2
-
-/* Generic information about a core. */
-struct bcm43xx_coreinfo {
- u8 available:1,
- enabled:1,
- initialized:1;
- /** core_rev revision number */
- u8 rev;
- /** Index number for _switch_core() */
- u8 index;
- /** core_id ID number */
- u16 id;
- /** Core-specific data. */
- void *priv;
-};
-
-/* Additional information for each 80211 core. */
-struct bcm43xx_coreinfo_80211 {
- /* PHY device. */
- struct bcm43xx_phyinfo phy;
- /* Radio device. */
- struct bcm43xx_radioinfo radio;
- union {
- /* DMA context. */
- struct bcm43xx_dma dma;
- /* PIO context. */
- struct bcm43xx_pio pio;
- };
-};
-
-/* Context information for a noise calculation (Link Quality). */
-struct bcm43xx_noise_calculation {
- struct bcm43xx_coreinfo *core_at_start;
- u8 channel_at_start;
- u8 calculation_running:1;
- u8 nr_samples;
- s8 samples[8][4];
-};
-
-struct bcm43xx_stats {
- u8 noise;
- struct iw_statistics wstats;
- /* Store the last TX/RX times here for updating the leds. */
- unsigned long last_tx;
- unsigned long last_rx;
-};
-
-struct bcm43xx_key {
- u8 enabled:1;
- u8 algorithm;
-};
-
-/* Driver initialization status. */
-enum {
- BCM43xx_STAT_UNINIT, /* Uninitialized. */
- BCM43xx_STAT_INITIALIZING, /* init_board() in progress. */
- BCM43xx_STAT_INITIALIZED, /* Fully operational. */
- BCM43xx_STAT_SHUTTINGDOWN, /* free_board() in progress. */
- BCM43xx_STAT_RESTARTING, /* controller_restart() called. */
-};
-#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status)
-#define bcm43xx_set_status(bcm, stat) do { \
- atomic_set(&(bcm)->init_status, (stat)); \
- smp_wmb(); \
- } while (0)
-
-/* *** THEORY OF LOCKING ***
- *
- * We have two different locks in the bcm43xx driver.
- * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
- * and the device registers. This mutex does _not_ protect
- * against concurrency from the IRQ handler.
- * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
- *
- * Please note that, if you only take the irq_lock, you are not protected
- * against concurrency from the periodic work handlers.
- * Most times you want to take _both_ locks.
- */
-
-struct bcm43xx_private {
- struct ieee80211_device *ieee;
- struct ieee80211softmac_device *softmac;
-
- struct net_device *net_dev;
- struct pci_dev *pci_dev;
- unsigned int irq;
-
- void __iomem *mmio_addr;
-
- spinlock_t irq_lock;
- struct mutex mutex;
-
- /* Driver initialization status BCM43xx_STAT_*** */
- atomic_t init_status;
-
- u16 was_initialized:1, /* for PCI suspend/resume. */
- __using_pio:1, /* Internal, use bcm43xx_using_pio(). */
- bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */
- reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */
- short_preamble:1, /* TRUE, if short preamble is enabled. */
- firmware_norelease:1, /* Do not release the firmware. Used on suspend. */
- radio_hw_enable:1; /* TRUE if radio is hardware enabled */
-
- struct bcm43xx_stats stats;
-
- /* Bus type we are connected to.
- * This is currently always BCM43xx_BUSTYPE_PCI
- */
- u8 bustype;
- u64 dma_mask;
-
- u16 board_vendor;
- u16 board_type;
- u16 board_revision;
-
- u16 chip_id;
- u8 chip_rev;
- u8 chip_package;
-
- struct bcm43xx_sprominfo sprom;
-#define BCM43xx_NR_LEDS 4
- struct bcm43xx_led leds[BCM43xx_NR_LEDS];
- spinlock_t leds_lock;
-
- /* The currently active core. */
- struct bcm43xx_coreinfo *current_core;
- struct bcm43xx_coreinfo *active_80211_core;
- /* coreinfo structs for all possible cores follow.
- * Note that a core might not exist.
- * So check the coreinfo flags before using it.
- */
- struct bcm43xx_coreinfo core_chipcommon;
- struct bcm43xx_coreinfo core_pci;
- struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
- /* Additional information, specific to the 80211 cores. */
- struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
- /* Number of available 80211 cores. */
- int nr_80211_available;
-
- u32 chipcommon_capabilities;
-
- /* Reason code of the last interrupt. */
- u32 irq_reason;
- u32 dma_reason[6];
- /* saved irq enable/disable state bitfield. */
- u32 irq_savedstate;
- /* Link Quality calculation context. */
- struct bcm43xx_noise_calculation noisecalc;
- /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
- int mac_suspended;
-
- /* Threshold values. */
- //TODO: The RTS thr has to be _used_. Currently, it is only set via WX.
- u32 rts_threshold;
-
- /* Interrupt Service Routine tasklet (bottom-half) */
- struct tasklet_struct isr_tasklet;
-
- /* Periodic tasks */
- struct delayed_work periodic_work;
- unsigned int periodic_state;
-
- struct work_struct restart_work;
-
- /* Informational stuff. */
- char nick[IW_ESSID_MAX_SIZE + 1];
-
- /* encryption/decryption */
- u16 security_offset;
- struct bcm43xx_key key[54];
- u8 default_key_idx;
-
- /* Random Number Generator. */
- struct hwrng rng;
- char rng_name[20 + 1];
-
- /* Debugging stuff follows. */
-#ifdef CONFIG_BCM43XX_DEBUG
- struct bcm43xx_dfsentry *dfsentry;
-#endif
-};
-
-
-static inline
-struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
-{
- return ieee80211softmac_priv(dev);
-}
-
-struct device;
-
-static inline
-struct bcm43xx_private * dev_to_bcm(struct device *dev)
-{
- struct net_device *net_dev;
- struct bcm43xx_private *bcm;
-
- net_dev = dev_get_drvdata(dev);
- bcm = bcm43xx_priv(net_dev);
-
- return bcm;
-}
-
-
-/* Helper function, which returns a boolean.
- * TRUE, if PIO is used; FALSE, if DMA is used.
- */
-#if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO)
-static inline
-int bcm43xx_using_pio(struct bcm43xx_private *bcm)
-{
- return bcm->__using_pio;
-}
-#elif defined(CONFIG_BCM43XX_DMA)
-static inline
-int bcm43xx_using_pio(struct bcm43xx_private *bcm)
-{
- return 0;
-}
-#elif defined(CONFIG_BCM43XX_PIO)
-static inline
-int bcm43xx_using_pio(struct bcm43xx_private *bcm)
-{
- return 1;
-}
-#else
-# error "Using neither DMA nor PIO? Confused..."
-#endif
-
-/* Helper functions to access data structures private to the 80211 cores.
- * Note that we _must_ have an 80211 core mapped when calling
- * any of these functions.
- */
-static inline
-struct bcm43xx_coreinfo_80211 *
-bcm43xx_current_80211_priv(struct bcm43xx_private *bcm)
-{
- assert(bcm->current_core->id == BCM43xx_COREID_80211);
- return bcm->current_core->priv;
-}
-static inline
-struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
-{
- assert(bcm43xx_using_pio(bcm));
- return &(bcm43xx_current_80211_priv(bcm)->pio);
-}
-static inline
-struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
-{
- assert(!bcm43xx_using_pio(bcm));
- return &(bcm43xx_current_80211_priv(bcm)->dma);
-}
-static inline
-struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
-{
- return &(bcm43xx_current_80211_priv(bcm)->phy);
-}
-static inline
-struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
-{
- return &(bcm43xx_current_80211_priv(bcm)->radio);
-}
-
-
-static inline
-struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy,
- u16 radio_attenuation,
- u16 baseband_attenuation)
-{
- return phy->_lo_pairs + (radio_attenuation + 14 * (baseband_attenuation / 2));
-}
-
-
-static inline
-u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset)
-{
- return ioread16(bcm->mmio_addr + offset);
-}
-
-static inline
-void bcm43xx_write16(struct bcm43xx_private *bcm, u16 offset, u16 value)
-{
- iowrite16(value, bcm->mmio_addr + offset);
-}
-
-static inline
-u32 bcm43xx_read32(struct bcm43xx_private *bcm, u16 offset)
-{
- return ioread32(bcm->mmio_addr + offset);
-}
-
-static inline
-void bcm43xx_write32(struct bcm43xx_private *bcm, u16 offset, u32 value)
-{
- iowrite32(value, bcm->mmio_addr + offset);
-}
-
-static inline
-int bcm43xx_pci_read_config16(struct bcm43xx_private *bcm, int offset, u16 *value)
-{
- return pci_read_config_word(bcm->pci_dev, offset, value);
-}
-
-static inline
-int bcm43xx_pci_read_config32(struct bcm43xx_private *bcm, int offset, u32 *value)
-{
- return pci_read_config_dword(bcm->pci_dev, offset, value);
-}
-
-static inline
-int bcm43xx_pci_write_config16(struct bcm43xx_private *bcm, int offset, u16 value)
-{
- return pci_write_config_word(bcm->pci_dev, offset, value);
-}
-
-static inline
-int bcm43xx_pci_write_config32(struct bcm43xx_private *bcm, int offset, u32 value)
-{
- return pci_write_config_dword(bcm->pci_dev, offset, value);
-}
-
-/** Limit a value between two limits */
-#ifdef limit_value
-# undef limit_value
-#endif
-#define limit_value(value, min, max) \
- ({ \
- typeof(value) __value = (value); \
- typeof(value) __min = (min); \
- typeof(value) __max = (max); \
- if (__value < __min) \
- __value = __min; \
- else if (__value > __max) \
- __value = __max; \
- __value; \
- })
-
-#endif /* BCM43xx_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
deleted file mode 100644
index 76e9dd843faa..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
-
- 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");
-}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
deleted file mode 100644
index a40d1af35545..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
deleted file mode 100644
index 1f7731fcfbd5..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+++ /dev/null
@@ -1,1263 +0,0 @@
-/*
-
- Broadcom BCM43xx wireless driver
-
- DMA ringbuffer and descriptor allocation/management
-
- Copyright (c) 2005, 2006 Michael Buesch <mbuesch@freenet.de>
-
- Some code in this file is derived from the b44.c driver
- Copyright (C) 2002 David S. Miller
- Copyright (C) Pekka Pietikainen
-
- 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_dma.h"
-#include "bcm43xx_main.h"
-#include "bcm43xx_debugfs.h"
-#include "bcm43xx_power.h"
-#include "bcm43xx_xmit.h"
-
-#include <linux/dma-mapping.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/skbuff.h>
-
-
-static inline int free_slots(struct bcm43xx_dmaring *ring)
-{
- return (ring->nr_slots - ring->used_slots);
-}
-
-static inline int next_slot(struct bcm43xx_dmaring *ring, int slot)
-{
- assert(slot >= -1 && slot <= ring->nr_slots - 1);
- if (slot == ring->nr_slots - 1)
- return 0;
- return slot + 1;
-}
-
-static inline int prev_slot(struct bcm43xx_dmaring *ring, int slot)
-{
- assert(slot >= 0 && slot <= ring->nr_slots - 1);
- if (slot == 0)
- return ring->nr_slots - 1;
- return slot - 1;
-}
-
-/* Request a slot for usage. */
-static inline
-int request_slot(struct bcm43xx_dmaring *ring)
-{
- int slot;
-
- assert(ring->tx);
- assert(!ring->suspended);
- assert(free_slots(ring) != 0);
-
- slot = next_slot(ring, ring->current_slot);
- ring->current_slot = slot;
- ring->used_slots++;
-
- /* Check the number of available slots and suspend TX,
- * if we are running low on free slots.
- */
- if (unlikely(free_slots(ring) < ring->suspend_mark)) {
- netif_stop_queue(ring->bcm->net_dev);
- ring->suspended = 1;
- }
-#ifdef CONFIG_BCM43XX_DEBUG
- if (ring->used_slots > ring->max_used_slots)
- ring->max_used_slots = ring->used_slots;
-#endif /* CONFIG_BCM43XX_DEBUG*/
-
- return slot;
-}
-
-/* Return a slot to the free slots. */
-static inline
-void return_slot(struct bcm43xx_dmaring *ring, int slot)
-{
- assert(ring->tx);
-
- ring->used_slots--;
-
- /* Check if TX is suspended and check if we have
- * enough free slots to resume it again.
- */
- if (unlikely(ring->suspended)) {
- if (free_slots(ring) >= ring->resume_mark) {
- ring->suspended = 0;
- netif_wake_queue(ring->bcm->net_dev);
- }
- }
-}
-
-u16 bcm43xx_dmacontroller_base(int dma64bit, int controller_idx)
-{
- static const u16 map64[] = {
- BCM43xx_MMIO_DMA64_BASE0,
- BCM43xx_MMIO_DMA64_BASE1,
- BCM43xx_MMIO_DMA64_BASE2,
- BCM43xx_MMIO_DMA64_BASE3,
- BCM43xx_MMIO_DMA64_BASE4,
- BCM43xx_MMIO_DMA64_BASE5,
- };
- static const u16 map32[] = {
- BCM43xx_MMIO_DMA32_BASE0,
- BCM43xx_MMIO_DMA32_BASE1,
- BCM43xx_MMIO_DMA32_BASE2,
- BCM43xx_MMIO_DMA32_BASE3,
- BCM43xx_MMIO_DMA32_BASE4,
- BCM43xx_MMIO_DMA32_BASE5,
- };
-
- if (dma64bit) {
- assert(controller_idx >= 0 &&
- controller_idx < ARRAY_SIZE(map64));
- return map64[controller_idx];
- }
- assert(controller_idx >= 0 &&
- controller_idx < ARRAY_SIZE(map32));
- return map32[controller_idx];
-}
-
-static inline
-dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
- unsigned char *buf,
- size_t len,
- int tx)
-{
- dma_addr_t dmaaddr;
- int direction = PCI_DMA_FROMDEVICE;
-
- if (tx)
- direction = PCI_DMA_TODEVICE;
-
- dmaaddr = pci_map_single(ring->bcm->pci_dev,
- buf, len,
- direction);
-
- return dmaaddr;
-}
-
-static inline
-void unmap_descbuffer(struct bcm43xx_dmaring *ring,
- dma_addr_t addr,
- size_t len,
- int tx)
-{
- if (tx) {
- pci_unmap_single(ring->bcm->pci_dev,
- addr, len,
- PCI_DMA_TODEVICE);
- } else {
- pci_unmap_single(ring->bcm->pci_dev,
- addr, len,
- PCI_DMA_FROMDEVICE);
- }
-}
-
-static inline
-void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,
- dma_addr_t addr,
- size_t len)
-{
- assert(!ring->tx);
-
- pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
- addr, len, PCI_DMA_FROMDEVICE);
-}
-
-static inline
-void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,
- dma_addr_t addr,
- size_t len)
-{
- assert(!ring->tx);
-
- pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
- addr, len, PCI_DMA_TODEVICE);
-}
-
-/* Unmap and free a descriptor buffer. */
-static inline
-void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
- struct bcm43xx_dmadesc_meta *meta,
- int irq_context)
-{
- assert(meta->skb);
- if (irq_context)
- dev_kfree_skb_irq(meta->skb);
- else
- dev_kfree_skb(meta->skb);
- meta->skb = NULL;
-}
-
-static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
-{
- ring->descbase = pci_alloc_consistent(ring->bcm->pci_dev, BCM43xx_DMA_RINGMEMSIZE,
- &(ring->dmabase));
- if (!ring->descbase) {
- /* Allocation may have failed due to pci_alloc_consistent
- insisting on use of GFP_DMA, which is more restrictive
- than necessary... */
- struct dma_desc *rx_ring;
- dma_addr_t rx_ring_dma;
-
- rx_ring = kzalloc(BCM43xx_DMA_RINGMEMSIZE, GFP_KERNEL);
- if (!rx_ring)
- goto out_err;
-
- rx_ring_dma = pci_map_single(ring->bcm->pci_dev, rx_ring,
- BCM43xx_DMA_RINGMEMSIZE,
- PCI_DMA_BIDIRECTIONAL);
-
- if (pci_dma_mapping_error(rx_ring_dma) ||
- rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {
- /* Sigh... */
- if (!pci_dma_mapping_error(rx_ring_dma))
- pci_unmap_single(ring->bcm->pci_dev,
- rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,
- PCI_DMA_BIDIRECTIONAL);
- rx_ring_dma = pci_map_single(ring->bcm->pci_dev,
- rx_ring, BCM43xx_DMA_RINGMEMSIZE,
- PCI_DMA_BIDIRECTIONAL);
- if (pci_dma_mapping_error(rx_ring_dma) ||
- rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {
- assert(0);
- if (!pci_dma_mapping_error(rx_ring_dma))
- pci_unmap_single(ring->bcm->pci_dev,
- rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,
- PCI_DMA_BIDIRECTIONAL);
- goto out_err;
- }
- }
-
- ring->descbase = rx_ring;
- ring->dmabase = rx_ring_dma;
- }
- memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
-
- return 0;
-out_err:
- printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
- return -ENOMEM;
-}
-
-static void free_ringmemory(struct bcm43xx_dmaring *ring)
-{
- struct device *dev = &(ring->bcm->pci_dev->dev);
-
- dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
- ring->descbase, ring->dmabase);
-}
-
-/* Reset the RX DMA channel */
-int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
- u16 mmio_base, int dma64)
-{
- int i;
- u32 value;
- u16 offset;
-
- offset = dma64 ? BCM43xx_DMA64_RXCTL : BCM43xx_DMA32_RXCTL;
- bcm43xx_write32(bcm, mmio_base + offset, 0);
- for (i = 0; i < 1000; i++) {
- offset = dma64 ? BCM43xx_DMA64_RXSTATUS : BCM43xx_DMA32_RXSTATUS;
- value = bcm43xx_read32(bcm, mmio_base + offset);
- if (dma64) {
- value &= BCM43xx_DMA64_RXSTAT;
- if (value == BCM43xx_DMA64_RXSTAT_DISABLED) {
- i = -1;
- break;
- }
- } else {
- value &= BCM43xx_DMA32_RXSTATE;
- if (value == BCM43xx_DMA32_RXSTAT_DISABLED) {
- i = -1;
- break;
- }
- }
- udelay(10);
- }
- if (i != -1) {
- printk(KERN_ERR PFX "Error: Wait on DMA RX status timed out.\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-/* Reset the RX DMA channel */
-int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
- u16 mmio_base, int dma64)
-{
- int i;
- u32 value;
- u16 offset;
-
- for (i = 0; i < 1000; i++) {
- offset = dma64 ? BCM43xx_DMA64_TXSTATUS : BCM43xx_DMA32_TXSTATUS;
- value = bcm43xx_read32(bcm, mmio_base + offset);
- if (dma64) {
- value &= BCM43xx_DMA64_TXSTAT;
- if (value == BCM43xx_DMA64_TXSTAT_DISABLED ||
- value == BCM43xx_DMA64_TXSTAT_IDLEWAIT ||
- value == BCM43xx_DMA64_TXSTAT_STOPPED)
- break;
- } else {
- value &= BCM43xx_DMA32_TXSTATE;
- if (value == BCM43xx_DMA32_TXSTAT_DISABLED ||
- value == BCM43xx_DMA32_TXSTAT_IDLEWAIT ||
- value == BCM43xx_DMA32_TXSTAT_STOPPED)
- break;
- }
- udelay(10);
- }
- offset = dma64 ? BCM43xx_DMA64_TXCTL : BCM43xx_DMA32_TXCTL;
- bcm43xx_write32(bcm, mmio_base + offset, 0);
- for (i = 0; i < 1000; i++) {
- offset = dma64 ? BCM43xx_DMA64_TXSTATUS : BCM43xx_DMA32_TXSTATUS;
- value = bcm43xx_read32(bcm, mmio_base + offset);
- if (dma64) {
- value &= BCM43xx_DMA64_TXSTAT;
- if (value == BCM43xx_DMA64_TXSTAT_DISABLED) {
- i = -1;
- break;
- }
- } else {
- value &= BCM43xx_DMA32_TXSTATE;
- if (value == BCM43xx_DMA32_TXSTAT_DISABLED) {
- i = -1;
- break;
- }
- }
- udelay(10);
- }
- if (i != -1) {
- printk(KERN_ERR PFX "Error: Wait on DMA TX status timed out.\n");
- return -ENODEV;
- }
- /* ensure the reset is completed. */
- udelay(300);
-
- return 0;
-}
-
-static void fill_descriptor(struct bcm43xx_dmaring *ring,
- struct bcm43xx_dmadesc_generic *desc,
- dma_addr_t dmaaddr,
- u16 bufsize,
- int start, int end, int irq)
-{
- int slot;
-
- slot = bcm43xx_dma_desc2idx(ring, desc);
- assert(slot >= 0 && slot < ring->nr_slots);
-
- if (ring->dma64) {
- u32 ctl0 = 0, ctl1 = 0;
- u32 addrlo, addrhi;
- u32 addrext;
-
- addrlo = (u32)(dmaaddr & 0xFFFFFFFF);
- addrhi = (((u64)dmaaddr >> 32) & ~BCM43xx_DMA64_ROUTING);
- addrext = (((u64)dmaaddr >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
- addrhi |= ring->routing;
- if (slot == ring->nr_slots - 1)
- ctl0 |= BCM43xx_DMA64_DCTL0_DTABLEEND;
- if (start)
- ctl0 |= BCM43xx_DMA64_DCTL0_FRAMESTART;
- if (end)
- ctl0 |= BCM43xx_DMA64_DCTL0_FRAMEEND;
- if (irq)
- ctl0 |= BCM43xx_DMA64_DCTL0_IRQ;
- ctl1 |= (bufsize - ring->frameoffset)
- & BCM43xx_DMA64_DCTL1_BYTECNT;
- ctl1 |= (addrext << BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT)
- & BCM43xx_DMA64_DCTL1_ADDREXT_MASK;
-
- desc->dma64.control0 = cpu_to_le32(ctl0);
- desc->dma64.control1 = cpu_to_le32(ctl1);
- desc->dma64.address_low = cpu_to_le32(addrlo);
- desc->dma64.address_high = cpu_to_le32(addrhi);
- } else {
- u32 ctl;
- u32 addr;
- u32 addrext;
-
- addr = (u32)(dmaaddr & ~BCM43xx_DMA32_ROUTING);
- addrext = (u32)(dmaaddr & BCM43xx_DMA32_ROUTING)
- >> BCM43xx_DMA32_ROUTING_SHIFT;
- addr |= ring->routing;
- ctl = (bufsize - ring->frameoffset)
- & BCM43xx_DMA32_DCTL_BYTECNT;
- if (slot == ring->nr_slots - 1)
- ctl |= BCM43xx_DMA32_DCTL_DTABLEEND;
- if (start)
- ctl |= BCM43xx_DMA32_DCTL_FRAMESTART;
- if (end)
- ctl |= BCM43xx_DMA32_DCTL_FRAMEEND;
- if (irq)
- ctl |= BCM43xx_DMA32_DCTL_IRQ;
- ctl |= (addrext << BCM43xx_DMA32_DCTL_ADDREXT_SHIFT)
- & BCM43xx_DMA32_DCTL_ADDREXT_MASK;
-
- desc->dma32.control = cpu_to_le32(ctl);
- desc->dma32.address = cpu_to_le32(addr);
- }
-}
-
-static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
- struct bcm43xx_dmadesc_generic *desc,
- struct bcm43xx_dmadesc_meta *meta,
- gfp_t gfp_flags)
-{
- struct bcm43xx_rxhdr *rxhdr;
- struct bcm43xx_hwxmitstatus *xmitstat;
- dma_addr_t dmaaddr;
- struct sk_buff *skb;
-
- assert(!ring->tx);
-
- skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
- if (unlikely(!skb))
- return -ENOMEM;
- dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
- /* This hardware bug work-around adapted from the b44 driver.
- The chip may be unable to do PCI DMA to/from anything above 1GB */
- if (pci_dma_mapping_error(dmaaddr) ||
- dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
- /* This one has 30-bit addressing... */
- if (!pci_dma_mapping_error(dmaaddr))
- pci_unmap_single(ring->bcm->pci_dev,
- dmaaddr, ring->rx_buffersize,
- PCI_DMA_FROMDEVICE);
- dev_kfree_skb_any(skb);
- skb = __dev_alloc_skb(ring->rx_buffersize,GFP_DMA);
- if (skb == NULL)
- return -ENOMEM;
- dmaaddr = pci_map_single(ring->bcm->pci_dev,
- skb->data, ring->rx_buffersize,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(dmaaddr) ||
- dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
- assert(0);
- dev_kfree_skb_any(skb);
- return -ENOMEM;
- }
- }
- meta->skb = skb;
- meta->dmaaddr = dmaaddr;
- skb->dev = ring->bcm->net_dev;
-
- fill_descriptor(ring, desc, dmaaddr,
- ring->rx_buffersize, 0, 0, 0);
-
- rxhdr = (struct bcm43xx_rxhdr *)(skb->data);
- rxhdr->frame_length = 0;
- rxhdr->flags1 = 0;
- xmitstat = (struct bcm43xx_hwxmitstatus *)(skb->data);
- xmitstat->cookie = 0;
-
- return 0;
-}
-
-/* Allocate the initial descbuffers.
- * This is used for an RX ring only.
- */
-static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring)
-{
- int i, err = -ENOMEM;
- struct bcm43xx_dmadesc_generic *desc;
- struct bcm43xx_dmadesc_meta *meta;
-
- for (i = 0; i < ring->nr_slots; i++) {
- desc = bcm43xx_dma_idx2desc(ring, i, &meta);
-
- err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
- if (err)
- goto err_unwind;
- }
- mb();
- ring->used_slots = ring->nr_slots;
- err = 0;
-out:
- return err;
-
-err_unwind:
- for (i--; i >= 0; i--) {
- desc = bcm43xx_dma_idx2desc(ring, i, &meta);
-
- unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
- dev_kfree_skb(meta->skb);
- }
- goto out;
-}
-
-/* Do initial setup of the DMA controller.
- * Reset the controller, write the ring busaddress
- * and switch the "enable" bit on.
- */
-static int dmacontroller_setup(struct bcm43xx_dmaring *ring)
-{
- int err = 0;
- u32 value;
- u32 addrext;
-
- if (ring->tx) {
- if (ring->dma64) {
- u64 ringbase = (u64)(ring->dmabase);
-
- addrext = ((ringbase >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
- value = BCM43xx_DMA64_TXENABLE;
- value |= (addrext << BCM43xx_DMA64_TXADDREXT_SHIFT)
- & BCM43xx_DMA64_TXADDREXT_MASK;
- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL, value);
- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO,
- (ringbase & 0xFFFFFFFF));
- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI,
- ((ringbase >> 32) & ~BCM43xx_DMA64_ROUTING)
- | ring->routing);
- } else {
- u32 ringbase = (u32)(ring->dmabase);
-
- addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
- value = BCM43xx_DMA32_TXENABLE;
- value |= (addrext << BCM43xx_DMA32_TXADDREXT_SHIFT)
- & BCM43xx_DMA32_TXADDREXT_MASK;
- bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL, value);
- bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING,
- (ringbase & ~BCM43xx_DMA32_ROUTING)
- | ring->routing);
- }
- } else {
- err = alloc_initial_descbuffers(ring);
- if (err)
- goto out;
- if (ring->dma64) {
- u64 ringbase = (u64)(ring->dmabase);
-
- addrext = ((ringbase >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
- value = (ring->frameoffset << BCM43xx_DMA64_RXFROFF_SHIFT);
- value |= BCM43xx_DMA64_RXENABLE;
- value |= (addrext << BCM43xx_DMA64_RXADDREXT_SHIFT)
- & BCM43xx_DMA64_RXADDREXT_MASK;
- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXCTL, value);
- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO,
- (ringbase & 0xFFFFFFFF));
- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI,
- ((ringbase >> 32) & ~BCM43xx_DMA64_ROUTING)
- | ring->routing);
- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX, 200);
- } else {
- u32 ringbase = (u32)(ring->dmabase);
-
- addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
- value = (ring->frameoffset << BCM43xx_DMA32_RXFROFF_SHIFT);
- value |= BCM43xx_DMA32_RXENABLE;
- value |= (addrext << BCM43xx_DMA32_RXADDREXT_SHIFT)
- & BCM43xx_DMA32_RXADDREXT_MASK;
- bcm43xx_dma_write(ring, BCM43xx_DMA32_RXCTL, value);
- bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING,
- (ringbase & ~BCM43xx_DMA32_ROUTING)
- | ring->routing);
- bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX, 200);
- }
- }
-
-out:
- return err;
-}
-
-/* Shutdown the DMA controller. */
-static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring)
-{
- if (ring->tx) {
- bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base, ring->dma64);
- if (ring->dma64) {
- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO, 0);
- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI, 0);
- } else
- bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING, 0);
- } else {
- bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base, ring->dma64);
- if (ring->dma64) {
- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO, 0);
- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI, 0);
- } else
- bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING, 0);
- }
-}
-
-static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
-{
- struct bcm43xx_dmadesc_generic *desc;
- struct bcm43xx_dmadesc_meta *meta;
- int i;
-
- if (!ring->used_slots)
- return;
- for (i = 0; i < ring->nr_slots; i++) {
- desc = bcm43xx_dma_idx2desc(ring, i, &meta);
-
- if (!meta->skb) {
- assert(ring->tx);
- continue;
- }
- if (ring->tx) {
- unmap_descbuffer(ring, meta->dmaaddr,
- meta->skb->len, 1);
- } else {
- unmap_descbuffer(ring, meta->dmaaddr,
- ring->rx_buffersize, 0);
- }
- free_descriptor_buffer(ring, meta, 0);
- }
-}
-
-/* Main initialization function. */
-static
-struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
- int controller_index,
- int for_tx,
- int dma64)
-{
- struct bcm43xx_dmaring *ring;
- int err;
- int nr_slots;
-
- ring = kzalloc(sizeof(*ring), GFP_KERNEL);
- if (!ring)
- goto out;
-
- nr_slots = BCM43xx_RXRING_SLOTS;
- if (for_tx)
- nr_slots = BCM43xx_TXRING_SLOTS;
-
- ring->meta = kcalloc(nr_slots, sizeof(struct bcm43xx_dmadesc_meta),
- GFP_KERNEL);
- if (!ring->meta)
- goto err_kfree_ring;
-
- ring->routing = BCM43xx_DMA32_CLIENTTRANS;
- if (dma64)
- ring->routing = BCM43xx_DMA64_CLIENTTRANS;
-
- ring->bcm = bcm;
- ring->nr_slots = nr_slots;
- ring->suspend_mark = ring->nr_slots * BCM43xx_TXSUSPEND_PERCENT / 100;
- ring->resume_mark = ring->nr_slots * BCM43xx_TXRESUME_PERCENT / 100;
- assert(ring->suspend_mark < ring->resume_mark);
- ring->mmio_base = bcm43xx_dmacontroller_base(dma64, controller_index);
- ring->index = controller_index;
- ring->dma64 = !!dma64;
- if (for_tx) {
- ring->tx = 1;
- ring->current_slot = -1;
- } else {
- if (ring->index == 0) {
- ring->rx_buffersize = BCM43xx_DMA0_RX_BUFFERSIZE;
- ring->frameoffset = BCM43xx_DMA0_RX_FRAMEOFFSET;
- } else if (ring->index == 3) {
- ring->rx_buffersize = BCM43xx_DMA3_RX_BUFFERSIZE;
- ring->frameoffset = BCM43xx_DMA3_RX_FRAMEOFFSET;
- } else
- assert(0);
- }
-
- err = alloc_ringmemory(ring);
- if (err)
- goto err_kfree_meta;
- err = dmacontroller_setup(ring);
- if (err)
- goto err_free_ringmemory;
- return ring;
-
-out:
- printk(KERN_ERR PFX "Error in bcm43xx_setup_dmaring\n");
- return ring;
-
-err_free_ringmemory:
- free_ringmemory(ring);
-err_kfree_meta:
- kfree(ring->meta);
-err_kfree_ring:
- kfree(ring);
- ring = NULL;
- goto out;
-}
-
-/* Main cleanup function. */
-static void bcm43xx_destroy_dmaring(struct bcm43xx_dmaring *ring)
-{
- if (!ring)
- return;
-
- dprintk(KERN_INFO PFX "DMA-%s 0x%04X (%s) max used slots: %d/%d\n",
- (ring->dma64) ? "64" : "32",
- ring->mmio_base,
- (ring->tx) ? "TX" : "RX",
- ring->max_used_slots, ring->nr_slots);
- /* Device IRQs are disabled prior entering this function,
- * so no need to take care of concurrency with rx handler stuff.
- */
- dmacontroller_cleanup(ring);
- free_all_descbuffers(ring);
- free_ringmemory(ring);
-
- kfree(ring->meta);
- kfree(ring);
-}
-
-void bcm43xx_dma_free(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_dma *dma;
-
- if (bcm43xx_using_pio(bcm))
- return;
- dma = bcm43xx_current_dma(bcm);
-
- bcm43xx_destroy_dmaring(dma->rx_ring3);
- dma->rx_ring3 = NULL;
- bcm43xx_destroy_dmaring(dma->rx_ring0);
- dma->rx_ring0 = NULL;
-
- bcm43xx_destroy_dmaring(dma->tx_ring5);
- dma->tx_ring5 = NULL;
- bcm43xx_destroy_dmaring(dma->tx_ring4);
- dma->tx_ring4 = NULL;
- bcm43xx_destroy_dmaring(dma->tx_ring3);
- dma->tx_ring3 = NULL;
- bcm43xx_destroy_dmaring(dma->tx_ring2);
- dma->tx_ring2 = NULL;
- bcm43xx_destroy_dmaring(dma->tx_ring1);
- dma->tx_ring1 = NULL;
- bcm43xx_destroy_dmaring(dma->tx_ring0);
- dma->tx_ring0 = NULL;
-}
-
-int bcm43xx_dma_init(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
- struct bcm43xx_dmaring *ring;
- int err = -ENOMEM;
- int dma64 = 0;
-
- bcm->dma_mask = bcm43xx_get_supported_dma_mask(bcm);
- if (bcm->dma_mask == DMA_64BIT_MASK)
- dma64 = 1;
- err = pci_set_dma_mask(bcm->pci_dev, bcm->dma_mask);
- if (err)
- goto no_dma;
- err = pci_set_consistent_dma_mask(bcm->pci_dev, bcm->dma_mask);
- if (err)
- goto no_dma;
-
- /* setup TX DMA channels. */
- ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
- if (!ring)
- goto out;
- dma->tx_ring0 = ring;
-
- ring = bcm43xx_setup_dmaring(bcm, 1, 1, dma64);
- if (!ring)
- goto err_destroy_tx0;
- dma->tx_ring1 = ring;
-
- ring = bcm43xx_setup_dmaring(bcm, 2, 1, dma64);
- if (!ring)
- goto err_destroy_tx1;
- dma->tx_ring2 = ring;
-
- ring = bcm43xx_setup_dmaring(bcm, 3, 1, dma64);
- if (!ring)
- goto err_destroy_tx2;
- dma->tx_ring3 = ring;
-
- ring = bcm43xx_setup_dmaring(bcm, 4, 1, dma64);
- if (!ring)
- goto err_destroy_tx3;
- dma->tx_ring4 = ring;
-
- ring = bcm43xx_setup_dmaring(bcm, 5, 1, dma64);
- if (!ring)
- goto err_destroy_tx4;
- dma->tx_ring5 = ring;
-
- /* setup RX DMA channels. */
- ring = bcm43xx_setup_dmaring(bcm, 0, 0, dma64);
- if (!ring)
- goto err_destroy_tx5;
- dma->rx_ring0 = ring;
-
- if (bcm->current_core->rev < 5) {
- ring = bcm43xx_setup_dmaring(bcm, 3, 0, dma64);
- if (!ring)
- goto err_destroy_rx0;
- dma->rx_ring3 = ring;
- }
-
- dprintk(KERN_INFO PFX "%d-bit DMA initialized\n",
- (bcm->dma_mask == DMA_64BIT_MASK) ? 64 :
- (bcm->dma_mask == DMA_32BIT_MASK) ? 32 : 30);
- err = 0;
-out:
- return err;
-
-err_destroy_rx0:
- bcm43xx_destroy_dmaring(dma->rx_ring0);
- dma->rx_ring0 = NULL;
-err_destroy_tx5:
- bcm43xx_destroy_dmaring(dma->tx_ring5);
- dma->tx_ring5 = NULL;
-err_destroy_tx4:
- bcm43xx_destroy_dmaring(dma->tx_ring4);
- dma->tx_ring4 = NULL;
-err_destroy_tx3:
- bcm43xx_destroy_dmaring(dma->tx_ring3);
- dma->tx_ring3 = NULL;
-err_destroy_tx2:
- bcm43xx_destroy_dmaring(dma->tx_ring2);
- dma->tx_ring2 = NULL;
-err_destroy_tx1:
- bcm43xx_destroy_dmaring(dma->tx_ring1);
- dma->tx_ring1 = NULL;
-err_destroy_tx0:
- bcm43xx_destroy_dmaring(dma->tx_ring0);
- dma->tx_ring0 = NULL;
-no_dma:
-#ifdef CONFIG_BCM43XX_PIO
- printk(KERN_WARNING PFX "DMA not supported on this device."
- " Falling back to PIO.\n");
- bcm->__using_pio = 1;
- return -ENOSYS;
-#else
- printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
- "Please recompile the driver with PIO support.\n");
- return -ENODEV;
-#endif /* CONFIG_BCM43XX_PIO */
-}
-
-/* Generate a cookie for the TX header. */
-static u16 generate_cookie(struct bcm43xx_dmaring *ring,
- int slot)
-{
- u16 cookie = 0x1000;
-
- /* Use the upper 4 bits of the cookie as
- * DMA controller ID and store the slot number
- * in the lower 12 bits.
- * Note that the cookie must never be 0, as this
- * is a special value used in RX path.
- */
- switch (ring->index) {
- case 0:
- cookie = 0xA000;
- break;
- case 1:
- cookie = 0xB000;
- break;
- case 2:
- cookie = 0xC000;
- break;
- case 3:
- cookie = 0xD000;
- break;
- case 4:
- cookie = 0xE000;
- break;
- case 5:
- cookie = 0xF000;
- break;
- }
- assert(((u16)slot & 0xF000) == 0x0000);
- cookie |= (u16)slot;
-
- return cookie;
-}
-
-/* Inspect a cookie and find out to which controller/slot it belongs. */
-static
-struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm,
- u16 cookie, int *slot)
-{
- struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
- struct bcm43xx_dmaring *ring = NULL;
-
- switch (cookie & 0xF000) {
- case 0xA000:
- ring = dma->tx_ring0;
- break;
- case 0xB000:
- ring = dma->tx_ring1;
- break;
- case 0xC000:
- ring = dma->tx_ring2;
- break;
- case 0xD000:
- ring = dma->tx_ring3;
- break;
- case 0xE000:
- ring = dma->tx_ring4;
- break;
- case 0xF000:
- ring = dma->tx_ring5;
- break;
- default:
- assert(0);
- }
- *slot = (cookie & 0x0FFF);
- assert(*slot >= 0 && *slot < ring->nr_slots);
-
- return ring;
-}
-
-static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
- int slot)
-{
- u16 offset;
- int descsize;
-
- /* Everything is ready to start. Buffers are DMA mapped and
- * associated with slots.
- * "slot" is the last slot of the new frame we want to transmit.
- * Close your seat belts now, please.
- */
- wmb();
- slot = next_slot(ring, slot);
- offset = (ring->dma64) ? BCM43xx_DMA64_TXINDEX : BCM43xx_DMA32_TXINDEX;
- descsize = (ring->dma64) ? sizeof(struct bcm43xx_dmadesc64)
- : sizeof(struct bcm43xx_dmadesc32);
- bcm43xx_dma_write(ring, offset,
- (u32)(slot * descsize));
-}
-
-static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
- struct sk_buff *skb,
- u8 cur_frag)
-{
- int slot;
- struct bcm43xx_dmadesc_generic *desc;
- struct bcm43xx_dmadesc_meta *meta;
- dma_addr_t dmaaddr;
- struct sk_buff *bounce_skb;
-
- assert(skb_shinfo(skb)->nr_frags == 0);
-
- slot = request_slot(ring);
- desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
-
- /* Add a device specific TX header. */
- assert(skb_headroom(skb) >= sizeof(struct bcm43xx_txhdr));
- /* Reserve enough headroom for the device tx header. */
- __skb_push(skb, sizeof(struct bcm43xx_txhdr));
- /* Now calculate and add the tx header.
- * The tx header includes the PLCP header.
- */
- bcm43xx_generate_txhdr(ring->bcm,
- (struct bcm43xx_txhdr *)skb->data,
- skb->data + sizeof(struct bcm43xx_txhdr),
- skb->len - sizeof(struct bcm43xx_txhdr),
- (cur_frag == 0),
- generate_cookie(ring, slot));
- dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
- if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > ring->bcm->dma_mask) {
- /* chip cannot handle DMA to/from > 1GB, use bounce buffer (copied from b44 driver) */
- if (!dma_mapping_error(dmaaddr))
- unmap_descbuffer(ring, dmaaddr, skb->len, 1);
- bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC|GFP_DMA);
- if (!bounce_skb)
- return;
- dmaaddr = map_descbuffer(ring, bounce_skb->data, bounce_skb->len, 1);
- if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > ring->bcm->dma_mask) {
- if (!dma_mapping_error(dmaaddr))
- unmap_descbuffer(ring, dmaaddr, skb->len, 1);
- dev_kfree_skb_any(bounce_skb);
- assert(0);
- return;
- }
- skb_copy_from_linear_data(skb, skb_put(bounce_skb, skb->len),
- skb->len);
- dev_kfree_skb_any(skb);
- skb = bounce_skb;
- }
-
- meta->skb = skb;
- meta->dmaaddr = dmaaddr;
-
- fill_descriptor(ring, desc, dmaaddr,
- skb->len, 1, 1, 1);
-
- /* Now transfer the whole frame. */
- dmacontroller_poke_tx(ring, slot);
-}
-
-int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
- struct ieee80211_txb *txb)
-{
- /* We just received a packet from the kernel network subsystem.
- * Add headers and DMA map the memory. Poke
- * the device to send the stuff.
- * Note that this is called from atomic context.
- */
- struct bcm43xx_dmaring *ring = bcm43xx_current_dma(bcm)->tx_ring1;
- u8 i;
- struct sk_buff *skb;
-
- assert(ring->tx);
- if (unlikely(free_slots(ring) < txb->nr_frags)) {
- /* The queue should be stopped,
- * if we are low on free slots.
- * If this ever triggers, we have to lower the suspend_mark.
- */
- dprintkl(KERN_ERR PFX "Out of DMA descriptor slots!\n");
- return -ENOMEM;
- }
-
- for (i = 0; i < txb->nr_frags; i++) {
- skb = txb->fragments[i];
- /* Take skb from ieee80211_txb_free */
- txb->fragments[i] = NULL;
- dma_tx_fragment(ring, skb, i);
- }
- ieee80211_txb_free(txb);
-
- return 0;
-}
-
-void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
- struct bcm43xx_xmitstatus *status)
-{
- struct bcm43xx_dmaring *ring;
- struct bcm43xx_dmadesc_generic *desc;
- struct bcm43xx_dmadesc_meta *meta;
- int is_last_fragment;
- int slot;
- u32 tmp;
-
- ring = parse_cookie(bcm, status->cookie, &slot);
- assert(ring);
- assert(ring->tx);
- while (1) {
- assert(slot >= 0 && slot < ring->nr_slots);
- desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
-
- if (ring->dma64) {
- tmp = le32_to_cpu(desc->dma64.control0);
- is_last_fragment = !!(tmp & BCM43xx_DMA64_DCTL0_FRAMEEND);
- } else {
- tmp = le32_to_cpu(desc->dma32.control);
- is_last_fragment = !!(tmp & BCM43xx_DMA32_DCTL_FRAMEEND);
- }
- unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
- free_descriptor_buffer(ring, meta, 1);
- /* Everything belonging to the slot is unmapped
- * and freed, so we can return it.
- */
- return_slot(ring, slot);
-
- if (is_last_fragment)
- break;
- slot = next_slot(ring, slot);
- }
- bcm->stats.last_tx = jiffies;
-}
-
-static void dma_rx(struct bcm43xx_dmaring *ring,
- int *slot)
-{
- struct bcm43xx_dmadesc_generic *desc;
- struct bcm43xx_dmadesc_meta *meta;
- struct bcm43xx_rxhdr *rxhdr;
- struct sk_buff *skb;
- u16 len;
- int err;
- dma_addr_t dmaaddr;
-
- desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
-
- sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
- skb = meta->skb;
-
- if (ring->index == 3) {
- /* We received an xmit status. */
- struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data;
- struct bcm43xx_xmitstatus stat;
- int i = 0;
-
- stat.cookie = le16_to_cpu(hw->cookie);
- while (stat.cookie == 0) {
- if (unlikely(++i >= 10000)) {
- assert(0);
- break;
- }
- udelay(2);
- barrier();
- stat.cookie = le16_to_cpu(hw->cookie);
- }
- stat.flags = hw->flags;
- stat.cnt1 = hw->cnt1;
- stat.cnt2 = hw->cnt2;
- stat.seq = le16_to_cpu(hw->seq);
- stat.unknown = le16_to_cpu(hw->unknown);
-
- bcm43xx_debugfs_log_txstat(ring->bcm, &stat);
- bcm43xx_dma_handle_xmitstatus(ring->bcm, &stat);
- /* recycle the descriptor buffer. */
- sync_descbuffer_for_device(ring, meta->dmaaddr, ring->rx_buffersize);
-
- return;
- }
- rxhdr = (struct bcm43xx_rxhdr *)skb->data;
- len = le16_to_cpu(rxhdr->frame_length);
- if (len == 0) {
- int i = 0;
-
- do {
- udelay(2);
- barrier();
- len = le16_to_cpu(rxhdr->frame_length);
- } while (len == 0 && i++ < 5);
- if (unlikely(len == 0)) {
- /* recycle the descriptor buffer. */
- sync_descbuffer_for_device(ring, meta->dmaaddr,
- ring->rx_buffersize);
- goto drop;
- }
- }
- if (unlikely(len > ring->rx_buffersize)) {
- /* The data did not fit into one descriptor buffer
- * and is split over multiple buffers.
- * This should never happen, as we try to allocate buffers
- * big enough. So simply ignore this packet.
- */
- int cnt = 0;
- s32 tmp = len;
-
- while (1) {
- desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
- /* recycle the descriptor buffer. */
- sync_descbuffer_for_device(ring, meta->dmaaddr,
- ring->rx_buffersize);
- *slot = next_slot(ring, *slot);
- cnt++;
- tmp -= ring->rx_buffersize;
- if (tmp <= 0)
- break;
- }
- printkl(KERN_ERR PFX "DMA RX buffer too small "
- "(len: %u, buffer: %u, nr-dropped: %d)\n",
- len, ring->rx_buffersize, cnt);
- goto drop;
- }
- len -= IEEE80211_FCS_LEN;
-
- dmaaddr = meta->dmaaddr;
- err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
- if (unlikely(err)) {
- dprintkl(KERN_ERR PFX "DMA RX: setup_rx_descbuffer() failed\n");
- sync_descbuffer_for_device(ring, dmaaddr,
- ring->rx_buffersize);
- goto drop;
- }
-
- unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
- skb_put(skb, len + ring->frameoffset);
- skb_pull(skb, ring->frameoffset);
-
- err = bcm43xx_rx(ring->bcm, skb, rxhdr);
- if (err) {
- dev_kfree_skb_irq(skb);
- goto drop;
- }
-
-drop:
- return;
-}
-
-void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
-{
- u32 status;
- u16 descptr;
- int slot, current_slot;
-#ifdef CONFIG_BCM43XX_DEBUG
- int used_slots = 0;
-#endif
-
- assert(!ring->tx);
- if (ring->dma64) {
- status = bcm43xx_dma_read(ring, BCM43xx_DMA64_RXSTATUS);
- descptr = (status & BCM43xx_DMA64_RXSTATDPTR);
- current_slot = descptr / sizeof(struct bcm43xx_dmadesc64);
- } else {
- status = bcm43xx_dma_read(ring, BCM43xx_DMA32_RXSTATUS);
- descptr = (status & BCM43xx_DMA32_RXDPTR);
- current_slot = descptr / sizeof(struct bcm43xx_dmadesc32);
- }
- assert(current_slot >= 0 && current_slot < ring->nr_slots);
-
- slot = ring->current_slot;
- for ( ; slot != current_slot; slot = next_slot(ring, slot)) {
- dma_rx(ring, &slot);
-#ifdef CONFIG_BCM43XX_DEBUG
- if (++used_slots > ring->max_used_slots)
- ring->max_used_slots = used_slots;
-#endif
- }
- if (ring->dma64) {
- bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX,
- (u32)(slot * sizeof(struct bcm43xx_dmadesc64)));
- } else {
- bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX,
- (u32)(slot * sizeof(struct bcm43xx_dmadesc32)));
- }
- ring->current_slot = slot;
-}
-
-void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring)
-{
- assert(ring->tx);
- bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1);
- if (ring->dma64) {
- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL,
- bcm43xx_dma_read(ring, BCM43xx_DMA64_TXCTL)
- | BCM43xx_DMA64_TXSUSPEND);
- } else {
- bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL,
- bcm43xx_dma_read(ring, BCM43xx_DMA32_TXCTL)
- | BCM43xx_DMA32_TXSUSPEND);
- }
-}
-
-void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
-{
- assert(ring->tx);
- if (ring->dma64) {
- bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL,
- bcm43xx_dma_read(ring, BCM43xx_DMA64_TXCTL)
- & ~BCM43xx_DMA64_TXSUSPEND);
- } else {
- bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL,
- bcm43xx_dma_read(ring, BCM43xx_DMA32_TXCTL)
- & ~BCM43xx_DMA32_TXSUSPEND);
- }
- bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1);
-}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
deleted file mode 100644
index d1105e569a41..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
+++ /dev/null
@@ -1,386 +0,0 @@
-#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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c
deleted file mode 100644
index d2df6a0100a1..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-
- 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,
-};
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h
deleted file mode 100644
index 6f8d42d3cdf5..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef BCM43xx_ETHTOOL_H_
-#define BCM43xx_ETHTOOL_H_
-
-#include <linux/ethtool.h>
-
-extern const struct ethtool_ops bcm43xx_ethtool_ops;
-
-#endif /* BCM43xx_ETHTOOL_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
deleted file mode 100644
index f2b8dbac55a4..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
-
- 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);
- }
-}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
deleted file mode 100644
index d7eaf5f25b7f..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
deleted file mode 100644
index cb51dc51cce6..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
-
- 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);
-}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
deleted file mode 100644
index 811e14a81198..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
deleted file mode 100644
index b96a325b6ec8..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ /dev/null
@@ -1,4281 +0,0 @@
-/*
-
- 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.
-
-*/
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/moduleparam.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/version.h>
-#include <linux/firmware.h>
-#include <linux/wireless.h>
-#include <linux/workqueue.h>
-#include <linux/skbuff.h>
-#include <linux/dma-mapping.h>
-#include <net/iw_handler.h>
-
-#include "bcm43xx.h"
-#include "bcm43xx_main.h"
-#include "bcm43xx_debugfs.h"
-#include "bcm43xx_radio.h"
-#include "bcm43xx_phy.h"
-#include "bcm43xx_dma.h"
-#include "bcm43xx_pio.h"
-#include "bcm43xx_power.h"
-#include "bcm43xx_wx.h"
-#include "bcm43xx_ethtool.h"
-#include "bcm43xx_xmit.h"
-#include "bcm43xx_sysfs.h"
-
-
-MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver");
-MODULE_AUTHOR("Martin Langer");
-MODULE_AUTHOR("Stefano Brivio");
-MODULE_AUTHOR("Michael Buesch");
-MODULE_LICENSE("GPL");
-
-#if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO)
-static int modparam_pio;
-module_param_named(pio, modparam_pio, int, 0444);
-MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
-#elif defined(CONFIG_BCM43XX_DMA)
-# define modparam_pio 0
-#elif defined(CONFIG_BCM43XX_PIO)
-# define modparam_pio 1
-#endif
-
-static int modparam_bad_frames_preempt;
-module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
-MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames Preemption");
-
-static int modparam_short_retry = BCM43xx_DEFAULT_SHORT_RETRY_LIMIT;
-module_param_named(short_retry, modparam_short_retry, int, 0444);
-MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)");
-
-static int modparam_long_retry = BCM43xx_DEFAULT_LONG_RETRY_LIMIT;
-module_param_named(long_retry, modparam_long_retry, int, 0444);
-MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)");
-
-static int modparam_locale = -1;
-module_param_named(locale, modparam_locale, int, 0444);
-MODULE_PARM_DESC(country, "Select LocaleCode 0-11 (For travelers)");
-
-static int modparam_noleds;
-module_param_named(noleds, modparam_noleds, int, 0444);
-MODULE_PARM_DESC(noleds, "Turn off all LED activity");
-
-static char modparam_fwpostfix[64];
-module_param_string(fwpostfix, modparam_fwpostfix, 64, 0444);
-MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for using multiple firmware image versions.");
-
-
-/* If you want to debug with just a single device, enable this,
- * where the string is the pci device ID (as given by the kernel's
- * pci_name function) of the device to be used.
- */
-//#define DEBUG_SINGLE_DEVICE_ONLY "0001:11:00.0"
-
-/* If you want to enable printing of each MMIO access, enable this. */
-//#define DEBUG_ENABLE_MMIO_PRINT
-
-/* If you want to enable printing of MMIO access within
- * ucode/pcm upload, initvals write, enable this.
- */
-//#define DEBUG_ENABLE_UCODE_MMIO_PRINT
-
-/* If you want to enable printing of PCI Config Space access, enable this */
-//#define DEBUG_ENABLE_PCILOG
-
-
-/* Detailed list maintained at:
- * http://openfacts.berlios.de/index-en.phtml?title=Bcm43xxDevices
- */
- static struct pci_device_id bcm43xx_pci_tbl[] = {
- /* Broadcom 4303 802.11b */
- { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4307 802.11b */
- { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4311 802.11(a)/b/g */
- { PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4312 802.11a/b/g */
- { PCI_VENDOR_ID_BROADCOM, 0x4312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4318 802.11b/g */
- { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4319 802.11a/b/g */
- { PCI_VENDOR_ID_BROADCOM, 0x4319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4306 802.11b/g */
- { PCI_VENDOR_ID_BROADCOM, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4306 802.11a */
-// { PCI_VENDOR_ID_BROADCOM, 0x4321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 4309 802.11a/b/g */
- { PCI_VENDOR_ID_BROADCOM, 0x4324, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- /* Broadcom 43XG 802.11b/g */
- { PCI_VENDOR_ID_BROADCOM, 0x4325, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { 0 },
-};
-MODULE_DEVICE_TABLE(pci, bcm43xx_pci_tbl);
-
-static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val)
-{
- u32 status;
-
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- if (!(status & BCM43xx_SBF_XFER_REG_BYTESWAP))
- val = swab32(val);
-
- bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset);
- mmiowb();
- bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val);
-}
-
-static inline
-void bcm43xx_shm_control_word(struct bcm43xx_private *bcm,
- u16 routing, u16 offset)
-{
- u32 control;
-
- /* "offset" is the WORD offset. */
-
- control = routing;
- control <<= 16;
- control |= offset;
- bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_CONTROL, control);
-}
-
-u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm,
- u16 routing, u16 offset)
-{
- u32 ret;
-
- if (routing == BCM43xx_SHM_SHARED) {
- if (offset & 0x0003) {
- /* Unaligned access */
- bcm43xx_shm_control_word(bcm, routing, offset >> 2);
- ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
- ret <<= 16;
- bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
- ret |= bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
-
- return ret;
- }
- offset >>= 2;
- }
- bcm43xx_shm_control_word(bcm, routing, offset);
- ret = bcm43xx_read32(bcm, BCM43xx_MMIO_SHM_DATA);
-
- return ret;
-}
-
-u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm,
- u16 routing, u16 offset)
-{
- u16 ret;
-
- if (routing == BCM43xx_SHM_SHARED) {
- if (offset & 0x0003) {
- /* Unaligned access */
- bcm43xx_shm_control_word(bcm, routing, offset >> 2);
- ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
-
- return ret;
- }
- offset >>= 2;
- }
- bcm43xx_shm_control_word(bcm, routing, offset);
- ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
-
- return ret;
-}
-
-void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
- u16 routing, u16 offset,
- u32 value)
-{
- if (routing == BCM43xx_SHM_SHARED) {
- if (offset & 0x0003) {
- /* Unaligned access */
- bcm43xx_shm_control_word(bcm, routing, offset >> 2);
- mmiowb();
- bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
- (value >> 16) & 0xffff);
- mmiowb();
- bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
- mmiowb();
- bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA,
- value & 0xffff);
- return;
- }
- offset >>= 2;
- }
- bcm43xx_shm_control_word(bcm, routing, offset);
- mmiowb();
- bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value);
-}
-
-void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
- u16 routing, u16 offset,
- u16 value)
-{
- if (routing == BCM43xx_SHM_SHARED) {
- if (offset & 0x0003) {
- /* Unaligned access */
- bcm43xx_shm_control_word(bcm, routing, offset >> 2);
- mmiowb();
- bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
- value);
- return;
- }
- offset >>= 2;
- }
- bcm43xx_shm_control_word(bcm, routing, offset);
- mmiowb();
- bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value);
-}
-
-void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf)
-{
- /* We need to be careful. As we read the TSF from multiple
- * registers, we should take care of register overflows.
- * In theory, the whole tsf read process should be atomic.
- * We try to be atomic here, by restaring the read process,
- * if any of the high registers changed (overflew).
- */
- if (bcm->current_core->rev >= 3) {
- u32 low, high, high2;
-
- do {
- high = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH);
- low = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW);
- high2 = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH);
- } while (unlikely(high != high2));
-
- *tsf = high;
- *tsf <<= 32;
- *tsf |= low;
- } else {
- u64 tmp;
- u16 v0, v1, v2, v3;
- u16 test1, test2, test3;
-
- do {
- v3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3);
- v2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2);
- v1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1);
- v0 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_0);
-
- test3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3);
- test2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2);
- test1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1);
- } while (v3 != test3 || v2 != test2 || v1 != test1);
-
- *tsf = v3;
- *tsf <<= 48;
- tmp = v2;
- tmp <<= 32;
- *tsf |= tmp;
- tmp = v1;
- tmp <<= 16;
- *tsf |= tmp;
- *tsf |= v0;
- }
-}
-
-void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
-{
- u32 status;
-
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- status |= BCM43xx_SBF_TIME_UPDATE;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
- mmiowb();
-
- /* Be careful with the in-progress timer.
- * First zero out the low register, so we have a full
- * register-overflow duration to complete the operation.
- */
- if (bcm->current_core->rev >= 3) {
- u32 lo = (tsf & 0x00000000FFFFFFFFULL);
- u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
-
- bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0);
- mmiowb();
- bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi);
- mmiowb();
- bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo);
- } else {
- u16 v0 = (tsf & 0x000000000000FFFFULL);
- u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
- u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
- u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
-
- bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0);
- mmiowb();
- bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3);
- mmiowb();
- bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2);
- mmiowb();
- bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1);
- mmiowb();
- bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0);
- }
-
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- status &= ~BCM43xx_SBF_TIME_UPDATE;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
-}
-
-static
-void bcm43xx_macfilter_set(struct bcm43xx_private *bcm,
- u16 offset,
- const u8 *mac)
-{
- u16 data;
-
- offset |= 0x0020;
- bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_CONTROL, offset);
-
- data = mac[0];
- data |= mac[1] << 8;
- bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
- data = mac[2];
- data |= mac[3] << 8;
- bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
- data = mac[4];
- data |= mac[5] << 8;
- bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
-}
-
-static void bcm43xx_macfilter_clear(struct bcm43xx_private *bcm,
- u16 offset)
-{
- const u8 zero_addr[ETH_ALEN] = { 0 };
-
- bcm43xx_macfilter_set(bcm, offset, zero_addr);
-}
-
-static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm)
-{
- const u8 *mac = (const u8 *)(bcm->net_dev->dev_addr);
- const u8 *bssid = (const u8 *)(bcm->ieee->bssid);
- u8 mac_bssid[ETH_ALEN * 2];
- int i;
-
- memcpy(mac_bssid, mac, ETH_ALEN);
- memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
-
- /* Write our MAC address and BSSID to template ram */
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x20 + i, *((u32 *)(mac_bssid + i)));
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x78 + i, *((u32 *)(mac_bssid + i)));
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i)));
-}
-
-//FIXME: Well, we should probably call them from somewhere.
-#if 0
-static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time)
-{
- /* slot_time is in usec. */
- if (bcm43xx_current_phy(bcm)->type != BCM43xx_PHYTYPE_G)
- return;
- bcm43xx_write16(bcm, 0x684, 510 + slot_time);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0010, slot_time);
-}
-
-static void bcm43xx_short_slot_timing_enable(struct bcm43xx_private *bcm)
-{
- bcm43xx_set_slot_time(bcm, 9);
-}
-
-static void bcm43xx_short_slot_timing_disable(struct bcm43xx_private *bcm)
-{
- bcm43xx_set_slot_time(bcm, 20);
-}
-#endif
-
-/* FIXME: To get the MAC-filter working, we need to implement the
- * following functions (and rename them :)
- */
-#if 0
-static void bcm43xx_disassociate(struct bcm43xx_private *bcm)
-{
- bcm43xx_mac_suspend(bcm);
- bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
-
- bcm43xx_ram_write(bcm, 0x0026, 0x0000);
- bcm43xx_ram_write(bcm, 0x0028, 0x0000);
- bcm43xx_ram_write(bcm, 0x007E, 0x0000);
- bcm43xx_ram_write(bcm, 0x0080, 0x0000);
- bcm43xx_ram_write(bcm, 0x047E, 0x0000);
- bcm43xx_ram_write(bcm, 0x0480, 0x0000);
-
- if (bcm->current_core->rev < 3) {
- bcm43xx_write16(bcm, 0x0610, 0x8000);
- bcm43xx_write16(bcm, 0x060E, 0x0000);
- } else
- bcm43xx_write32(bcm, 0x0188, 0x80000000);
-
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
-
- if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G &&
- ieee80211_is_ofdm_rate(bcm->softmac->txrates.default_rate))
- bcm43xx_short_slot_timing_enable(bcm);
-
- bcm43xx_mac_enable(bcm);
-}
-
-static void bcm43xx_associate(struct bcm43xx_private *bcm,
- const u8 *mac)
-{
- memcpy(bcm->ieee->bssid, mac, ETH_ALEN);
-
- bcm43xx_mac_suspend(bcm);
- bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_ASSOC, mac);
- bcm43xx_write_mac_bssid_templates(bcm);
- bcm43xx_mac_enable(bcm);
-}
-#endif
-
-/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 bcm43xx_interrupt_enable(struct bcm43xx_private *bcm, u32 mask)
-{
- u32 old_mask;
-
- old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
- bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask | mask);
-
- return old_mask;
-}
-
-/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mask)
-{
- u32 old_mask;
-
- old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
- bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
-
- return old_mask;
-}
-
-/* Synchronize IRQ top- and bottom-half.
- * IRQs must be masked before calling this.
- * This must not be called with the irq_lock held.
- */
-static void bcm43xx_synchronize_irq(struct bcm43xx_private *bcm)
-{
- synchronize_irq(bcm->irq);
- tasklet_disable(&bcm->isr_tasklet);
-}
-
-/* Make sure we don't receive more data from the device. */
-static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&bcm->irq_lock, flags);
- if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- return -EBUSY;
- }
- bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); /* flush */
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- bcm43xx_synchronize_irq(bcm);
-
- return 0;
-}
-
-static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u32 radio_id;
- u16 manufact;
- u16 version;
- u8 revision;
-
- if (bcm->chip_id == 0x4317) {
- if (bcm->chip_rev == 0x00)
- radio_id = 0x3205017F;
- else if (bcm->chip_rev == 0x01)
- radio_id = 0x4205017F;
- else
- radio_id = 0x5205017F;
- } else {
- bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID);
- radio_id = bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_HIGH);
- radio_id <<= 16;
- bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID);
- radio_id |= bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW);
- }
-
- manufact = (radio_id & 0x00000FFF);
- version = (radio_id & 0x0FFFF000) >> 12;
- revision = (radio_id & 0xF0000000) >> 28;
-
- dprintk(KERN_INFO PFX "Detected Radio: ID: %x (Manuf: %x Ver: %x Rev: %x)\n",
- radio_id, manufact, version, revision);
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- if ((version != 0x2060) || (revision != 1) || (manufact != 0x17f))
- goto err_unsupported_radio;
- break;
- case BCM43xx_PHYTYPE_B:
- if ((version & 0xFFF0) != 0x2050)
- goto err_unsupported_radio;
- break;
- case BCM43xx_PHYTYPE_G:
- if (version != 0x2050)
- goto err_unsupported_radio;
- break;
- }
-
- radio->manufact = manufact;
- radio->version = version;
- radio->revision = revision;
-
- if (phy->type == BCM43xx_PHYTYPE_A)
- radio->txpower_desired = bcm->sprom.maxpower_aphy;
- else
- radio->txpower_desired = bcm->sprom.maxpower_bgphy;
-
- return 0;
-
-err_unsupported_radio:
- printk(KERN_ERR PFX "Unsupported Radio connected to the PHY!\n");
- return -ENODEV;
-}
-
-static const char * bcm43xx_locale_iso(u8 locale)
-{
- /* ISO 3166-1 country codes.
- * Note that there aren't ISO 3166-1 codes for
- * all or locales. (Not all locales are countries)
- */
- switch (locale) {
- case BCM43xx_LOCALE_WORLD:
- case BCM43xx_LOCALE_ALL:
- return "XX";
- case BCM43xx_LOCALE_THAILAND:
- return "TH";
- case BCM43xx_LOCALE_ISRAEL:
- return "IL";
- case BCM43xx_LOCALE_JORDAN:
- return "JO";
- case BCM43xx_LOCALE_CHINA:
- return "CN";
- case BCM43xx_LOCALE_JAPAN:
- case BCM43xx_LOCALE_JAPAN_HIGH:
- return "JP";
- case BCM43xx_LOCALE_USA_CANADA_ANZ:
- case BCM43xx_LOCALE_USA_LOW:
- return "US";
- case BCM43xx_LOCALE_EUROPE:
- return "EU";
- case BCM43xx_LOCALE_NONE:
- return " ";
- }
- assert(0);
- return " ";
-}
-
-static const char * bcm43xx_locale_string(u8 locale)
-{
- switch (locale) {
- case BCM43xx_LOCALE_WORLD:
- return "World";
- case BCM43xx_LOCALE_THAILAND:
- return "Thailand";
- case BCM43xx_LOCALE_ISRAEL:
- return "Israel";
- case BCM43xx_LOCALE_JORDAN:
- return "Jordan";
- case BCM43xx_LOCALE_CHINA:
- return "China";
- case BCM43xx_LOCALE_JAPAN:
- return "Japan";
- case BCM43xx_LOCALE_USA_CANADA_ANZ:
- return "USA/Canada/ANZ";
- case BCM43xx_LOCALE_EUROPE:
- return "Europe";
- case BCM43xx_LOCALE_USA_LOW:
- return "USAlow";
- case BCM43xx_LOCALE_JAPAN_HIGH:
- return "JapanHigh";
- case BCM43xx_LOCALE_ALL:
- return "All";
- case BCM43xx_LOCALE_NONE:
- return "None";
- }
- assert(0);
- return "";
-}
-
-static inline u8 bcm43xx_crc8(u8 crc, u8 data)
-{
- static const u8 t[] = {
- 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
- 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
- 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
- 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
- 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
- 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
- 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
- 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
- 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
- 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
- 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
- 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
- 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
- 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
- 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
- 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
- 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
- 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
- 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
- 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
- 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
- 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
- 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
- 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
- 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
- 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
- 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
- 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
- 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
- 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
- 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
- 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
- };
- return t[crc ^ data];
-}
-
-static u8 bcm43xx_sprom_crc(const u16 *sprom)
-{
- int word;
- u8 crc = 0xFF;
-
- for (word = 0; word < BCM43xx_SPROM_SIZE - 1; word++) {
- crc = bcm43xx_crc8(crc, sprom[word] & 0x00FF);
- crc = bcm43xx_crc8(crc, (sprom[word] & 0xFF00) >> 8);
- }
- crc = bcm43xx_crc8(crc, sprom[BCM43xx_SPROM_VERSION] & 0x00FF);
- crc ^= 0xFF;
-
- return crc;
-}
-
-int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom)
-{
- int i;
- u8 crc, expected_crc;
-
- for (i = 0; i < BCM43xx_SPROM_SIZE; i++)
- sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2));
- /* CRC-8 check. */
- crc = bcm43xx_sprom_crc(sprom);
- expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8;
- if (crc != expected_crc) {
- printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum "
- "(0x%02X, expected: 0x%02X)\n",
- crc, expected_crc);
- return -EINVAL;
- }
-
- return 0;
-}
-
-int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom)
-{
- int i, err;
- u8 crc, expected_crc;
- u32 spromctl;
-
- /* CRC-8 validation of the input data. */
- crc = bcm43xx_sprom_crc(sprom);
- expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8;
- if (crc != expected_crc) {
- printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n");
- return -EINVAL;
- }
-
- printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
- err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl);
- if (err)
- goto err_ctlreg;
- spromctl |= 0x10; /* SPROM WRITE enable. */
- err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
- if (err)
- goto err_ctlreg;
- /* We must burn lots of CPU cycles here, but that does not
- * really matter as one does not write the SPROM every other minute...
- */
- printk(KERN_INFO PFX "[ 0%%");
- mdelay(500);
- for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
- if (i == 16)
- printk("25%%");
- else if (i == 32)
- printk("50%%");
- else if (i == 48)
- printk("75%%");
- else if (i % 2)
- printk(".");
- bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]);
- mmiowb();
- mdelay(20);
- }
- spromctl &= ~0x10; /* SPROM WRITE enable. */
- err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
- if (err)
- goto err_ctlreg;
- mdelay(500);
- printk("100%% ]\n");
- printk(KERN_INFO PFX "SPROM written.\n");
- bcm43xx_controller_restart(bcm, "SPROM update");
-
- return 0;
-err_ctlreg:
- printk(KERN_ERR PFX "Could not access SPROM control register.\n");
- return -ENODEV;
-}
-
-static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
-{
- u16 value;
- u16 *sprom;
-
- sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16),
- GFP_KERNEL);
- if (!sprom) {
- printk(KERN_ERR PFX "sprom_extract OOM\n");
- return -ENOMEM;
- }
- bcm43xx_sprom_read(bcm, sprom);
-
- /* boardflags2 */
- value = sprom[BCM43xx_SPROM_BOARDFLAGS2];
- bcm->sprom.boardflags2 = value;
-
- /* il0macaddr */
- value = sprom[BCM43xx_SPROM_IL0MACADDR + 0];
- *(((__be16 *)bcm->sprom.il0macaddr) + 0) = cpu_to_be16(value);
- value = sprom[BCM43xx_SPROM_IL0MACADDR + 1];
- *(((__be16 *)bcm->sprom.il0macaddr) + 1) = cpu_to_be16(value);
- value = sprom[BCM43xx_SPROM_IL0MACADDR + 2];
- *(((__be16 *)bcm->sprom.il0macaddr) + 2) = cpu_to_be16(value);
-
- /* et0macaddr */
- value = sprom[BCM43xx_SPROM_ET0MACADDR + 0];
- *(((__be16 *)bcm->sprom.et0macaddr) + 0) = cpu_to_be16(value);
- value = sprom[BCM43xx_SPROM_ET0MACADDR + 1];
- *(((__be16 *)bcm->sprom.et0macaddr) + 1) = cpu_to_be16(value);
- value = sprom[BCM43xx_SPROM_ET0MACADDR + 2];
- *(((__be16 *)bcm->sprom.et0macaddr) + 2) = cpu_to_be16(value);
-
- /* et1macaddr */
- value = sprom[BCM43xx_SPROM_ET1MACADDR + 0];
- *(((__be16 *)bcm->sprom.et1macaddr) + 0) = cpu_to_be16(value);
- value = sprom[BCM43xx_SPROM_ET1MACADDR + 1];
- *(((__be16 *)bcm->sprom.et1macaddr) + 1) = cpu_to_be16(value);
- value = sprom[BCM43xx_SPROM_ET1MACADDR + 2];
- *(((__be16 *)bcm->sprom.et1macaddr) + 2) = cpu_to_be16(value);
-
- /* ethernet phy settings */
- value = sprom[BCM43xx_SPROM_ETHPHY];
- bcm->sprom.et0phyaddr = (value & 0x001F);
- bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5;
-
- /* boardrev, antennas, locale */
- value = sprom[BCM43xx_SPROM_BOARDREV];
- bcm->sprom.boardrev = (value & 0x00FF);
- bcm->sprom.locale = (value & 0x0F00) >> 8;
- bcm->sprom.antennas_aphy = (value & 0x3000) >> 12;
- bcm->sprom.antennas_bgphy = (value & 0xC000) >> 14;
- if (modparam_locale != -1) {
- if (modparam_locale >= 0 && modparam_locale <= 11) {
- bcm->sprom.locale = modparam_locale;
- printk(KERN_WARNING PFX "Operating with modified "
- "LocaleCode %u (%s)\n",
- bcm->sprom.locale,
- bcm43xx_locale_string(bcm->sprom.locale));
- } else {
- printk(KERN_WARNING PFX "Module parameter \"locale\" "
- "invalid value. (0 - 11)\n");
- }
- }
-
- /* pa0b* */
- value = sprom[BCM43xx_SPROM_PA0B0];
- bcm->sprom.pa0b0 = value;
- value = sprom[BCM43xx_SPROM_PA0B1];
- bcm->sprom.pa0b1 = value;
- value = sprom[BCM43xx_SPROM_PA0B2];
- bcm->sprom.pa0b2 = value;
-
- /* wl0gpio* */
- value = sprom[BCM43xx_SPROM_WL0GPIO0];
- if (value == 0x0000)
- value = 0xFFFF;
- bcm->sprom.wl0gpio0 = value & 0x00FF;
- bcm->sprom.wl0gpio1 = (value & 0xFF00) >> 8;
- value = sprom[BCM43xx_SPROM_WL0GPIO2];
- if (value == 0x0000)
- value = 0xFFFF;
- bcm->sprom.wl0gpio2 = value & 0x00FF;
- bcm->sprom.wl0gpio3 = (value & 0xFF00) >> 8;
-
- /* maxpower */
- value = sprom[BCM43xx_SPROM_MAXPWR];
- bcm->sprom.maxpower_aphy = (value & 0xFF00) >> 8;
- bcm->sprom.maxpower_bgphy = value & 0x00FF;
-
- /* pa1b* */
- value = sprom[BCM43xx_SPROM_PA1B0];
- bcm->sprom.pa1b0 = value;
- value = sprom[BCM43xx_SPROM_PA1B1];
- bcm->sprom.pa1b1 = value;
- value = sprom[BCM43xx_SPROM_PA1B2];
- bcm->sprom.pa1b2 = value;
-
- /* idle tssi target */
- value = sprom[BCM43xx_SPROM_IDL_TSSI_TGT];
- bcm->sprom.idle_tssi_tgt_aphy = value & 0x00FF;
- bcm->sprom.idle_tssi_tgt_bgphy = (value & 0xFF00) >> 8;
-
- /* boardflags */
- value = sprom[BCM43xx_SPROM_BOARDFLAGS];
- if (value == 0xFFFF)
- value = 0x0000;
- bcm->sprom.boardflags = value;
- /* boardflags workarounds */
- if (bcm->board_vendor == PCI_VENDOR_ID_DELL &&
- bcm->chip_id == 0x4301 &&
- bcm->board_revision == 0x74)
- bcm->sprom.boardflags |= BCM43xx_BFL_BTCOEXIST;
- if (bcm->board_vendor == PCI_VENDOR_ID_APPLE &&
- bcm->board_type == 0x4E &&
- bcm->board_revision > 0x40)
- bcm->sprom.boardflags |= BCM43xx_BFL_PACTRL;
-
- /* antenna gain */
- value = sprom[BCM43xx_SPROM_ANTENNA_GAIN];
- if (value == 0x0000 || value == 0xFFFF)
- value = 0x0202;
- /* convert values to Q5.2 */
- bcm->sprom.antennagain_aphy = ((value & 0xFF00) >> 8) * 4;
- bcm->sprom.antennagain_bgphy = (value & 0x00FF) * 4;
-
- kfree(sprom);
-
- return 0;
-}
-
-static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
-{
- struct ieee80211_geo *geo;
- struct ieee80211_channel *chan;
- int have_a = 0, have_bg = 0;
- int i;
- u8 channel;
- struct bcm43xx_phyinfo *phy;
- const char *iso_country;
- u8 max_bg_channel;
-
- geo = kzalloc(sizeof(*geo), GFP_KERNEL);
- if (!geo)
- return -ENOMEM;
-
- for (i = 0; i < bcm->nr_80211_available; i++) {
- phy = &(bcm->core_80211_ext[i].phy);
- switch (phy->type) {
- case BCM43xx_PHYTYPE_B:
- case BCM43xx_PHYTYPE_G:
- have_bg = 1;
- break;
- case BCM43xx_PHYTYPE_A:
- have_a = 1;
- break;
- default:
- assert(0);
- }
- }
- iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
-
-/* set the maximum channel based on locale set in sprom or witle locale option */
- switch (bcm->sprom.locale) {
- case BCM43xx_LOCALE_THAILAND:
- case BCM43xx_LOCALE_ISRAEL:
- case BCM43xx_LOCALE_JORDAN:
- case BCM43xx_LOCALE_USA_CANADA_ANZ:
- case BCM43xx_LOCALE_USA_LOW:
- max_bg_channel = 11;
- break;
- case BCM43xx_LOCALE_JAPAN:
- case BCM43xx_LOCALE_JAPAN_HIGH:
- max_bg_channel = 14;
- break;
- default:
- max_bg_channel = 13;
- }
-
- if (have_a) {
- for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
- channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
- chan = &geo->a[i++];
- chan->freq = bcm43xx_channel_to_freq_a(channel);
- chan->channel = channel;
- }
- geo->a_channels = i;
- }
- if (have_bg) {
- for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
- channel <= max_bg_channel; channel++) {
- chan = &geo->bg[i++];
- chan->freq = bcm43xx_channel_to_freq_bg(channel);
- chan->channel = channel;
- }
- geo->bg_channels = i;
- }
- memcpy(geo->name, iso_country, 2);
- if (0 /*TODO: Outdoor use only */)
- geo->name[2] = 'O';
- else if (0 /*TODO: Indoor use only */)
- geo->name[2] = 'I';
- else
- geo->name[2] = ' ';
- geo->name[3] = '\0';
-
- ieee80211_set_geo(bcm->ieee, geo);
- kfree(geo);
-
- return 0;
-}
-
-/* DummyTransmission function, as documented on
- * http://bcm-specs.sipsolutions.net/DummyTransmission
- */
-void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- unsigned int i, max_loop;
- u16 value = 0;
- u32 buffer[5] = {
- 0x00000000,
- 0x0000D400,
- 0x00000000,
- 0x00000001,
- 0x00000000,
- };
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- max_loop = 0x1E;
- buffer[0] = 0xCC010200;
- break;
- case BCM43xx_PHYTYPE_B:
- case BCM43xx_PHYTYPE_G:
- max_loop = 0xFA;
- buffer[0] = 0x6E840B00;
- break;
- default:
- assert(0);
- return;
- }
-
- for (i = 0; i < 5; i++)
- bcm43xx_ram_write(bcm, i * 4, buffer[i]);
-
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
-
- bcm43xx_write16(bcm, 0x0568, 0x0000);
- bcm43xx_write16(bcm, 0x07C0, 0x0000);
- bcm43xx_write16(bcm, 0x050C, ((phy->type == BCM43xx_PHYTYPE_A) ? 1 : 0));
- bcm43xx_write16(bcm, 0x0508, 0x0000);
- bcm43xx_write16(bcm, 0x050A, 0x0000);
- bcm43xx_write16(bcm, 0x054C, 0x0000);
- bcm43xx_write16(bcm, 0x056A, 0x0014);
- bcm43xx_write16(bcm, 0x0568, 0x0826);
- bcm43xx_write16(bcm, 0x0500, 0x0000);
- bcm43xx_write16(bcm, 0x0502, 0x0030);
-
- if (radio->version == 0x2050 && radio->revision <= 0x5)
- bcm43xx_radio_write16(bcm, 0x0051, 0x0017);
- for (i = 0x00; i < max_loop; i++) {
- value = bcm43xx_read16(bcm, 0x050E);
- if (value & 0x0080)
- break;
- udelay(10);
- }
- for (i = 0x00; i < 0x0A; i++) {
- value = bcm43xx_read16(bcm, 0x050E);
- if (value & 0x0400)
- break;
- udelay(10);
- }
- for (i = 0x00; i < 0x0A; i++) {
- value = bcm43xx_read16(bcm, 0x0690);
- if (!(value & 0x0100))
- break;
- udelay(10);
- }
- if (radio->version == 0x2050 && radio->revision <= 0x5)
- bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
-}
-
-static void key_write(struct bcm43xx_private *bcm,
- u8 index, u8 algorithm, const __le16 *key)
-{
- unsigned int i, basic_wep = 0;
- u32 offset;
- u16 value;
-
- /* Write associated key information */
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x100 + (index * 2),
- ((index << 4) | (algorithm & 0x0F)));
-
- /* The first 4 WEP keys need extra love */
- if (((algorithm == BCM43xx_SEC_ALGO_WEP) ||
- (algorithm == BCM43xx_SEC_ALGO_WEP104)) && (index < 4))
- basic_wep = 1;
-
- /* Write key payload, 8 little endian words */
- offset = bcm->security_offset + (index * BCM43xx_SEC_KEYSIZE);
- for (i = 0; i < (BCM43xx_SEC_KEYSIZE / sizeof(u16)); i++) {
- value = le16_to_cpu(key[i]);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
- offset + (i * 2), value);
-
- if (!basic_wep)
- continue;
-
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
- offset + (i * 2) + 4 * BCM43xx_SEC_KEYSIZE,
- value);
- }
-}
-
-static void keymac_write(struct bcm43xx_private *bcm,
- u8 index, const __be32 *addr)
-{
- /* for keys 0-3 there is no associated mac address */
- if (index < 4)
- return;
-
- index -= 4;
- if (bcm->current_core->rev >= 5) {
- bcm43xx_shm_write32(bcm,
- BCM43xx_SHM_HWMAC,
- index * 2,
- be32_to_cpu(*addr));
- bcm43xx_shm_write16(bcm,
- BCM43xx_SHM_HWMAC,
- (index * 2) + 1,
- be16_to_cpu(*((__be16 *)(addr + 1))));
- } else {
- if (index < 8) {
- TODO(); /* Put them in the macaddress filter */
- } else {
- TODO();
- /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
- Keep in mind to update the count of keymacs in 0x003E as well! */
- }
- }
-}
-
-static int bcm43xx_key_write(struct bcm43xx_private *bcm,
- u8 index, u8 algorithm,
- const u8 *_key, int key_len,
- const u8 *mac_addr)
-{
- u8 key[BCM43xx_SEC_KEYSIZE] = { 0 };
-
- if (index >= ARRAY_SIZE(bcm->key))
- return -EINVAL;
- if (key_len > ARRAY_SIZE(key))
- return -EINVAL;
- if (algorithm < 1 || algorithm > 5)
- return -EINVAL;
-
- memcpy(key, _key, key_len);
- key_write(bcm, index, algorithm, (const __le16 *)key);
- keymac_write(bcm, index, (const __be32 *)mac_addr);
-
- bcm->key[index].algorithm = algorithm;
-
- return 0;
-}
-
-static void bcm43xx_clear_keys(struct bcm43xx_private *bcm)
-{
- static const __be32 zero_mac[2] = { 0 };
- unsigned int i,j, nr_keys = 54;
- u16 offset;
-
- if (bcm->current_core->rev < 5)
- nr_keys = 16;
- assert(nr_keys <= ARRAY_SIZE(bcm->key));
-
- for (i = 0; i < nr_keys; i++) {
- bcm->key[i].enabled = 0;
- /* returns for i < 4 immediately */
- keymac_write(bcm, i, zero_mac);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
- 0x100 + (i * 2), 0x0000);
- for (j = 0; j < 8; j++) {
- offset = bcm->security_offset + (j * 4) + (i * BCM43xx_SEC_KEYSIZE);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
- offset, 0x0000);
- }
- }
- dprintk(KERN_INFO PFX "Keys cleared\n");
-}
-
-/* Lowlevel core-switch function. This is only to be used in
- * bcm43xx_switch_core() and bcm43xx_probe_cores()
- */
-static int _switch_core(struct bcm43xx_private *bcm, int core)
-{
- int err;
- int attempts = 0;
- u32 current_core;
-
- assert(core >= 0);
- while (1) {
- err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
- (core * 0x1000) + 0x18000000);
- if (unlikely(err))
- goto error;
- err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
- &current_core);
- if (unlikely(err))
- goto error;
- current_core = (current_core - 0x18000000) / 0x1000;
- if (current_core == core)
- break;
-
- if (unlikely(attempts++ > BCM43xx_SWITCH_CORE_MAX_RETRIES))
- goto error;
- udelay(10);
- }
-
- return 0;
-error:
- printk(KERN_ERR PFX "Failed to switch to core %d\n", core);
- return -ENODEV;
-}
-
-int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core)
-{
- int err;
-
- if (unlikely(!new_core))
- return 0;
- if (!new_core->available)
- return -ENODEV;
- if (bcm->current_core == new_core)
- return 0;
- err = _switch_core(bcm, new_core->index);
- if (unlikely(err))
- goto out;
-
- bcm->current_core = new_core;
-out:
- return err;
-}
-
-static int bcm43xx_core_enabled(struct bcm43xx_private *bcm)
-{
- u32 value;
-
- value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- value &= BCM43xx_SBTMSTATELOW_CLOCK | BCM43xx_SBTMSTATELOW_RESET
- | BCM43xx_SBTMSTATELOW_REJECT;
-
- return (value == BCM43xx_SBTMSTATELOW_CLOCK);
-}
-
-/* disable current core */
-static int bcm43xx_core_disable(struct bcm43xx_private *bcm, u32 core_flags)
-{
- u32 sbtmstatelow;
- u32 sbtmstatehigh;
- int i;
-
- /* fetch sbtmstatelow from core information registers */
- sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
-
- /* core is already in reset */
- if (sbtmstatelow & BCM43xx_SBTMSTATELOW_RESET)
- goto out;
-
- if (sbtmstatelow & BCM43xx_SBTMSTATELOW_CLOCK) {
- sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
- BCM43xx_SBTMSTATELOW_REJECT;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
-
- for (i = 0; i < 1000; i++) {
- sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- if (sbtmstatelow & BCM43xx_SBTMSTATELOW_REJECT) {
- i = -1;
- break;
- }
- udelay(10);
- }
- if (i != -1) {
- printk(KERN_ERR PFX "Error: core_disable() REJECT timeout!\n");
- return -EBUSY;
- }
-
- for (i = 0; i < 1000; i++) {
- sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
- if (!(sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_BUSY)) {
- i = -1;
- break;
- }
- udelay(10);
- }
- if (i != -1) {
- printk(KERN_ERR PFX "Error: core_disable() BUSY timeout!\n");
- return -EBUSY;
- }
-
- sbtmstatelow = BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
- BCM43xx_SBTMSTATELOW_REJECT |
- BCM43xx_SBTMSTATELOW_RESET |
- BCM43xx_SBTMSTATELOW_CLOCK |
- core_flags;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
- udelay(10);
- }
-
- sbtmstatelow = BCM43xx_SBTMSTATELOW_RESET |
- BCM43xx_SBTMSTATELOW_REJECT |
- core_flags;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
-
-out:
- bcm->current_core->enabled = 0;
-
- return 0;
-}
-
-/* enable (reset) current core */
-static int bcm43xx_core_enable(struct bcm43xx_private *bcm, u32 core_flags)
-{
- u32 sbtmstatelow;
- u32 sbtmstatehigh;
- u32 sbimstate;
- int err;
-
- err = bcm43xx_core_disable(bcm, core_flags);
- if (err)
- goto out;
-
- sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
- BCM43xx_SBTMSTATELOW_RESET |
- BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
- core_flags;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
- udelay(1);
-
- sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
- if (sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_SERROR) {
- sbtmstatehigh = 0x00000000;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATEHIGH, sbtmstatehigh);
- }
-
- sbimstate = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMSTATE);
- if (sbimstate & (BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT)) {
- sbimstate &= ~(BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT);
- bcm43xx_write32(bcm, BCM43xx_CIR_SBIMSTATE, sbimstate);
- }
-
- sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
- BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
- core_flags;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
- udelay(1);
-
- sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | core_flags;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
- udelay(1);
-
- bcm->current_core->enabled = 1;
- assert(err == 0);
-out:
- return err;
-}
-
-/* http://bcm-specs.sipsolutions.net/80211CoreReset */
-void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
-{
- u32 flags = 0x00040000;
-
- if ((bcm43xx_core_enabled(bcm)) &&
- !bcm43xx_using_pio(bcm)) {
- }
- if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
- & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002));
- } else {
- if (connect_phy)
- flags |= BCM43xx_SBTMSTATELOW_G_MODE_ENABLE;
- bcm43xx_phy_connect(bcm, connect_phy);
- bcm43xx_core_enable(bcm, flags);
- bcm43xx_write16(bcm, 0x03E6, 0x0000);
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
- | BCM43xx_SBF_400);
- }
-}
-
-static void bcm43xx_wireless_core_disable(struct bcm43xx_private *bcm)
-{
- bcm43xx_radio_turn_off(bcm);
- bcm43xx_write16(bcm, 0x03E6, 0x00F4);
- bcm43xx_core_disable(bcm, 0);
-}
-
-/* Mark the current 80211 core inactive. */
-static void bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm)
-{
- u32 sbtmstatelow;
-
- bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_radio_turn_off(bcm);
- sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- sbtmstatelow &= 0xDFF5FFFF;
- sbtmstatelow |= 0x000A0000;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
- udelay(1);
- sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- sbtmstatelow &= 0xFFF5FFFF;
- sbtmstatelow |= 0x00080000;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
- udelay(1);
-}
-
-static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
-{
- u32 v0, v1;
- u16 tmp;
- struct bcm43xx_xmitstatus stat;
-
- while (1) {
- v0 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
- if (!v0)
- break;
- v1 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
-
- stat.cookie = (v0 >> 16) & 0x0000FFFF;
- tmp = (u16)((v0 & 0xFFF0) | ((v0 & 0xF) >> 1));
- stat.flags = tmp & 0xFF;
- stat.cnt1 = (tmp & 0x0F00) >> 8;
- stat.cnt2 = (tmp & 0xF000) >> 12;
- stat.seq = (u16)(v1 & 0xFFFF);
- stat.unknown = (u16)((v1 >> 16) & 0xFF);
-
- bcm43xx_debugfs_log_txstat(bcm, &stat);
-
- if (stat.flags & BCM43xx_TXSTAT_FLAG_AMPDU)
- continue;
- if (stat.flags & BCM43xx_TXSTAT_FLAG_INTER)
- continue;
-
- if (bcm43xx_using_pio(bcm))
- bcm43xx_pio_handle_xmitstatus(bcm, &stat);
- else
- bcm43xx_dma_handle_xmitstatus(bcm, &stat);
- }
-}
-
-static void drain_txstatus_queue(struct bcm43xx_private *bcm)
-{
- u32 dummy;
-
- if (bcm->current_core->rev < 5)
- return;
- /* Read all entries from the microcode TXstatus FIFO
- * and throw them away.
- */
- while (1) {
- dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
- if (!dummy)
- break;
- dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
- }
-}
-
-static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm)
-{
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x40A, 0x7F7F);
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD) | (1 << 4));
- assert(bcm->noisecalc.core_at_start == bcm->current_core);
- assert(bcm->noisecalc.channel_at_start == bcm43xx_current_radio(bcm)->channel);
-}
-
-static void bcm43xx_calculate_link_quality(struct bcm43xx_private *bcm)
-{
- /* Top half of Link Quality calculation. */
-
- if (bcm->noisecalc.calculation_running)
- return;
- bcm->noisecalc.core_at_start = bcm->current_core;
- bcm->noisecalc.channel_at_start = bcm43xx_current_radio(bcm)->channel;
- bcm->noisecalc.calculation_running = 1;
- bcm->noisecalc.nr_samples = 0;
-
- bcm43xx_generate_noise_sample(bcm);
-}
-
-static void handle_irq_noise(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 tmp;
- u8 noise[4];
- u8 i, j;
- s32 average;
-
- /* Bottom half of Link Quality calculation. */
-
- assert(bcm->noisecalc.calculation_running);
- if (bcm->noisecalc.core_at_start != bcm->current_core ||
- bcm->noisecalc.channel_at_start != radio->channel)
- goto drop_calculation;
- tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x408);
- noise[0] = (tmp & 0x00FF);
- noise[1] = (tmp & 0xFF00) >> 8;
- tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40A);
- noise[2] = (tmp & 0x00FF);
- noise[3] = (tmp & 0xFF00) >> 8;
- if (noise[0] == 0x7F || noise[1] == 0x7F ||
- noise[2] == 0x7F || noise[3] == 0x7F)
- goto generate_new;
-
- /* Get the noise samples. */
- assert(bcm->noisecalc.nr_samples < 8);
- i = bcm->noisecalc.nr_samples;
- noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
- noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
- noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
- noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
- bcm->noisecalc.samples[i][0] = radio->nrssi_lt[noise[0]];
- bcm->noisecalc.samples[i][1] = radio->nrssi_lt[noise[1]];
- bcm->noisecalc.samples[i][2] = radio->nrssi_lt[noise[2]];
- bcm->noisecalc.samples[i][3] = radio->nrssi_lt[noise[3]];
- bcm->noisecalc.nr_samples++;
- if (bcm->noisecalc.nr_samples == 8) {
- /* Calculate the Link Quality by the noise samples. */
- average = 0;
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 4; j++)
- average += bcm->noisecalc.samples[i][j];
- }
- average /= (8 * 4);
- average *= 125;
- average += 64;
- average /= 128;
-
- tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40C);
- tmp = (tmp / 128) & 0x1F;
- if (tmp >= 8)
- average += 2;
- else
- average -= 25;
- if (tmp == 8)
- average -= 72;
- else
- average -= 48;
-
- bcm->stats.noise = average;
-drop_calculation:
- bcm->noisecalc.calculation_running = 0;
- return;
- }
-generate_new:
- bcm43xx_generate_noise_sample(bcm);
-}
-
-static void handle_irq_ps(struct bcm43xx_private *bcm)
-{
- if (bcm->ieee->iw_mode == IW_MODE_MASTER) {
- ///TODO: PS TBTT
- } else {
- if (1/*FIXME: the last PSpoll frame was sent successfully */)
- bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
- }
- if (bcm->ieee->iw_mode == IW_MODE_ADHOC)
- bcm->reg124_set_0x4 = 1;
- //FIXME else set to false?
-}
-
-static void handle_irq_reg124(struct bcm43xx_private *bcm)
-{
- if (!bcm->reg124_set_0x4)
- return;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD)
- | 0x4);
- //FIXME: reset reg124_set_0x4 to false?
-}
-
-static void handle_irq_pmq(struct bcm43xx_private *bcm)
-{
- u32 tmp;
-
- //TODO: AP mode.
-
- while (1) {
- tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_PS_STATUS);
- if (!(tmp & 0x00000008))
- break;
- }
- /* 16bit write is odd, but correct. */
- bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002);
-}
-
-static void bcm43xx_generate_beacon_template(struct bcm43xx_private *bcm,
- u16 ram_offset, u16 shm_size_offset)
-{
- u32 value;
- u16 size = 0;
-
- /* Timestamp. */
- //FIXME: assumption: The chip sets the timestamp
- value = 0;
- bcm43xx_ram_write(bcm, ram_offset++, value);
- bcm43xx_ram_write(bcm, ram_offset++, value);
- size += 8;
-
- /* Beacon Interval / Capability Information */
- value = 0x0000;//FIXME: Which interval?
- value |= (1 << 0) << 16; /* ESS */
- value |= (1 << 2) << 16; /* CF Pollable */ //FIXME?
- value |= (1 << 3) << 16; /* CF Poll Request */ //FIXME?
- if (!bcm->ieee->open_wep)
- value |= (1 << 4) << 16; /* Privacy */
- bcm43xx_ram_write(bcm, ram_offset++, value);
- size += 4;
-
- /* SSID */
- //TODO
-
- /* FH Parameter Set */
- //TODO
-
- /* DS Parameter Set */
- //TODO
-
- /* CF Parameter Set */
- //TODO
-
- /* TIM */
- //TODO
-
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size);
-}
-
-static void handle_irq_beacon(struct bcm43xx_private *bcm)
-{
- u32 status;
-
- bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON;
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
-
- if ((status & 0x1) && (status & 0x2)) {
- /* ACK beacon IRQ. */
- bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
- BCM43xx_IRQ_BEACON);
- bcm->irq_savedstate |= BCM43xx_IRQ_BEACON;
- return;
- }
- if (!(status & 0x1)) {
- bcm43xx_generate_beacon_template(bcm, 0x68, 0x18);
- status |= 0x1;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
- }
- if (!(status & 0x2)) {
- bcm43xx_generate_beacon_template(bcm, 0x468, 0x1A);
- status |= 0x2;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
- }
-}
-
-/* Interrupt handler bottom-half */
-static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
-{
- u32 reason;
- u32 dma_reason[6];
- u32 merged_dma_reason = 0;
- int i, activity = 0;
- unsigned long flags;
-
-#ifdef CONFIG_BCM43XX_DEBUG
- u32 _handled = 0x00000000;
-# define bcmirq_handled(irq) do { _handled |= (irq); } while (0)
-#else
-# define bcmirq_handled(irq) do { /* nothing */ } while (0)
-#endif /* CONFIG_BCM43XX_DEBUG*/
-
- spin_lock_irqsave(&bcm->irq_lock, flags);
- reason = bcm->irq_reason;
- for (i = 5; i >= 0; i--) {
- dma_reason[i] = bcm->dma_reason[i];
- merged_dma_reason |= dma_reason[i];
- }
-
- if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
- /* TX error. We get this when Template Ram is written in wrong endianess
- * in dummy_tx(). We also get this if something is wrong with the TX header
- * on DMA or PIO queues.
- * Maybe we get this in other error conditions, too.
- */
- printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
- bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
- }
- if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK)) {
- printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
- "0x%08X, 0x%08X, 0x%08X, "
- "0x%08X, 0x%08X, 0x%08X\n",
- dma_reason[0], dma_reason[1],
- dma_reason[2], dma_reason[3],
- dma_reason[4], dma_reason[5]);
- bcm43xx_controller_restart(bcm, "DMA error");
- mmiowb();
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- return;
- }
- if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK)) {
- printkl(KERN_ERR PFX "DMA error: "
- "0x%08X, 0x%08X, 0x%08X, "
- "0x%08X, 0x%08X, 0x%08X\n",
- dma_reason[0], dma_reason[1],
- dma_reason[2], dma_reason[3],
- dma_reason[4], dma_reason[5]);
- }
-
- if (reason & BCM43xx_IRQ_PS) {
- handle_irq_ps(bcm);
- bcmirq_handled(BCM43xx_IRQ_PS);
- }
-
- if (reason & BCM43xx_IRQ_REG124) {
- handle_irq_reg124(bcm);
- bcmirq_handled(BCM43xx_IRQ_REG124);
- }
-
- if (reason & BCM43xx_IRQ_BEACON) {
- if (bcm->ieee->iw_mode == IW_MODE_MASTER)
- handle_irq_beacon(bcm);
- bcmirq_handled(BCM43xx_IRQ_BEACON);
- }
-
- if (reason & BCM43xx_IRQ_PMQ) {
- handle_irq_pmq(bcm);
- bcmirq_handled(BCM43xx_IRQ_PMQ);
- }
-
- if (reason & BCM43xx_IRQ_SCAN) {
- /*TODO*/
- //bcmirq_handled(BCM43xx_IRQ_SCAN);
- }
-
- if (reason & BCM43xx_IRQ_NOISE) {
- handle_irq_noise(bcm);
- bcmirq_handled(BCM43xx_IRQ_NOISE);
- }
-
- /* Check the DMA reason registers for received data. */
- if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
- if (bcm43xx_using_pio(bcm))
- bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
- else
- bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
- /* We intentionally don't set "activity" to 1, here. */
- }
- assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
- assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
- if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
- if (bcm43xx_using_pio(bcm))
- bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
- else
- bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring3);
- activity = 1;
- }
- assert(!(dma_reason[4] & BCM43xx_DMAIRQ_RX_DONE));
- assert(!(dma_reason[5] & BCM43xx_DMAIRQ_RX_DONE));
- bcmirq_handled(BCM43xx_IRQ_RX);
-
- if (reason & BCM43xx_IRQ_XMIT_STATUS) {
- handle_irq_transmit_status(bcm);
- activity = 1;
- //TODO: In AP mode, this also causes sending of powersave responses.
- bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS);
- }
-
- /* IRQ_PIO_WORKAROUND is handled in the top-half. */
- bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND);
-#ifdef CONFIG_BCM43XX_DEBUG
- if (unlikely(reason & ~_handled)) {
- printkl(KERN_WARNING PFX
- "Unhandled IRQ! Reason: 0x%08x, Unhandled: 0x%08x, "
- "DMA: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
- reason, (reason & ~_handled),
- dma_reason[0], dma_reason[1],
- dma_reason[2], dma_reason[3]);
- }
-#endif
-#undef bcmirq_handled
-
- if (!modparam_noleds)
- bcm43xx_leds_update(bcm, activity);
- bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
- mmiowb();
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-}
-
-static void pio_irq_workaround(struct bcm43xx_private *bcm,
- u16 base, int queueidx)
-{
- u16 rxctl;
-
- rxctl = bcm43xx_read16(bcm, base + BCM43xx_PIO_RXCTL);
- if (rxctl & BCM43xx_PIO_RXCTL_DATAAVAILABLE)
- bcm->dma_reason[queueidx] |= BCM43xx_DMAIRQ_RX_DONE;
- else
- bcm->dma_reason[queueidx] &= ~BCM43xx_DMAIRQ_RX_DONE;
-}
-
-static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason)
-{
- if (bcm43xx_using_pio(bcm) &&
- (bcm->current_core->rev < 3) &&
- (!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) {
- /* Apply a PIO specific workaround to the dma_reasons */
- pio_irq_workaround(bcm, BCM43xx_MMIO_PIO1_BASE, 0);
- pio_irq_workaround(bcm, BCM43xx_MMIO_PIO2_BASE, 1);
- pio_irq_workaround(bcm, BCM43xx_MMIO_PIO3_BASE, 2);
- pio_irq_workaround(bcm, BCM43xx_MMIO_PIO4_BASE, 3);
- }
-
- bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
-
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
- bcm->dma_reason[0]);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
- bcm->dma_reason[1]);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
- bcm->dma_reason[2]);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
- bcm->dma_reason[3]);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
- bcm->dma_reason[4]);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
- bcm->dma_reason[5]);
-}
-
-/* Interrupt handler top-half */
-static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id)
-{
- irqreturn_t ret = IRQ_HANDLED;
- struct bcm43xx_private *bcm = dev_id;
- u32 reason;
-
- if (!bcm)
- return IRQ_NONE;
-
- spin_lock(&bcm->irq_lock);
-
- reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
- if (reason == 0xffffffff) {
- /* irq not for us (shared irq) */
- ret = IRQ_NONE;
- goto out;
- }
- reason &= bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
- if (!reason)
- goto out;
-
- assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
- assert(bcm->current_core->id == BCM43xx_COREID_80211);
-
- bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
- & 0x0001DC00;
- bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
- & 0x0000DC00;
- bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
- & 0x0000DC00;
- bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
- & 0x0001DC00;
- bcm->dma_reason[4] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
- & 0x0000DC00;
- bcm->dma_reason[5] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA5_REASON)
- & 0x0000DC00;
-
- bcm43xx_interrupt_ack(bcm, reason);
-
- /* disable all IRQs. They are enabled again in the bottom half. */
- bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- /* save the reason code and call our bottom half. */
- bcm->irq_reason = reason;
- tasklet_schedule(&bcm->isr_tasklet);
-
-out:
- mmiowb();
- spin_unlock(&bcm->irq_lock);
-
- return ret;
-}
-
-static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-
- if (bcm->firmware_norelease && !force)
- return; /* Suspending or controller reset. */
- release_firmware(phy->ucode);
- phy->ucode = NULL;
- release_firmware(phy->pcm);
- phy->pcm = NULL;
- release_firmware(phy->initvals0);
- phy->initvals0 = NULL;
- release_firmware(phy->initvals1);
- phy->initvals1 = NULL;
-}
-
-static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u8 rev = bcm->current_core->rev;
- int err = 0;
- int nr;
- char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
-
- if (!phy->ucode) {
- snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
- (rev >= 5 ? 5 : rev),
- modparam_fwpostfix);
- err = request_firmware(&phy->ucode, buf, &bcm->pci_dev->dev);
- if (err) {
- printk(KERN_ERR PFX
- "Error: Microcode \"%s\" not available or load failed.\n",
- buf);
- goto error;
- }
- }
-
- if (!phy->pcm) {
- snprintf(buf, ARRAY_SIZE(buf),
- "bcm43xx_pcm%d%s.fw",
- (rev < 5 ? 4 : 5),
- modparam_fwpostfix);
- err = request_firmware(&phy->pcm, buf, &bcm->pci_dev->dev);
- if (err) {
- printk(KERN_ERR PFX
- "Error: PCM \"%s\" not available or load failed.\n",
- buf);
- goto error;
- }
- }
-
- if (!phy->initvals0) {
- if (rev == 2 || rev == 4) {
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- nr = 3;
- break;
- case BCM43xx_PHYTYPE_B:
- case BCM43xx_PHYTYPE_G:
- nr = 1;
- break;
- default:
- goto err_noinitval;
- }
-
- } else if (rev >= 5) {
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- nr = 7;
- break;
- case BCM43xx_PHYTYPE_B:
- case BCM43xx_PHYTYPE_G:
- nr = 5;
- break;
- default:
- goto err_noinitval;
- }
- } else
- goto err_noinitval;
- snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
- nr, modparam_fwpostfix);
-
- err = request_firmware(&phy->initvals0, buf, &bcm->pci_dev->dev);
- if (err) {
- printk(KERN_ERR PFX
- "Error: InitVals \"%s\" not available or load failed.\n",
- buf);
- goto error;
- }
- if (phy->initvals0->size % sizeof(struct bcm43xx_initval)) {
- printk(KERN_ERR PFX "InitVals fileformat error.\n");
- goto error;
- }
- }
-
- if (!phy->initvals1) {
- if (rev >= 5) {
- u32 sbtmstatehigh;
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
- if (sbtmstatehigh & 0x00010000)
- nr = 9;
- else
- nr = 10;
- break;
- case BCM43xx_PHYTYPE_B:
- case BCM43xx_PHYTYPE_G:
- nr = 6;
- break;
- default:
- goto err_noinitval;
- }
- snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
- nr, modparam_fwpostfix);
-
- err = request_firmware(&phy->initvals1, buf, &bcm->pci_dev->dev);
- if (err) {
- printk(KERN_ERR PFX
- "Error: InitVals \"%s\" not available or load failed.\n",
- buf);
- goto error;
- }
- if (phy->initvals1->size % sizeof(struct bcm43xx_initval)) {
- printk(KERN_ERR PFX "InitVals fileformat error.\n");
- goto error;
- }
- }
- }
-
-out:
- return err;
-error:
- bcm43xx_release_firmware(bcm, 1);
- goto out;
-err_noinitval:
- printk(KERN_ERR PFX "Error: No InitVals available!\n");
- err = -ENOENT;
- goto error;
-}
-
-static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- const __be32 *data;
- unsigned int i, len;
-
- /* Upload Microcode. */
- data = (__be32 *)(phy->ucode->data);
- len = phy->ucode->size / sizeof(u32);
- bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
- for (i = 0; i < len; i++) {
- bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
- be32_to_cpu(data[i]));
- udelay(10);
- }
-
- /* Upload PCM data. */
- data = (__be32 *)(phy->pcm->data);
- len = phy->pcm->size / sizeof(u32);
- bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
- bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
- bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
- for (i = 0; i < len; i++) {
- bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
- be32_to_cpu(data[i]));
- udelay(10);
- }
-}
-
-static int bcm43xx_write_initvals(struct bcm43xx_private *bcm,
- const struct bcm43xx_initval *data,
- const unsigned int len)
-{
- u16 offset, size;
- u32 value;
- unsigned int i;
-
- for (i = 0; i < len; i++) {
- offset = be16_to_cpu(data[i].offset);
- size = be16_to_cpu(data[i].size);
- value = be32_to_cpu(data[i].value);
-
- if (unlikely(offset >= 0x1000))
- goto err_format;
- if (size == 2) {
- if (unlikely(value & 0xFFFF0000))
- goto err_format;
- bcm43xx_write16(bcm, offset, (u16)value);
- } else if (size == 4) {
- bcm43xx_write32(bcm, offset, value);
- } else
- goto err_format;
- }
-
- return 0;
-
-err_format:
- printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. "
- "Please fix your bcm43xx firmware files.\n");
- return -EPROTO;
-}
-
-static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- int err;
-
- err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals0->data,
- phy->initvals0->size / sizeof(struct bcm43xx_initval));
- if (err)
- goto out;
- if (phy->initvals1) {
- err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals1->data,
- phy->initvals1->size / sizeof(struct bcm43xx_initval));
- if (err)
- goto out;
- }
-out:
- return err;
-}
-
-static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
-{
- int err;
-
- bcm->irq = bcm->pci_dev->irq;
- err = request_irq(bcm->irq, bcm43xx_interrupt_handler,
- IRQF_SHARED, KBUILD_MODNAME, bcm);
- if (err)
- printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq);
-
- return err;
-}
-
-/* Switch to the core used to write the GPIO register.
- * This is either the ChipCommon, or the PCI core.
- */
-static int switch_to_gpio_core(struct bcm43xx_private *bcm)
-{
- int err;
-
- /* Where to find the GPIO register depends on the chipset.
- * If it has a ChipCommon, its register at offset 0x6c is the GPIO
- * control register. Otherwise the register at offset 0x6c in the
- * PCI core is the GPIO control register.
- */
- err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
- if (err == -ENODEV) {
- err = bcm43xx_switch_core(bcm, &bcm->core_pci);
- if (unlikely(err == -ENODEV)) {
- printk(KERN_ERR PFX "gpio error: "
- "Neither ChipCommon nor PCI core available!\n");
- }
- }
-
- return err;
-}
-
-/* Initialize the GPIOs
- * http://bcm-specs.sipsolutions.net/GPIO
- */
-static int bcm43xx_gpio_init(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_coreinfo *old_core;
- int err;
- u32 mask, set;
-
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
- & 0xFFFF3FFF);
-
- bcm43xx_leds_switch_all(bcm, 0);
- bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
- bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) | 0x000F);
-
- mask = 0x0000001F;
- set = 0x0000000F;
- if (bcm->chip_id == 0x4301) {
- mask |= 0x0060;
- set |= 0x0060;
- }
- if (0 /* FIXME: conditional unknown */) {
- bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
- bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK)
- | 0x0100);
- mask |= 0x0180;
- set |= 0x0180;
- }
- if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) {
- bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
- bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK)
- | 0x0200);
- mask |= 0x0200;
- set |= 0x0200;
- }
- if (bcm->current_core->rev >= 2)
- mask |= 0x0010; /* FIXME: This is redundant. */
-
- old_core = bcm->current_core;
- err = switch_to_gpio_core(bcm);
- if (err)
- goto out;
- bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL,
- (bcm43xx_read32(bcm, BCM43xx_GPIO_CONTROL) & mask) | set);
- err = bcm43xx_switch_core(bcm, old_core);
-out:
- return err;
-}
-
-/* Turn off all GPIO stuff. Call this on module unload, for example. */
-static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_coreinfo *old_core;
- int err;
-
- old_core = bcm->current_core;
- err = switch_to_gpio_core(bcm);
- if (err)
- return err;
- bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL, 0x00000000);
- err = bcm43xx_switch_core(bcm, old_core);
- assert(err == 0);
-
- return 0;
-}
-
-/* http://bcm-specs.sipsolutions.net/EnableMac */
-void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
-{
- bcm->mac_suspended--;
- assert(bcm->mac_suspended >= 0);
- if (bcm->mac_suspended == 0) {
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
- | BCM43xx_SBF_MAC_ENABLED);
- bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
- bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
- bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
- }
-}
-
-/* http://bcm-specs.sipsolutions.net/SuspendMAC */
-void bcm43xx_mac_suspend(struct bcm43xx_private *bcm)
-{
- int i;
- u32 tmp;
-
- assert(bcm->mac_suspended >= 0);
- if (bcm->mac_suspended == 0) {
- bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
- & ~BCM43xx_SBF_MAC_ENABLED);
- bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
- for (i = 10000; i; i--) {
- tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
- if (tmp & BCM43xx_IRQ_READY)
- goto out;
- udelay(1);
- }
- printkl(KERN_ERR PFX "MAC suspend failed\n");
- }
-out:
- bcm->mac_suspended++;
-}
-
-void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
- int iw_mode)
-{
- unsigned long flags;
- struct net_device *net_dev = bcm->net_dev;
- u32 status;
- u16 value;
-
- spin_lock_irqsave(&bcm->ieee->lock, flags);
- bcm->ieee->iw_mode = iw_mode;
- spin_unlock_irqrestore(&bcm->ieee->lock, flags);
- if (iw_mode == IW_MODE_MONITOR)
- net_dev->type = ARPHRD_IEEE80211;
- else
- net_dev->type = ARPHRD_ETHER;
-
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- /* Reset status to infrastructured mode */
- status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR);
- status &= ~BCM43xx_SBF_MODE_PROMISC;
- status |= BCM43xx_SBF_MODE_NOTADHOC;
-
-/* FIXME: Always enable promisc mode, until we get the MAC filters working correctly. */
-status |= BCM43xx_SBF_MODE_PROMISC;
-
- switch (iw_mode) {
- case IW_MODE_MONITOR:
- status |= BCM43xx_SBF_MODE_MONITOR;
- status |= BCM43xx_SBF_MODE_PROMISC;
- break;
- case IW_MODE_ADHOC:
- status &= ~BCM43xx_SBF_MODE_NOTADHOC;
- break;
- case IW_MODE_MASTER:
- status |= BCM43xx_SBF_MODE_AP;
- break;
- case IW_MODE_SECOND:
- case IW_MODE_REPEAT:
- TODO(); /* TODO */
- break;
- case IW_MODE_INFRA:
- /* nothing to be done here... */
- break;
- default:
- dprintk(KERN_ERR PFX "Unknown mode in set_iwmode: %d\n", iw_mode);
- }
- if (net_dev->flags & IFF_PROMISC)
- status |= BCM43xx_SBF_MODE_PROMISC;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
-
- value = 0x0002;
- if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) {
- if (bcm->chip_id == 0x4306 && bcm->chip_rev == 3)
- value = 0x0064;
- else
- value = 0x0032;
- }
- bcm43xx_write16(bcm, 0x0612, value);
-}
-
-/* This is the opposite of bcm43xx_chip_init() */
-static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm)
-{
- bcm43xx_radio_turn_off(bcm);
- if (!modparam_noleds)
- bcm43xx_leds_exit(bcm);
- bcm43xx_gpio_cleanup(bcm);
- bcm43xx_release_firmware(bcm, 0);
-}
-
-/* Initialize the chip
- * http://bcm-specs.sipsolutions.net/ChipInit
- */
-static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- int err;
- int i, tmp;
- u32 value32;
- u16 value16;
-
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
- BCM43xx_SBF_CORE_READY
- | BCM43xx_SBF_400);
-
- err = bcm43xx_request_firmware(bcm);
- if (err)
- goto out;
- bcm43xx_upload_microcode(bcm);
-
- bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xFFFFFFFF);
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
- i = 0;
- while (1) {
- value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
- if (value32 == BCM43xx_IRQ_READY)
- break;
- i++;
- if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
- printk(KERN_ERR PFX "IRQ_READY timeout\n");
- err = -ENODEV;
- goto err_release_fw;
- }
- udelay(10);
- }
- bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
-
- value16 = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODE_REVISION);
-
- dprintk(KERN_INFO PFX "Microcode rev 0x%x, pl 0x%x "
- "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", value16,
- bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODE_PATCHLEVEL),
- (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODE_DATE) >> 12) & 0xf,
- (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODE_DATE) >> 8) & 0xf,
- bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODE_DATE) & 0xff,
- (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODE_TIME) >> 11) & 0x1f,
- (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODE_TIME) >> 5) & 0x3f,
- bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODE_TIME) & 0x1f);
-
- if ( value16 > 0x128 ) {
- printk(KERN_ERR PFX
- "Firmware: no support for microcode extracted "
- "from version 4.x binary drivers.\n");
- err = -EOPNOTSUPP;
- goto err_release_fw;
- }
-
- err = bcm43xx_gpio_init(bcm);
- if (err)
- goto err_release_fw;
-
- err = bcm43xx_upload_initvals(bcm);
- if (err)
- goto err_gpio_cleanup;
- bcm43xx_radio_turn_on(bcm);
- bcm->radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm);
- printk(KERN_INFO PFX "Radio %s by hardware\n",
- (bcm->radio_hw_enable == 0) ? "disabled" : "enabled");
-
- bcm43xx_write16(bcm, 0x03E6, 0x0000);
- err = bcm43xx_phy_init(bcm);
- if (err)
- goto err_radio_off;
-
- /* Select initial Interference Mitigation. */
- tmp = radio->interfmode;
- radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
- bcm43xx_radio_set_interference_mitigation(bcm, tmp);
-
- bcm43xx_phy_set_antenna_diversity(bcm);
- bcm43xx_radio_set_txantenna(bcm, BCM43xx_RADIO_TXANTENNA_DEFAULT);
- if (phy->type == BCM43xx_PHYTYPE_B) {
- value16 = bcm43xx_read16(bcm, 0x005E);
- value16 |= 0x0004;
- bcm43xx_write16(bcm, 0x005E, value16);
- }
- bcm43xx_write32(bcm, 0x0100, 0x01000000);
- if (bcm->current_core->rev < 5)
- bcm43xx_write32(bcm, 0x010C, 0x01000000);
-
- value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- value32 &= ~ BCM43xx_SBF_MODE_NOTADHOC;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
- value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- value32 |= BCM43xx_SBF_MODE_NOTADHOC;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
-
- value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- value32 |= 0x100000;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
-
- if (bcm43xx_using_pio(bcm)) {
- bcm43xx_write32(bcm, 0x0210, 0x00000100);
- bcm43xx_write32(bcm, 0x0230, 0x00000100);
- bcm43xx_write32(bcm, 0x0250, 0x00000100);
- bcm43xx_write32(bcm, 0x0270, 0x00000100);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0034, 0x0000);
- }
-
- /* Probe Response Timeout value */
- /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000);
-
- /* Initially set the wireless operation mode. */
- bcm43xx_set_iwmode(bcm, bcm->ieee->iw_mode);
-
- if (bcm->current_core->rev < 3) {
- bcm43xx_write16(bcm, 0x060E, 0x0000);
- bcm43xx_write16(bcm, 0x0610, 0x8000);
- bcm43xx_write16(bcm, 0x0604, 0x0000);
- bcm43xx_write16(bcm, 0x0606, 0x0200);
- } else {
- bcm43xx_write32(bcm, 0x0188, 0x80000000);
- bcm43xx_write32(bcm, 0x018C, 0x02000000);
- }
- bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
-
- value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- value32 |= 0x00100000;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, value32);
-
- bcm43xx_write16(bcm, BCM43xx_MMIO_POWERUP_DELAY, bcm43xx_pctl_powerup_delay(bcm));
-
- assert(err == 0);
- dprintk(KERN_INFO PFX "Chip initialized\n");
-out:
- return err;
-
-err_radio_off:
- bcm43xx_radio_turn_off(bcm);
-err_gpio_cleanup:
- bcm43xx_gpio_cleanup(bcm);
-err_release_fw:
- bcm43xx_release_firmware(bcm, 1);
- goto out;
-}
-
-/* Validate chip access
- * http://bcm-specs.sipsolutions.net/ValidateChipAccess */
-static int bcm43xx_validate_chip(struct bcm43xx_private *bcm)
-{
- u32 value;
- u32 shm_backup;
-
- shm_backup = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000);
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0xAA5555AA);
- if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0xAA5555AA)
- goto error;
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0x55AAAA55);
- if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0x55AAAA55)
- goto error;
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, shm_backup);
-
- value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- if ((value | 0x80000000) != 0x80000400)
- goto error;
-
- value = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
- if (value != 0x00000000)
- goto error;
-
- return 0;
-error:
- printk(KERN_ERR PFX "Failed to validate the chipaccess\n");
- return -ENODEV;
-}
-
-static void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy)
-{
- /* Initialize a "phyinfo" structure. The structure is already
- * zeroed out.
- * This is called on insmod time to initialize members.
- */
- phy->savedpctlreg = 0xFFFF;
- spin_lock_init(&phy->lock);
-}
-
-static void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio)
-{
- /* Initialize a "radioinfo" structure. The structure is already
- * zeroed out.
- * This is called on insmod time to initialize members.
- */
- radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
- radio->channel = 0xFF;
- radio->initial_channel = 0xFF;
-}
-
-static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
-{
- int err, i;
- int current_core;
- u32 core_vendor, core_id, core_rev;
- u32 sb_id_hi, chip_id_32 = 0;
- u16 pci_device, chip_id_16;
- u8 core_count;
-
- memset(&bcm->core_chipcommon, 0, sizeof(struct bcm43xx_coreinfo));
- memset(&bcm->core_pci, 0, sizeof(struct bcm43xx_coreinfo));
- memset(&bcm->core_80211, 0, sizeof(struct bcm43xx_coreinfo)
- * BCM43xx_MAX_80211_CORES);
- memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211)
- * BCM43xx_MAX_80211_CORES);
- bcm->nr_80211_available = 0;
- bcm->current_core = NULL;
- bcm->active_80211_core = NULL;
-
- /* map core 0 */
- err = _switch_core(bcm, 0);
- if (err)
- goto out;
-
- /* fetch sb_id_hi from core information registers */
- sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
-
- core_id = (sb_id_hi & 0x8FF0) >> 4;
- core_rev = (sb_id_hi & 0x7000) >> 8;
- core_rev |= (sb_id_hi & 0xF);
- core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
-
- /* if present, chipcommon is always core 0; read the chipid from it */
- if (core_id == BCM43xx_COREID_CHIPCOMMON) {
- chip_id_32 = bcm43xx_read32(bcm, 0);
- chip_id_16 = chip_id_32 & 0xFFFF;
- bcm->core_chipcommon.available = 1;
- bcm->core_chipcommon.id = core_id;
- bcm->core_chipcommon.rev = core_rev;
- bcm->core_chipcommon.index = 0;
- /* While we are at it, also read the capabilities. */
- bcm->chipcommon_capabilities = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_CAPABILITIES);
- } else {
- /* without a chipCommon, use a hard coded table. */
- pci_device = bcm->pci_dev->device;
- if (pci_device == 0x4301)
- chip_id_16 = 0x4301;
- else if ((pci_device >= 0x4305) && (pci_device <= 0x4307))
- chip_id_16 = 0x4307;
- else if ((pci_device >= 0x4402) && (pci_device <= 0x4403))
- chip_id_16 = 0x4402;
- else if ((pci_device >= 0x4610) && (pci_device <= 0x4615))
- chip_id_16 = 0x4610;
- else if ((pci_device >= 0x4710) && (pci_device <= 0x4715))
- chip_id_16 = 0x4710;
- else {
- printk(KERN_ERR PFX "Could not determine Chip ID\n");
- return -ENODEV;
- }
- }
-
- /* ChipCommon with Core Rev >=4 encodes number of cores,
- * otherwise consult hardcoded table */
- if ((core_id == BCM43xx_COREID_CHIPCOMMON) && (core_rev >= 4)) {
- core_count = (chip_id_32 & 0x0F000000) >> 24;
- } else {
- switch (chip_id_16) {
- case 0x4610:
- case 0x4704:
- case 0x4710:
- core_count = 9;
- break;
- case 0x4310:
- core_count = 8;
- break;
- case 0x5365:
- core_count = 7;
- break;
- case 0x4306:
- core_count = 6;
- break;
- case 0x4301:
- case 0x4307:
- core_count = 5;
- break;
- case 0x4402:
- core_count = 3;
- break;
- default:
- /* SOL if we get here */
- assert(0);
- core_count = 1;
- }
- }
-
- bcm->chip_id = chip_id_16;
- bcm->chip_rev = (chip_id_32 & 0x000F0000) >> 16;
- bcm->chip_package = (chip_id_32 & 0x00F00000) >> 20;
-
- dprintk(KERN_INFO PFX "Chip ID 0x%x, rev 0x%x\n",
- bcm->chip_id, bcm->chip_rev);
- dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count);
- if (bcm->core_chipcommon.available) {
- dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x\n",
- core_id, core_rev, core_vendor);
- current_core = 1;
- } else
- current_core = 0;
- for ( ; current_core < core_count; current_core++) {
- struct bcm43xx_coreinfo *core;
- struct bcm43xx_coreinfo_80211 *ext_80211;
-
- err = _switch_core(bcm, current_core);
- if (err)
- goto out;
- /* Gather information */
- /* fetch sb_id_hi from core information registers */
- sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
-
- /* extract core_id, core_rev, core_vendor */
- core_id = (sb_id_hi & 0x8FF0) >> 4;
- core_rev = ((sb_id_hi & 0xF) | ((sb_id_hi & 0x7000) >> 8));
- core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
-
- dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x\n",
- current_core, core_id, core_rev, core_vendor);
-
- core = NULL;
- switch (core_id) {
- case BCM43xx_COREID_PCI:
- case BCM43xx_COREID_PCIE:
- core = &bcm->core_pci;
- if (core->available) {
- printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
- continue;
- }
- break;
- case BCM43xx_COREID_80211:
- for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
- core = &(bcm->core_80211[i]);
- ext_80211 = &(bcm->core_80211_ext[i]);
- if (!core->available)
- break;
- core = NULL;
- }
- if (!core) {
- printk(KERN_WARNING PFX "More than %d cores of type 802.11 found.\n",
- BCM43xx_MAX_80211_CORES);
- continue;
- }
- if (i != 0) {
- /* More than one 80211 core is only supported
- * by special chips.
- * There are chips with two 80211 cores, but with
- * dangling pins on the second core. Be careful
- * and ignore these cores here.
- */
- if (1 /*bcm->pci_dev->device != 0x4324*/ ) {
- /* TODO: A PHY */
- dprintk(KERN_INFO PFX "Ignoring additional 802.11a core.\n");
- continue;
- }
- }
- switch (core_rev) {
- case 2:
- case 4:
- case 5:
- case 6:
- case 7:
- case 9:
- case 10:
- break;
- default:
- printk(KERN_WARNING PFX
- "Unsupported 80211 core revision %u\n",
- core_rev);
- }
- bcm->nr_80211_available++;
- core->priv = ext_80211;
- bcm43xx_init_struct_phyinfo(&ext_80211->phy);
- bcm43xx_init_struct_radioinfo(&ext_80211->radio);
- break;
- case BCM43xx_COREID_CHIPCOMMON:
- printk(KERN_WARNING PFX "Multiple CHIPCOMMON cores found.\n");
- break;
- }
- if (core) {
- core->available = 1;
- core->id = core_id;
- core->rev = core_rev;
- core->index = current_core;
- }
- }
-
- if (!bcm->core_80211[0].available) {
- printk(KERN_ERR PFX "Error: No 80211 core found!\n");
- err = -ENODEV;
- goto out;
- }
-
- err = bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
-
- assert(err == 0);
-out:
- return err;
-}
-
-static void bcm43xx_gen_bssid(struct bcm43xx_private *bcm)
-{
- const u8 *mac = (const u8*)(bcm->net_dev->dev_addr);
- u8 *bssid = bcm->ieee->bssid;
-
- switch (bcm->ieee->iw_mode) {
- case IW_MODE_ADHOC:
- random_ether_addr(bssid);
- break;
- case IW_MODE_MASTER:
- case IW_MODE_INFRA:
- case IW_MODE_REPEAT:
- case IW_MODE_SECOND:
- case IW_MODE_MONITOR:
- memcpy(bssid, mac, ETH_ALEN);
- break;
- default:
- assert(0);
- }
-}
-
-static void bcm43xx_rate_memory_write(struct bcm43xx_private *bcm,
- u16 rate,
- int is_ofdm)
-{
- u16 offset;
-
- if (is_ofdm) {
- offset = 0x480;
- offset += (bcm43xx_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2;
- }
- else {
- offset = 0x4C0;
- offset += (bcm43xx_plcp_get_ratecode_cck(rate) & 0x000F) * 2;
- }
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, offset + 0x20,
- bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, offset));
-}
-
-static void bcm43xx_rate_memory_init(struct bcm43xx_private *bcm)
-{
- switch (bcm43xx_current_phy(bcm)->type) {
- case BCM43xx_PHYTYPE_A:
- case BCM43xx_PHYTYPE_G:
- bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_6MB, 1);
- bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_12MB, 1);
- bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_18MB, 1);
- bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_24MB, 1);
- bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_36MB, 1);
- bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_48MB, 1);
- bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_54MB, 1);
- case BCM43xx_PHYTYPE_B:
- bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_1MB, 0);
- bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_2MB, 0);
- bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_5MB, 0);
- bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_11MB, 0);
- break;
- default:
- assert(0);
- }
-}
-
-static void bcm43xx_wireless_core_cleanup(struct bcm43xx_private *bcm)
-{
- bcm43xx_chip_cleanup(bcm);
- bcm43xx_pio_free(bcm);
- bcm43xx_dma_free(bcm);
-
- bcm->current_core->initialized = 0;
-}
-
-/* http://bcm-specs.sipsolutions.net/80211Init */
-static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
- int active_wlcore)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u32 ucodeflags;
- int err;
- u32 sbimconfiglow;
- u8 limit;
-
- if (bcm->core_pci.rev <= 5 && bcm->core_pci.id != BCM43xx_COREID_PCIE) {
- sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
- sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
- sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
- if (bcm->bustype == BCM43xx_BUSTYPE_PCI)
- sbimconfiglow |= 0x32;
- else
- sbimconfiglow |= 0x53;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
- }
-
- bcm43xx_phy_calibrate(bcm);
- err = bcm43xx_chip_init(bcm);
- if (err)
- goto out;
-
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0016, bcm->current_core->rev);
- ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, BCM43xx_UCODEFLAGS_OFFSET);
-
- if (0 /*FIXME: which condition has to be used here? */)
- ucodeflags |= 0x00000010;
-
- /* HW decryption needs to be set now */
- ucodeflags |= 0x40000000;
-
- if (phy->type == BCM43xx_PHYTYPE_G) {
- ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
- if (phy->rev == 1)
- ucodeflags |= BCM43xx_UCODEFLAG_UNKGPHY;
- if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
- ucodeflags |= BCM43xx_UCODEFLAG_UNKPACTRL;
- } else if (phy->type == BCM43xx_PHYTYPE_B) {
- ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
- if (phy->rev >= 2 && radio->version == 0x2050)
- ucodeflags &= ~BCM43xx_UCODEFLAG_UNKGPHY;
- }
-
- if (ucodeflags != bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET)) {
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET, ucodeflags);
- }
-
- /* Short/Long Retry Limit.
- * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing
- * the chip-internal counter.
- */
- limit = limit_value(modparam_short_retry, 0, 0xF);
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0006, limit);
- limit = limit_value(modparam_long_retry, 0, 0xF);
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0007, limit);
-
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0044, 3);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0046, 2);
-
- bcm43xx_rate_memory_init(bcm);
-
- /* Minimum Contention Window */
- if (phy->type == BCM43xx_PHYTYPE_B)
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000001f);
- else
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000000f);
- /* Maximum Contention Window */
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
-
- bcm43xx_gen_bssid(bcm);
- bcm43xx_write_mac_bssid_templates(bcm);
-
- if (bcm->current_core->rev >= 5)
- bcm43xx_write16(bcm, 0x043C, 0x000C);
-
- if (active_wlcore) {
- if (bcm43xx_using_pio(bcm)) {
- err = bcm43xx_pio_init(bcm);
- } else {
- err = bcm43xx_dma_init(bcm);
- if (err == -ENOSYS)
- err = bcm43xx_pio_init(bcm);
- }
- if (err)
- goto err_chip_cleanup;
- }
- bcm43xx_write16(bcm, 0x0612, 0x0050);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
-
- if (active_wlcore) {
- if (radio->initial_channel != 0xFF)
- bcm43xx_radio_selectchannel(bcm, radio->initial_channel, 0);
- }
-
- /* Don't enable MAC/IRQ here, as it will race with the IRQ handler.
- * We enable it later.
- */
- bcm->current_core->initialized = 1;
-out:
- return err;
-
-err_chip_cleanup:
- bcm43xx_chip_cleanup(bcm);
- goto out;
-}
-
-static int bcm43xx_chipset_attach(struct bcm43xx_private *bcm)
-{
- int err;
- u16 pci_status;
-
- err = bcm43xx_pctl_set_crystal(bcm, 1);
- if (err)
- goto out;
- err = bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status);
- if (err)
- goto out;
- err = bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT);
-
-out:
- return err;
-}
-
-static void bcm43xx_chipset_detach(struct bcm43xx_private *bcm)
-{
- bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
- bcm43xx_pctl_set_crystal(bcm, 0);
-}
-
-static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm,
- u32 address,
- u32 data)
-{
- bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_ADDR, address);
- bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_DATA, data);
-}
-
-static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
-{
- int err = 0;
-
- bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
-
- if (bcm->core_chipcommon.available) {
- err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
- if (err)
- goto out;
-
- bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
-
- /* this function is always called when a PCI core is mapped */
- err = bcm43xx_switch_core(bcm, &bcm->core_pci);
- if (err)
- goto out;
- } else
- bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
-
- bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
-
-out:
- return err;
-}
-
-static u32 bcm43xx_pcie_reg_read(struct bcm43xx_private *bcm, u32 address)
-{
- bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
- return bcm43xx_read32(bcm, BCM43xx_PCIECORE_REG_DATA);
-}
-
-static void bcm43xx_pcie_reg_write(struct bcm43xx_private *bcm, u32 address,
- u32 data)
-{
- bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
- bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_DATA, data);
-}
-
-static void bcm43xx_pcie_mdio_write(struct bcm43xx_private *bcm, u8 dev, u8 reg,
- u16 data)
-{
- int i;
-
- bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0x0082);
- bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_DATA, BCM43xx_PCIE_MDIO_ST |
- BCM43xx_PCIE_MDIO_WT | (dev << BCM43xx_PCIE_MDIO_DEV) |
- (reg << BCM43xx_PCIE_MDIO_REG) | BCM43xx_PCIE_MDIO_TA |
- data);
- udelay(10);
-
- for (i = 0; i < 10; i++) {
- if (bcm43xx_read32(bcm, BCM43xx_PCIECORE_MDIO_CTL) &
- BCM43xx_PCIE_MDIO_TC)
- break;
- msleep(1);
- }
- bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0);
-}
-
-/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
- * To enable core 0, pass a core_mask of 1<<0
- */
-static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
- u32 core_mask)
-{
- u32 backplane_flag_nr;
- u32 value;
- struct bcm43xx_coreinfo *old_core;
- int err = 0;
-
- value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTPSFLAG);
- backplane_flag_nr = value & BCM43xx_BACKPLANE_FLAG_NR_MASK;
-
- old_core = bcm->current_core;
- err = bcm43xx_switch_core(bcm, &bcm->core_pci);
- if (err)
- goto out;
-
- if (bcm->current_core->rev < 6 &&
- bcm->current_core->id == BCM43xx_COREID_PCI) {
- value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
- value |= (1 << backplane_flag_nr);
- bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
- } else {
- err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ICR, &value);
- if (err) {
- printk(KERN_ERR PFX "Error: ICR setup failure!\n");
- goto out_switch_back;
- }
- value |= core_mask << 8;
- err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ICR, value);
- if (err) {
- printk(KERN_ERR PFX "Error: ICR setup failure!\n");
- goto out_switch_back;
- }
- }
-
- if (bcm->current_core->id == BCM43xx_COREID_PCI) {
- value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
- value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
- bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
-
- if (bcm->current_core->rev < 5) {
- value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
- value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
- & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
- value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
- & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
- err = bcm43xx_pcicore_commit_settings(bcm);
- assert(err == 0);
- } else if (bcm->current_core->rev >= 11) {
- value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
- value |= BCM43xx_SBTOPCI2_MEMREAD_MULTI;
- bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
- }
- } else {
- if (bcm->current_core->rev == 0 || bcm->current_core->rev == 1) {
- value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_TLP_WORKAROUND);
- value |= 0x8;
- bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_TLP_WORKAROUND,
- value);
- }
- if (bcm->current_core->rev == 0) {
- bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
- BCM43xx_SERDES_RXTIMER, 0x8128);
- bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
- BCM43xx_SERDES_CDR, 0x0100);
- bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
- BCM43xx_SERDES_CDR_BW, 0x1466);
- } else if (bcm->current_core->rev == 1) {
- value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_DLLP_LINKCTL);
- value |= 0x40;
- bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_DLLP_LINKCTL,
- value);
- }
- }
-out_switch_back:
- err = bcm43xx_switch_core(bcm, old_core);
-out:
- return err;
-}
-
-static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-
- if (phy->type != BCM43xx_PHYTYPE_G || phy->rev < 2)
- return;
-
- bcm43xx_mac_suspend(bcm);
- bcm43xx_phy_lo_g_measure(bcm);
- bcm43xx_mac_enable(bcm);
-}
-
-static void bcm43xx_periodic_every60sec(struct bcm43xx_private *bcm)
-{
- bcm43xx_phy_lo_mark_all_unused(bcm);
- if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
- bcm43xx_mac_suspend(bcm);
- bcm43xx_calc_nrssi_slope(bcm);
- bcm43xx_mac_enable(bcm);
- }
-}
-
-static void bcm43xx_periodic_every30sec(struct bcm43xx_private *bcm)
-{
- /* Update device statistics. */
- bcm43xx_calculate_link_quality(bcm);
-}
-
-static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
-{
- bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
- //TODO for APHY (temperature?)
-}
-
-static void bcm43xx_periodic_every1sec(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- int radio_hw_enable;
-
- /* check if radio hardware enabled status changed */
- radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm);
- if (unlikely(bcm->radio_hw_enable != radio_hw_enable)) {
- bcm->radio_hw_enable = radio_hw_enable;
- printk(KERN_INFO PFX "Radio hardware status changed to %s\n",
- (radio_hw_enable == 0) ? "disabled" : "enabled");
- bcm43xx_leds_update(bcm, 0);
- }
- if (phy->type == BCM43xx_PHYTYPE_G) {
- //TODO: update_aci_moving_average
- if (radio->aci_enable && radio->aci_wlan_automatic) {
- bcm43xx_mac_suspend(bcm);
- if (!radio->aci_enable && 1 /*TODO: not scanning? */) {
- if (0 /*TODO: bunch of conditions*/) {
- bcm43xx_radio_set_interference_mitigation(bcm,
- BCM43xx_RADIO_INTERFMODE_MANUALWLAN);
- }
- } else if (1/*TODO*/) {
- /*
- if ((aci_average > 1000) && !(bcm43xx_radio_aci_scan(bcm))) {
- bcm43xx_radio_set_interference_mitigation(bcm,
- BCM43xx_RADIO_INTERFMODE_NONE);
- }
- */
- }
- bcm43xx_mac_enable(bcm);
- } else if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN &&
- phy->rev == 1) {
- //TODO: implement rev1 workaround
- }
- }
-}
-
-static void do_periodic_work(struct bcm43xx_private *bcm)
-{
- if (bcm->periodic_state % 120 == 0)
- bcm43xx_periodic_every120sec(bcm);
- if (bcm->periodic_state % 60 == 0)
- bcm43xx_periodic_every60sec(bcm);
- if (bcm->periodic_state % 30 == 0)
- bcm43xx_periodic_every30sec(bcm);
- if (bcm->periodic_state % 15 == 0)
- bcm43xx_periodic_every15sec(bcm);
- bcm43xx_periodic_every1sec(bcm);
-
- schedule_delayed_work(&bcm->periodic_work, HZ);
-}
-
-static void bcm43xx_periodic_work_handler(struct work_struct *work)
-{
- struct bcm43xx_private *bcm =
- container_of(work, struct bcm43xx_private, periodic_work.work);
- struct net_device *net_dev = bcm->net_dev;
- unsigned long flags;
- u32 savedirqs = 0;
- unsigned long orig_trans_start = 0;
-
- mutex_lock(&bcm->mutex);
- /* keep from doing and rearming periodic work if shutting down */
- if (bcm43xx_status(bcm) == BCM43xx_STAT_UNINIT)
- goto unlock_mutex;
- if (unlikely(bcm->periodic_state % 60 == 0)) {
- /* Periodic work will take a long time, so we want it to
- * be preemtible.
- */
-
- netif_tx_lock_bh(net_dev);
- /* We must fake a started transmission here, as we are going to
- * disable TX. If we wouldn't fake a TX, it would be possible to
- * trigger the netdev watchdog, if the last real TX is already
- * some time on the past (slightly less than 5secs)
- */
- orig_trans_start = net_dev->trans_start;
- net_dev->trans_start = jiffies;
- netif_stop_queue(net_dev);
- netif_tx_unlock_bh(net_dev);
-
- spin_lock_irqsave(&bcm->irq_lock, flags);
- bcm43xx_mac_suspend(bcm);
- if (bcm43xx_using_pio(bcm))
- bcm43xx_pio_freeze_txqueues(bcm);
- savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- bcm43xx_synchronize_irq(bcm);
- } else {
- /* Periodic work should take short time, so we want low
- * locking overhead.
- */
- spin_lock_irqsave(&bcm->irq_lock, flags);
- }
-
- do_periodic_work(bcm);
-
- if (unlikely(bcm->periodic_state % 60 == 0)) {
- spin_lock_irqsave(&bcm->irq_lock, flags);
- tasklet_enable(&bcm->isr_tasklet);
- bcm43xx_interrupt_enable(bcm, savedirqs);
- if (bcm43xx_using_pio(bcm))
- bcm43xx_pio_thaw_txqueues(bcm);
- bcm43xx_mac_enable(bcm);
- netif_wake_queue(bcm->net_dev);
- net_dev->trans_start = orig_trans_start;
- }
- mmiowb();
- bcm->periodic_state++;
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-unlock_mutex:
- mutex_unlock(&bcm->mutex);
-}
-
-void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
-{
- struct delayed_work *work = &bcm->periodic_work;
-
- assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
- INIT_DELAYED_WORK(work, bcm43xx_periodic_work_handler);
- schedule_delayed_work(work, 0);
-}
-
-static void bcm43xx_security_init(struct bcm43xx_private *bcm)
-{
- bcm->security_offset = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
- 0x0056) * 2;
- bcm43xx_clear_keys(bcm);
-}
-
-static int bcm43xx_rng_read(struct hwrng *rng, u32 *data)
-{
- struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv;
- unsigned long flags;
-
- spin_lock_irqsave(&(bcm)->irq_lock, flags);
- *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG);
- spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
-
- return (sizeof(u16));
-}
-
-static void bcm43xx_rng_exit(struct bcm43xx_private *bcm)
-{
- hwrng_unregister(&bcm->rng);
-}
-
-static int bcm43xx_rng_init(struct bcm43xx_private *bcm)
-{
- int err;
-
- snprintf(bcm->rng_name, ARRAY_SIZE(bcm->rng_name),
- "%s_%s", KBUILD_MODNAME, bcm->net_dev->name);
- bcm->rng.name = bcm->rng_name;
- bcm->rng.data_read = bcm43xx_rng_read;
- bcm->rng.priv = (unsigned long)bcm;
- err = hwrng_register(&bcm->rng);
- if (err)
- printk(KERN_ERR PFX "RNG init failed (%d)\n", err);
-
- return err;
-}
-
-void bcm43xx_cancel_work(struct bcm43xx_private *bcm)
-{
- /* The system must be unlocked when this routine is entered.
- * If not, the next 2 steps may deadlock */
- cancel_work_sync(&bcm->restart_work);
- cancel_delayed_work_sync(&bcm->periodic_work);
-}
-
-static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
-{
- int ret = 0;
- int i, err;
- struct bcm43xx_coreinfo *core;
-
- bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
- for (i = 0; i < bcm->nr_80211_available; i++) {
- core = &(bcm->core_80211[i]);
- assert(core->available);
- if (!core->initialized)
- continue;
- err = bcm43xx_switch_core(bcm, core);
- if (err) {
- dprintk(KERN_ERR PFX "shutdown_all_wireless_cores "
- "switch_core failed (%d)\n", err);
- ret = err;
- continue;
- }
- bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
- bcm43xx_wireless_core_cleanup(bcm);
- if (core == bcm->active_80211_core)
- bcm->active_80211_core = NULL;
- }
- free_irq(bcm->irq, bcm);
- bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
-
- return ret;
-}
-
-/* This is the opposite of bcm43xx_init_board() */
-static void bcm43xx_free_board(struct bcm43xx_private *bcm)
-{
- bcm43xx_rng_exit(bcm);
- bcm43xx_sysfs_unregister(bcm);
-
- mutex_lock(&(bcm)->mutex);
- bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
- mutex_unlock(&(bcm)->mutex);
-
- bcm43xx_cancel_work(bcm);
-
- mutex_lock(&(bcm)->mutex);
- bcm43xx_shutdown_all_wireless_cores(bcm);
- bcm43xx_pctl_set_crystal(bcm, 0);
- mutex_unlock(&(bcm)->mutex);
-}
-
-static void prepare_phydata_for_init(struct bcm43xx_phyinfo *phy)
-{
- phy->antenna_diversity = 0xFFFF;
- memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
- memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
-
- /* Flags */
- phy->calibrated = 0;
- phy->is_locked = 0;
-
- if (phy->_lo_pairs) {
- memset(phy->_lo_pairs, 0,
- sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT);
- }
- memset(phy->loopback_gain, 0, sizeof(phy->loopback_gain));
-}
-
-static void prepare_radiodata_for_init(struct bcm43xx_private *bcm,
- struct bcm43xx_radioinfo *radio)
-{
- int i;
-
- /* Set default attenuation values. */
- radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
- radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
- radio->txctl1 = bcm43xx_default_txctl1(bcm);
- radio->txctl2 = 0xFFFF;
- radio->txpwr_offset = 0;
-
- /* NRSSI */
- radio->nrssislope = 0;
- for (i = 0; i < ARRAY_SIZE(radio->nrssi); i++)
- radio->nrssi[i] = -1000;
- for (i = 0; i < ARRAY_SIZE(radio->nrssi_lt); i++)
- radio->nrssi_lt[i] = i;
-
- radio->lofcal = 0xFFFF;
- radio->initval = 0xFFFF;
-
- radio->aci_enable = 0;
- radio->aci_wlan_automatic = 0;
- radio->aci_hw_rssi = 0;
-}
-
-static void prepare_priv_for_init(struct bcm43xx_private *bcm)
-{
- int i;
- struct bcm43xx_coreinfo *core;
- struct bcm43xx_coreinfo_80211 *wlext;
-
- assert(!bcm->active_80211_core);
-
- bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
-
- /* Flags */
- bcm->was_initialized = 0;
- bcm->reg124_set_0x4 = 0;
-
- /* Stats */
- memset(&bcm->stats, 0, sizeof(bcm->stats));
-
- /* Wireless core data */
- for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
- core = &(bcm->core_80211[i]);
- wlext = core->priv;
-
- if (!core->available)
- continue;
- assert(wlext == &(bcm->core_80211_ext[i]));
-
- prepare_phydata_for_init(&wlext->phy);
- prepare_radiodata_for_init(bcm, &wlext->radio);
- }
-
- /* IRQ related flags */
- bcm->irq_reason = 0;
- memset(bcm->dma_reason, 0, sizeof(bcm->dma_reason));
- bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
-
- bcm->mac_suspended = 1;
-
- /* Noise calculation context */
- memset(&bcm->noisecalc, 0, sizeof(bcm->noisecalc));
-
- /* Periodic work context */
- bcm->periodic_state = 0;
-}
-
-static int wireless_core_up(struct bcm43xx_private *bcm,
- int active_wlcore)
-{
- int err;
-
- if (!bcm43xx_core_enabled(bcm))
- bcm43xx_wireless_core_reset(bcm, 1);
- if (!active_wlcore)
- bcm43xx_wireless_core_mark_inactive(bcm);
- err = bcm43xx_wireless_core_init(bcm, active_wlcore);
- if (err)
- goto out;
- if (!active_wlcore)
- bcm43xx_radio_turn_off(bcm);
-out:
- return err;
-}
-
-/* Select and enable the "to be used" wireless core.
- * Locking: bcm->mutex must be aquired before calling this.
- * bcm->irq_lock must not be aquired.
- */
-int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
- int phytype)
-{
- int i, err;
- struct bcm43xx_coreinfo *active_core = NULL;
- struct bcm43xx_coreinfo_80211 *active_wlext = NULL;
- struct bcm43xx_coreinfo *core;
- struct bcm43xx_coreinfo_80211 *wlext;
- int adjust_active_sbtmstatelow = 0;
-
- might_sleep();
-
- if (phytype < 0) {
- /* If no phytype is requested, select the first core. */
- assert(bcm->core_80211[0].available);
- wlext = bcm->core_80211[0].priv;
- phytype = wlext->phy.type;
- }
- /* Find the requested core. */
- for (i = 0; i < bcm->nr_80211_available; i++) {
- core = &(bcm->core_80211[i]);
- wlext = core->priv;
- if (wlext->phy.type == phytype) {
- active_core = core;
- active_wlext = wlext;
- break;
- }
- }
- if (!active_core)
- return -ESRCH; /* No such PHYTYPE on this board. */
-
- if (bcm->active_80211_core) {
- /* We already selected a wl core in the past.
- * So first clean up everything.
- */
- dprintk(KERN_INFO PFX "select_wireless_core: cleanup\n");
- ieee80211softmac_stop(bcm->net_dev);
- bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
- err = bcm43xx_disable_interrupts_sync(bcm);
- assert(!err);
- tasklet_enable(&bcm->isr_tasklet);
- err = bcm43xx_shutdown_all_wireless_cores(bcm);
- if (err)
- goto error;
- /* Ok, everything down, continue to re-initialize. */
- bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
- }
-
- /* Reset all data structures. */
- prepare_priv_for_init(bcm);
-
- err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
- if (err)
- goto error;
-
- /* Mark all unused cores "inactive". */
- for (i = 0; i < bcm->nr_80211_available; i++) {
- core = &(bcm->core_80211[i]);
- wlext = core->priv;
-
- if (core == active_core)
- continue;
- err = bcm43xx_switch_core(bcm, core);
- if (err) {
- dprintk(KERN_ERR PFX "Could not switch to inactive "
- "802.11 core (%d)\n", err);
- goto error;
- }
- err = wireless_core_up(bcm, 0);
- if (err) {
- dprintk(KERN_ERR PFX "core_up for inactive 802.11 core "
- "failed (%d)\n", err);
- goto error;
- }
- adjust_active_sbtmstatelow = 1;
- }
-
- /* Now initialize the active 802.11 core. */
- err = bcm43xx_switch_core(bcm, active_core);
- if (err) {
- dprintk(KERN_ERR PFX "Could not switch to active "
- "802.11 core (%d)\n", err);
- goto error;
- }
- if (adjust_active_sbtmstatelow &&
- active_wlext->phy.type == BCM43xx_PHYTYPE_G) {
- u32 sbtmstatelow;
-
- sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- sbtmstatelow |= BCM43xx_SBTMSTATELOW_G_MODE_ENABLE;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
- }
- err = wireless_core_up(bcm, 1);
- if (err) {
- dprintk(KERN_ERR PFX "core_up for active 802.11 core "
- "failed (%d)\n", err);
- goto error;
- }
- err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
- if (err)
- goto error;
- bcm->active_80211_core = active_core;
-
- bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
- bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
- bcm43xx_security_init(bcm);
- drain_txstatus_queue(bcm);
- ieee80211softmac_start(bcm->net_dev);
-
- /* Let's go! Be careful after enabling the IRQs.
- * Don't switch cores, for example.
- */
- bcm43xx_mac_enable(bcm);
- bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
- err = bcm43xx_initialize_irq(bcm);
- if (err)
- goto error;
- bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
-
- dprintk(KERN_INFO PFX "Selected 802.11 core (phytype %d)\n",
- active_wlext->phy.type);
-
- return 0;
-
-error:
- bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
- bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
- return err;
-}
-
-static int bcm43xx_init_board(struct bcm43xx_private *bcm)
-{
- int err;
-
- mutex_lock(&(bcm)->mutex);
-
- tasklet_enable(&bcm->isr_tasklet);
- err = bcm43xx_pctl_set_crystal(bcm, 1);
- if (err)
- goto err_tasklet;
- err = bcm43xx_pctl_init(bcm);
- if (err)
- goto err_crystal_off;
- err = bcm43xx_select_wireless_core(bcm, -1);
- if (err)
- goto err_crystal_off;
- err = bcm43xx_sysfs_register(bcm);
- if (err)
- goto err_wlshutdown;
- err = bcm43xx_rng_init(bcm);
- if (err)
- goto err_sysfs_unreg;
- bcm43xx_periodic_tasks_setup(bcm);
-
- /*FIXME: This should be handled by softmac instead. */
- schedule_delayed_work(&bcm->softmac->associnfo.work, 0);
-
-out:
- mutex_unlock(&(bcm)->mutex);
-
- return err;
-
-err_sysfs_unreg:
- bcm43xx_sysfs_unregister(bcm);
-err_wlshutdown:
- bcm43xx_shutdown_all_wireless_cores(bcm);
-err_crystal_off:
- bcm43xx_pctl_set_crystal(bcm, 0);
-err_tasklet:
- tasklet_disable(&bcm->isr_tasklet);
- goto out;
-}
-
-static void bcm43xx_detach_board(struct bcm43xx_private *bcm)
-{
- struct pci_dev *pci_dev = bcm->pci_dev;
- int i;
-
- bcm43xx_chipset_detach(bcm);
- /* Do _not_ access the chip, after it is detached. */
- pci_iounmap(pci_dev, bcm->mmio_addr);
- pci_release_regions(pci_dev);
- pci_disable_device(pci_dev);
-
- /* Free allocated structures/fields */
- for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
- kfree(bcm->core_80211_ext[i].phy._lo_pairs);
- if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl)
- kfree(bcm->core_80211_ext[i].phy.tssi2dbm);
- }
-}
-
-static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 value;
- u8 phy_analog;
- u8 phy_type;
- u8 phy_rev;
- int phy_rev_ok = 1;
- void *p;
-
- value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER);
-
- phy_analog = (value & 0xF000) >> 12;
- phy_type = (value & 0x0F00) >> 8;
- phy_rev = (value & 0x000F);
-
- dprintk(KERN_INFO PFX "Detected PHY: Analog: %x, Type %x, Revision %x\n",
- phy_analog, phy_type, phy_rev);
-
- switch (phy_type) {
- case BCM43xx_PHYTYPE_A:
- if (phy_rev >= 4)
- phy_rev_ok = 0;
- /*FIXME: We need to switch the ieee->modulation, etc.. flags,
- * if we switch 80211 cores after init is done.
- * As we do not implement on the fly switching between
- * wireless cores, I will leave this as a future task.
- */
- bcm->ieee->modulation = IEEE80211_OFDM_MODULATION;
- bcm->ieee->mode = IEEE_A;
- bcm->ieee->freq_band = IEEE80211_52GHZ_BAND |
- IEEE80211_24GHZ_BAND;
- break;
- case BCM43xx_PHYTYPE_B:
- if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6 && phy_rev != 7)
- phy_rev_ok = 0;
- bcm->ieee->modulation = IEEE80211_CCK_MODULATION;
- bcm->ieee->mode = IEEE_B;
- bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
- break;
- case BCM43xx_PHYTYPE_G:
- if (phy_rev > 8)
- phy_rev_ok = 0;
- bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
- IEEE80211_CCK_MODULATION;
- bcm->ieee->mode = IEEE_G;
- bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
- break;
- default:
- printk(KERN_ERR PFX "Error: Unknown PHY Type %x\n",
- phy_type);
- return -ENODEV;
- };
- bcm->ieee->perfect_rssi = RX_RSSI_MAX;
- bcm->ieee->worst_rssi = 0;
- if (!phy_rev_ok) {
- printk(KERN_WARNING PFX "Invalid PHY Revision %x\n",
- phy_rev);
- }
-
- phy->analog = phy_analog;
- phy->type = phy_type;
- phy->rev = phy_rev;
- if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) {
- p = kzalloc(sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT,
- GFP_KERNEL);
- if (!p)
- return -ENOMEM;
- phy->_lo_pairs = p;
- }
-
- return 0;
-}
-
-static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
-{
- struct pci_dev *pci_dev = bcm->pci_dev;
- struct net_device *net_dev = bcm->net_dev;
- int err;
- int i;
- u32 coremask;
-
- err = pci_enable_device(pci_dev);
- if (err) {
- printk(KERN_ERR PFX "pci_enable_device() failed\n");
- goto out;
- }
- err = pci_request_regions(pci_dev, KBUILD_MODNAME);
- if (err) {
- printk(KERN_ERR PFX "pci_request_regions() failed\n");
- goto err_pci_disable;
- }
- /* enable PCI bus-mastering */
- pci_set_master(pci_dev);
- bcm->mmio_addr = pci_iomap(pci_dev, 0, ~0UL);
- if (!bcm->mmio_addr) {
- printk(KERN_ERR PFX "pci_iomap() failed\n");
- err = -EIO;
- goto err_pci_release;
- }
- net_dev->base_addr = (unsigned long)bcm->mmio_addr;
-
- err = bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
- &bcm->board_vendor);
- if (err)
- goto err_iounmap;
- err = bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
- &bcm->board_type);
- if (err)
- goto err_iounmap;
-
- bcm->board_revision = bcm->pci_dev->revision;
-
- err = bcm43xx_chipset_attach(bcm);
- if (err)
- goto err_iounmap;
- err = bcm43xx_pctl_init(bcm);
- if (err)
- goto err_chipset_detach;
- err = bcm43xx_probe_cores(bcm);
- if (err)
- goto err_chipset_detach;
-
- /* Attach all IO cores to the backplane. */
- coremask = 0;
- for (i = 0; i < bcm->nr_80211_available; i++)
- coremask |= (1 << bcm->core_80211[i].index);
- //FIXME: Also attach some non80211 cores?
- err = bcm43xx_setup_backplane_pci_connection(bcm, coremask);
- if (err) {
- printk(KERN_ERR PFX "Backplane->PCI connection failed!\n");
- goto err_chipset_detach;
- }
-
- err = bcm43xx_sprom_extract(bcm);
- if (err)
- goto err_chipset_detach;
- err = bcm43xx_leds_init(bcm);
- if (err)
- goto err_chipset_detach;
-
- for (i = 0; i < bcm->nr_80211_available; i++) {
- err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
- assert(err != -ENODEV);
- if (err)
- goto err_80211_unwind;
-
- /* Enable the selected wireless core.
- * Connect PHY only on the first core.
- */
- bcm43xx_wireless_core_reset(bcm, (i == 0));
-
- err = bcm43xx_read_phyinfo(bcm);
- if (err && (i == 0))
- goto err_80211_unwind;
-
- err = bcm43xx_read_radioinfo(bcm);
- if (err && (i == 0))
- goto err_80211_unwind;
-
- err = bcm43xx_validate_chip(bcm);
- if (err && (i == 0))
- goto err_80211_unwind;
-
- bcm43xx_radio_turn_off(bcm);
- err = bcm43xx_phy_init_tssi2dbm_table(bcm);
- if (err)
- goto err_80211_unwind;
- bcm43xx_wireless_core_disable(bcm);
- }
- err = bcm43xx_geo_init(bcm);
- if (err)
- goto err_80211_unwind;
- bcm43xx_pctl_set_crystal(bcm, 0);
-
- /* Set the MAC address in the networking subsystem */
- if (is_valid_ether_addr(bcm->sprom.et1macaddr))
- memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
- else
- memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
-
- snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
- "Broadcom %04X", bcm->chip_id);
-
- assert(err == 0);
-out:
- return err;
-
-err_80211_unwind:
- for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
- kfree(bcm->core_80211_ext[i].phy._lo_pairs);
- if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl)
- kfree(bcm->core_80211_ext[i].phy.tssi2dbm);
- }
-err_chipset_detach:
- bcm43xx_chipset_detach(bcm);
-err_iounmap:
- pci_iounmap(pci_dev, bcm->mmio_addr);
-err_pci_release:
- pci_release_regions(pci_dev);
-err_pci_disable:
- pci_disable_device(pci_dev);
- printk(KERN_ERR PFX "Unable to attach board\n");
- goto out;
-}
-
-/* Do the Hardware IO operations to send the txb */
-static inline int bcm43xx_tx(struct bcm43xx_private *bcm,
- struct ieee80211_txb *txb)
-{
- int err = -ENODEV;
-
- if (bcm43xx_using_pio(bcm))
- err = bcm43xx_pio_tx(bcm, txb);
- else
- err = bcm43xx_dma_tx(bcm, txb);
- bcm->net_dev->trans_start = jiffies;
-
- return err;
-}
-
-static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
- u8 channel)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- struct bcm43xx_radioinfo *radio;
- unsigned long flags;
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
- bcm43xx_mac_suspend(bcm);
- bcm43xx_radio_selectchannel(bcm, channel, 0);
- bcm43xx_mac_enable(bcm);
- } else {
- radio = bcm43xx_current_radio(bcm);
- radio->initial_channel = channel;
- }
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-}
-
-/* set_security() callback in struct ieee80211_device */
-static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
- struct ieee80211_security *sec)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- struct ieee80211_security *secinfo = &bcm->ieee->sec;
- unsigned long flags;
- int keyidx;
-
- dprintk(KERN_INFO PFX "set security called");
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
-
- for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
- if (sec->flags & (1<<keyidx)) {
- secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx];
- secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx];
- memcpy(secinfo->keys[keyidx], sec->keys[keyidx], SCM_KEY_LEN);
- }
-
- if (sec->flags & SEC_ACTIVE_KEY) {
- secinfo->active_key = sec->active_key;
- dprintk(", .active_key = %d", sec->active_key);
- }
- if (sec->flags & SEC_UNICAST_GROUP) {
- secinfo->unicast_uses_group = sec->unicast_uses_group;
- dprintk(", .unicast_uses_group = %d", sec->unicast_uses_group);
- }
- if (sec->flags & SEC_LEVEL) {
- secinfo->level = sec->level;
- dprintk(", .level = %d", sec->level);
- }
- if (sec->flags & SEC_ENABLED) {
- secinfo->enabled = sec->enabled;
- dprintk(", .enabled = %d", sec->enabled);
- }
- if (sec->flags & SEC_ENCRYPT) {
- secinfo->encrypt = sec->encrypt;
- dprintk(", .encrypt = %d", sec->encrypt);
- }
- if (sec->flags & SEC_AUTH_MODE) {
- secinfo->auth_mode = sec->auth_mode;
- dprintk(", .auth_mode = %d", sec->auth_mode);
- }
- dprintk("\n");
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED &&
- !bcm->ieee->host_encrypt) {
- if (secinfo->enabled) {
- /* upload WEP keys to hardware */
- char null_address[6] = { 0 };
- u8 algorithm = 0;
- for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) {
- if (!(sec->flags & (1<<keyidx)))
- continue;
- switch (sec->encode_alg[keyidx]) {
- case SEC_ALG_NONE: algorithm = BCM43xx_SEC_ALGO_NONE; break;
- case SEC_ALG_WEP:
- algorithm = BCM43xx_SEC_ALGO_WEP;
- if (secinfo->key_sizes[keyidx] == 13)
- algorithm = BCM43xx_SEC_ALGO_WEP104;
- break;
- case SEC_ALG_TKIP:
- FIXME();
- algorithm = BCM43xx_SEC_ALGO_TKIP;
- break;
- case SEC_ALG_CCMP:
- FIXME();
- algorithm = BCM43xx_SEC_ALGO_AES;
- break;
- default:
- assert(0);
- break;
- }
- bcm43xx_key_write(bcm, keyidx, algorithm, sec->keys[keyidx], secinfo->key_sizes[keyidx], &null_address[0]);
- bcm->key[keyidx].enabled = 1;
- bcm->key[keyidx].algorithm = algorithm;
- }
- } else
- bcm43xx_clear_keys(bcm);
- }
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-}
-
-/* hard_start_xmit() callback in struct ieee80211_device */
-static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
- struct net_device *net_dev,
- int pri)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int err = -ENODEV;
- unsigned long flags;
-
- spin_lock_irqsave(&bcm->irq_lock, flags);
- if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
- err = bcm43xx_tx(bcm, txb);
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-
- if (unlikely(err))
- return NETDEV_TX_BUSY;
- return NETDEV_TX_OK;
-}
-
-static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
-
- spin_lock_irqsave(&bcm->irq_lock, flags);
- bcm43xx_controller_restart(bcm, "TX timeout");
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void bcm43xx_net_poll_controller(struct net_device *net_dev)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
-
- local_irq_save(flags);
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
- bcm43xx_interrupt_handler(bcm->irq, bcm);
- local_irq_restore(flags);
-}
-#endif /* CONFIG_NET_POLL_CONTROLLER */
-
-static int bcm43xx_net_open(struct net_device *net_dev)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-
- return bcm43xx_init_board(bcm);
-}
-
-static int bcm43xx_net_stop(struct net_device *net_dev)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int err;
-
- ieee80211softmac_stop(net_dev);
- err = bcm43xx_disable_interrupts_sync(bcm);
- assert(!err);
- bcm43xx_free_board(bcm);
- bcm43xx_cancel_work(bcm);
-
- return 0;
-}
-
-static int bcm43xx_init_private(struct bcm43xx_private *bcm,
- struct net_device *net_dev,
- struct pci_dev *pci_dev)
-{
- bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
- bcm->ieee = netdev_priv(net_dev);
- bcm->softmac = ieee80211_priv(net_dev);
- bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
-
- bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
- bcm->mac_suspended = 1;
- bcm->pci_dev = pci_dev;
- bcm->net_dev = net_dev;
- bcm->bad_frames_preempt = modparam_bad_frames_preempt;
- spin_lock_init(&bcm->irq_lock);
- spin_lock_init(&bcm->leds_lock);
- mutex_init(&bcm->mutex);
- tasklet_init(&bcm->isr_tasklet,
- (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
- (unsigned long)bcm);
- tasklet_disable_nosync(&bcm->isr_tasklet);
- if (modparam_pio)
- bcm->__using_pio = 1;
- bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
-
- /* default to sw encryption for now */
- bcm->ieee->host_build_iv = 0;
- bcm->ieee->host_encrypt = 1;
- bcm->ieee->host_decrypt = 1;
-
- bcm->ieee->iw_mode = BCM43xx_INITIAL_IWMODE;
- bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr);
- bcm->ieee->set_security = bcm43xx_ieee80211_set_security;
- bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit;
-
- return 0;
-}
-
-static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct net_device *net_dev;
- struct bcm43xx_private *bcm;
- int err;
-
-#ifdef DEBUG_SINGLE_DEVICE_ONLY
- if (strcmp(pci_name(pdev), DEBUG_SINGLE_DEVICE_ONLY))
- return -ENODEV;
-#endif
-
- net_dev = alloc_ieee80211softmac(sizeof(*bcm));
- if (!net_dev) {
- printk(KERN_ERR PFX
- "could not allocate ieee80211 device %s\n",
- pci_name(pdev));
- err = -ENOMEM;
- goto out;
- }
- /* initialize the net_device struct */
- SET_NETDEV_DEV(net_dev, &pdev->dev);
-
- net_dev->open = bcm43xx_net_open;
- net_dev->stop = bcm43xx_net_stop;
- net_dev->tx_timeout = bcm43xx_net_tx_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- net_dev->poll_controller = bcm43xx_net_poll_controller;
-#endif
- net_dev->wireless_handlers = &bcm43xx_wx_handlers_def;
- net_dev->irq = pdev->irq;
- SET_ETHTOOL_OPS(net_dev, &bcm43xx_ethtool_ops);
-
- /* initialize the bcm43xx_private struct */
- bcm = bcm43xx_priv(net_dev);
- memset(bcm, 0, sizeof(*bcm));
- err = bcm43xx_init_private(bcm, net_dev, pdev);
- if (err)
- goto err_free_netdev;
-
- pci_set_drvdata(pdev, net_dev);
-
- err = bcm43xx_attach_board(bcm);
- if (err)
- goto err_free_netdev;
-
- err = register_netdev(net_dev);
- if (err) {
- printk(KERN_ERR PFX "Cannot register net device, "
- "aborting.\n");
- err = -ENOMEM;
- goto err_detach_board;
- }
-
- bcm43xx_debugfs_add_device(bcm);
-
- assert(err == 0);
-out:
- return err;
-
-err_detach_board:
- bcm43xx_detach_board(bcm);
-err_free_netdev:
- free_ieee80211softmac(net_dev);
- goto out;
-}
-
-static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
-{
- struct net_device *net_dev = pci_get_drvdata(pdev);
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-
- bcm43xx_debugfs_remove_device(bcm);
- unregister_netdev(net_dev);
- bcm43xx_detach_board(bcm);
- free_ieee80211softmac(net_dev);
-}
-
-/* Hard-reset the chip. Do not call this directly.
- * Use bcm43xx_controller_restart()
- */
-static void bcm43xx_chip_reset(struct work_struct *work)
-{
- struct bcm43xx_private *bcm =
- container_of(work, struct bcm43xx_private, restart_work);
- struct bcm43xx_phyinfo *phy;
- int err = -ENODEV;
-
- bcm43xx_cancel_work(bcm);
- mutex_lock(&(bcm)->mutex);
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
- phy = bcm43xx_current_phy(bcm);
- err = bcm43xx_select_wireless_core(bcm, phy->type);
- if (!err)
- bcm43xx_periodic_tasks_setup(bcm);
- }
- mutex_unlock(&(bcm)->mutex);
-
- printk(KERN_ERR PFX "Controller restart%s\n",
- (err == 0) ? "ed" : " failed");
-}
-
-/* Hard-reset the chip.
- * This can be called from interrupt or process context.
- * bcm->irq_lock must be locked.
- */
-void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
-{
- if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
- return;
- printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
- INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset);
- schedule_work(&bcm->restart_work);
-}
-
-#ifdef CONFIG_PM
-
-static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *net_dev = pci_get_drvdata(pdev);
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int err;
-
- dprintk(KERN_INFO PFX "Suspending...\n");
-
- netif_device_detach(net_dev);
- bcm->was_initialized = 0;
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
- bcm->was_initialized = 1;
- ieee80211softmac_stop(net_dev);
- err = bcm43xx_disable_interrupts_sync(bcm);
- if (unlikely(err)) {
- dprintk(KERN_ERR PFX "Suspend failed.\n");
- return -EAGAIN;
- }
- bcm->firmware_norelease = 1;
- bcm43xx_free_board(bcm);
- bcm->firmware_norelease = 0;
- }
- bcm43xx_chipset_detach(bcm);
-
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
- dprintk(KERN_INFO PFX "Device suspended.\n");
-
- return 0;
-}
-
-static int bcm43xx_resume(struct pci_dev *pdev)
-{
- struct net_device *net_dev = pci_get_drvdata(pdev);
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int err = 0;
-
- dprintk(KERN_INFO PFX "Resuming...\n");
-
- pci_set_power_state(pdev, 0);
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR PFX "Failure with pci_enable_device!\n");
- return err;
- }
- pci_restore_state(pdev);
-
- bcm43xx_chipset_attach(bcm);
- if (bcm->was_initialized)
- err = bcm43xx_init_board(bcm);
- if (err) {
- printk(KERN_ERR PFX "Resume failed!\n");
- return err;
- }
- netif_device_attach(net_dev);
-
- dprintk(KERN_INFO PFX "Device resumed.\n");
-
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
-static struct pci_driver bcm43xx_pci_driver = {
- .name = KBUILD_MODNAME,
- .id_table = bcm43xx_pci_tbl,
- .probe = bcm43xx_init_one,
- .remove = __devexit_p(bcm43xx_remove_one),
-#ifdef CONFIG_PM
- .suspend = bcm43xx_suspend,
- .resume = bcm43xx_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init bcm43xx_init(void)
-{
- printk(KERN_INFO KBUILD_MODNAME " driver\n");
- bcm43xx_debugfs_init();
- return pci_register_driver(&bcm43xx_pci_driver);
-}
-
-static void __exit bcm43xx_exit(void)
-{
- pci_unregister_driver(&bcm43xx_pci_driver);
- bcm43xx_debugfs_exit();
-}
-
-module_init(bcm43xx_init)
-module_exit(bcm43xx_exit)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
deleted file mode 100644
index 14cfbeb582ef..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-
- 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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
deleted file mode 100644
index af3de3343650..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ /dev/null
@@ -1,2346 +0,0 @@
-/*
-
- 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.
-
-*/
-
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-
-#include "bcm43xx.h"
-#include "bcm43xx_phy.h"
-#include "bcm43xx_main.h"
-#include "bcm43xx_radio.h"
-#include "bcm43xx_ilt.h"
-#include "bcm43xx_power.h"
-
-
-static const s8 bcm43xx_tssi2dbm_b_table[] = {
- 0x4D, 0x4C, 0x4B, 0x4A,
- 0x4A, 0x49, 0x48, 0x47,
- 0x47, 0x46, 0x45, 0x45,
- 0x44, 0x43, 0x42, 0x42,
- 0x41, 0x40, 0x3F, 0x3E,
- 0x3D, 0x3C, 0x3B, 0x3A,
- 0x39, 0x38, 0x37, 0x36,
- 0x35, 0x34, 0x32, 0x31,
- 0x30, 0x2F, 0x2D, 0x2C,
- 0x2B, 0x29, 0x28, 0x26,
- 0x25, 0x23, 0x21, 0x1F,
- 0x1D, 0x1A, 0x17, 0x14,
- 0x10, 0x0C, 0x06, 0x00,
- -7, -7, -7, -7,
- -7, -7, -7, -7,
- -7, -7, -7, -7,
-};
-
-static const s8 bcm43xx_tssi2dbm_g_table[] = {
- 77, 77, 77, 76,
- 76, 76, 75, 75,
- 74, 74, 73, 73,
- 73, 72, 72, 71,
- 71, 70, 70, 69,
- 68, 68, 67, 67,
- 66, 65, 65, 64,
- 63, 63, 62, 61,
- 60, 59, 58, 57,
- 56, 55, 54, 53,
- 52, 50, 49, 47,
- 45, 43, 40, 37,
- 33, 28, 22, 14,
- 5, -7, -20, -20,
- -20, -20, -20, -20,
- -20, -20, -20, -20,
-};
-
-static void bcm43xx_phy_initg(struct bcm43xx_private *bcm);
-
-
-static inline
-void bcm43xx_voluntary_preempt(void)
-{
- assert(!in_atomic() && !in_irq() &&
- !in_interrupt() && !irqs_disabled());
-#ifndef CONFIG_PREEMPT
- cond_resched();
-#endif /* CONFIG_PREEMPT */
-}
-
-void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-
- assert(irqs_disabled());
- if (bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) == 0x00000000) {
- phy->is_locked = 0;
- return;
- }
- if (bcm->current_core->rev < 3) {
- bcm43xx_mac_suspend(bcm);
- spin_lock(&phy->lock);
- } else {
- if (bcm->ieee->iw_mode != IW_MODE_MASTER)
- bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
- }
- phy->is_locked = 1;
-}
-
-void bcm43xx_raw_phy_unlock(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-
- assert(irqs_disabled());
- if (bcm->current_core->rev < 3) {
- if (phy->is_locked) {
- spin_unlock(&phy->lock);
- bcm43xx_mac_enable(bcm);
- }
- } else {
- if (bcm->ieee->iw_mode != IW_MODE_MASTER)
- bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
- }
- phy->is_locked = 0;
-}
-
-u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset)
-{
- bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_CONTROL, offset);
- return bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_DATA);
-}
-
-void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
-{
- bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_CONTROL, offset);
- mmiowb();
- bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_DATA, val);
-}
-
-void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */
- if (phy->calibrated)
- return;
- if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) {
- bcm43xx_wireless_core_reset(bcm, 0);
- bcm43xx_phy_initg(bcm);
- bcm43xx_wireless_core_reset(bcm, 1);
- }
- phy->calibrated = 1;
-}
-
-/* Connect the PHY
- * http://bcm-specs.sipsolutions.net/SetPHY
- */
-int bcm43xx_phy_connect(struct bcm43xx_private *bcm, int connect)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u32 flags;
-
- if (bcm->current_core->rev < 5)
- goto out;
-
- flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
- if (connect) {
- if (!(flags & BCM43xx_SBTMSTATEHIGH_G_PHY_AVAIL))
- return -ENODEV;
- flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- flags |= BCM43xx_SBTMSTATELOW_G_MODE_ENABLE;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags);
- } else {
- if (!(flags & BCM43xx_SBTMSTATEHIGH_A_PHY_AVAIL))
- return -ENODEV;
- flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- flags &= ~BCM43xx_SBTMSTATELOW_G_MODE_ENABLE;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags);
- }
-out:
- phy->connected = connect;
- if (connect)
- dprintk(KERN_INFO PFX "PHY connected\n");
- else
- dprintk(KERN_INFO PFX "PHY disconnected\n");
-
- return 0;
-}
-
-/* intialize B PHY power control
- * as described in http://bcm-specs.sipsolutions.net/InitPowerControl
- */
-static void bcm43xx_phy_init_pctl(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 saved_batt = 0, saved_ratt = 0, saved_txctl1 = 0;
- int must_reset_txpower = 0;
-
- assert(phy->type != BCM43xx_PHYTYPE_A);
- if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) &&
- (bcm->board_type == 0x0416))
- return;
-
- bcm43xx_phy_write(bcm, 0x0028, 0x8018);
- bcm43xx_write16(bcm, 0x03E6, bcm43xx_read16(bcm, 0x03E6) & 0xFFDF);
-
- if (phy->type == BCM43xx_PHYTYPE_G) {
- if (!phy->connected)
- return;
- bcm43xx_phy_write(bcm, 0x047A, 0xC111);
- }
- if (phy->savedpctlreg != 0xFFFF)
- return;
-
- if (phy->type == BCM43xx_PHYTYPE_B &&
- phy->rev >= 2 &&
- radio->version == 0x2050) {
- bcm43xx_radio_write16(bcm, 0x0076,
- bcm43xx_radio_read16(bcm, 0x0076) | 0x0084);
- } else {
- saved_batt = radio->baseband_atten;
- saved_ratt = radio->radio_atten;
- saved_txctl1 = radio->txctl1;
- if ((radio->revision >= 6) && (radio->revision <= 8)
- && /*FIXME: incomplete specs for 5 < revision < 9 */ 0)
- bcm43xx_radio_set_txpower_bg(bcm, 0xB, 0x1F, 0);
- else
- bcm43xx_radio_set_txpower_bg(bcm, 0xB, 9, 0);
- must_reset_txpower = 1;
- }
- bcm43xx_dummy_transmission(bcm);
-
- phy->savedpctlreg = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_PCTL);
-
- if (must_reset_txpower)
- bcm43xx_radio_set_txpower_bg(bcm, saved_batt, saved_ratt, saved_txctl1);
- else
- bcm43xx_radio_write16(bcm, 0x0076, bcm43xx_radio_read16(bcm, 0x0076) & 0xFF7B);
- bcm43xx_radio_clear_tssi(bcm);
-}
-
-static void bcm43xx_phy_agcsetup(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 offset = 0x0000;
-
- if (phy->rev == 1)
- offset = 0x4C00;
-
- bcm43xx_ilt_write(bcm, offset, 0x00FE);
- bcm43xx_ilt_write(bcm, offset + 1, 0x000D);
- bcm43xx_ilt_write(bcm, offset + 2, 0x0013);
- bcm43xx_ilt_write(bcm, offset + 3, 0x0019);
-
- if (phy->rev == 1) {
- bcm43xx_ilt_write(bcm, 0x1800, 0x2710);
- bcm43xx_ilt_write(bcm, 0x1801, 0x9B83);
- bcm43xx_ilt_write(bcm, 0x1802, 0x9B83);
- bcm43xx_ilt_write(bcm, 0x1803, 0x0F8D);
- bcm43xx_phy_write(bcm, 0x0455, 0x0004);
- }
-
- bcm43xx_phy_write(bcm, 0x04A5, (bcm43xx_phy_read(bcm, 0x04A5) & 0x00FF) | 0x5700);
- bcm43xx_phy_write(bcm, 0x041A, (bcm43xx_phy_read(bcm, 0x041A) & 0xFF80) | 0x000F);
- bcm43xx_phy_write(bcm, 0x041A, (bcm43xx_phy_read(bcm, 0x041A) & 0xC07F) | 0x2B80);
- bcm43xx_phy_write(bcm, 0x048C, (bcm43xx_phy_read(bcm, 0x048C) & 0xF0FF) | 0x0300);
-
- bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0008);
-
- bcm43xx_phy_write(bcm, 0x04A0, (bcm43xx_phy_read(bcm, 0x04A0) & 0xFFF0) | 0x0008);
- bcm43xx_phy_write(bcm, 0x04A1, (bcm43xx_phy_read(bcm, 0x04A1) & 0xF0FF) | 0x0600);
- bcm43xx_phy_write(bcm, 0x04A2, (bcm43xx_phy_read(bcm, 0x04A2) & 0xF0FF) | 0x0700);
- bcm43xx_phy_write(bcm, 0x04A0, (bcm43xx_phy_read(bcm, 0x04A0) & 0xF0FF) | 0x0100);
-
- if (phy->rev == 1)
- bcm43xx_phy_write(bcm, 0x04A2, (bcm43xx_phy_read(bcm, 0x04A2) & 0xFFF0) | 0x0007);
-
- bcm43xx_phy_write(bcm, 0x0488, (bcm43xx_phy_read(bcm, 0x0488) & 0xFF00) | 0x001C);
- bcm43xx_phy_write(bcm, 0x0488, (bcm43xx_phy_read(bcm, 0x0488) & 0xC0FF) | 0x0200);
- bcm43xx_phy_write(bcm, 0x0496, (bcm43xx_phy_read(bcm, 0x0496) & 0xFF00) | 0x001C);
- bcm43xx_phy_write(bcm, 0x0489, (bcm43xx_phy_read(bcm, 0x0489) & 0xFF00) | 0x0020);
- bcm43xx_phy_write(bcm, 0x0489, (bcm43xx_phy_read(bcm, 0x0489) & 0xC0FF) | 0x0200);
- bcm43xx_phy_write(bcm, 0x0482, (bcm43xx_phy_read(bcm, 0x0482) & 0xFF00) | 0x002E);
- bcm43xx_phy_write(bcm, 0x0496, (bcm43xx_phy_read(bcm, 0x0496) & 0x00FF) | 0x1A00);
- bcm43xx_phy_write(bcm, 0x0481, (bcm43xx_phy_read(bcm, 0x0481) & 0xFF00) | 0x0028);
- bcm43xx_phy_write(bcm, 0x0481, (bcm43xx_phy_read(bcm, 0x0481) & 0x00FF) | 0x2C00);
-
- if (phy->rev == 1) {
- bcm43xx_phy_write(bcm, 0x0430, 0x092B);
- bcm43xx_phy_write(bcm, 0x041B, (bcm43xx_phy_read(bcm, 0x041B) & 0xFFE1) | 0x0002);
- } else {
- bcm43xx_phy_write(bcm, 0x041B, bcm43xx_phy_read(bcm, 0x041B) & 0xFFE1);
- bcm43xx_phy_write(bcm, 0x041F, 0x287A);
- bcm43xx_phy_write(bcm, 0x0420, (bcm43xx_phy_read(bcm, 0x0420) & 0xFFF0) | 0x0004);
- }
-
- if (phy->rev > 2) {
- bcm43xx_phy_write(bcm, 0x0422, 0x287A);
- bcm43xx_phy_write(bcm, 0x0420, (bcm43xx_phy_read(bcm, 0x0420)
- & 0x0FFF) | 0x3000);
- }
-
- bcm43xx_phy_write(bcm, 0x04A8, (bcm43xx_phy_read(bcm, 0x04A8) & 0x8080)
- | 0x7874);
- bcm43xx_phy_write(bcm, 0x048E, 0x1C00);
-
- if (phy->rev == 1) {
- bcm43xx_phy_write(bcm, 0x04AB, (bcm43xx_phy_read(bcm, 0x04AB)
- & 0xF0FF) | 0x0600);
- bcm43xx_phy_write(bcm, 0x048B, 0x005E);
- bcm43xx_phy_write(bcm, 0x048C, (bcm43xx_phy_read(bcm, 0x048C)
- & 0xFF00) | 0x001E);
- bcm43xx_phy_write(bcm, 0x048D, 0x0002);
- }
-
- bcm43xx_ilt_write(bcm, offset + 0x0800, 0);
- bcm43xx_ilt_write(bcm, offset + 0x0801, 7);
- bcm43xx_ilt_write(bcm, offset + 0x0802, 16);
- bcm43xx_ilt_write(bcm, offset + 0x0803, 28);
-
- if (phy->rev >= 6) {
- bcm43xx_phy_write(bcm, 0x0426, (bcm43xx_phy_read(bcm, 0x0426)
- & 0xFFFC));
- bcm43xx_phy_write(bcm, 0x0426, (bcm43xx_phy_read(bcm, 0x0426)
- & 0xEFFF));
- }
-}
-
-static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 i;
-
- assert(phy->type == BCM43xx_PHYTYPE_G);
- if (phy->rev == 1) {
- bcm43xx_phy_write(bcm, 0x0406, 0x4F19);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
- (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS)
- & 0xFC3F) | 0x0340);
- bcm43xx_phy_write(bcm, 0x042C, 0x005A);
- bcm43xx_phy_write(bcm, 0x0427, 0x001A);
-
- for (i = 0; i < BCM43xx_ILT_FINEFREQG_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x5800 + i, bcm43xx_ilt_finefreqg[i]);
- for (i = 0; i < BCM43xx_ILT_NOISEG1_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg1[i]);
- for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++)
- bcm43xx_ilt_write32(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
- } else {
- /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */
- bcm43xx_nrssi_hw_write(bcm, 0xBA98, (s16)0x7654);
-
- if (phy->rev == 2) {
- bcm43xx_phy_write(bcm, 0x04C0, 0x1861);
- bcm43xx_phy_write(bcm, 0x04C1, 0x0271);
- } else if (phy->rev > 2) {
- bcm43xx_phy_write(bcm, 0x04C0, 0x0098);
- bcm43xx_phy_write(bcm, 0x04C1, 0x0070);
- bcm43xx_phy_write(bcm, 0x04C9, 0x0080);
- }
- bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x800);
-
- for (i = 0; i < 64; i++)
- bcm43xx_ilt_write(bcm, 0x4000 + i, i);
- for (i = 0; i < BCM43xx_ILT_NOISEG2_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg2[i]);
- }
-
- if (phy->rev <= 2)
- for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]);
- else if ((phy->rev >= 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
- for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]);
- else
- for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg2[i]);
-
- if (phy->rev == 2)
- for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]);
- else if ((phy->rev > 2) && (phy->rev <= 8))
- for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]);
-
- if (phy->rev == 1) {
- for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++)
- bcm43xx_ilt_write32(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
- for (i = 0; i < 4; i++) {
- bcm43xx_ilt_write(bcm, 0x5404 + i, 0x0020);
- bcm43xx_ilt_write(bcm, 0x5408 + i, 0x0020);
- bcm43xx_ilt_write(bcm, 0x540C + i, 0x0020);
- bcm43xx_ilt_write(bcm, 0x5410 + i, 0x0020);
- }
- bcm43xx_phy_agcsetup(bcm);
-
- if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) &&
- (bcm->board_type == 0x0416) &&
- (bcm->board_revision == 0x0017))
- return;
-
- bcm43xx_ilt_write(bcm, 0x5001, 0x0002);
- bcm43xx_ilt_write(bcm, 0x5002, 0x0001);
- } else {
- for (i = 0; i <= 0x2F; i++)
- bcm43xx_ilt_write(bcm, 0x1000 + i, 0x0820);
- bcm43xx_phy_agcsetup(bcm);
- bcm43xx_phy_read(bcm, 0x0400); /* dummy read */
- bcm43xx_phy_write(bcm, 0x0403, 0x1000);
- bcm43xx_ilt_write(bcm, 0x3C02, 0x000F);
- bcm43xx_ilt_write(bcm, 0x3C03, 0x0014);
-
- if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) &&
- (bcm->board_type == 0x0416) &&
- (bcm->board_revision == 0x0017))
- return;
-
- bcm43xx_ilt_write(bcm, 0x0401, 0x0002);
- bcm43xx_ilt_write(bcm, 0x0402, 0x0001);
- }
-}
-
-/* Initialize the noisescaletable for APHY */
-static void bcm43xx_phy_init_noisescaletbl(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- int i;
-
- bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, 0x1400);
- for (i = 0; i < 12; i++) {
- if (phy->rev == 2)
- bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6767);
- else
- bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2323);
- }
- if (phy->rev == 2)
- bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6700);
- else
- bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2300);
- for (i = 0; i < 11; i++) {
- if (phy->rev == 2)
- bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6767);
- else
- bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2323);
- }
- if (phy->rev == 2)
- bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x0067);
- else
- bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x0023);
-}
-
-static void bcm43xx_phy_setupa(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 i;
-
- assert(phy->type == BCM43xx_PHYTYPE_A);
- switch (phy->rev) {
- case 2:
- bcm43xx_phy_write(bcm, 0x008E, 0x3800);
- bcm43xx_phy_write(bcm, 0x0035, 0x03FF);
- bcm43xx_phy_write(bcm, 0x0036, 0x0400);
-
- bcm43xx_ilt_write(bcm, 0x3807, 0x0051);
-
- bcm43xx_phy_write(bcm, 0x001C, 0x0FF9);
- bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F);
- bcm43xx_ilt_write(bcm, 0x3C0C, 0x07BF);
- bcm43xx_radio_write16(bcm, 0x0002, 0x07BF);
-
- bcm43xx_phy_write(bcm, 0x0024, 0x4680);
- bcm43xx_phy_write(bcm, 0x0020, 0x0003);
- bcm43xx_phy_write(bcm, 0x001D, 0x0F40);
- bcm43xx_phy_write(bcm, 0x001F, 0x1C00);
-
- bcm43xx_phy_write(bcm, 0x002A, (bcm43xx_phy_read(bcm, 0x002A) & 0x00FF) | 0x0400);
- bcm43xx_phy_write(bcm, 0x002B, bcm43xx_phy_read(bcm, 0x002B) & 0xFBFF);
- bcm43xx_phy_write(bcm, 0x008E, 0x58C1);
-
- bcm43xx_ilt_write(bcm, 0x0803, 0x000F);
- bcm43xx_ilt_write(bcm, 0x0804, 0x001F);
- bcm43xx_ilt_write(bcm, 0x0805, 0x002A);
- bcm43xx_ilt_write(bcm, 0x0805, 0x0030);
- bcm43xx_ilt_write(bcm, 0x0807, 0x003A);
-
- bcm43xx_ilt_write(bcm, 0x0000, 0x0013);
- bcm43xx_ilt_write(bcm, 0x0001, 0x0013);
- bcm43xx_ilt_write(bcm, 0x0002, 0x0013);
- bcm43xx_ilt_write(bcm, 0x0003, 0x0013);
- bcm43xx_ilt_write(bcm, 0x0004, 0x0015);
- bcm43xx_ilt_write(bcm, 0x0005, 0x0015);
- bcm43xx_ilt_write(bcm, 0x0006, 0x0019);
-
- bcm43xx_ilt_write(bcm, 0x0404, 0x0003);
- bcm43xx_ilt_write(bcm, 0x0405, 0x0003);
- bcm43xx_ilt_write(bcm, 0x0406, 0x0007);
-
- for (i = 0; i < 16; i++)
- bcm43xx_ilt_write(bcm, 0x4000 + i, (0x8 + i) & 0x000F);
-
- bcm43xx_ilt_write(bcm, 0x3003, 0x1044);
- bcm43xx_ilt_write(bcm, 0x3004, 0x7201);
- bcm43xx_ilt_write(bcm, 0x3006, 0x0040);
- bcm43xx_ilt_write(bcm, 0x3001, (bcm43xx_ilt_read(bcm, 0x3001) & 0x0010) | 0x0008);
-
- for (i = 0; i < BCM43xx_ILT_FINEFREQA_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x5800 + i, bcm43xx_ilt_finefreqa[i]);
- for (i = 0; i < BCM43xx_ILT_NOISEA2_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea2[i]);
- for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++)
- bcm43xx_ilt_write32(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
- bcm43xx_phy_init_noisescaletbl(bcm);
- for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++)
- bcm43xx_ilt_write32(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
- break;
- case 3:
- for (i = 0; i < 64; i++)
- bcm43xx_ilt_write(bcm, 0x4000 + i, i);
-
- bcm43xx_ilt_write(bcm, 0x3807, 0x0051);
-
- bcm43xx_phy_write(bcm, 0x001C, 0x0FF9);
- bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F);
- bcm43xx_radio_write16(bcm, 0x0002, 0x07BF);
-
- bcm43xx_phy_write(bcm, 0x0024, 0x4680);
- bcm43xx_phy_write(bcm, 0x0020, 0x0003);
- bcm43xx_phy_write(bcm, 0x001D, 0x0F40);
- bcm43xx_phy_write(bcm, 0x001F, 0x1C00);
- bcm43xx_phy_write(bcm, 0x002A, (bcm43xx_phy_read(bcm, 0x002A) & 0x00FF) | 0x0400);
-
- bcm43xx_ilt_write(bcm, 0x3001, (bcm43xx_ilt_read(bcm, 0x3001) & 0x0010) | 0x0008);
- for (i = 0; i < BCM43xx_ILT_NOISEA3_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea3[i]);
- bcm43xx_phy_init_noisescaletbl(bcm);
- for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
- bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]);
-
- bcm43xx_phy_write(bcm, 0x0003, 0x1808);
-
- bcm43xx_ilt_write(bcm, 0x0803, 0x000F);
- bcm43xx_ilt_write(bcm, 0x0804, 0x001F);
- bcm43xx_ilt_write(bcm, 0x0805, 0x002A);
- bcm43xx_ilt_write(bcm, 0x0805, 0x0030);
- bcm43xx_ilt_write(bcm, 0x0807, 0x003A);
-
- bcm43xx_ilt_write(bcm, 0x0000, 0x0013);
- bcm43xx_ilt_write(bcm, 0x0001, 0x0013);
- bcm43xx_ilt_write(bcm, 0x0002, 0x0013);
- bcm43xx_ilt_write(bcm, 0x0003, 0x0013);
- bcm43xx_ilt_write(bcm, 0x0004, 0x0015);
- bcm43xx_ilt_write(bcm, 0x0005, 0x0015);
- bcm43xx_ilt_write(bcm, 0x0006, 0x0019);
-
- bcm43xx_ilt_write(bcm, 0x0404, 0x0003);
- bcm43xx_ilt_write(bcm, 0x0405, 0x0003);
- bcm43xx_ilt_write(bcm, 0x0406, 0x0007);
-
- bcm43xx_ilt_write(bcm, 0x3C02, 0x000F);
- bcm43xx_ilt_write(bcm, 0x3C03, 0x0014);
- break;
- default:
- assert(0);
- }
-}
-
-/* Initialize APHY. This is also called for the GPHY in some cases. */
-static void bcm43xx_phy_inita(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 tval;
-
- if (phy->type == BCM43xx_PHYTYPE_A) {
- bcm43xx_phy_setupa(bcm);
- } else {
- bcm43xx_phy_setupg(bcm);
- if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
- bcm43xx_phy_write(bcm, 0x046E, 0x03CF);
- return;
- }
-
- bcm43xx_phy_write(bcm, BCM43xx_PHY_A_CRS,
- (bcm43xx_phy_read(bcm, BCM43xx_PHY_A_CRS) & 0xF83C) | 0x0340);
- bcm43xx_phy_write(bcm, 0x0034, 0x0001);
-
- TODO();//TODO: RSSI AGC
- bcm43xx_phy_write(bcm, BCM43xx_PHY_A_CRS,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_A_CRS) | (1 << 14));
- bcm43xx_radio_init2060(bcm);
-
- if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM)
- && ((bcm->board_type == 0x0416) || (bcm->board_type == 0x040A))) {
- if (radio->lofcal == 0xFFFF) {
- TODO();//TODO: LOF Cal
- bcm43xx_radio_set_tx_iq(bcm);
- } else
- bcm43xx_radio_write16(bcm, 0x001E, radio->lofcal);
- }
-
- bcm43xx_phy_write(bcm, 0x007A, 0xF111);
-
- if (phy->savedpctlreg == 0xFFFF) {
- bcm43xx_radio_write16(bcm, 0x0019, 0x0000);
- bcm43xx_radio_write16(bcm, 0x0017, 0x0020);
-
- tval = bcm43xx_ilt_read(bcm, 0x3001);
- if (phy->rev == 1) {
- bcm43xx_ilt_write(bcm, 0x3001,
- (bcm43xx_ilt_read(bcm, 0x3001) & 0xFF87)
- | 0x0058);
- } else {
- bcm43xx_ilt_write(bcm, 0x3001,
- (bcm43xx_ilt_read(bcm, 0x3001) & 0xFFC3)
- | 0x002C);
- }
- bcm43xx_dummy_transmission(bcm);
- phy->savedpctlreg = bcm43xx_phy_read(bcm, BCM43xx_PHY_A_PCTL);
- bcm43xx_ilt_write(bcm, 0x3001, tval);
-
- bcm43xx_radio_set_txpower_a(bcm, 0x0018);
- }
- bcm43xx_radio_clear_tssi(bcm);
-}
-
-static void bcm43xx_phy_initb2(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 offset, val;
-
- bcm43xx_write16(bcm, 0x03EC, 0x3F22);
- bcm43xx_phy_write(bcm, 0x0020, 0x301C);
- bcm43xx_phy_write(bcm, 0x0026, 0x0000);
- bcm43xx_phy_write(bcm, 0x0030, 0x00C6);
- bcm43xx_phy_write(bcm, 0x0088, 0x3E00);
- val = 0x3C3D;
- for (offset = 0x0089; offset < 0x00A7; offset++) {
- bcm43xx_phy_write(bcm, offset, val);
- val -= 0x0202;
- }
- bcm43xx_phy_write(bcm, 0x03E4, 0x3000);
- if (radio->channel == 0xFF)
- bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0);
- else
- bcm43xx_radio_selectchannel(bcm, radio->channel, 0);
- if (radio->version != 0x2050) {
- bcm43xx_radio_write16(bcm, 0x0075, 0x0080);
- bcm43xx_radio_write16(bcm, 0x0079, 0x0081);
- }
- bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
- bcm43xx_radio_write16(bcm, 0x0050, 0x0023);
- if (radio->version == 0x2050) {
- bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
- bcm43xx_radio_write16(bcm, 0x005A, 0x0070);
- bcm43xx_radio_write16(bcm, 0x005B, 0x007B);
- bcm43xx_radio_write16(bcm, 0x005C, 0x00B0);
- bcm43xx_radio_write16(bcm, 0x007A, 0x000F);
- bcm43xx_phy_write(bcm, 0x0038, 0x0677);
- bcm43xx_radio_init2050(bcm);
- }
- bcm43xx_phy_write(bcm, 0x0014, 0x0080);
- bcm43xx_phy_write(bcm, 0x0032, 0x00CA);
- bcm43xx_phy_write(bcm, 0x0032, 0x00CC);
- bcm43xx_phy_write(bcm, 0x0035, 0x07C2);
- bcm43xx_phy_lo_b_measure(bcm);
- bcm43xx_phy_write(bcm, 0x0026, 0xCC00);
- if (radio->version != 0x2050)
- bcm43xx_phy_write(bcm, 0x0026, 0xCE00);
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x1000);
- bcm43xx_phy_write(bcm, 0x002A, 0x88A3);
- if (radio->version != 0x2050)
- bcm43xx_phy_write(bcm, 0x002A, 0x88C2);
- bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
- bcm43xx_phy_init_pctl(bcm);
-}
-
-static void bcm43xx_phy_initb4(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 offset, val;
-
- bcm43xx_write16(bcm, 0x03EC, 0x3F22);
- bcm43xx_phy_write(bcm, 0x0020, 0x301C);
- bcm43xx_phy_write(bcm, 0x0026, 0x0000);
- bcm43xx_phy_write(bcm, 0x0030, 0x00C6);
- bcm43xx_phy_write(bcm, 0x0088, 0x3E00);
- val = 0x3C3D;
- for (offset = 0x0089; offset < 0x00A7; offset++) {
- bcm43xx_phy_write(bcm, offset, val);
- val -= 0x0202;
- }
- bcm43xx_phy_write(bcm, 0x03E4, 0x3000);
- if (radio->channel == 0xFF)
- bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0);
- else
- bcm43xx_radio_selectchannel(bcm, radio->channel, 0);
- if (radio->version != 0x2050) {
- bcm43xx_radio_write16(bcm, 0x0075, 0x0080);
- bcm43xx_radio_write16(bcm, 0x0079, 0x0081);
- }
- bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
- bcm43xx_radio_write16(bcm, 0x0050, 0x0023);
- if (radio->version == 0x2050) {
- bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
- bcm43xx_radio_write16(bcm, 0x005A, 0x0070);
- bcm43xx_radio_write16(bcm, 0x005B, 0x007B);
- bcm43xx_radio_write16(bcm, 0x005C, 0x00B0);
- bcm43xx_radio_write16(bcm, 0x007A, 0x000F);
- bcm43xx_phy_write(bcm, 0x0038, 0x0677);
- bcm43xx_radio_init2050(bcm);
- }
- bcm43xx_phy_write(bcm, 0x0014, 0x0080);
- bcm43xx_phy_write(bcm, 0x0032, 0x00CA);
- if (radio->version == 0x2050)
- bcm43xx_phy_write(bcm, 0x0032, 0x00E0);
- bcm43xx_phy_write(bcm, 0x0035, 0x07C2);
-
- bcm43xx_phy_lo_b_measure(bcm);
-
- bcm43xx_phy_write(bcm, 0x0026, 0xCC00);
- if (radio->version == 0x2050)
- bcm43xx_phy_write(bcm, 0x0026, 0xCE00);
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x1100);
- bcm43xx_phy_write(bcm, 0x002A, 0x88A3);
- if (radio->version == 0x2050)
- bcm43xx_phy_write(bcm, 0x002A, 0x88C2);
- bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
- if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
- bcm43xx_calc_nrssi_slope(bcm);
- bcm43xx_calc_nrssi_threshold(bcm);
- }
- bcm43xx_phy_init_pctl(bcm);
-}
-
-static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 offset;
- u16 value;
- u8 old_channel;
-
- if (phy->analog == 1)
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A)
- | 0x0050);
- if ((bcm->board_vendor != PCI_VENDOR_ID_BROADCOM) &&
- (bcm->board_type != 0x0416)) {
- value = 0x2120;
- for (offset = 0x00A8 ; offset < 0x00C7; offset++) {
- bcm43xx_phy_write(bcm, offset, value);
- value += 0x0202;
- }
- }
- bcm43xx_phy_write(bcm, 0x0035,
- (bcm43xx_phy_read(bcm, 0x0035) & 0xF0FF)
- | 0x0700);
- if (radio->version == 0x2050)
- bcm43xx_phy_write(bcm, 0x0038, 0x0667);
-
- if (phy->connected) {
- if (radio->version == 0x2050) {
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A)
- | 0x0020);
- bcm43xx_radio_write16(bcm, 0x0051,
- bcm43xx_radio_read16(bcm, 0x0051)
- | 0x0004);
- }
- bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO, 0x0000);
-
- bcm43xx_phy_write(bcm, 0x0802, bcm43xx_phy_read(bcm, 0x0802) | 0x0100);
- bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x2000);
-
- bcm43xx_phy_write(bcm, 0x001C, 0x186A);
-
- bcm43xx_phy_write(bcm, 0x0013, (bcm43xx_phy_read(bcm, 0x0013) & 0x00FF) | 0x1900);
- bcm43xx_phy_write(bcm, 0x0035, (bcm43xx_phy_read(bcm, 0x0035) & 0xFFC0) | 0x0064);
- bcm43xx_phy_write(bcm, 0x005D, (bcm43xx_phy_read(bcm, 0x005D) & 0xFF80) | 0x000A);
- }
-
- if (bcm->bad_frames_preempt) {
- bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | (1 << 11));
- }
-
- if (phy->analog == 1) {
- bcm43xx_phy_write(bcm, 0x0026, 0xCE00);
- bcm43xx_phy_write(bcm, 0x0021, 0x3763);
- bcm43xx_phy_write(bcm, 0x0022, 0x1BC3);
- bcm43xx_phy_write(bcm, 0x0023, 0x06F9);
- bcm43xx_phy_write(bcm, 0x0024, 0x037E);
- } else
- bcm43xx_phy_write(bcm, 0x0026, 0xCC00);
- bcm43xx_phy_write(bcm, 0x0030, 0x00C6);
- bcm43xx_write16(bcm, 0x03EC, 0x3F22);
-
- if (phy->analog == 1)
- bcm43xx_phy_write(bcm, 0x0020, 0x3E1C);
- else
- bcm43xx_phy_write(bcm, 0x0020, 0x301C);
-
- if (phy->analog == 0)
- bcm43xx_write16(bcm, 0x03E4, 0x3000);
-
- old_channel = radio->channel;
- /* Force to channel 7, even if not supported. */
- bcm43xx_radio_selectchannel(bcm, 7, 0);
-
- if (radio->version != 0x2050) {
- bcm43xx_radio_write16(bcm, 0x0075, 0x0080);
- bcm43xx_radio_write16(bcm, 0x0079, 0x0081);
- }
-
- bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
- bcm43xx_radio_write16(bcm, 0x0050, 0x0023);
-
- if (radio->version == 0x2050) {
- bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
- bcm43xx_radio_write16(bcm, 0x005A, 0x0070);
- }
-
- bcm43xx_radio_write16(bcm, 0x005B, 0x007B);
- bcm43xx_radio_write16(bcm, 0x005C, 0x00B0);
-
- bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0007);
-
- bcm43xx_radio_selectchannel(bcm, old_channel, 0);
-
- bcm43xx_phy_write(bcm, 0x0014, 0x0080);
- bcm43xx_phy_write(bcm, 0x0032, 0x00CA);
- bcm43xx_phy_write(bcm, 0x002A, 0x88A3);
-
- bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
-
- if (radio->version == 0x2050)
- bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
-
- bcm43xx_write16(bcm, 0x03E4, (bcm43xx_read16(bcm, 0x03E4) & 0xFFC0) | 0x0004);
-}
-
-static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 offset, val;
- u8 old_channel;
-
- bcm43xx_phy_write(bcm, 0x003E, 0x817A);
- bcm43xx_radio_write16(bcm, 0x007A,
- (bcm43xx_radio_read16(bcm, 0x007A) | 0x0058));
- if (radio->revision == 4 ||
- radio->revision == 5) {
- bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
- bcm43xx_radio_write16(bcm, 0x0052, 0x0070);
- bcm43xx_radio_write16(bcm, 0x0053, 0x00B3);
- bcm43xx_radio_write16(bcm, 0x0054, 0x009B);
- bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
- bcm43xx_radio_write16(bcm, 0x005B, 0x0088);
- bcm43xx_radio_write16(bcm, 0x005D, 0x0088);
- bcm43xx_radio_write16(bcm, 0x005E, 0x0088);
- bcm43xx_radio_write16(bcm, 0x007D, 0x0088);
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET,
- (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET)
- | 0x00000200));
- }
- if (radio->revision == 8) {
- bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
- bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
- bcm43xx_radio_write16(bcm, 0x0053, 0x00B7);
- bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
- bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
- bcm43xx_radio_write16(bcm, 0x005B, 0x006B);
- bcm43xx_radio_write16(bcm, 0x005C, 0x000F);
- if (bcm->sprom.boardflags & 0x8000) {
- bcm43xx_radio_write16(bcm, 0x005D, 0x00FA);
- bcm43xx_radio_write16(bcm, 0x005E, 0x00D8);
- } else {
- bcm43xx_radio_write16(bcm, 0x005D, 0x00F5);
- bcm43xx_radio_write16(bcm, 0x005E, 0x00B8);
- }
- bcm43xx_radio_write16(bcm, 0x0073, 0x0003);
- bcm43xx_radio_write16(bcm, 0x007D, 0x00A8);
- bcm43xx_radio_write16(bcm, 0x007C, 0x0001);
- bcm43xx_radio_write16(bcm, 0x007E, 0x0008);
- }
- val = 0x1E1F;
- for (offset = 0x0088; offset < 0x0098; offset++) {
- bcm43xx_phy_write(bcm, offset, val);
- val -= 0x0202;
- }
- val = 0x3E3F;
- for (offset = 0x0098; offset < 0x00A8; offset++) {
- bcm43xx_phy_write(bcm, offset, val);
- val -= 0x0202;
- }
- val = 0x2120;
- for (offset = 0x00A8; offset < 0x00C8; offset++) {
- bcm43xx_phy_write(bcm, offset, (val & 0x3F3F));
- val += 0x0202;
- }
- if (phy->type == BCM43xx_PHYTYPE_G) {
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) | 0x0020);
- bcm43xx_radio_write16(bcm, 0x0051,
- bcm43xx_radio_read16(bcm, 0x0051) | 0x0004);
- bcm43xx_phy_write(bcm, 0x0802,
- bcm43xx_phy_read(bcm, 0x0802) | 0x0100);
- bcm43xx_phy_write(bcm, 0x042B,
- bcm43xx_phy_read(bcm, 0x042B) | 0x2000);
- bcm43xx_phy_write(bcm, 0x5B, 0x0000);
- bcm43xx_phy_write(bcm, 0x5C, 0x0000);
- }
-
- old_channel = radio->channel;
- if (old_channel >= 8)
- bcm43xx_radio_selectchannel(bcm, 1, 0);
- else
- bcm43xx_radio_selectchannel(bcm, 13, 0);
-
- bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
- bcm43xx_radio_write16(bcm, 0x0050, 0x0023);
- udelay(40);
- if (radio->revision < 6 || radio-> revision == 8) {
- bcm43xx_radio_write16(bcm, 0x007C, (bcm43xx_radio_read16(bcm, 0x007C)
- | 0x0002));
- bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
- }
- if (radio->revision <= 2) {
- bcm43xx_radio_write16(bcm, 0x007C, 0x0020);
- bcm43xx_radio_write16(bcm, 0x005A, 0x0070);
- bcm43xx_radio_write16(bcm, 0x005B, 0x007B);
- bcm43xx_radio_write16(bcm, 0x005C, 0x00B0);
- }
- bcm43xx_radio_write16(bcm, 0x007A,
- (bcm43xx_radio_read16(bcm, 0x007A) & 0x00F8) | 0x0007);
-
- bcm43xx_radio_selectchannel(bcm, old_channel, 0);
-
- bcm43xx_phy_write(bcm, 0x0014, 0x0200);
- if (radio->revision >= 6)
- bcm43xx_phy_write(bcm, 0x002A, 0x88C2);
- else
- bcm43xx_phy_write(bcm, 0x002A, 0x8AC0);
- bcm43xx_phy_write(bcm, 0x0038, 0x0668);
- bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
- if (radio->revision <= 5)
- bcm43xx_phy_write(bcm, 0x005D, (bcm43xx_phy_read(bcm, 0x005D)
- & 0xFF80) | 0x0003);
- if (radio->revision <= 2)
- bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
-
- if (phy->analog == 4){
- bcm43xx_write16(bcm, 0x03E4, 0x0009);
- bcm43xx_phy_write(bcm, 0x61, bcm43xx_phy_read(bcm, 0x61) & 0xFFF);
- } else {
- bcm43xx_phy_write(bcm, 0x0002, (bcm43xx_phy_read(bcm, 0x0002) & 0xFFC0) | 0x0004);
- }
- if (phy->type == BCM43xx_PHYTYPE_G)
- bcm43xx_write16(bcm, 0x03E6, 0x0);
- if (phy->type == BCM43xx_PHYTYPE_B) {
- bcm43xx_write16(bcm, 0x03E6, 0x8140);
- bcm43xx_phy_write(bcm, 0x0016, 0x0410);
- bcm43xx_phy_write(bcm, 0x0017, 0x0820);
- bcm43xx_phy_write(bcm, 0x0062, 0x0007);
- bcm43xx_radio_init2050(bcm);
- bcm43xx_phy_lo_g_measure(bcm);
- if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
- bcm43xx_calc_nrssi_slope(bcm);
- bcm43xx_calc_nrssi_threshold(bcm);
- }
- bcm43xx_phy_init_pctl(bcm);
- }
-}
-
-static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 backup_phy[15] = {0};
- u16 backup_radio[3];
- u16 backup_bband;
- u16 i;
- u16 loop1_cnt, loop1_done, loop1_omitted;
- u16 loop2_done;
-
- backup_phy[0] = bcm43xx_phy_read(bcm, 0x0429);
- backup_phy[1] = bcm43xx_phy_read(bcm, 0x0001);
- backup_phy[2] = bcm43xx_phy_read(bcm, 0x0811);
- backup_phy[3] = bcm43xx_phy_read(bcm, 0x0812);
- if (phy->rev != 1) {
- backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814);
- backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815);
- }
- backup_phy[6] = bcm43xx_phy_read(bcm, 0x005A);
- backup_phy[7] = bcm43xx_phy_read(bcm, 0x0059);
- backup_phy[8] = bcm43xx_phy_read(bcm, 0x0058);
- backup_phy[9] = bcm43xx_phy_read(bcm, 0x000A);
- backup_phy[10] = bcm43xx_phy_read(bcm, 0x0003);
- backup_phy[11] = bcm43xx_phy_read(bcm, 0x080F);
- backup_phy[12] = bcm43xx_phy_read(bcm, 0x0810);
- backup_phy[13] = bcm43xx_phy_read(bcm, 0x002B);
- backup_phy[14] = bcm43xx_phy_read(bcm, 0x0015);
- bcm43xx_phy_read(bcm, 0x002D); /* dummy read */
- backup_bband = radio->baseband_atten;
- backup_radio[0] = bcm43xx_radio_read16(bcm, 0x0052);
- backup_radio[1] = bcm43xx_radio_read16(bcm, 0x0043);
- backup_radio[2] = bcm43xx_radio_read16(bcm, 0x007A);
-
- bcm43xx_phy_write(bcm, 0x0429,
- bcm43xx_phy_read(bcm, 0x0429) & 0x3FFF);
- bcm43xx_phy_write(bcm, 0x0001,
- bcm43xx_phy_read(bcm, 0x0001) & 0x8000);
- bcm43xx_phy_write(bcm, 0x0811,
- bcm43xx_phy_read(bcm, 0x0811) | 0x0002);
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_phy_read(bcm, 0x0812) & 0xFFFD);
- bcm43xx_phy_write(bcm, 0x0811,
- bcm43xx_phy_read(bcm, 0x0811) | 0x0001);
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_phy_read(bcm, 0x0812) & 0xFFFE);
- if (phy->rev != 1) {
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0001);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE);
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0002);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD);
- }
- bcm43xx_phy_write(bcm, 0x0811,
- bcm43xx_phy_read(bcm, 0x0811) | 0x000C);
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_phy_read(bcm, 0x0812) | 0x000C);
-
- bcm43xx_phy_write(bcm, 0x0811,
- (bcm43xx_phy_read(bcm, 0x0811)
- & 0xFFCF) | 0x0030);
- bcm43xx_phy_write(bcm, 0x0812,
- (bcm43xx_phy_read(bcm, 0x0812)
- & 0xFFCF) | 0x0010);
-
- bcm43xx_phy_write(bcm, 0x005A, 0x0780);
- bcm43xx_phy_write(bcm, 0x0059, 0xC810);
- bcm43xx_phy_write(bcm, 0x0058, 0x000D);
- if (phy->analog == 0) {
- bcm43xx_phy_write(bcm, 0x0003, 0x0122);
- } else {
- bcm43xx_phy_write(bcm, 0x000A,
- bcm43xx_phy_read(bcm, 0x000A)
- | 0x2000);
- }
- if (phy->rev != 1) {
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0004);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB);
- }
- bcm43xx_phy_write(bcm, 0x0003,
- (bcm43xx_phy_read(bcm, 0x0003)
- & 0xFF9F) | 0x0040);
- if (radio->version == 0x2050 && radio->revision == 2) {
- bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
- bcm43xx_radio_write16(bcm, 0x0043,
- (bcm43xx_radio_read16(bcm, 0x0043)
- & 0xFFF0) | 0x0009);
- loop1_cnt = 9;
- } else if (radio->revision == 8) {
- bcm43xx_radio_write16(bcm, 0x0043, 0x000F);
- loop1_cnt = 15;
- } else
- loop1_cnt = 0;
-
- bcm43xx_phy_set_baseband_attenuation(bcm, 11);
-
- if (phy->rev >= 3)
- bcm43xx_phy_write(bcm, 0x080F, 0xC020);
- else
- bcm43xx_phy_write(bcm, 0x080F, 0x8020);
- bcm43xx_phy_write(bcm, 0x0810, 0x0000);
-
- bcm43xx_phy_write(bcm, 0x002B,
- (bcm43xx_phy_read(bcm, 0x002B)
- & 0xFFC0) | 0x0001);
- bcm43xx_phy_write(bcm, 0x002B,
- (bcm43xx_phy_read(bcm, 0x002B)
- & 0xC0FF) | 0x0800);
- bcm43xx_phy_write(bcm, 0x0811,
- bcm43xx_phy_read(bcm, 0x0811) | 0x0100);
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_phy_read(bcm, 0x0812) & 0xCFFF);
- if (bcm->sprom.boardflags & BCM43xx_BFL_EXTLNA) {
- if (phy->rev >= 7) {
- bcm43xx_phy_write(bcm, 0x0811,
- bcm43xx_phy_read(bcm, 0x0811)
- | 0x0800);
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_phy_read(bcm, 0x0812)
- | 0x8000);
- }
- }
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A)
- & 0x00F7);
-
- for (i = 0; i < loop1_cnt; i++) {
- bcm43xx_radio_write16(bcm, 0x0043, loop1_cnt);
- bcm43xx_phy_write(bcm, 0x0812,
- (bcm43xx_phy_read(bcm, 0x0812)
- & 0xF0FF) | (i << 8));
- bcm43xx_phy_write(bcm, 0x0015,
- (bcm43xx_phy_read(bcm, 0x0015)
- & 0x0FFF) | 0xA000);
- bcm43xx_phy_write(bcm, 0x0015,
- (bcm43xx_phy_read(bcm, 0x0015)
- & 0x0FFF) | 0xF000);
- udelay(20);
- if (bcm43xx_phy_read(bcm, 0x002D) >= 0x0DFC)
- break;
- }
- loop1_done = i;
- loop1_omitted = loop1_cnt - loop1_done;
-
- loop2_done = 0;
- if (loop1_done >= 8) {
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_phy_read(bcm, 0x0812)
- | 0x0030);
- for (i = loop1_done - 8; i < 16; i++) {
- bcm43xx_phy_write(bcm, 0x0812,
- (bcm43xx_phy_read(bcm, 0x0812)
- & 0xF0FF) | (i << 8));
- bcm43xx_phy_write(bcm, 0x0015,
- (bcm43xx_phy_read(bcm, 0x0015)
- & 0x0FFF) | 0xA000);
- bcm43xx_phy_write(bcm, 0x0015,
- (bcm43xx_phy_read(bcm, 0x0015)
- & 0x0FFF) | 0xF000);
- udelay(20);
- if (bcm43xx_phy_read(bcm, 0x002D) >= 0x0DFC)
- break;
- }
- }
-
- if (phy->rev != 1) {
- bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]);
- bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]);
- }
- bcm43xx_phy_write(bcm, 0x005A, backup_phy[6]);
- bcm43xx_phy_write(bcm, 0x0059, backup_phy[7]);
- bcm43xx_phy_write(bcm, 0x0058, backup_phy[8]);
- bcm43xx_phy_write(bcm, 0x000A, backup_phy[9]);
- bcm43xx_phy_write(bcm, 0x0003, backup_phy[10]);
- bcm43xx_phy_write(bcm, 0x080F, backup_phy[11]);
- bcm43xx_phy_write(bcm, 0x0810, backup_phy[12]);
- bcm43xx_phy_write(bcm, 0x002B, backup_phy[13]);
- bcm43xx_phy_write(bcm, 0x0015, backup_phy[14]);
-
- bcm43xx_phy_set_baseband_attenuation(bcm, backup_bband);
-
- bcm43xx_radio_write16(bcm, 0x0052, backup_radio[0]);
- bcm43xx_radio_write16(bcm, 0x0043, backup_radio[1]);
- bcm43xx_radio_write16(bcm, 0x007A, backup_radio[2]);
-
- bcm43xx_phy_write(bcm, 0x0811, backup_phy[2] | 0x0003);
- udelay(10);
- bcm43xx_phy_write(bcm, 0x0811, backup_phy[2]);
- bcm43xx_phy_write(bcm, 0x0812, backup_phy[3]);
- bcm43xx_phy_write(bcm, 0x0429, backup_phy[0]);
- bcm43xx_phy_write(bcm, 0x0001, backup_phy[1]);
-
- phy->loopback_gain[0] = ((loop1_done * 6) - (loop1_omitted * 4)) - 11;
- phy->loopback_gain[1] = (24 - (3 * loop2_done)) * 2;
-}
-
-static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 tmp;
-
- if (phy->rev == 1)
- bcm43xx_phy_initb5(bcm);
- else
- bcm43xx_phy_initb6(bcm);
- if (phy->rev >= 2 || phy->connected)
- bcm43xx_phy_inita(bcm);
-
- if (phy->rev >= 2) {
- bcm43xx_phy_write(bcm, 0x0814, 0x0000);
- bcm43xx_phy_write(bcm, 0x0815, 0x0000);
- }
- if (phy->rev == 2) {
- bcm43xx_phy_write(bcm, 0x0811, 0x0000);
- bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
- }
- if (phy->rev > 5) {
- bcm43xx_phy_write(bcm, 0x0811, 0x0400);
- bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
- }
- if (phy->rev >= 2 && phy->connected) {
- tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF;
- if (tmp ==3 || tmp == 5) {
- bcm43xx_phy_write(bcm, 0x04C2, 0x1816);
- bcm43xx_phy_write(bcm, 0x04C3, 0x8006);
- if (tmp == 5) {
- bcm43xx_phy_write(bcm, 0x04CC,
- (bcm43xx_phy_read(bcm, 0x04CC)
- & 0x00FF) | 0x1F00);
- }
- }
- bcm43xx_phy_write(bcm, 0x047E, 0x0078);
- }
- if (radio->revision == 8) {
- bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080);
- bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004);
- }
- if (phy->rev >= 2 && phy->connected)
- bcm43xx_calc_loopback_gain(bcm);
- if (radio->revision != 8) {
- if (radio->initval == 0xFFFF)
- radio->initval = bcm43xx_radio_init2050(bcm);
- else
- bcm43xx_radio_write16(bcm, 0x0078, radio->initval);
- }
- if (radio->txctl2 == 0xFFFF) {
- bcm43xx_phy_lo_g_measure(bcm);
- } else {
- if (radio->version == 0x2050 && radio->revision == 8) {
- bcm43xx_radio_write16(bcm, 0x0052,
- (radio->txctl1 << 4) | radio->txctl2);
- } else {
- bcm43xx_radio_write16(bcm, 0x0052,
- (bcm43xx_radio_read16(bcm, 0x0052)
- & 0xFFF0) | radio->txctl1);
- }
- if (phy->rev >= 6) {
- bcm43xx_phy_write(bcm, 0x0036,
- (bcm43xx_phy_read(bcm, 0x0036)
- & 0x0FFF) | (radio->txctl2 << 12));
- }
- if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
- bcm43xx_phy_write(bcm, 0x002E, 0x8075);
- else
- bcm43xx_phy_write(bcm, 0x002E, 0x807F);
- if (phy->rev < 2)
- bcm43xx_phy_write(bcm, 0x002F, 0x0101);
- else
- bcm43xx_phy_write(bcm, 0x002F, 0x0202);
- }
- if (phy->connected || phy->rev >= 2) {
- bcm43xx_phy_lo_adjust(bcm, 0);
- bcm43xx_phy_write(bcm, 0x080F, 0x8078);
- }
-
- if (!(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) {
- /* The specs state to update the NRSSI LT with
- * the value 0x7FFFFFFF here. I think that is some weird
- * compiler optimization in the original driver.
- * Essentially, what we do here is resetting all NRSSI LT
- * entries to -32 (see the limit_value() in nrssi_hw_update())
- */
- bcm43xx_nrssi_hw_update(bcm, 0xFFFF);
- bcm43xx_calc_nrssi_threshold(bcm);
- } else if (phy->connected || phy->rev >= 2) {
- if (radio->nrssi[0] == -1000) {
- assert(radio->nrssi[1] == -1000);
- bcm43xx_calc_nrssi_slope(bcm);
- } else {
- assert(radio->nrssi[1] != -1000);
- bcm43xx_calc_nrssi_threshold(bcm);
- }
- }
- if (radio->revision == 8)
- bcm43xx_phy_write(bcm, 0x0805, 0x3230);
- bcm43xx_phy_init_pctl(bcm);
- if (bcm->chip_id == 0x4306 && bcm->chip_package == 2) {
- bcm43xx_phy_write(bcm, 0x0429,
- bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF);
- bcm43xx_phy_write(bcm, 0x04C3,
- bcm43xx_phy_read(bcm, 0x04C3) & 0x7FFF);
- }
-}
-
-static u16 bcm43xx_phy_lo_b_r15_loop(struct bcm43xx_private *bcm)
-{
- int i;
- u16 ret = 0;
- unsigned long flags;
-
- local_irq_save(flags);
- for (i = 0; i < 10; i++){
- bcm43xx_phy_write(bcm, 0x0015, 0xAFA0);
- udelay(1);
- bcm43xx_phy_write(bcm, 0x0015, 0xEFA0);
- udelay(10);
- bcm43xx_phy_write(bcm, 0x0015, 0xFFA0);
- udelay(40);
- ret += bcm43xx_phy_read(bcm, 0x002C);
- }
- local_irq_restore(flags);
- bcm43xx_voluntary_preempt();
-
- return ret;
-}
-
-void bcm43xx_phy_lo_b_measure(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 regstack[12] = { 0 };
- u16 mls;
- u16 fval;
- int i, j;
-
- regstack[0] = bcm43xx_phy_read(bcm, 0x0015);
- regstack[1] = bcm43xx_radio_read16(bcm, 0x0052) & 0xFFF0;
-
- if (radio->version == 0x2053) {
- regstack[2] = bcm43xx_phy_read(bcm, 0x000A);
- regstack[3] = bcm43xx_phy_read(bcm, 0x002A);
- regstack[4] = bcm43xx_phy_read(bcm, 0x0035);
- regstack[5] = bcm43xx_phy_read(bcm, 0x0003);
- regstack[6] = bcm43xx_phy_read(bcm, 0x0001);
- regstack[7] = bcm43xx_phy_read(bcm, 0x0030);
-
- regstack[8] = bcm43xx_radio_read16(bcm, 0x0043);
- regstack[9] = bcm43xx_radio_read16(bcm, 0x007A);
- regstack[10] = bcm43xx_read16(bcm, 0x03EC);
- regstack[11] = bcm43xx_radio_read16(bcm, 0x0052) & 0x00F0;
-
- bcm43xx_phy_write(bcm, 0x0030, 0x00FF);
- bcm43xx_write16(bcm, 0x03EC, 0x3F3F);
- bcm43xx_phy_write(bcm, 0x0035, regstack[4] & 0xFF7F);
- bcm43xx_radio_write16(bcm, 0x007A, regstack[9] & 0xFFF0);
- }
- bcm43xx_phy_write(bcm, 0x0015, 0xB000);
- bcm43xx_phy_write(bcm, 0x002B, 0x0004);
-
- if (radio->version == 0x2053) {
- bcm43xx_phy_write(bcm, 0x002B, 0x0203);
- bcm43xx_phy_write(bcm, 0x002A, 0x08A3);
- }
-
- phy->minlowsig[0] = 0xFFFF;
-
- for (i = 0; i < 4; i++) {
- bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | i);
- bcm43xx_phy_lo_b_r15_loop(bcm);
- }
- for (i = 0; i < 10; i++) {
- bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | i);
- mls = bcm43xx_phy_lo_b_r15_loop(bcm) / 10;
- if (mls < phy->minlowsig[0]) {
- phy->minlowsig[0] = mls;
- phy->minlowsigpos[0] = i;
- }
- }
- bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | phy->minlowsigpos[0]);
-
- phy->minlowsig[1] = 0xFFFF;
-
- for (i = -4; i < 5; i += 2) {
- for (j = -4; j < 5; j += 2) {
- if (j < 0)
- fval = (0x0100 * i) + j + 0x0100;
- else
- fval = (0x0100 * i) + j;
- bcm43xx_phy_write(bcm, 0x002F, fval);
- mls = bcm43xx_phy_lo_b_r15_loop(bcm) / 10;
- if (mls < phy->minlowsig[1]) {
- phy->minlowsig[1] = mls;
- phy->minlowsigpos[1] = fval;
- }
- }
- }
- phy->minlowsigpos[1] += 0x0101;
-
- bcm43xx_phy_write(bcm, 0x002F, phy->minlowsigpos[1]);
- if (radio->version == 0x2053) {
- bcm43xx_phy_write(bcm, 0x000A, regstack[2]);
- bcm43xx_phy_write(bcm, 0x002A, regstack[3]);
- bcm43xx_phy_write(bcm, 0x0035, regstack[4]);
- bcm43xx_phy_write(bcm, 0x0003, regstack[5]);
- bcm43xx_phy_write(bcm, 0x0001, regstack[6]);
- bcm43xx_phy_write(bcm, 0x0030, regstack[7]);
-
- bcm43xx_radio_write16(bcm, 0x0043, regstack[8]);
- bcm43xx_radio_write16(bcm, 0x007A, regstack[9]);
-
- bcm43xx_radio_write16(bcm, 0x0052,
- (bcm43xx_radio_read16(bcm, 0x0052) & 0x000F)
- | regstack[11]);
-
- bcm43xx_write16(bcm, 0x03EC, regstack[10]);
- }
- bcm43xx_phy_write(bcm, 0x0015, regstack[0]);
-}
-
-static inline
-u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 ret;
- unsigned long flags;
-
- local_irq_save(flags);
- if (phy->connected) {
- bcm43xx_phy_write(bcm, 0x15, 0xE300);
- control <<= 8;
- bcm43xx_phy_write(bcm, 0x0812, control | 0x00B0);
- udelay(5);
- bcm43xx_phy_write(bcm, 0x0812, control | 0x00B2);
- udelay(2);
- bcm43xx_phy_write(bcm, 0x0812, control | 0x00B3);
- udelay(4);
- bcm43xx_phy_write(bcm, 0x0015, 0xF300);
- udelay(8);
- } else {
- bcm43xx_phy_write(bcm, 0x0015, control | 0xEFA0);
- udelay(2);
- bcm43xx_phy_write(bcm, 0x0015, control | 0xEFE0);
- udelay(4);
- bcm43xx_phy_write(bcm, 0x0015, control | 0xFFE0);
- udelay(8);
- }
- ret = bcm43xx_phy_read(bcm, 0x002D);
- local_irq_restore(flags);
- bcm43xx_voluntary_preempt();
-
- return ret;
-}
-
-static u32 bcm43xx_phy_lo_g_singledeviation(struct bcm43xx_private *bcm, u16 control)
-{
- int i;
- u32 ret = 0;
-
- for (i = 0; i < 8; i++)
- ret += bcm43xx_phy_lo_g_deviation_subval(bcm, control);
-
- return ret;
-}
-
-/* Write the LocalOscillator CONTROL */
-static inline
-void bcm43xx_lo_write(struct bcm43xx_private *bcm,
- struct bcm43xx_lopair *pair)
-{
- u16 value;
-
- value = (u8)(pair->low);
- value |= ((u8)(pair->high)) << 8;
-
-#ifdef CONFIG_BCM43XX_DEBUG
- /* Sanity check. */
- if (pair->low < -8 || pair->low > 8 ||
- pair->high < -8 || pair->high > 8) {
- printk(KERN_WARNING PFX
- "WARNING: Writing invalid LOpair "
- "(low: %d, high: %d, index: %lu)\n",
- pair->low, pair->high,
- (unsigned long)(pair - bcm43xx_current_phy(bcm)->_lo_pairs));
- dump_stack();
- }
-#endif
-
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, value);
-}
-
-static inline
-struct bcm43xx_lopair * bcm43xx_find_lopair(struct bcm43xx_private *bcm,
- u16 baseband_attenuation,
- u16 radio_attenuation,
- u16 tx)
-{
- static const u8 dict[10] = { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 };
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-
- if (baseband_attenuation > 6)
- baseband_attenuation = 6;
- assert(radio_attenuation < 10);
-
- if (tx == 3) {
- return bcm43xx_get_lopair(phy,
- radio_attenuation,
- baseband_attenuation);
- }
- return bcm43xx_get_lopair(phy, dict[radio_attenuation], baseband_attenuation);
-}
-
-static inline
-struct bcm43xx_lopair * bcm43xx_current_lopair(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
-
- return bcm43xx_find_lopair(bcm,
- radio->baseband_atten,
- radio->radio_atten,
- radio->txctl1);
-}
-
-/* Adjust B/G LO */
-void bcm43xx_phy_lo_adjust(struct bcm43xx_private *bcm, int fixed)
-{
- struct bcm43xx_lopair *pair;
-
- if (fixed) {
- /* Use fixed values. Only for initialization. */
- pair = bcm43xx_find_lopair(bcm, 2, 3, 0);
- } else
- pair = bcm43xx_current_lopair(bcm);
- bcm43xx_lo_write(bcm, pair);
-}
-
-static void bcm43xx_phy_lo_g_measure_txctl2(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 txctl2 = 0, i;
- u32 smallest, tmp;
-
- bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
- udelay(10);
- smallest = bcm43xx_phy_lo_g_singledeviation(bcm, 0);
- for (i = 0; i < 16; i++) {
- bcm43xx_radio_write16(bcm, 0x0052, i);
- udelay(10);
- tmp = bcm43xx_phy_lo_g_singledeviation(bcm, 0);
- if (tmp < smallest) {
- smallest = tmp;
- txctl2 = i;
- }
- }
- radio->txctl2 = txctl2;
-}
-
-static
-void bcm43xx_phy_lo_g_state(struct bcm43xx_private *bcm,
- const struct bcm43xx_lopair *in_pair,
- struct bcm43xx_lopair *out_pair,
- u16 r27)
-{
- static const struct bcm43xx_lopair transitions[8] = {
- { .high = 1, .low = 1, },
- { .high = 1, .low = 0, },
- { .high = 1, .low = -1, },
- { .high = 0, .low = -1, },
- { .high = -1, .low = -1, },
- { .high = -1, .low = 0, },
- { .high = -1, .low = 1, },
- { .high = 0, .low = 1, },
- };
- struct bcm43xx_lopair lowest_transition = {
- .high = in_pair->high,
- .low = in_pair->low,
- };
- struct bcm43xx_lopair tmp_pair;
- struct bcm43xx_lopair transition;
- int i = 12;
- int state = 0;
- int found_lower;
- int j, begin, end;
- u32 lowest_deviation;
- u32 tmp;
-
- /* Note that in_pair and out_pair can point to the same pair. Be careful. */
-
- bcm43xx_lo_write(bcm, &lowest_transition);
- lowest_deviation = bcm43xx_phy_lo_g_singledeviation(bcm, r27);
- do {
- found_lower = 0;
- assert(state >= 0 && state <= 8);
- if (state == 0) {
- begin = 1;
- end = 8;
- } else if (state % 2 == 0) {
- begin = state - 1;
- end = state + 1;
- } else {
- begin = state - 2;
- end = state + 2;
- }
- if (begin < 1)
- begin += 8;
- if (end > 8)
- end -= 8;
-
- j = begin;
- tmp_pair.high = lowest_transition.high;
- tmp_pair.low = lowest_transition.low;
- while (1) {
- assert(j >= 1 && j <= 8);
- transition.high = tmp_pair.high + transitions[j - 1].high;
- transition.low = tmp_pair.low + transitions[j - 1].low;
- if ((abs(transition.low) < 9) && (abs(transition.high) < 9)) {
- bcm43xx_lo_write(bcm, &transition);
- tmp = bcm43xx_phy_lo_g_singledeviation(bcm, r27);
- if (tmp < lowest_deviation) {
- lowest_deviation = tmp;
- state = j;
- found_lower = 1;
-
- lowest_transition.high = transition.high;
- lowest_transition.low = transition.low;
- }
- }
- if (j == end)
- break;
- if (j == 8)
- j = 1;
- else
- j++;
- }
- } while (i-- && found_lower);
-
- out_pair->high = lowest_transition.high;
- out_pair->low = lowest_transition.low;
-}
-
-/* Set the baseband attenuation value on chip. */
-void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
- u16 baseband_attenuation)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 value;
-
- if (phy->analog == 0) {
- value = (bcm43xx_read16(bcm, 0x03E6) & 0xFFF0);
- value |= (baseband_attenuation & 0x000F);
- bcm43xx_write16(bcm, 0x03E6, value);
- return;
- }
-
- if (phy->analog > 1) {
- value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C;
- value |= (baseband_attenuation << 2) & 0x003C;
- } else {
- value = bcm43xx_phy_read(bcm, 0x0060) & ~0x0078;
- value |= (baseband_attenuation << 3) & 0x0078;
- }
- bcm43xx_phy_write(bcm, 0x0060, value);
-}
-
-/* http://bcm-specs.sipsolutions.net/LocalOscillator/Measure */
-void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
-{
- static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 };
- const int is_initializing = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZING);
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 h, i, oldi = 0, j;
- struct bcm43xx_lopair control;
- struct bcm43xx_lopair *tmp_control;
- u16 tmp;
- u16 regstack[16] = { 0 };
- u8 oldchannel;
-
- //XXX: What are these?
- u8 r27 = 0, r31;
-
- oldchannel = radio->channel;
- /* Setup */
- if (phy->connected) {
- regstack[0] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS);
- regstack[1] = bcm43xx_phy_read(bcm, 0x0802);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0] & 0x7FFF);
- bcm43xx_phy_write(bcm, 0x0802, regstack[1] & 0xFFFC);
- }
- regstack[3] = bcm43xx_read16(bcm, 0x03E2);
- bcm43xx_write16(bcm, 0x03E2, regstack[3] | 0x8000);
- regstack[4] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
- regstack[5] = bcm43xx_phy_read(bcm, 0x15);
- regstack[6] = bcm43xx_phy_read(bcm, 0x2A);
- regstack[7] = bcm43xx_phy_read(bcm, 0x35);
- regstack[8] = bcm43xx_phy_read(bcm, 0x60);
- regstack[9] = bcm43xx_radio_read16(bcm, 0x43);
- regstack[10] = bcm43xx_radio_read16(bcm, 0x7A);
- regstack[11] = bcm43xx_radio_read16(bcm, 0x52);
- if (phy->connected) {
- regstack[12] = bcm43xx_phy_read(bcm, 0x0811);
- regstack[13] = bcm43xx_phy_read(bcm, 0x0812);
- regstack[14] = bcm43xx_phy_read(bcm, 0x0814);
- regstack[15] = bcm43xx_phy_read(bcm, 0x0815);
- }
- bcm43xx_radio_selectchannel(bcm, 6, 0);
- if (phy->connected) {
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0] & 0x7FFF);
- bcm43xx_phy_write(bcm, 0x0802, regstack[1] & 0xFFFC);
- bcm43xx_dummy_transmission(bcm);
- }
- bcm43xx_radio_write16(bcm, 0x0043, 0x0006);
-
- bcm43xx_phy_set_baseband_attenuation(bcm, 2);
-
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x0000);
- bcm43xx_phy_write(bcm, 0x002E, 0x007F);
- bcm43xx_phy_write(bcm, 0x080F, 0x0078);
- bcm43xx_phy_write(bcm, 0x0035, regstack[7] & ~(1 << 7));
- bcm43xx_radio_write16(bcm, 0x007A, regstack[10] & 0xFFF0);
- bcm43xx_phy_write(bcm, 0x002B, 0x0203);
- bcm43xx_phy_write(bcm, 0x002A, 0x08A3);
- if (phy->connected) {
- bcm43xx_phy_write(bcm, 0x0814, regstack[14] | 0x0003);
- bcm43xx_phy_write(bcm, 0x0815, regstack[15] & 0xFFFC);
- bcm43xx_phy_write(bcm, 0x0811, 0x01B3);
- bcm43xx_phy_write(bcm, 0x0812, 0x00B2);
- }
- if (is_initializing)
- bcm43xx_phy_lo_g_measure_txctl2(bcm);
- bcm43xx_phy_write(bcm, 0x080F, 0x8078);
-
- /* Measure */
- control.low = 0;
- control.high = 0;
- for (h = 0; h < 10; h++) {
- /* Loop over each possible RadioAttenuation (0-9) */
- i = pairorder[h];
- if (is_initializing) {
- if (i == 3) {
- control.low = 0;
- control.high = 0;
- } else if (((i % 2 == 1) && (oldi % 2 == 1)) ||
- ((i % 2 == 0) && (oldi % 2 == 0))) {
- tmp_control = bcm43xx_get_lopair(phy, oldi, 0);
- memcpy(&control, tmp_control, sizeof(control));
- } else {
- tmp_control = bcm43xx_get_lopair(phy, 3, 0);
- memcpy(&control, tmp_control, sizeof(control));
- }
- }
- /* Loop over each possible BasebandAttenuation/2 */
- for (j = 0; j < 4; j++) {
- if (is_initializing) {
- tmp = i * 2 + j;
- r27 = 0;
- r31 = 0;
- if (tmp > 14) {
- r31 = 1;
- if (tmp > 17)
- r27 = 1;
- if (tmp > 19)
- r27 = 2;
- }
- } else {
- tmp_control = bcm43xx_get_lopair(phy, i, j * 2);
- if (!tmp_control->used)
- continue;
- memcpy(&control, tmp_control, sizeof(control));
- r27 = 3;
- r31 = 0;
- }
- bcm43xx_radio_write16(bcm, 0x43, i);
- bcm43xx_radio_write16(bcm, 0x52, radio->txctl2);
- udelay(10);
- bcm43xx_voluntary_preempt();
-
- bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
-
- tmp = (regstack[10] & 0xFFF0);
- if (r31)
- tmp |= 0x0008;
- bcm43xx_radio_write16(bcm, 0x007A, tmp);
-
- tmp_control = bcm43xx_get_lopair(phy, i, j * 2);
- bcm43xx_phy_lo_g_state(bcm, &control, tmp_control, r27);
- }
- oldi = i;
- }
- /* Loop over each possible RadioAttenuation (10-13) */
- for (i = 10; i < 14; i++) {
- /* Loop over each possible BasebandAttenuation/2 */
- for (j = 0; j < 4; j++) {
- if (is_initializing) {
- tmp_control = bcm43xx_get_lopair(phy, i - 9, j * 2);
- memcpy(&control, tmp_control, sizeof(control));
- tmp = (i - 9) * 2 + j - 5;//FIXME: This is wrong, as the following if statement can never trigger.
- r27 = 0;
- r31 = 0;
- if (tmp > 14) {
- r31 = 1;
- if (tmp > 17)
- r27 = 1;
- if (tmp > 19)
- r27 = 2;
- }
- } else {
- tmp_control = bcm43xx_get_lopair(phy, i - 9, j * 2);
- if (!tmp_control->used)
- continue;
- memcpy(&control, tmp_control, sizeof(control));
- r27 = 3;
- r31 = 0;
- }
- bcm43xx_radio_write16(bcm, 0x43, i - 9);
- bcm43xx_radio_write16(bcm, 0x52,
- radio->txctl2
- | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above?
- udelay(10);
- bcm43xx_voluntary_preempt();
-
- bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
-
- tmp = (regstack[10] & 0xFFF0);
- if (r31)
- tmp |= 0x0008;
- bcm43xx_radio_write16(bcm, 0x7A, tmp);
-
- tmp_control = bcm43xx_get_lopair(phy, i, j * 2);
- bcm43xx_phy_lo_g_state(bcm, &control, tmp_control, r27);
- }
- }
-
- /* Restoration */
- if (phy->connected) {
- bcm43xx_phy_write(bcm, 0x0015, 0xE300);
- bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA0);
- udelay(5);
- bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2);
- udelay(2);
- bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3);
- bcm43xx_voluntary_preempt();
- } else
- bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0);
- bcm43xx_phy_lo_adjust(bcm, is_initializing);
- bcm43xx_phy_write(bcm, 0x002E, 0x807F);
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x002F, 0x0202);
- else
- bcm43xx_phy_write(bcm, 0x002F, 0x0101);
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, regstack[4]);
- bcm43xx_phy_write(bcm, 0x0015, regstack[5]);
- bcm43xx_phy_write(bcm, 0x002A, regstack[6]);
- bcm43xx_phy_write(bcm, 0x0035, regstack[7]);
- bcm43xx_phy_write(bcm, 0x0060, regstack[8]);
- bcm43xx_radio_write16(bcm, 0x0043, regstack[9]);
- bcm43xx_radio_write16(bcm, 0x007A, regstack[10]);
- regstack[11] &= 0x00F0;
- regstack[11] |= (bcm43xx_radio_read16(bcm, 0x52) & 0x000F);
- bcm43xx_radio_write16(bcm, 0x52, regstack[11]);
- bcm43xx_write16(bcm, 0x03E2, regstack[3]);
- if (phy->connected) {
- bcm43xx_phy_write(bcm, 0x0811, regstack[12]);
- bcm43xx_phy_write(bcm, 0x0812, regstack[13]);
- bcm43xx_phy_write(bcm, 0x0814, regstack[14]);
- bcm43xx_phy_write(bcm, 0x0815, regstack[15]);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0]);
- bcm43xx_phy_write(bcm, 0x0802, regstack[1]);
- }
- bcm43xx_radio_selectchannel(bcm, oldchannel, 1);
-
-#ifdef CONFIG_BCM43XX_DEBUG
- {
- /* Sanity check for all lopairs. */
- for (i = 0; i < BCM43xx_LO_COUNT; i++) {
- tmp_control = phy->_lo_pairs + i;
- if (tmp_control->low < -8 || tmp_control->low > 8 ||
- tmp_control->high < -8 || tmp_control->high > 8) {
- printk(KERN_WARNING PFX
- "WARNING: Invalid LOpair (low: %d, high: %d, index: %d)\n",
- tmp_control->low, tmp_control->high, i);
- }
- }
- }
-#endif /* CONFIG_BCM43XX_DEBUG */
-}
-
-static
-void bcm43xx_phy_lo_mark_current_used(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_lopair *pair;
-
- pair = bcm43xx_current_lopair(bcm);
- pair->used = 1;
-}
-
-void bcm43xx_phy_lo_mark_all_unused(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_lopair *pair;
- int i;
-
- for (i = 0; i < BCM43xx_LO_COUNT; i++) {
- pair = phy->_lo_pairs + i;
- pair->used = 0;
- }
-}
-
-/* http://bcm-specs.sipsolutions.net/EstimatePowerOut
- * This function converts a TSSI value to dBm in Q5.2
- */
-static s8 bcm43xx_phy_estimate_power_out(struct bcm43xx_private *bcm, s8 tssi)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- s8 dbm = 0;
- s32 tmp;
-
- tmp = phy->idle_tssi;
- tmp += tssi;
- tmp -= phy->savedpctlreg;
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- tmp += 0x80;
- tmp = limit_value(tmp, 0x00, 0xFF);
- dbm = phy->tssi2dbm[tmp];
- TODO(); //TODO: There's a FIXME on the specs
- break;
- case BCM43xx_PHYTYPE_B:
- case BCM43xx_PHYTYPE_G:
- tmp = limit_value(tmp, 0x00, 0x3F);
- dbm = phy->tssi2dbm[tmp];
- break;
- default:
- assert(0);
- }
-
- return dbm;
-}
-
-/* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */
-void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-
- if (phy->savedpctlreg == 0xFFFF)
- return;
- if ((bcm->board_type == 0x0416) &&
- (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM))
- return;
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A: {
-
- TODO(); //TODO: Nothing for A PHYs yet :-/
-
- break;
- }
- case BCM43xx_PHYTYPE_B:
- case BCM43xx_PHYTYPE_G: {
- u16 tmp;
- u16 txpower;
- s8 v0, v1, v2, v3;
- s8 average;
- u8 max_pwr;
- s16 desired_pwr, estimated_pwr, pwr_adjust;
- s16 radio_att_delta, baseband_att_delta;
- s16 radio_attenuation, baseband_attenuation;
- unsigned long phylock_flags;
-
- tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0058);
- v0 = (s8)(tmp & 0x00FF);
- v1 = (s8)((tmp & 0xFF00) >> 8);
- tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x005A);
- v2 = (s8)(tmp & 0x00FF);
- v3 = (s8)((tmp & 0xFF00) >> 8);
- tmp = 0;
-
- if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F || v3 == 0x7F) {
- tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0070);
- v0 = (s8)(tmp & 0x00FF);
- v1 = (s8)((tmp & 0xFF00) >> 8);
- tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0072);
- v2 = (s8)(tmp & 0x00FF);
- v3 = (s8)((tmp & 0xFF00) >> 8);
- if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F || v3 == 0x7F)
- return;
- v0 = (v0 + 0x20) & 0x3F;
- v1 = (v1 + 0x20) & 0x3F;
- v2 = (v2 + 0x20) & 0x3F;
- v3 = (v3 + 0x20) & 0x3F;
- tmp = 1;
- }
- bcm43xx_radio_clear_tssi(bcm);
-
- average = (v0 + v1 + v2 + v3 + 2) / 4;
-
- if (tmp && (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x005E) & 0x8))
- average -= 13;
-
- estimated_pwr = bcm43xx_phy_estimate_power_out(bcm, average);
-
- max_pwr = bcm->sprom.maxpower_bgphy;
-
- if ((bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) &&
- (phy->type == BCM43xx_PHYTYPE_G))
- max_pwr -= 0x3;
-
- /*TODO:
- max_pwr = min(REG - bcm->sprom.antennagain_bgphy - 0x6, max_pwr)
- where REG is the max power as per the regulatory domain
- */
-
- desired_pwr = limit_value(radio->txpower_desired, 0, max_pwr);
- /* Check if we need to adjust the current power. */
- pwr_adjust = desired_pwr - estimated_pwr;
- radio_att_delta = -(pwr_adjust + 7) >> 3;
- baseband_att_delta = -(pwr_adjust >> 1) - (4 * radio_att_delta);
- if ((radio_att_delta == 0) && (baseband_att_delta == 0)) {
- bcm43xx_phy_lo_mark_current_used(bcm);
- return;
- }
-
- /* Calculate the new attenuation values. */
- baseband_attenuation = radio->baseband_atten;
- baseband_attenuation += baseband_att_delta;
- radio_attenuation = radio->radio_atten;
- radio_attenuation += radio_att_delta;
-
- /* Get baseband and radio attenuation values into their permitted ranges.
- * baseband 0-11, radio 0-9.
- * Radio attenuation affects power level 4 times as much as baseband.
- */
- if (radio_attenuation < 0) {
- baseband_attenuation -= (4 * -radio_attenuation);
- radio_attenuation = 0;
- } else if (radio_attenuation > 9) {
- baseband_attenuation += (4 * (radio_attenuation - 9));
- radio_attenuation = 9;
- } else {
- while (baseband_attenuation < 0 && radio_attenuation > 0) {
- baseband_attenuation += 4;
- radio_attenuation--;
- }
- while (baseband_attenuation > 11 && radio_attenuation < 9) {
- baseband_attenuation -= 4;
- radio_attenuation++;
- }
- }
- baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
-
- txpower = radio->txctl1;
- if ((radio->version == 0x2050) && (radio->revision == 2)) {
- if (radio_attenuation <= 1) {
- if (txpower == 0) {
- txpower = 3;
- radio_attenuation += 2;
- baseband_attenuation += 2;
- } else if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) {
- baseband_attenuation += 4 * (radio_attenuation - 2);
- radio_attenuation = 2;
- }
- } else if (radio_attenuation > 4 && txpower != 0) {
- txpower = 0;
- if (baseband_attenuation < 3) {
- radio_attenuation -= 3;
- baseband_attenuation += 2;
- } else {
- radio_attenuation -= 2;
- baseband_attenuation -= 2;
- }
- }
- }
- radio->txctl1 = txpower;
- baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
- radio_attenuation = limit_value(radio_attenuation, 0, 9);
-
- bcm43xx_phy_lock(bcm, phylock_flags);
- bcm43xx_radio_lock(bcm);
- bcm43xx_radio_set_txpower_bg(bcm, baseband_attenuation,
- radio_attenuation, txpower);
- bcm43xx_phy_lo_mark_current_used(bcm);
- bcm43xx_radio_unlock(bcm);
- bcm43xx_phy_unlock(bcm, phylock_flags);
- break;
- }
- default:
- assert(0);
- }
-}
-
-static inline
-s32 bcm43xx_tssi2dbm_ad(s32 num, s32 den)
-{
- if (num < 0)
- return num/den;
- else
- return (num+den/2)/den;
-}
-
-static inline
-s8 bcm43xx_tssi2dbm_entry(s8 entry [], u8 index, s16 pab0, s16 pab1, s16 pab2)
-{
- s32 m1, m2, f = 256, q, delta;
- s8 i = 0;
-
- m1 = bcm43xx_tssi2dbm_ad(16 * pab0 + index * pab1, 32);
- m2 = max(bcm43xx_tssi2dbm_ad(32768 + index * pab2, 256), 1);
- do {
- if (i > 15)
- return -EINVAL;
- q = bcm43xx_tssi2dbm_ad(f * 4096 -
- bcm43xx_tssi2dbm_ad(m2 * f, 16) * f, 2048);
- delta = abs(q - f);
- f = q;
- i++;
- } while (delta >= 2);
- entry[index] = limit_value(bcm43xx_tssi2dbm_ad(m1 * f, 8192), -127, 128);
- return 0;
-}
-
-/* http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table */
-int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- s16 pab0, pab1, pab2;
- u8 idx;
- s8 *dyn_tssi2dbm;
-
- if (phy->type == BCM43xx_PHYTYPE_A) {
- pab0 = (s16)(bcm->sprom.pa1b0);
- pab1 = (s16)(bcm->sprom.pa1b1);
- pab2 = (s16)(bcm->sprom.pa1b2);
- } else {
- pab0 = (s16)(bcm->sprom.pa0b0);
- pab1 = (s16)(bcm->sprom.pa0b1);
- pab2 = (s16)(bcm->sprom.pa0b2);
- }
-
- if ((bcm->chip_id == 0x4301) && (radio->version != 0x2050)) {
- phy->idle_tssi = 0x34;
- phy->tssi2dbm = bcm43xx_tssi2dbm_b_table;
- return 0;
- }
-
- if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
- pab0 != -1 && pab1 != -1 && pab2 != -1) {
- /* The pabX values are set in SPROM. Use them. */
- if (phy->type == BCM43xx_PHYTYPE_A) {
- if ((s8)bcm->sprom.idle_tssi_tgt_aphy != 0 &&
- (s8)bcm->sprom.idle_tssi_tgt_aphy != -1)
- phy->idle_tssi = (s8)(bcm->sprom.idle_tssi_tgt_aphy);
- else
- phy->idle_tssi = 62;
- } else {
- if ((s8)bcm->sprom.idle_tssi_tgt_bgphy != 0 &&
- (s8)bcm->sprom.idle_tssi_tgt_bgphy != -1)
- phy->idle_tssi = (s8)(bcm->sprom.idle_tssi_tgt_bgphy);
- else
- phy->idle_tssi = 62;
- }
- dyn_tssi2dbm = kmalloc(64, GFP_KERNEL);
- if (dyn_tssi2dbm == NULL) {
- printk(KERN_ERR PFX "Could not allocate memory "
- "for tssi2dbm table\n");
- return -ENOMEM;
- }
- for (idx = 0; idx < 64; idx++)
- if (bcm43xx_tssi2dbm_entry(dyn_tssi2dbm, idx, pab0, pab1, pab2)) {
- phy->tssi2dbm = NULL;
- printk(KERN_ERR PFX "Could not generate "
- "tssi2dBm table\n");
- kfree(dyn_tssi2dbm);
- return -ENODEV;
- }
- phy->tssi2dbm = dyn_tssi2dbm;
- phy->dyn_tssi_tbl = 1;
- } else {
- /* pabX values not set in SPROM. */
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- /* APHY needs a generated table. */
- phy->tssi2dbm = NULL;
- printk(KERN_ERR PFX "Could not generate tssi2dBm "
- "table (wrong SPROM info)!\n");
- return -ENODEV;
- case BCM43xx_PHYTYPE_B:
- phy->idle_tssi = 0x34;
- phy->tssi2dbm = bcm43xx_tssi2dbm_b_table;
- break;
- case BCM43xx_PHYTYPE_G:
- phy->idle_tssi = 0x34;
- phy->tssi2dbm = bcm43xx_tssi2dbm_g_table;
- break;
- }
- }
-
- return 0;
-}
-
-int bcm43xx_phy_init(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- int err = -ENODEV;
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- if (phy->rev == 2 || phy->rev == 3) {
- bcm43xx_phy_inita(bcm);
- err = 0;
- }
- break;
- case BCM43xx_PHYTYPE_B:
- switch (phy->rev) {
- case 2:
- bcm43xx_phy_initb2(bcm);
- err = 0;
- break;
- case 4:
- bcm43xx_phy_initb4(bcm);
- err = 0;
- break;
- case 5:
- bcm43xx_phy_initb5(bcm);
- err = 0;
- break;
- case 6:
- bcm43xx_phy_initb6(bcm);
- err = 0;
- break;
- }
- break;
- case BCM43xx_PHYTYPE_G:
- bcm43xx_phy_initg(bcm);
- err = 0;
- break;
- }
- if (err)
- printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n");
-
- return err;
-}
-
-void bcm43xx_phy_set_antenna_diversity(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 antennadiv;
- u16 offset;
- u16 value;
- u32 ucodeflags;
-
- antennadiv = phy->antenna_diversity;
-
- if (antennadiv == 0xFFFF)
- antennadiv = 3;
- assert(antennadiv <= 3);
-
- ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET);
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET,
- ucodeflags & ~BCM43xx_UCODEFLAG_AUTODIV);
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- case BCM43xx_PHYTYPE_G:
- if (phy->type == BCM43xx_PHYTYPE_A)
- offset = 0x0000;
- else
- offset = 0x0400;
-
- if (antennadiv == 2)
- value = (3/*automatic*/ << 7);
- else
- value = (antennadiv << 7);
- bcm43xx_phy_write(bcm, offset + 1,
- (bcm43xx_phy_read(bcm, offset + 1)
- & 0x7E7F) | value);
-
- if (antennadiv >= 2) {
- if (antennadiv == 2)
- value = (antennadiv << 7);
- else
- value = (0/*force0*/ << 7);
- bcm43xx_phy_write(bcm, offset + 0x2B,
- (bcm43xx_phy_read(bcm, offset + 0x2B)
- & 0xFEFF) | value);
- }
-
- if (phy->type == BCM43xx_PHYTYPE_G) {
- if (antennadiv >= 2)
- bcm43xx_phy_write(bcm, 0x048C,
- bcm43xx_phy_read(bcm, 0x048C)
- | 0x2000);
- else
- bcm43xx_phy_write(bcm, 0x048C,
- bcm43xx_phy_read(bcm, 0x048C)
- & ~0x2000);
- if (phy->rev >= 2) {
- bcm43xx_phy_write(bcm, 0x0461,
- bcm43xx_phy_read(bcm, 0x0461)
- | 0x0010);
- bcm43xx_phy_write(bcm, 0x04AD,
- (bcm43xx_phy_read(bcm, 0x04AD)
- & 0x00FF) | 0x0015);
- if (phy->rev == 2)
- bcm43xx_phy_write(bcm, 0x0427, 0x0008);
- else
- bcm43xx_phy_write(bcm, 0x0427,
- (bcm43xx_phy_read(bcm, 0x0427)
- & 0x00FF) | 0x0008);
- }
- else if (phy->rev >= 6)
- bcm43xx_phy_write(bcm, 0x049B, 0x00DC);
- } else {
- if (phy->rev < 3)
- bcm43xx_phy_write(bcm, 0x002B,
- (bcm43xx_phy_read(bcm, 0x002B)
- & 0x00FF) | 0x0024);
- else {
- bcm43xx_phy_write(bcm, 0x0061,
- bcm43xx_phy_read(bcm, 0x0061)
- | 0x0010);
- if (phy->rev == 3) {
- bcm43xx_phy_write(bcm, 0x0093, 0x001D);
- bcm43xx_phy_write(bcm, 0x0027, 0x0008);
- } else {
- bcm43xx_phy_write(bcm, 0x0093, 0x003A);
- bcm43xx_phy_write(bcm, 0x0027,
- (bcm43xx_phy_read(bcm, 0x0027)
- & 0x00FF) | 0x0008);
- }
- }
- }
- break;
- case BCM43xx_PHYTYPE_B:
- if (bcm->current_core->rev == 2)
- value = (3/*automatic*/ << 7);
- else
- value = (antennadiv << 7);
- bcm43xx_phy_write(bcm, 0x03E2,
- (bcm43xx_phy_read(bcm, 0x03E2)
- & 0xFE7F) | value);
- break;
- default:
- assert(0);
- }
-
- if (antennadiv >= 2) {
- ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET);
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET,
- ucodeflags | BCM43xx_UCODEFLAG_AUTODIV);
- }
-
- phy->antenna_diversity = antennadiv;
-}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.h b/drivers/net/wireless/bcm43xx/bcm43xx_phy.h
deleted file mode 100644
index 73118364b552..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-
- 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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
deleted file mode 100644
index 76ab109cd2db..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
-
- Broadcom BCM43xx wireless driver
-
- PIO Transmission
-
- 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 "bcm43xx.h"
-#include "bcm43xx_pio.h"
-#include "bcm43xx_main.h"
-#include "bcm43xx_xmit.h"
-#include "bcm43xx_power.h"
-
-#include <linux/delay.h>
-
-
-static void tx_start(struct bcm43xx_pioqueue *queue)
-{
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
- BCM43xx_PIO_TXCTL_INIT);
-}
-
-static void tx_octet(struct bcm43xx_pioqueue *queue,
- u8 octet)
-{
- if (queue->need_workarounds) {
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
- octet);
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
- BCM43xx_PIO_TXCTL_WRITELO);
- } else {
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
- BCM43xx_PIO_TXCTL_WRITELO);
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
- octet);
- }
-}
-
-static u16 tx_get_next_word(struct bcm43xx_txhdr *txhdr,
- const u8 *packet,
- unsigned int *pos)
-{
- const u8 *source;
- unsigned int i = *pos;
- u16 ret;
-
- if (i < sizeof(*txhdr)) {
- source = (const u8 *)txhdr;
- } else {
- source = packet;
- i -= sizeof(*txhdr);
- }
- ret = le16_to_cpu( *((__le16 *)(source + i)) );
- *pos += 2;
-
- return ret;
-}
-
-static void tx_data(struct bcm43xx_pioqueue *queue,
- struct bcm43xx_txhdr *txhdr,
- const u8 *packet,
- unsigned int octets)
-{
- u16 data;
- unsigned int i = 0;
-
- if (queue->need_workarounds) {
- data = tx_get_next_word(txhdr, packet, &i);
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, data);
- }
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
- BCM43xx_PIO_TXCTL_WRITELO |
- BCM43xx_PIO_TXCTL_WRITEHI);
- while (i < octets - 1) {
- data = tx_get_next_word(txhdr, packet, &i);
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, data);
- }
- if (octets % 2)
- tx_octet(queue, packet[octets - sizeof(*txhdr) - 1]);
-}
-
-static void tx_complete(struct bcm43xx_pioqueue *queue,
- struct sk_buff *skb)
-{
- if (queue->need_workarounds) {
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
- skb->data[skb->len - 1]);
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
- BCM43xx_PIO_TXCTL_WRITELO |
- BCM43xx_PIO_TXCTL_COMPLETE);
- } else {
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
- BCM43xx_PIO_TXCTL_COMPLETE);
- }
-}
-
-static u16 generate_cookie(struct bcm43xx_pioqueue *queue,
- struct bcm43xx_pio_txpacket *packet)
-{
- u16 cookie = 0x0000;
- int packetindex;
-
- /* We use the upper 4 bits for the PIO
- * controller ID and the lower 12 bits
- * for the packet index (in the cache).
- */
- switch (queue->mmio_base) {
- case BCM43xx_MMIO_PIO1_BASE:
- break;
- case BCM43xx_MMIO_PIO2_BASE:
- cookie = 0x1000;
- break;
- case BCM43xx_MMIO_PIO3_BASE:
- cookie = 0x2000;
- break;
- case BCM43xx_MMIO_PIO4_BASE:
- cookie = 0x3000;
- break;
- default:
- assert(0);
- }
- packetindex = pio_txpacket_getindex(packet);
- assert(((u16)packetindex & 0xF000) == 0x0000);
- cookie |= (u16)packetindex;
-
- return cookie;
-}
-
-static
-struct bcm43xx_pioqueue * parse_cookie(struct bcm43xx_private *bcm,
- u16 cookie,
- struct bcm43xx_pio_txpacket **packet)
-{
- struct bcm43xx_pio *pio = bcm43xx_current_pio(bcm);
- struct bcm43xx_pioqueue *queue = NULL;
- int packetindex;
-
- switch (cookie & 0xF000) {
- case 0x0000:
- queue = pio->queue0;
- break;
- case 0x1000:
- queue = pio->queue1;
- break;
- case 0x2000:
- queue = pio->queue2;
- break;
- case 0x3000:
- queue = pio->queue3;
- break;
- default:
- assert(0);
- }
- packetindex = (cookie & 0x0FFF);
- assert(packetindex >= 0 && packetindex < BCM43xx_PIO_MAXTXPACKETS);
- *packet = &(queue->tx_packets_cache[packetindex]);
-
- return queue;
-}
-
-static void pio_tx_write_fragment(struct bcm43xx_pioqueue *queue,
- struct sk_buff *skb,
- struct bcm43xx_pio_txpacket *packet)
-{
- struct bcm43xx_txhdr txhdr;
- unsigned int octets;
-
- assert(skb_shinfo(skb)->nr_frags == 0);
- bcm43xx_generate_txhdr(queue->bcm,
- &txhdr, skb->data, skb->len,
- (packet->xmitted_frags == 0),
- generate_cookie(queue, packet));
-
- tx_start(queue);
- octets = skb->len + sizeof(txhdr);
- if (queue->need_workarounds)
- octets--;
- tx_data(queue, &txhdr, (u8 *)skb->data, octets);
- tx_complete(queue, skb);
-}
-
-static void free_txpacket(struct bcm43xx_pio_txpacket *packet,
- int irq_context)
-{
- struct bcm43xx_pioqueue *queue = packet->queue;
-
- ieee80211_txb_free(packet->txb);
- list_move(&packet->list, &queue->txfree);
- queue->nr_txfree++;
-
- assert(queue->tx_devq_used >= packet->xmitted_octets);
- assert(queue->tx_devq_packets >= packet->xmitted_frags);
- queue->tx_devq_used -= packet->xmitted_octets;
- queue->tx_devq_packets -= packet->xmitted_frags;
-}
-
-static int pio_tx_packet(struct bcm43xx_pio_txpacket *packet)
-{
- struct bcm43xx_pioqueue *queue = packet->queue;
- struct ieee80211_txb *txb = packet->txb;
- struct sk_buff *skb;
- u16 octets;
- int i;
-
- for (i = packet->xmitted_frags; i < txb->nr_frags; i++) {
- skb = txb->fragments[i];
-
- octets = (u16)skb->len + sizeof(struct bcm43xx_txhdr);
- assert(queue->tx_devq_size >= octets);
- assert(queue->tx_devq_packets <= BCM43xx_PIO_MAXTXDEVQPACKETS);
- assert(queue->tx_devq_used <= queue->tx_devq_size);
- /* Check if there is sufficient free space on the device
- * TX queue. If not, return and let the TX tasklet
- * retry later.
- */
- if (queue->tx_devq_packets == BCM43xx_PIO_MAXTXDEVQPACKETS)
- return -EBUSY;
- if (queue->tx_devq_used + octets > queue->tx_devq_size)
- return -EBUSY;
- /* Now poke the device. */
- pio_tx_write_fragment(queue, skb, packet);
-
- /* Account for the packet size.
- * (We must not overflow the device TX queue)
- */
- queue->tx_devq_packets++;
- queue->tx_devq_used += octets;
-
- assert(packet->xmitted_frags < packet->txb->nr_frags);
- packet->xmitted_frags++;
- packet->xmitted_octets += octets;
- }
- list_move_tail(&packet->list, &queue->txrunning);
-
- return 0;
-}
-
-static void tx_tasklet(unsigned long d)
-{
- struct bcm43xx_pioqueue *queue = (struct bcm43xx_pioqueue *)d;
- struct bcm43xx_private *bcm = queue->bcm;
- unsigned long flags;
- struct bcm43xx_pio_txpacket *packet, *tmp_packet;
- int err;
- u16 txctl;
-
- spin_lock_irqsave(&bcm->irq_lock, flags);
-
- if (queue->tx_frozen)
- goto out_unlock;
- txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL);
- if (txctl & BCM43xx_PIO_TXCTL_SUSPEND)
- goto out_unlock;
-
- list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) {
- assert(packet->xmitted_frags < packet->txb->nr_frags);
- if (packet->xmitted_frags == 0) {
- int i;
- struct sk_buff *skb;
-
- /* Check if the device queue is big
- * enough for every fragment. If not, drop the
- * whole packet.
- */
- for (i = 0; i < packet->txb->nr_frags; i++) {
- skb = packet->txb->fragments[i];
- if (unlikely(skb->len > queue->tx_devq_size)) {
- dprintkl(KERN_ERR PFX "PIO TX device queue too small. "
- "Dropping packet.\n");
- free_txpacket(packet, 1);
- goto next_packet;
- }
- }
- }
- /* Try to transmit the packet.
- * This may not completely succeed.
- */
- err = pio_tx_packet(packet);
- if (err)
- break;
- next_packet:
- continue;
- }
-out_unlock:
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
-}
-
-static void setup_txqueues(struct bcm43xx_pioqueue *queue)
-{
- struct bcm43xx_pio_txpacket *packet;
- int i;
-
- queue->nr_txfree = BCM43xx_PIO_MAXTXPACKETS;
- for (i = 0; i < BCM43xx_PIO_MAXTXPACKETS; i++) {
- packet = &(queue->tx_packets_cache[i]);
-
- packet->queue = queue;
- INIT_LIST_HEAD(&packet->list);
-
- list_add(&packet->list, &queue->txfree);
- }
-}
-
-static
-struct bcm43xx_pioqueue * bcm43xx_setup_pioqueue(struct bcm43xx_private *bcm,
- u16 pio_mmio_base)
-{
- struct bcm43xx_pioqueue *queue;
- u32 value;
- u16 qsize;
-
- queue = kzalloc(sizeof(*queue), GFP_KERNEL);
- if (!queue)
- goto out;
-
- queue->bcm = bcm;
- queue->mmio_base = pio_mmio_base;
- queue->need_workarounds = (bcm->current_core->rev < 3);
-
- INIT_LIST_HEAD(&queue->txfree);
- INIT_LIST_HEAD(&queue->txqueue);
- INIT_LIST_HEAD(&queue->txrunning);
- tasklet_init(&queue->txtask, tx_tasklet,
- (unsigned long)queue);
-
- value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- value &= ~BCM43xx_SBF_XFER_REG_BYTESWAP;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value);
-
- qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE);
- if (qsize == 0) {
- printk(KERN_ERR PFX "ERROR: This card does not support PIO "
- "operation mode. Please use DMA mode "
- "(module parameter pio=0).\n");
- goto err_freequeue;
- }
- if (qsize <= BCM43xx_PIO_TXQADJUST) {
- printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n",
- qsize);
- goto err_freequeue;
- }
- qsize -= BCM43xx_PIO_TXQADJUST;
- queue->tx_devq_size = qsize;
-
- setup_txqueues(queue);
-
-out:
- return queue;
-
-err_freequeue:
- kfree(queue);
- queue = NULL;
- goto out;
-}
-
-static void cancel_transfers(struct bcm43xx_pioqueue *queue)
-{
- struct bcm43xx_pio_txpacket *packet, *tmp_packet;
-
- netif_tx_disable(queue->bcm->net_dev);
- tasklet_disable(&queue->txtask);
-
- list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list)
- free_txpacket(packet, 0);
- list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list)
- free_txpacket(packet, 0);
-}
-
-static void bcm43xx_destroy_pioqueue(struct bcm43xx_pioqueue *queue)
-{
- if (!queue)
- return;
-
- cancel_transfers(queue);
- kfree(queue);
-}
-
-void bcm43xx_pio_free(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_pio *pio;
-
- if (!bcm43xx_using_pio(bcm))
- return;
- pio = bcm43xx_current_pio(bcm);
-
- bcm43xx_destroy_pioqueue(pio->queue3);
- pio->queue3 = NULL;
- bcm43xx_destroy_pioqueue(pio->queue2);
- pio->queue2 = NULL;
- bcm43xx_destroy_pioqueue(pio->queue1);
- pio->queue1 = NULL;
- bcm43xx_destroy_pioqueue(pio->queue0);
- pio->queue0 = NULL;
-}
-
-int bcm43xx_pio_init(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_pio *pio = bcm43xx_current_pio(bcm);
- struct bcm43xx_pioqueue *queue;
- int err = -ENOMEM;
-
- queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO1_BASE);
- if (!queue)
- goto out;
- pio->queue0 = queue;
-
- queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO2_BASE);
- if (!queue)
- goto err_destroy0;
- pio->queue1 = queue;
-
- queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO3_BASE);
- if (!queue)
- goto err_destroy1;
- pio->queue2 = queue;
-
- queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO4_BASE);
- if (!queue)
- goto err_destroy2;
- pio->queue3 = queue;
-
- if (bcm->current_core->rev < 3)
- bcm->irq_savedstate |= BCM43xx_IRQ_PIO_WORKAROUND;
-
- dprintk(KERN_INFO PFX "PIO initialized\n");
- err = 0;
-out:
- return err;
-
-err_destroy2:
- bcm43xx_destroy_pioqueue(pio->queue2);
- pio->queue2 = NULL;
-err_destroy1:
- bcm43xx_destroy_pioqueue(pio->queue1);
- pio->queue1 = NULL;
-err_destroy0:
- bcm43xx_destroy_pioqueue(pio->queue0);
- pio->queue0 = NULL;
- goto out;
-}
-
-int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
- struct ieee80211_txb *txb)
-{
- struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1;
- struct bcm43xx_pio_txpacket *packet;
-
- assert(!queue->tx_suspended);
- assert(!list_empty(&queue->txfree));
-
- packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list);
- packet->txb = txb;
- packet->xmitted_frags = 0;
- packet->xmitted_octets = 0;
- list_move_tail(&packet->list, &queue->txqueue);
- queue->nr_txfree--;
- assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS);
-
- /* Suspend TX, if we are out of packets in the "free" queue. */
- if (list_empty(&queue->txfree)) {
- netif_stop_queue(queue->bcm->net_dev);
- queue->tx_suspended = 1;
- }
-
- tasklet_schedule(&queue->txtask);
-
- return 0;
-}
-
-void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
- struct bcm43xx_xmitstatus *status)
-{
- struct bcm43xx_pioqueue *queue;
- struct bcm43xx_pio_txpacket *packet;
-
- queue = parse_cookie(bcm, status->cookie, &packet);
- assert(queue);
-
- free_txpacket(packet, 1);
- if (queue->tx_suspended) {
- queue->tx_suspended = 0;
- netif_wake_queue(queue->bcm->net_dev);
- }
- /* If there are packets on the txqueue, poke the tasklet
- * to transmit them.
- */
- if (!list_empty(&queue->txqueue))
- tasklet_schedule(&queue->txtask);
-}
-
-static void pio_rx_error(struct bcm43xx_pioqueue *queue,
- int clear_buffers,
- const char *error)
-{
- int i;
-
- printkl("PIO RX error: %s\n", error);
- bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL,
- BCM43xx_PIO_RXCTL_READY);
- if (clear_buffers) {
- assert(queue->mmio_base == BCM43xx_MMIO_PIO1_BASE);
- for (i = 0; i < 15; i++) {
- /* Dummy read. */
- bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
- }
- }
-}
-
-void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue)
-{
- __le16 preamble[21] = { 0 };
- struct bcm43xx_rxhdr *rxhdr;
- u16 tmp, len, rxflags2;
- int i, preamble_readwords;
- struct sk_buff *skb;
-
- tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL);
- if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE))
- return;
- bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL,
- BCM43xx_PIO_RXCTL_DATAAVAILABLE);
-
- for (i = 0; i < 10; i++) {
- tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL);
- if (tmp & BCM43xx_PIO_RXCTL_READY)
- goto data_ready;
- udelay(10);
- }
- dprintkl(KERN_ERR PFX "PIO RX timed out\n");
- return;
-data_ready:
-
- len = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
- if (unlikely(len > 0x700)) {
- pio_rx_error(queue, 0, "len > 0x700");
- return;
- }
- if (unlikely(len == 0 && queue->mmio_base != BCM43xx_MMIO_PIO4_BASE)) {
- pio_rx_error(queue, 0, "len == 0");
- return;
- }
- preamble[0] = cpu_to_le16(len);
- if (queue->mmio_base == BCM43xx_MMIO_PIO4_BASE)
- preamble_readwords = 14 / sizeof(u16);
- else
- preamble_readwords = 18 / sizeof(u16);
- for (i = 0; i < preamble_readwords; i++) {
- tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
- preamble[i + 1] = cpu_to_le16(tmp);
- }
- rxhdr = (struct bcm43xx_rxhdr *)preamble;
- rxflags2 = le16_to_cpu(rxhdr->flags2);
- if (unlikely(rxflags2 & BCM43xx_RXHDR_FLAGS2_INVALIDFRAME)) {
- pio_rx_error(queue,
- (queue->mmio_base == BCM43xx_MMIO_PIO1_BASE),
- "invalid frame");
- return;
- }
- if (queue->mmio_base == BCM43xx_MMIO_PIO4_BASE) {
- /* We received an xmit status. */
- struct bcm43xx_hwxmitstatus *hw;
- struct bcm43xx_xmitstatus stat;
-
- hw = (struct bcm43xx_hwxmitstatus *)(preamble + 1);
- stat.cookie = le16_to_cpu(hw->cookie);
- stat.flags = hw->flags;
- stat.cnt1 = hw->cnt1;
- stat.cnt2 = hw->cnt2;
- stat.seq = le16_to_cpu(hw->seq);
- stat.unknown = le16_to_cpu(hw->unknown);
-
- bcm43xx_debugfs_log_txstat(queue->bcm, &stat);
- bcm43xx_pio_handle_xmitstatus(queue->bcm, &stat);
-
- return;
- }
-
- skb = dev_alloc_skb(len);
- if (unlikely(!skb)) {
- pio_rx_error(queue, 1, "OOM");
- return;
- }
- skb_put(skb, len);
- for (i = 0; i < len - 1; i += 2) {
- tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
- *((__le16 *)(skb->data + i)) = cpu_to_le16(tmp);
- }
- if (len % 2) {
- tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
- skb->data[len - 1] = (tmp & 0x00FF);
-/* The specs say the following is required, but
- * it is wrong and corrupts the PLCP. If we don't do
- * this, the PLCP seems to be correct. So ifdef it out for now.
- */
-#if 0
- if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME)
- skb->data[2] = (tmp & 0xFF00) >> 8;
- else
- skb->data[0] = (tmp & 0xFF00) >> 8;
-#endif
- }
- skb_trim(skb, len - IEEE80211_FCS_LEN);
- bcm43xx_rx(queue->bcm, skb, rxhdr);
-}
-
-void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue)
-{
- bcm43xx_power_saving_ctl_bits(queue->bcm, -1, 1);
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
- bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL)
- | BCM43xx_PIO_TXCTL_SUSPEND);
-}
-
-void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue)
-{
- bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
- bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL)
- & ~BCM43xx_PIO_TXCTL_SUSPEND);
- bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1);
- if (!list_empty(&queue->txqueue))
- tasklet_schedule(&queue->txtask);
-}
-
-void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_pio *pio;
-
- assert(bcm43xx_using_pio(bcm));
- pio = bcm43xx_current_pio(bcm);
- pio->queue0->tx_frozen = 1;
- pio->queue1->tx_frozen = 1;
- pio->queue2->tx_frozen = 1;
- pio->queue3->tx_frozen = 1;
-}
-
-void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_pio *pio;
-
- assert(bcm43xx_using_pio(bcm));
- pio = bcm43xx_current_pio(bcm);
- pio->queue0->tx_frozen = 0;
- pio->queue1->tx_frozen = 0;
- pio->queue2->tx_frozen = 0;
- pio->queue3->tx_frozen = 0;
- if (!list_empty(&pio->queue0->txqueue))
- tasklet_schedule(&pio->queue0->txtask);
- if (!list_empty(&pio->queue1->txqueue))
- tasklet_schedule(&pio->queue1->txtask);
- if (!list_empty(&pio->queue2->txqueue))
- tasklet_schedule(&pio->queue2->txtask);
- if (!list_empty(&pio->queue3->txqueue))
- tasklet_schedule(&pio->queue3->txtask);
-}
-
-
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h
deleted file mode 100644
index bc78a3c2cafb..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h
+++ /dev/null
@@ -1,163 +0,0 @@
-#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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.c b/drivers/net/wireless/bcm43xx/bcm43xx_power.c
deleted file mode 100644
index 7e774f410953..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_power.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
-
- 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.
-
-*/
-
-#include <linux/delay.h>
-
-#include "bcm43xx.h"
-#include "bcm43xx_power.h"
-#include "bcm43xx_main.h"
-
-
-/* Get the Slow Clock Source */
-static int bcm43xx_pctl_get_slowclksrc(struct bcm43xx_private *bcm)
-{
- u32 tmp;
- int err;
-
- assert(bcm->current_core == &bcm->core_chipcommon);
- if (bcm->current_core->rev < 6) {
- if (bcm->bustype == BCM43xx_BUSTYPE_PCMCIA ||
- bcm->bustype == BCM43xx_BUSTYPE_SB)
- return BCM43xx_PCTL_CLKSRC_XTALOS;
- if (bcm->bustype == BCM43xx_BUSTYPE_PCI) {
- err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp);
- assert(!err);
- if (tmp & 0x10)
- return BCM43xx_PCTL_CLKSRC_PCI;
- return BCM43xx_PCTL_CLKSRC_XTALOS;
- }
- }
- if (bcm->current_core->rev < 10) {
- tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
- tmp &= 0x7;
- if (tmp == 0)
- return BCM43xx_PCTL_CLKSRC_LOPWROS;
- if (tmp == 1)
- return BCM43xx_PCTL_CLKSRC_XTALOS;
- if (tmp == 2)
- return BCM43xx_PCTL_CLKSRC_PCI;
- }
-
- return BCM43xx_PCTL_CLKSRC_XTALOS;
-}
-
-/* Get max/min slowclock frequency
- * as described in http://bcm-specs.sipsolutions.net/PowerControl
- */
-static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm,
- int get_max)
-{
- int limit;
- int clocksrc;
- int divisor;
- u32 tmp;
-
- assert(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL);
- assert(bcm->current_core == &bcm->core_chipcommon);
-
- clocksrc = bcm43xx_pctl_get_slowclksrc(bcm);
- if (bcm->current_core->rev < 6) {
- switch (clocksrc) {
- case BCM43xx_PCTL_CLKSRC_PCI:
- divisor = 64;
- break;
- case BCM43xx_PCTL_CLKSRC_XTALOS:
- divisor = 32;
- break;
- default:
- assert(0);
- divisor = 1;
- }
- } else if (bcm->current_core->rev < 10) {
- switch (clocksrc) {
- case BCM43xx_PCTL_CLKSRC_LOPWROS:
- divisor = 1;
- break;
- case BCM43xx_PCTL_CLKSRC_XTALOS:
- case BCM43xx_PCTL_CLKSRC_PCI:
- tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
- divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
- divisor *= 4;
- break;
- default:
- assert(0);
- divisor = 1;
- }
- } else {
- tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL);
- divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
- divisor *= 4;
- }
-
- switch (clocksrc) {
- case BCM43xx_PCTL_CLKSRC_LOPWROS:
- if (get_max)
- limit = 43000;
- else
- limit = 25000;
- break;
- case BCM43xx_PCTL_CLKSRC_XTALOS:
- if (get_max)
- limit = 20200000;
- else
- limit = 19800000;
- break;
- case BCM43xx_PCTL_CLKSRC_PCI:
- if (get_max)
- limit = 34000000;
- else
- limit = 25000000;
- break;
- default:
- assert(0);
- limit = 0;
- }
- limit /= divisor;
-
- return limit;
-}
-
-
-/* init power control
- * as described in http://bcm-specs.sipsolutions.net/PowerControl
- */
-int bcm43xx_pctl_init(struct bcm43xx_private *bcm)
-{
- int err, maxfreq;
- struct bcm43xx_coreinfo *old_core;
-
- old_core = bcm->current_core;
- err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
- if (err == -ENODEV)
- return 0;
- if (err)
- goto out;
-
- if (bcm->chip_id == 0x4321) {
- if (bcm->chip_rev == 0)
- bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x03A4);
- if (bcm->chip_rev == 1)
- bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x00A4);
- }
-
- if (bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) {
- if (bcm->current_core->rev >= 10) {
- /* Set Idle Power clock rate to 1Mhz */
- bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL,
- (bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL)
- & 0x0000FFFF) | 0x40000);
- } else {
- maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1);
- bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY,
- (maxfreq * 150 + 999999) / 1000000);
- bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY,
- (maxfreq * 15 + 999999) / 1000000);
- }
- }
-
- err = bcm43xx_switch_core(bcm, old_core);
- assert(err == 0);
-
-out:
- return err;
-}
-
-u16 bcm43xx_pctl_powerup_delay(struct bcm43xx_private *bcm)
-{
- u16 delay = 0;
- int err;
- u32 pll_on_delay;
- struct bcm43xx_coreinfo *old_core;
- int minfreq;
-
- if (bcm->bustype != BCM43xx_BUSTYPE_PCI)
- goto out;
- if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
- goto out;
- old_core = bcm->current_core;
- err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
- if (err == -ENODEV)
- goto out;
-
- minfreq = bcm43xx_pctl_clockfreqlimit(bcm, 0);
- pll_on_delay = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY);
- delay = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq;
-
- err = bcm43xx_switch_core(bcm, old_core);
- assert(err == 0);
-
-out:
- return delay;
-}
-
-/* set the powercontrol clock
- * as described in http://bcm-specs.sipsolutions.net/PowerControl
- */
-int bcm43xx_pctl_set_clock(struct bcm43xx_private *bcm, u16 mode)
-{
- int err;
- struct bcm43xx_coreinfo *old_core;
- u32 tmp;
-
- old_core = bcm->current_core;
- err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
- if (err == -ENODEV)
- return 0;
- if (err)
- goto out;
-
- if (bcm->core_chipcommon.rev < 6) {
- if (mode == BCM43xx_PCTL_CLK_FAST) {
- err = bcm43xx_pctl_set_crystal(bcm, 1);
- if (err)
- goto out;
- }
- } else {
- if ((bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) &&
- (bcm->core_chipcommon.rev < 10)) {
- switch (mode) {
- case BCM43xx_PCTL_CLK_FAST:
- tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
- tmp = (tmp & ~BCM43xx_PCTL_FORCE_SLOW) | BCM43xx_PCTL_FORCE_PLL;
- bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp);
- break;
- case BCM43xx_PCTL_CLK_SLOW:
- tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
- tmp |= BCM43xx_PCTL_FORCE_SLOW;
- bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp);
- break;
- case BCM43xx_PCTL_CLK_DYNAMIC:
- tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
- tmp &= ~BCM43xx_PCTL_FORCE_SLOW;
- tmp |= BCM43xx_PCTL_FORCE_PLL;
- tmp &= ~BCM43xx_PCTL_DYN_XTAL;
- bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp);
- }
- }
- }
-
- err = bcm43xx_switch_core(bcm, old_core);
- assert(err == 0);
-
-out:
- return err;
-}
-
-int bcm43xx_pctl_set_crystal(struct bcm43xx_private *bcm, int on)
-{
- int err;
- u32 in, out, outenable;
-
- err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_IN, &in);
- if (err)
- goto err_pci;
- err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &out);
- if (err)
- goto err_pci;
- err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUTENABLE, &outenable);
- if (err)
- goto err_pci;
-
- outenable |= (BCM43xx_PCTL_XTAL_POWERUP | BCM43xx_PCTL_PLL_POWERDOWN);
-
- if (on) {
- if (in & 0x40)
- return 0;
-
- out |= (BCM43xx_PCTL_XTAL_POWERUP | BCM43xx_PCTL_PLL_POWERDOWN);
-
- err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out);
- if (err)
- goto err_pci;
- err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUTENABLE, outenable);
- if (err)
- goto err_pci;
- udelay(1000);
-
- out &= ~BCM43xx_PCTL_PLL_POWERDOWN;
- err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out);
- if (err)
- goto err_pci;
- udelay(5000);
- } else {
- if (bcm->current_core->rev < 5)
- return 0;
- if (bcm->sprom.boardflags & BCM43xx_BFL_XTAL_NOSLOW)
- return 0;
-
-/* XXX: Why BCM43xx_MMIO_RADIO_HWENABLED_xx can't be read at this time?
- * err = bcm43xx_switch_core(bcm, bcm->active_80211_core);
- * if (err)
- * return err;
- * if (((bcm->current_core->rev >= 3) &&
- * (bcm43xx_read32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI) & (1 << 16))) ||
- * ((bcm->current_core->rev < 3) &&
- * !(bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO) & (1 << 4))))
- * return 0;
- * err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
- * if (err)
- * return err;
- */
-
- err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
- if (err)
- goto out;
- out &= ~BCM43xx_PCTL_XTAL_POWERUP;
- out |= BCM43xx_PCTL_PLL_POWERDOWN;
- err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out);
- if (err)
- goto err_pci;
- err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUTENABLE, outenable);
- if (err)
- goto err_pci;
- }
-
-out:
- return err;
-
-err_pci:
- printk(KERN_ERR PFX "Error: pctl_set_clock() could not access PCI config space!\n");
- err = -EBUSY;
- goto out;
-}
-
-/* Set the PowerSavingControlBits.
- * Bitvalues:
- * 0 => unset the bit
- * 1 => set the bit
- * -1 => calculate the bit
- */
-void bcm43xx_power_saving_ctl_bits(struct bcm43xx_private *bcm,
- int bit25, int bit26)
-{
- int i;
- u32 status;
-
-//FIXME: Force 25 to off and 26 to on for now:
-bit25 = 0;
-bit26 = 1;
-
- if (bit25 == -1) {
- //TODO: If powersave is not off and FIXME is not set and we are not in adhoc
- // and thus is not an AP and we are associated, set bit 25
- }
- if (bit26 == -1) {
- //TODO: If the device is awake or this is an AP, or we are scanning, or FIXME,
- // or we are associated, or FIXME, or the latest PS-Poll packet sent was
- // successful, set bit26
- }
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- if (bit25)
- status |= BCM43xx_SBF_PS1;
- else
- status &= ~BCM43xx_SBF_PS1;
- if (bit26)
- status |= BCM43xx_SBF_PS2;
- else
- status &= ~BCM43xx_SBF_PS2;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
- if (bit26 && bcm->current_core->rev >= 5) {
- for (i = 0; i < 100; i++) {
- if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0040) != 4)
- break;
- udelay(10);
- }
- }
-}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.h b/drivers/net/wireless/bcm43xx/bcm43xx_power.h
deleted file mode 100644
index c966ab3a5a8c..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_power.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-
- 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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
deleted file mode 100644
index c605099c9baf..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
+++ /dev/null
@@ -1,2170 +0,0 @@
-/*
-
- 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.
-
-*/
-
-#include <linux/delay.h>
-
-#include "bcm43xx.h"
-#include "bcm43xx_main.h"
-#include "bcm43xx_phy.h"
-#include "bcm43xx_radio.h"
-#include "bcm43xx_ilt.h"
-
-
-/* Table for bcm43xx_radio_calibrationvalue() */
-static const u16 rcc_table[16] = {
- 0x0002, 0x0003, 0x0001, 0x000F,
- 0x0006, 0x0007, 0x0005, 0x000F,
- 0x000A, 0x000B, 0x0009, 0x000F,
- 0x000E, 0x000F, 0x000D, 0x000F,
-};
-
-/* Reverse the bits of a 4bit value.
- * Example: 1101 is flipped 1011
- */
-static u16 flip_4bit(u16 value)
-{
- u16 flipped = 0x0000;
-
- assert((value & ~0x000F) == 0x0000);
-
- flipped |= (value & 0x0001) << 3;
- flipped |= (value & 0x0002) << 1;
- flipped |= (value & 0x0004) >> 1;
- flipped |= (value & 0x0008) >> 3;
-
- return flipped;
-}
-
-/* Get the freq, as it has to be written to the device. */
-static inline
-u16 channel2freq_bg(u8 channel)
-{
- /* Frequencies are given as frequencies_bg[index] + 2.4GHz
- * Starting with channel 1
- */
- static const u16 frequencies_bg[14] = {
- 12, 17, 22, 27,
- 32, 37, 42, 47,
- 52, 57, 62, 67,
- 72, 84,
- };
-
- assert(channel >= 1 && channel <= 14);
-
- return frequencies_bg[channel - 1];
-}
-
-/* Get the freq, as it has to be written to the device. */
-static inline
-u16 channel2freq_a(u8 channel)
-{
- assert(channel <= 200);
-
- return (5000 + 5 * channel);
-}
-
-void bcm43xx_radio_lock(struct bcm43xx_private *bcm)
-{
- u32 status;
-
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- status |= BCM43xx_SBF_RADIOREG_LOCK;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
- mmiowb();
- udelay(10);
-}
-
-void bcm43xx_radio_unlock(struct bcm43xx_private *bcm)
-{
- u32 status;
-
- bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER); /* dummy read */
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- status &= ~BCM43xx_SBF_RADIOREG_LOCK;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
- mmiowb();
-}
-
-u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- offset |= 0x0040;
- break;
- case BCM43xx_PHYTYPE_B:
- if (radio->version == 0x2053) {
- if (offset < 0x70)
- offset += 0x80;
- else if (offset < 0x80)
- offset += 0x70;
- } else if (radio->version == 0x2050) {
- offset |= 0x80;
- } else
- assert(0);
- break;
- case BCM43xx_PHYTYPE_G:
- offset |= 0x80;
- break;
- }
-
- bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset);
- return bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW);
-}
-
-void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val)
-{
- bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset);
- mmiowb();
- bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW, val);
-}
-
-static void bcm43xx_set_all_gains(struct bcm43xx_private *bcm,
- s16 first, s16 second, s16 third)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 i;
- u16 start = 0x08, end = 0x18;
- u16 offset = 0x0400;
- u16 tmp;
-
- if (phy->rev <= 1) {
- offset = 0x5000;
- start = 0x10;
- end = 0x20;
- }
-
- for (i = 0; i < 4; i++)
- bcm43xx_ilt_write(bcm, offset + i, first);
-
- for (i = start; i < end; i++)
- bcm43xx_ilt_write(bcm, offset + i, second);
-
- if (third != -1) {
- tmp = ((u16)third << 14) | ((u16)third << 6);
- bcm43xx_phy_write(bcm, 0x04A0,
- (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | tmp);
- bcm43xx_phy_write(bcm, 0x04A1,
- (bcm43xx_phy_read(bcm, 0x04A1) & 0xBFBF) | tmp);
- bcm43xx_phy_write(bcm, 0x04A2,
- (bcm43xx_phy_read(bcm, 0x04A2) & 0xBFBF) | tmp);
- }
- bcm43xx_dummy_transmission(bcm);
-}
-
-static void bcm43xx_set_original_gains(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 i, tmp;
- u16 offset = 0x0400;
- u16 start = 0x0008, end = 0x0018;
-
- if (phy->rev <= 1) {
- offset = 0x5000;
- start = 0x0010;
- end = 0x0020;
- }
-
- for (i = 0; i < 4; i++) {
- tmp = (i & 0xFFFC);
- tmp |= (i & 0x0001) << 1;
- tmp |= (i & 0x0002) >> 1;
-
- bcm43xx_ilt_write(bcm, offset + i, tmp);
- }
-
- for (i = start; i < end; i++)
- bcm43xx_ilt_write(bcm, offset + i, i - start);
-
- bcm43xx_phy_write(bcm, 0x04A0,
- (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | 0x4040);
- bcm43xx_phy_write(bcm, 0x04A1,
- (bcm43xx_phy_read(bcm, 0x04A1) & 0xBFBF) | 0x4040);
- bcm43xx_phy_write(bcm, 0x04A2,
- (bcm43xx_phy_read(bcm, 0x04A2) & 0xBFBF) | 0x4000);
- bcm43xx_dummy_transmission(bcm);
-}
-
-/* Synthetic PU workaround */
-static void bcm43xx_synth_pu_workaround(struct bcm43xx_private *bcm, u8 channel)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
-
- if (radio->version != 0x2050 || radio->revision >= 6) {
- /* We do not need the workaround. */
- return;
- }
-
- if (channel <= 10) {
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL,
- channel2freq_bg(channel + 4));
- } else {
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL,
- channel2freq_bg(1));
- }
- udelay(100);
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL,
- channel2freq_bg(channel));
-}
-
-u8 bcm43xx_radio_aci_detect(struct bcm43xx_private *bcm, u8 channel)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u8 ret = 0;
- u16 saved, rssi, temp;
- int i, j = 0;
-
- saved = bcm43xx_phy_read(bcm, 0x0403);
- bcm43xx_radio_selectchannel(bcm, channel, 0);
- bcm43xx_phy_write(bcm, 0x0403, (saved & 0xFFF8) | 5);
- if (radio->aci_hw_rssi)
- rssi = bcm43xx_phy_read(bcm, 0x048A) & 0x3F;
- else
- rssi = saved & 0x3F;
- /* clamp temp to signed 5bit */
- if (rssi > 32)
- rssi -= 64;
- for (i = 0;i < 100; i++) {
- temp = (bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x3F;
- if (temp > 32)
- temp -= 64;
- if (temp < rssi)
- j++;
- if (j >= 20)
- ret = 1;
- }
- bcm43xx_phy_write(bcm, 0x0403, saved);
-
- return ret;
-}
-
-u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u8 ret[13];
- unsigned int channel = radio->channel;
- unsigned int i, j, start, end;
- unsigned long phylock_flags;
-
- if (!((phy->type == BCM43xx_PHYTYPE_G) && (phy->rev > 0)))
- return 0;
-
- bcm43xx_phy_lock(bcm, phylock_flags);
- bcm43xx_radio_lock(bcm);
- bcm43xx_phy_write(bcm, 0x0802,
- bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF);
- bcm43xx_set_all_gains(bcm, 3, 8, 1);
-
- start = (channel - 5 > 0) ? channel - 5 : 1;
- end = (channel + 5 < 14) ? channel + 5 : 13;
-
- for (i = start; i <= end; i++) {
- if (abs(channel - i) > 2)
- ret[i-1] = bcm43xx_radio_aci_detect(bcm, i);
- }
- bcm43xx_radio_selectchannel(bcm, channel, 0);
- bcm43xx_phy_write(bcm, 0x0802,
- (bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC) | 0x0003);
- bcm43xx_phy_write(bcm, 0x0403,
- bcm43xx_phy_read(bcm, 0x0403) & 0xFFF8);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x8000);
- bcm43xx_set_original_gains(bcm);
- for (i = 0; i < 13; i++) {
- if (!ret[i])
- continue;
- end = (i + 5 < 13) ? i + 5 : 13;
- for (j = i; j < end; j++)
- ret[j] = 1;
- }
- bcm43xx_radio_unlock(bcm);
- bcm43xx_phy_unlock(bcm, phylock_flags);
-
- return ret[channel - 1];
-}
-
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
-void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val)
-{
- bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset);
- mmiowb();
- bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_DATA, (u16)val);
-}
-
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
-s16 bcm43xx_nrssi_hw_read(struct bcm43xx_private *bcm, u16 offset)
-{
- u16 val;
-
- bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset);
- val = bcm43xx_phy_read(bcm, BCM43xx_PHY_NRSSILT_DATA);
-
- return (s16)val;
-}
-
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
-void bcm43xx_nrssi_hw_update(struct bcm43xx_private *bcm, u16 val)
-{
- u16 i;
- s16 tmp;
-
- for (i = 0; i < 64; i++) {
- tmp = bcm43xx_nrssi_hw_read(bcm, i);
- tmp -= val;
- tmp = limit_value(tmp, -32, 31);
- bcm43xx_nrssi_hw_write(bcm, i, tmp);
- }
-}
-
-/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
-void bcm43xx_nrssi_mem_update(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- s16 i, delta;
- s32 tmp;
-
- delta = 0x1F - radio->nrssi[0];
- for (i = 0; i < 64; i++) {
- tmp = (i - delta) * radio->nrssislope;
- tmp /= 0x10000;
- tmp += 0x3A;
- tmp = limit_value(tmp, 0, 0x3F);
- radio->nrssi_lt[i] = tmp;
- }
-}
-
-static void bcm43xx_calc_nrssi_offset(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- u16 backup[20] = { 0 };
- s16 v47F;
- u16 i;
- u16 saved = 0xFFFF;
-
- backup[0] = bcm43xx_phy_read(bcm, 0x0001);
- backup[1] = bcm43xx_phy_read(bcm, 0x0811);
- backup[2] = bcm43xx_phy_read(bcm, 0x0812);
- backup[3] = bcm43xx_phy_read(bcm, 0x0814);
- backup[4] = bcm43xx_phy_read(bcm, 0x0815);
- backup[5] = bcm43xx_phy_read(bcm, 0x005A);
- backup[6] = bcm43xx_phy_read(bcm, 0x0059);
- backup[7] = bcm43xx_phy_read(bcm, 0x0058);
- backup[8] = bcm43xx_phy_read(bcm, 0x000A);
- backup[9] = bcm43xx_phy_read(bcm, 0x0003);
- backup[10] = bcm43xx_radio_read16(bcm, 0x007A);
- backup[11] = bcm43xx_radio_read16(bcm, 0x0043);
-
- bcm43xx_phy_write(bcm, 0x0429,
- bcm43xx_phy_read(bcm, 0x0429) & 0x7FFF);
- bcm43xx_phy_write(bcm, 0x0001,
- (bcm43xx_phy_read(bcm, 0x0001) & 0x3FFF) | 0x4000);
- bcm43xx_phy_write(bcm, 0x0811,
- bcm43xx_phy_read(bcm, 0x0811) | 0x000C);
- bcm43xx_phy_write(bcm, 0x0812,
- (bcm43xx_phy_read(bcm, 0x0812) & 0xFFF3) | 0x0004);
- bcm43xx_phy_write(bcm, 0x0802,
- bcm43xx_phy_read(bcm, 0x0802) & ~(0x1 | 0x2));
- if (phy->rev >= 6) {
- backup[12] = bcm43xx_phy_read(bcm, 0x002E);
- backup[13] = bcm43xx_phy_read(bcm, 0x002F);
- backup[14] = bcm43xx_phy_read(bcm, 0x080F);
- backup[15] = bcm43xx_phy_read(bcm, 0x0810);
- backup[16] = bcm43xx_phy_read(bcm, 0x0801);
- backup[17] = bcm43xx_phy_read(bcm, 0x0060);
- backup[18] = bcm43xx_phy_read(bcm, 0x0014);
- backup[19] = bcm43xx_phy_read(bcm, 0x0478);
-
- bcm43xx_phy_write(bcm, 0x002E, 0);
- bcm43xx_phy_write(bcm, 0x002F, 0);
- bcm43xx_phy_write(bcm, 0x080F, 0);
- bcm43xx_phy_write(bcm, 0x0810, 0);
- bcm43xx_phy_write(bcm, 0x0478,
- bcm43xx_phy_read(bcm, 0x0478) | 0x0100);
- bcm43xx_phy_write(bcm, 0x0801,
- bcm43xx_phy_read(bcm, 0x0801) | 0x0040);
- bcm43xx_phy_write(bcm, 0x0060,
- bcm43xx_phy_read(bcm, 0x0060) | 0x0040);
- bcm43xx_phy_write(bcm, 0x0014,
- bcm43xx_phy_read(bcm, 0x0014) | 0x0200);
- }
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) | 0x0070);
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) | 0x0080);
- udelay(30);
-
- v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
- if (v47F >= 0x20)
- v47F -= 0x40;
- if (v47F == 31) {
- for (i = 7; i >= 4; i--) {
- bcm43xx_radio_write16(bcm, 0x007B, i);
- udelay(20);
- v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
- if (v47F >= 0x20)
- v47F -= 0x40;
- if (v47F < 31 && saved == 0xFFFF)
- saved = i;
- }
- if (saved == 0xFFFF)
- saved = 4;
- } else {
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0001);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE);
- bcm43xx_phy_write(bcm, 0x0811,
- bcm43xx_phy_read(bcm, 0x0811) | 0x000C);
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_phy_read(bcm, 0x0812) | 0x000C);
- bcm43xx_phy_write(bcm, 0x0811,
- bcm43xx_phy_read(bcm, 0x0811) | 0x0030);
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_phy_read(bcm, 0x0812) | 0x0030);
- bcm43xx_phy_write(bcm, 0x005A, 0x0480);
- bcm43xx_phy_write(bcm, 0x0059, 0x0810);
- bcm43xx_phy_write(bcm, 0x0058, 0x000D);
- if (phy->analog == 0) {
- bcm43xx_phy_write(bcm, 0x0003, 0x0122);
- } else {
- bcm43xx_phy_write(bcm, 0x000A,
- bcm43xx_phy_read(bcm, 0x000A)
- | 0x2000);
- }
- bcm43xx_phy_write(bcm, 0x0814,
- bcm43xx_phy_read(bcm, 0x0814) | 0x0004);
- bcm43xx_phy_write(bcm, 0x0815,
- bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB);
- bcm43xx_phy_write(bcm, 0x0003,
- (bcm43xx_phy_read(bcm, 0x0003) & 0xFF9F)
- | 0x0040);
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) | 0x000F);
- bcm43xx_set_all_gains(bcm, 3, 0, 1);
- bcm43xx_radio_write16(bcm, 0x0043,
- (bcm43xx_radio_read16(bcm, 0x0043)
- & 0x00F0) | 0x000F);
- udelay(30);
- v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
- if (v47F >= 0x20)
- v47F -= 0x40;
- if (v47F == -32) {
- for (i = 0; i < 4; i++) {
- bcm43xx_radio_write16(bcm, 0x007B, i);
- udelay(20);
- v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
- if (v47F >= 0x20)
- v47F -= 0x40;
- if (v47F > -31 && saved == 0xFFFF)
- saved = i;
- }
- if (saved == 0xFFFF)
- saved = 3;
- } else
- saved = 0;
- }
- bcm43xx_radio_write16(bcm, 0x007B, saved);
-
- if (phy->rev >= 6) {
- bcm43xx_phy_write(bcm, 0x002E, backup[12]);
- bcm43xx_phy_write(bcm, 0x002F, backup[13]);
- bcm43xx_phy_write(bcm, 0x080F, backup[14]);
- bcm43xx_phy_write(bcm, 0x0810, backup[15]);
- }
- bcm43xx_phy_write(bcm, 0x0814, backup[3]);
- bcm43xx_phy_write(bcm, 0x0815, backup[4]);
- bcm43xx_phy_write(bcm, 0x005A, backup[5]);
- bcm43xx_phy_write(bcm, 0x0059, backup[6]);
- bcm43xx_phy_write(bcm, 0x0058, backup[7]);
- bcm43xx_phy_write(bcm, 0x000A, backup[8]);
- bcm43xx_phy_write(bcm, 0x0003, backup[9]);
- bcm43xx_radio_write16(bcm, 0x0043, backup[11]);
- bcm43xx_radio_write16(bcm, 0x007A, backup[10]);
- bcm43xx_phy_write(bcm, 0x0802,
- bcm43xx_phy_read(bcm, 0x0802) | 0x1 | 0x2);
- bcm43xx_phy_write(bcm, 0x0429,
- bcm43xx_phy_read(bcm, 0x0429) | 0x8000);
- bcm43xx_set_original_gains(bcm);
- if (phy->rev >= 6) {
- bcm43xx_phy_write(bcm, 0x0801, backup[16]);
- bcm43xx_phy_write(bcm, 0x0060, backup[17]);
- bcm43xx_phy_write(bcm, 0x0014, backup[18]);
- bcm43xx_phy_write(bcm, 0x0478, backup[19]);
- }
- bcm43xx_phy_write(bcm, 0x0001, backup[0]);
- bcm43xx_phy_write(bcm, 0x0812, backup[2]);
- bcm43xx_phy_write(bcm, 0x0811, backup[1]);
-}
-
-void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 backup[18] = { 0 };
- u16 tmp;
- s16 nrssi0, nrssi1;
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_B:
- backup[0] = bcm43xx_radio_read16(bcm, 0x007A);
- backup[1] = bcm43xx_radio_read16(bcm, 0x0052);
- backup[2] = bcm43xx_radio_read16(bcm, 0x0043);
- backup[3] = bcm43xx_phy_read(bcm, 0x0030);
- backup[4] = bcm43xx_phy_read(bcm, 0x0026);
- backup[5] = bcm43xx_phy_read(bcm, 0x0015);
- backup[6] = bcm43xx_phy_read(bcm, 0x002A);
- backup[7] = bcm43xx_phy_read(bcm, 0x0020);
- backup[8] = bcm43xx_phy_read(bcm, 0x005A);
- backup[9] = bcm43xx_phy_read(bcm, 0x0059);
- backup[10] = bcm43xx_phy_read(bcm, 0x0058);
- backup[11] = bcm43xx_read16(bcm, 0x03E2);
- backup[12] = bcm43xx_read16(bcm, 0x03E6);
- backup[13] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
-
- tmp = bcm43xx_radio_read16(bcm, 0x007A);
- tmp &= (phy->rev >= 5) ? 0x007F : 0x000F;
- bcm43xx_radio_write16(bcm, 0x007A, tmp);
- bcm43xx_phy_write(bcm, 0x0030, 0x00FF);
- bcm43xx_write16(bcm, 0x03EC, 0x7F7F);
- bcm43xx_phy_write(bcm, 0x0026, 0x0000);
- bcm43xx_phy_write(bcm, 0x0015,
- bcm43xx_phy_read(bcm, 0x0015) | 0x0020);
- bcm43xx_phy_write(bcm, 0x002A, 0x08A3);
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) | 0x0080);
-
- nrssi0 = (s16)bcm43xx_phy_read(bcm, 0x0027);
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
- if (phy->analog >= 2) {
- bcm43xx_write16(bcm, 0x03E6, 0x0040);
- } else if (phy->analog == 0) {
- bcm43xx_write16(bcm, 0x03E6, 0x0122);
- } else {
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
- bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) & 0x2000);
- }
- bcm43xx_phy_write(bcm, 0x0020, 0x3F3F);
- bcm43xx_phy_write(bcm, 0x0015, 0xF330);
- bcm43xx_radio_write16(bcm, 0x005A, 0x0060);
- bcm43xx_radio_write16(bcm, 0x0043,
- bcm43xx_radio_read16(bcm, 0x0043) & 0x00F0);
- bcm43xx_phy_write(bcm, 0x005A, 0x0480);
- bcm43xx_phy_write(bcm, 0x0059, 0x0810);
- bcm43xx_phy_write(bcm, 0x0058, 0x000D);
- udelay(20);
-
- nrssi1 = (s16)bcm43xx_phy_read(bcm, 0x0027);
- bcm43xx_phy_write(bcm, 0x0030, backup[3]);
- bcm43xx_radio_write16(bcm, 0x007A, backup[0]);
- bcm43xx_write16(bcm, 0x03E2, backup[11]);
- bcm43xx_phy_write(bcm, 0x0026, backup[4]);
- bcm43xx_phy_write(bcm, 0x0015, backup[5]);
- bcm43xx_phy_write(bcm, 0x002A, backup[6]);
- bcm43xx_synth_pu_workaround(bcm, radio->channel);
- if (phy->analog != 0)
- bcm43xx_write16(bcm, 0x03F4, backup[13]);
-
- bcm43xx_phy_write(bcm, 0x0020, backup[7]);
- bcm43xx_phy_write(bcm, 0x005A, backup[8]);
- bcm43xx_phy_write(bcm, 0x0059, backup[9]);
- bcm43xx_phy_write(bcm, 0x0058, backup[10]);
- bcm43xx_radio_write16(bcm, 0x0052, backup[1]);
- bcm43xx_radio_write16(bcm, 0x0043, backup[2]);
-
- if (nrssi0 == nrssi1)
- radio->nrssislope = 0x00010000;
- else
- radio->nrssislope = 0x00400000 / (nrssi0 - nrssi1);
-
- if (nrssi0 <= -4) {
- radio->nrssi[0] = nrssi0;
- radio->nrssi[1] = nrssi1;
- }
- break;
- case BCM43xx_PHYTYPE_G:
- if (radio->revision >= 9)
- return;
- if (radio->revision == 8)
- bcm43xx_calc_nrssi_offset(bcm);
-
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF);
- bcm43xx_phy_write(bcm, 0x0802,
- bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC);
- backup[7] = bcm43xx_read16(bcm, 0x03E2);
- bcm43xx_write16(bcm, 0x03E2,
- bcm43xx_read16(bcm, 0x03E2) | 0x8000);
- backup[0] = bcm43xx_radio_read16(bcm, 0x007A);
- backup[1] = bcm43xx_radio_read16(bcm, 0x0052);
- backup[2] = bcm43xx_radio_read16(bcm, 0x0043);
- backup[3] = bcm43xx_phy_read(bcm, 0x0015);
- backup[4] = bcm43xx_phy_read(bcm, 0x005A);
- backup[5] = bcm43xx_phy_read(bcm, 0x0059);
- backup[6] = bcm43xx_phy_read(bcm, 0x0058);
- backup[8] = bcm43xx_read16(bcm, 0x03E6);
- backup[9] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
- if (phy->rev >= 3) {
- backup[10] = bcm43xx_phy_read(bcm, 0x002E);
- backup[11] = bcm43xx_phy_read(bcm, 0x002F);
- backup[12] = bcm43xx_phy_read(bcm, 0x080F);
- backup[13] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_LO_CONTROL);
- backup[14] = bcm43xx_phy_read(bcm, 0x0801);
- backup[15] = bcm43xx_phy_read(bcm, 0x0060);
- backup[16] = bcm43xx_phy_read(bcm, 0x0014);
- backup[17] = bcm43xx_phy_read(bcm, 0x0478);
- bcm43xx_phy_write(bcm, 0x002E, 0);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, 0);
- switch (phy->rev) {
- case 4: case 6: case 7:
- bcm43xx_phy_write(bcm, 0x0478,
- bcm43xx_phy_read(bcm, 0x0478)
- | 0x0100);
- bcm43xx_phy_write(bcm, 0x0801,
- bcm43xx_phy_read(bcm, 0x0801)
- | 0x0040);
- break;
- case 3: case 5:
- bcm43xx_phy_write(bcm, 0x0801,
- bcm43xx_phy_read(bcm, 0x0801)
- & 0xFFBF);
- break;
- }
- bcm43xx_phy_write(bcm, 0x0060,
- bcm43xx_phy_read(bcm, 0x0060)
- | 0x0040);
- bcm43xx_phy_write(bcm, 0x0014,
- bcm43xx_phy_read(bcm, 0x0014)
- | 0x0200);
- }
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) | 0x0070);
- bcm43xx_set_all_gains(bcm, 0, 8, 0);
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) & 0x00F7);
- if (phy->rev >= 2) {
- bcm43xx_phy_write(bcm, 0x0811,
- (bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF) | 0x0030);
- bcm43xx_phy_write(bcm, 0x0812,
- (bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF) | 0x0010);
- }
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) | 0x0080);
- udelay(20);
-
- nrssi0 = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
- if (nrssi0 >= 0x0020)
- nrssi0 -= 0x0040;
-
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
- if (phy->analog >= 2) {
- bcm43xx_phy_write(bcm, 0x0003,
- (bcm43xx_phy_read(bcm, 0x0003)
- & 0xFF9F) | 0x0040);
- }
-
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
- bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT)
- | 0x2000);
- bcm43xx_radio_write16(bcm, 0x007A,
- bcm43xx_radio_read16(bcm, 0x007A) | 0x000F);
- bcm43xx_phy_write(bcm, 0x0015, 0xF330);
- if (phy->rev >= 2) {
- bcm43xx_phy_write(bcm, 0x0812,
- (bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF) | 0x0020);
- bcm43xx_phy_write(bcm, 0x0811,
- (bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF) | 0x0020);
- }
-
- bcm43xx_set_all_gains(bcm, 3, 0, 1);
- if (radio->revision == 8) {
- bcm43xx_radio_write16(bcm, 0x0043, 0x001F);
- } else {
- tmp = bcm43xx_radio_read16(bcm, 0x0052) & 0xFF0F;
- bcm43xx_radio_write16(bcm, 0x0052, tmp | 0x0060);
- tmp = bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0;
- bcm43xx_radio_write16(bcm, 0x0043, tmp | 0x0009);
- }
- bcm43xx_phy_write(bcm, 0x005A, 0x0480);
- bcm43xx_phy_write(bcm, 0x0059, 0x0810);
- bcm43xx_phy_write(bcm, 0x0058, 0x000D);
- udelay(20);
- nrssi1 = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
- if (nrssi1 >= 0x0020)
- nrssi1 -= 0x0040;
- if (nrssi0 == nrssi1)
- radio->nrssislope = 0x00010000;
- else
- radio->nrssislope = 0x00400000 / (nrssi0 - nrssi1);
- if (nrssi0 >= -4) {
- radio->nrssi[0] = nrssi1;
- radio->nrssi[1] = nrssi0;
- }
- if (phy->rev >= 3) {
- bcm43xx_phy_write(bcm, 0x002E, backup[10]);
- bcm43xx_phy_write(bcm, 0x002F, backup[11]);
- bcm43xx_phy_write(bcm, 0x080F, backup[12]);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, backup[13]);
- }
- if (phy->rev >= 2) {
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF);
- bcm43xx_phy_write(bcm, 0x0811,
- bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF);
- }
-
- bcm43xx_radio_write16(bcm, 0x007A, backup[0]);
- bcm43xx_radio_write16(bcm, 0x0052, backup[1]);
- bcm43xx_radio_write16(bcm, 0x0043, backup[2]);
- bcm43xx_write16(bcm, 0x03E2, backup[7]);
- bcm43xx_write16(bcm, 0x03E6, backup[8]);
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[9]);
- bcm43xx_phy_write(bcm, 0x0015, backup[3]);
- bcm43xx_phy_write(bcm, 0x005A, backup[4]);
- bcm43xx_phy_write(bcm, 0x0059, backup[5]);
- bcm43xx_phy_write(bcm, 0x0058, backup[6]);
- bcm43xx_synth_pu_workaround(bcm, radio->channel);
- bcm43xx_phy_write(bcm, 0x0802,
- bcm43xx_phy_read(bcm, 0x0802) | (0x0001 | 0x0002));
- bcm43xx_set_original_gains(bcm);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x8000);
- if (phy->rev >= 3) {
- bcm43xx_phy_write(bcm, 0x0801, backup[14]);
- bcm43xx_phy_write(bcm, 0x0060, backup[15]);
- bcm43xx_phy_write(bcm, 0x0014, backup[16]);
- bcm43xx_phy_write(bcm, 0x0478, backup[17]);
- }
- bcm43xx_nrssi_mem_update(bcm);
- bcm43xx_calc_nrssi_threshold(bcm);
- break;
- default:
- assert(0);
- }
-}
-
-void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- s32 threshold;
- s32 a, b;
- s16 tmp16;
- u16 tmp_u16;
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_B: {
- if (radio->version != 0x2050)
- return;
- if (!(bcm->sprom.boardflags & BCM43xx_BFL_RSSI))
- return;
-
- if (radio->revision >= 6) {
- threshold = (radio->nrssi[1] - radio->nrssi[0]) * 32;
- threshold += 20 * (radio->nrssi[0] + 1);
- threshold /= 40;
- } else
- threshold = radio->nrssi[1] - 5;
-
- threshold = limit_value(threshold, 0, 0x3E);
- bcm43xx_phy_read(bcm, 0x0020); /* dummy read */
- bcm43xx_phy_write(bcm, 0x0020, (((u16)threshold) << 8) | 0x001C);
-
- if (radio->revision >= 6) {
- bcm43xx_phy_write(bcm, 0x0087, 0x0E0D);
- bcm43xx_phy_write(bcm, 0x0086, 0x0C0B);
- bcm43xx_phy_write(bcm, 0x0085, 0x0A09);
- bcm43xx_phy_write(bcm, 0x0084, 0x0808);
- bcm43xx_phy_write(bcm, 0x0083, 0x0808);
- bcm43xx_phy_write(bcm, 0x0082, 0x0604);
- bcm43xx_phy_write(bcm, 0x0081, 0x0302);
- bcm43xx_phy_write(bcm, 0x0080, 0x0100);
- }
- break;
- }
- case BCM43xx_PHYTYPE_G:
- if (!phy->connected ||
- !(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) {
- tmp16 = bcm43xx_nrssi_hw_read(bcm, 0x20);
- if (tmp16 >= 0x20)
- tmp16 -= 0x40;
- if (tmp16 < 3) {
- bcm43xx_phy_write(bcm, 0x048A,
- (bcm43xx_phy_read(bcm, 0x048A)
- & 0xF000) | 0x09EB);
- } else {
- bcm43xx_phy_write(bcm, 0x048A,
- (bcm43xx_phy_read(bcm, 0x048A)
- & 0xF000) | 0x0AED);
- }
- } else {
- if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN) {
- a = 0xE;
- b = 0xA;
- } else if (!radio->aci_wlan_automatic && radio->aci_enable) {
- a = 0x13;
- b = 0x12;
- } else {
- a = 0xE;
- b = 0x11;
- }
-
- a = a * (radio->nrssi[1] - radio->nrssi[0]);
- a += (radio->nrssi[0] << 6);
- if (a < 32)
- a += 31;
- else
- a += 32;
- a = a >> 6;
- a = limit_value(a, -31, 31);
-
- b = b * (radio->nrssi[1] - radio->nrssi[0]);
- b += (radio->nrssi[0] << 6);
- if (b < 32)
- b += 31;
- else
- b += 32;
- b = b >> 6;
- b = limit_value(b, -31, 31);
-
- tmp_u16 = bcm43xx_phy_read(bcm, 0x048A) & 0xF000;
- tmp_u16 |= ((u32)b & 0x0000003F);
- tmp_u16 |= (((u32)a & 0x0000003F) << 6);
- bcm43xx_phy_write(bcm, 0x048A, tmp_u16);
- }
- break;
- default:
- assert(0);
- }
-}
-
-/* Stack implementation to save/restore values from the
- * interference mitigation code.
- * It is save to restore values in random order.
- */
-static void _stack_save(u32 *_stackptr, size_t *stackidx,
- u8 id, u16 offset, u16 value)
-{
- u32 *stackptr = &(_stackptr[*stackidx]);
-
- assert((offset & 0xE000) == 0x0000);
- assert((id & 0xF8) == 0x00);
- *stackptr = offset;
- *stackptr |= ((u32)id) << 13;
- *stackptr |= ((u32)value) << 16;
- (*stackidx)++;
- assert(*stackidx < BCM43xx_INTERFSTACK_SIZE);
-}
-
-static u16 _stack_restore(u32 *stackptr,
- u8 id, u16 offset)
-{
- size_t i;
-
- assert((offset & 0xE000) == 0x0000);
- assert((id & 0xF8) == 0x00);
- for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) {
- if ((*stackptr & 0x00001FFF) != offset)
- continue;
- if (((*stackptr & 0x00007000) >> 13) != id)
- continue;
- return ((*stackptr & 0xFFFF0000) >> 16);
- }
- assert(0);
-
- return 0;
-}
-
-#define phy_stacksave(offset) \
- do { \
- _stack_save(stack, &stackidx, 0x1, (offset), \
- bcm43xx_phy_read(bcm, (offset))); \
- } while (0)
-#define phy_stackrestore(offset) \
- do { \
- bcm43xx_phy_write(bcm, (offset), \
- _stack_restore(stack, 0x1, \
- (offset))); \
- } while (0)
-#define radio_stacksave(offset) \
- do { \
- _stack_save(stack, &stackidx, 0x2, (offset), \
- bcm43xx_radio_read16(bcm, (offset))); \
- } while (0)
-#define radio_stackrestore(offset) \
- do { \
- bcm43xx_radio_write16(bcm, (offset), \
- _stack_restore(stack, 0x2, \
- (offset))); \
- } while (0)
-#define ilt_stacksave(offset) \
- do { \
- _stack_save(stack, &stackidx, 0x3, (offset), \
- bcm43xx_ilt_read(bcm, (offset))); \
- } while (0)
-#define ilt_stackrestore(offset) \
- do { \
- bcm43xx_ilt_write(bcm, (offset), \
- _stack_restore(stack, 0x3, \
- (offset))); \
- } while (0)
-
-static void
-bcm43xx_radio_interference_mitigation_enable(struct bcm43xx_private *bcm,
- int mode)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 tmp, flipped;
- u32 tmp32;
- size_t stackidx = 0;
- u32 *stack = radio->interfstack;
-
- switch (mode) {
- case BCM43xx_RADIO_INTERFMODE_NONWLAN:
- if (phy->rev != 1) {
- bcm43xx_phy_write(bcm, 0x042B,
- bcm43xx_phy_read(bcm, 0x042B) | 0x0800);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & ~0x4000);
- break;
- }
- radio_stacksave(0x0078);
- tmp = (bcm43xx_radio_read16(bcm, 0x0078) & 0x001E);
- flipped = flip_4bit(tmp);
- if (flipped < 10 && flipped >= 8)
- flipped = 7;
- else if (flipped >= 10)
- flipped -= 3;
- flipped = flip_4bit(flipped);
- flipped = (flipped << 1) | 0x0020;
- bcm43xx_radio_write16(bcm, 0x0078, flipped);
-
- bcm43xx_calc_nrssi_threshold(bcm);
-
- phy_stacksave(0x0406);
- bcm43xx_phy_write(bcm, 0x0406, 0x7E28);
-
- bcm43xx_phy_write(bcm, 0x042B,
- bcm43xx_phy_read(bcm, 0x042B) | 0x0800);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | 0x1000);
-
- phy_stacksave(0x04A0);
- bcm43xx_phy_write(bcm, 0x04A0,
- (bcm43xx_phy_read(bcm, 0x04A0) & 0xC0C0) | 0x0008);
- phy_stacksave(0x04A1);
- bcm43xx_phy_write(bcm, 0x04A1,
- (bcm43xx_phy_read(bcm, 0x04A1) & 0xC0C0) | 0x0605);
- phy_stacksave(0x04A2);
- bcm43xx_phy_write(bcm, 0x04A2,
- (bcm43xx_phy_read(bcm, 0x04A2) & 0xC0C0) | 0x0204);
- phy_stacksave(0x04A8);
- bcm43xx_phy_write(bcm, 0x04A8,
- (bcm43xx_phy_read(bcm, 0x04A8) & 0xC0C0) | 0x0803);
- phy_stacksave(0x04AB);
- bcm43xx_phy_write(bcm, 0x04AB,
- (bcm43xx_phy_read(bcm, 0x04AB) & 0xC0C0) | 0x0605);
-
- phy_stacksave(0x04A7);
- bcm43xx_phy_write(bcm, 0x04A7, 0x0002);
- phy_stacksave(0x04A3);
- bcm43xx_phy_write(bcm, 0x04A3, 0x287A);
- phy_stacksave(0x04A9);
- bcm43xx_phy_write(bcm, 0x04A9, 0x2027);
- phy_stacksave(0x0493);
- bcm43xx_phy_write(bcm, 0x0493, 0x32F5);
- phy_stacksave(0x04AA);
- bcm43xx_phy_write(bcm, 0x04AA, 0x2027);
- phy_stacksave(0x04AC);
- bcm43xx_phy_write(bcm, 0x04AC, 0x32F5);
- break;
- case BCM43xx_RADIO_INTERFMODE_MANUALWLAN:
- if (bcm43xx_phy_read(bcm, 0x0033) & 0x0800)
- break;
-
- radio->aci_enable = 1;
-
- phy_stacksave(BCM43xx_PHY_RADIO_BITFIELD);
- phy_stacksave(BCM43xx_PHY_G_CRS);
- if (phy->rev < 2) {
- phy_stacksave(0x0406);
- } else {
- phy_stacksave(0x04C0);
- phy_stacksave(0x04C1);
- }
- phy_stacksave(0x0033);
- phy_stacksave(0x04A7);
- phy_stacksave(0x04A3);
- phy_stacksave(0x04A9);
- phy_stacksave(0x04AA);
- phy_stacksave(0x04AC);
- phy_stacksave(0x0493);
- phy_stacksave(0x04A1);
- phy_stacksave(0x04A0);
- phy_stacksave(0x04A2);
- phy_stacksave(0x048A);
- phy_stacksave(0x04A8);
- phy_stacksave(0x04AB);
- if (phy->rev == 2) {
- phy_stacksave(0x04AD);
- phy_stacksave(0x04AE);
- } else if (phy->rev >= 3) {
- phy_stacksave(0x04AD);
- phy_stacksave(0x0415);
- phy_stacksave(0x0416);
- phy_stacksave(0x0417);
- ilt_stacksave(0x1A00 + 0x2);
- ilt_stacksave(0x1A00 + 0x3);
- }
- phy_stacksave(0x042B);
- phy_stacksave(0x048C);
-
- bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD)
- & ~0x1000);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
- (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS)
- & 0xFFFC) | 0x0002);
-
- bcm43xx_phy_write(bcm, 0x0033, 0x0800);
- bcm43xx_phy_write(bcm, 0x04A3, 0x2027);
- bcm43xx_phy_write(bcm, 0x04A9, 0x1CA8);
- bcm43xx_phy_write(bcm, 0x0493, 0x287A);
- bcm43xx_phy_write(bcm, 0x04AA, 0x1CA8);
- bcm43xx_phy_write(bcm, 0x04AC, 0x287A);
-
- bcm43xx_phy_write(bcm, 0x04A0,
- (bcm43xx_phy_read(bcm, 0x04A0)
- & 0xFFC0) | 0x001A);
- bcm43xx_phy_write(bcm, 0x04A7, 0x000D);
-
- if (phy->rev < 2) {
- bcm43xx_phy_write(bcm, 0x0406, 0xFF0D);
- } else if (phy->rev == 2) {
- bcm43xx_phy_write(bcm, 0x04C0, 0xFFFF);
- bcm43xx_phy_write(bcm, 0x04C1, 0x00A9);
- } else {
- bcm43xx_phy_write(bcm, 0x04C0, 0x00C1);
- bcm43xx_phy_write(bcm, 0x04C1, 0x0059);
- }
-
- bcm43xx_phy_write(bcm, 0x04A1,
- (bcm43xx_phy_read(bcm, 0x04A1)
- & 0xC0FF) | 0x1800);
- bcm43xx_phy_write(bcm, 0x04A1,
- (bcm43xx_phy_read(bcm, 0x04A1)
- & 0xFFC0) | 0x0015);
- bcm43xx_phy_write(bcm, 0x04A8,
- (bcm43xx_phy_read(bcm, 0x04A8)
- & 0xCFFF) | 0x1000);
- bcm43xx_phy_write(bcm, 0x04A8,
- (bcm43xx_phy_read(bcm, 0x04A8)
- & 0xF0FF) | 0x0A00);
- bcm43xx_phy_write(bcm, 0x04AB,
- (bcm43xx_phy_read(bcm, 0x04AB)
- & 0xCFFF) | 0x1000);
- bcm43xx_phy_write(bcm, 0x04AB,
- (bcm43xx_phy_read(bcm, 0x04AB)
- & 0xF0FF) | 0x0800);
- bcm43xx_phy_write(bcm, 0x04AB,
- (bcm43xx_phy_read(bcm, 0x04AB)
- & 0xFFCF) | 0x0010);
- bcm43xx_phy_write(bcm, 0x04AB,
- (bcm43xx_phy_read(bcm, 0x04AB)
- & 0xFFF0) | 0x0005);
- bcm43xx_phy_write(bcm, 0x04A8,
- (bcm43xx_phy_read(bcm, 0x04A8)
- & 0xFFCF) | 0x0010);
- bcm43xx_phy_write(bcm, 0x04A8,
- (bcm43xx_phy_read(bcm, 0x04A8)
- & 0xFFF0) | 0x0006);
- bcm43xx_phy_write(bcm, 0x04A2,
- (bcm43xx_phy_read(bcm, 0x04A2)
- & 0xF0FF) | 0x0800);
- bcm43xx_phy_write(bcm, 0x04A0,
- (bcm43xx_phy_read(bcm, 0x04A0)
- & 0xF0FF) | 0x0500);
- bcm43xx_phy_write(bcm, 0x04A2,
- (bcm43xx_phy_read(bcm, 0x04A2)
- & 0xFFF0) | 0x000B);
-
- if (phy->rev >= 3) {
- bcm43xx_phy_write(bcm, 0x048A,
- bcm43xx_phy_read(bcm, 0x048A)
- & ~0x8000);
- bcm43xx_phy_write(bcm, 0x0415,
- (bcm43xx_phy_read(bcm, 0x0415)
- & 0x8000) | 0x36D8);
- bcm43xx_phy_write(bcm, 0x0416,
- (bcm43xx_phy_read(bcm, 0x0416)
- & 0x8000) | 0x36D8);
- bcm43xx_phy_write(bcm, 0x0417,
- (bcm43xx_phy_read(bcm, 0x0417)
- & 0xFE00) | 0x016D);
- } else {
- bcm43xx_phy_write(bcm, 0x048A,
- bcm43xx_phy_read(bcm, 0x048A)
- | 0x1000);
- bcm43xx_phy_write(bcm, 0x048A,
- (bcm43xx_phy_read(bcm, 0x048A)
- & 0x9FFF) | 0x2000);
- tmp32 = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET);
- if (!(tmp32 & 0x800)) {
- tmp32 |= 0x800;
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET,
- tmp32);
- }
- }
- if (phy->rev >= 2) {
- bcm43xx_phy_write(bcm, 0x042B,
- bcm43xx_phy_read(bcm, 0x042B)
- | 0x0800);
- }
- bcm43xx_phy_write(bcm, 0x048C,
- (bcm43xx_phy_read(bcm, 0x048C)
- & 0xF0FF) | 0x0200);
- if (phy->rev == 2) {
- bcm43xx_phy_write(bcm, 0x04AE,
- (bcm43xx_phy_read(bcm, 0x04AE)
- & 0xFF00) | 0x007F);
- bcm43xx_phy_write(bcm, 0x04AD,
- (bcm43xx_phy_read(bcm, 0x04AD)
- & 0x00FF) | 0x1300);
- } else if (phy->rev >= 6) {
- bcm43xx_ilt_write(bcm, 0x1A00 + 0x3, 0x007F);
- bcm43xx_ilt_write(bcm, 0x1A00 + 0x2, 0x007F);
- bcm43xx_phy_write(bcm, 0x04AD,
- bcm43xx_phy_read(bcm, 0x04AD)
- & 0x00FF);
- }
- bcm43xx_calc_nrssi_slope(bcm);
- break;
- default:
- assert(0);
- }
-}
-
-static void
-bcm43xx_radio_interference_mitigation_disable(struct bcm43xx_private *bcm,
- int mode)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u32 tmp32;
- u32 *stack = radio->interfstack;
-
- switch (mode) {
- case BCM43xx_RADIO_INTERFMODE_NONWLAN:
- if (phy->rev != 1) {
- bcm43xx_phy_write(bcm, 0x042B,
- bcm43xx_phy_read(bcm, 0x042B) & ~0x0800);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x4000);
- break;
- }
- phy_stackrestore(0x0078);
- bcm43xx_calc_nrssi_threshold(bcm);
- phy_stackrestore(0x0406);
- bcm43xx_phy_write(bcm, 0x042B,
- bcm43xx_phy_read(bcm, 0x042B) & ~0x0800);
- if (!bcm->bad_frames_preempt) {
- bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD)
- & ~(1 << 11));
- }
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
- bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x4000);
- phy_stackrestore(0x04A0);
- phy_stackrestore(0x04A1);
- phy_stackrestore(0x04A2);
- phy_stackrestore(0x04A8);
- phy_stackrestore(0x04AB);
- phy_stackrestore(0x04A7);
- phy_stackrestore(0x04A3);
- phy_stackrestore(0x04A9);
- phy_stackrestore(0x0493);
- phy_stackrestore(0x04AA);
- phy_stackrestore(0x04AC);
- break;
- case BCM43xx_RADIO_INTERFMODE_MANUALWLAN:
- if (!(bcm43xx_phy_read(bcm, 0x0033) & 0x0800))
- break;
-
- radio->aci_enable = 0;
-
- phy_stackrestore(BCM43xx_PHY_RADIO_BITFIELD);
- phy_stackrestore(BCM43xx_PHY_G_CRS);
- phy_stackrestore(0x0033);
- phy_stackrestore(0x04A3);
- phy_stackrestore(0x04A9);
- phy_stackrestore(0x0493);
- phy_stackrestore(0x04AA);
- phy_stackrestore(0x04AC);
- phy_stackrestore(0x04A0);
- phy_stackrestore(0x04A7);
- if (phy->rev >= 2) {
- phy_stackrestore(0x04C0);
- phy_stackrestore(0x04C1);
- } else
- phy_stackrestore(0x0406);
- phy_stackrestore(0x04A1);
- phy_stackrestore(0x04AB);
- phy_stackrestore(0x04A8);
- if (phy->rev == 2) {
- phy_stackrestore(0x04AD);
- phy_stackrestore(0x04AE);
- } else if (phy->rev >= 3) {
- phy_stackrestore(0x04AD);
- phy_stackrestore(0x0415);
- phy_stackrestore(0x0416);
- phy_stackrestore(0x0417);
- ilt_stackrestore(0x1A00 + 0x2);
- ilt_stackrestore(0x1A00 + 0x3);
- }
- phy_stackrestore(0x04A2);
- phy_stackrestore(0x04A8);
- phy_stackrestore(0x042B);
- phy_stackrestore(0x048C);
- tmp32 = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET);
- if (tmp32 & 0x800) {
- tmp32 &= ~0x800;
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET,
- tmp32);
- }
- bcm43xx_calc_nrssi_slope(bcm);
- break;
- default:
- assert(0);
- }
-}
-
-#undef phy_stacksave
-#undef phy_stackrestore
-#undef radio_stacksave
-#undef radio_stackrestore
-#undef ilt_stacksave
-#undef ilt_stackrestore
-
-int bcm43xx_radio_set_interference_mitigation(struct bcm43xx_private *bcm,
- int mode)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- int currentmode;
-
- if ((phy->type != BCM43xx_PHYTYPE_G) ||
- (phy->rev == 0) ||
- (!phy->connected))
- return -ENODEV;
-
- radio->aci_wlan_automatic = 0;
- switch (mode) {
- case BCM43xx_RADIO_INTERFMODE_AUTOWLAN:
- radio->aci_wlan_automatic = 1;
- if (radio->aci_enable)
- mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN;
- else
- mode = BCM43xx_RADIO_INTERFMODE_NONE;
- break;
- case BCM43xx_RADIO_INTERFMODE_NONE:
- case BCM43xx_RADIO_INTERFMODE_NONWLAN:
- case BCM43xx_RADIO_INTERFMODE_MANUALWLAN:
- break;
- default:
- return -EINVAL;
- }
-
- currentmode = radio->interfmode;
- if (currentmode == mode)
- return 0;
- if (currentmode != BCM43xx_RADIO_INTERFMODE_NONE)
- bcm43xx_radio_interference_mitigation_disable(bcm, currentmode);
-
- if (mode == BCM43xx_RADIO_INTERFMODE_NONE) {
- radio->aci_enable = 0;
- radio->aci_hw_rssi = 0;
- } else
- bcm43xx_radio_interference_mitigation_enable(bcm, mode);
- radio->interfmode = mode;
-
- return 0;
-}
-
-u16 bcm43xx_radio_calibrationvalue(struct bcm43xx_private *bcm)
-{
- u16 reg, index, ret;
-
- reg = bcm43xx_radio_read16(bcm, 0x0060);
- index = (reg & 0x001E) >> 1;
- ret = rcc_table[index] << 1;
- ret |= (reg & 0x0001);
- ret |= 0x0020;
-
- return ret;
-}
-
-#define LPD(L, P, D) (((L) << 2) | ((P) << 1) | ((D) << 0))
-static u16 bcm43xx_get_812_value(struct bcm43xx_private *bcm, u8 lpd)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 loop_or = 0;
- u16 adj_loopback_gain = phy->loopback_gain[0];
- u8 loop;
- u16 extern_lna_control;
-
- if (!phy->connected)
- return 0;
- if (!has_loopback_gain(phy)) {
- if (phy->rev < 7 || !(bcm->sprom.boardflags
- & BCM43xx_BFL_EXTLNA)) {
- switch (lpd) {
- case LPD(0, 1, 1):
- return 0x0FB2;
- case LPD(0, 0, 1):
- return 0x00B2;
- case LPD(1, 0, 1):
- return 0x30B2;
- case LPD(1, 0, 0):
- return 0x30B3;
- default:
- assert(0);
- }
- } else {
- switch (lpd) {
- case LPD(0, 1, 1):
- return 0x8FB2;
- case LPD(0, 0, 1):
- return 0x80B2;
- case LPD(1, 0, 1):
- return 0x20B2;
- case LPD(1, 0, 0):
- return 0x20B3;
- default:
- assert(0);
- }
- }
- } else {
- if (radio->revision == 8)
- adj_loopback_gain += 0x003E;
- else
- adj_loopback_gain += 0x0026;
- if (adj_loopback_gain >= 0x46) {
- adj_loopback_gain -= 0x46;
- extern_lna_control = 0x3000;
- } else if (adj_loopback_gain >= 0x3A) {
- adj_loopback_gain -= 0x3A;
- extern_lna_control = 0x2000;
- } else if (adj_loopback_gain >= 0x2E) {
- adj_loopback_gain -= 0x2E;
- extern_lna_control = 0x1000;
- } else {
- adj_loopback_gain -= 0x10;
- extern_lna_control = 0x0000;
- }
- for (loop = 0; loop < 16; loop++) {
- u16 tmp = adj_loopback_gain - 6 * loop;
- if (tmp < 6)
- break;
- }
-
- loop_or = (loop << 8) | extern_lna_control;
- if (phy->rev >= 7 && bcm->sprom.boardflags
- & BCM43xx_BFL_EXTLNA) {
- if (extern_lna_control)
- loop_or |= 0x8000;
- switch (lpd) {
- case LPD(0, 1, 1):
- return 0x8F92;
- case LPD(0, 0, 1):
- return (0x8092 | loop_or);
- case LPD(1, 0, 1):
- return (0x2092 | loop_or);
- case LPD(1, 0, 0):
- return (0x2093 | loop_or);
- default:
- assert(0);
- }
- } else {
- switch (lpd) {
- case LPD(0, 1, 1):
- return 0x0F92;
- case LPD(0, 0, 1):
- case LPD(1, 0, 1):
- return (0x0092 | loop_or);
- case LPD(1, 0, 0):
- return (0x0093 | loop_or);
- default:
- assert(0);
- }
- }
- }
- return 0;
-}
-
-u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 backup[21] = { 0 };
- u16 ret;
- u16 i, j;
- u32 tmp1 = 0, tmp2 = 0;
-
- backup[0] = bcm43xx_radio_read16(bcm, 0x0043);
- backup[14] = bcm43xx_radio_read16(bcm, 0x0051);
- backup[15] = bcm43xx_radio_read16(bcm, 0x0052);
- backup[1] = bcm43xx_phy_read(bcm, 0x0015);
- backup[16] = bcm43xx_phy_read(bcm, 0x005A);
- backup[17] = bcm43xx_phy_read(bcm, 0x0059);
- backup[18] = bcm43xx_phy_read(bcm, 0x0058);
- if (phy->type == BCM43xx_PHYTYPE_B) {
- backup[2] = bcm43xx_phy_read(bcm, 0x0030);
- backup[3] = bcm43xx_read16(bcm, 0x03EC);
- bcm43xx_phy_write(bcm, 0x0030, 0x00FF);
- bcm43xx_write16(bcm, 0x03EC, 0x3F3F);
- } else {
- if (phy->connected) {
- backup[4] = bcm43xx_phy_read(bcm, 0x0811);
- backup[5] = bcm43xx_phy_read(bcm, 0x0812);
- backup[6] = bcm43xx_phy_read(bcm, 0x0814);
- backup[7] = bcm43xx_phy_read(bcm, 0x0815);
- backup[8] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS);
- backup[9] = bcm43xx_phy_read(bcm, 0x0802);
- bcm43xx_phy_write(bcm, 0x0814,
- (bcm43xx_phy_read(bcm, 0x0814)
- | 0x0003));
- bcm43xx_phy_write(bcm, 0x0815,
- (bcm43xx_phy_read(bcm, 0x0815)
- & 0xFFFC));
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
- (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS)
- & 0x7FFF));
- bcm43xx_phy_write(bcm, 0x0802,
- (bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC));
- if (phy->rev > 1) { /* loopback gain enabled */
- backup[19] = bcm43xx_phy_read(bcm, 0x080F);
- backup[20] = bcm43xx_phy_read(bcm, 0x0810);
- if (phy->rev >= 3)
- bcm43xx_phy_write(bcm, 0x080F, 0xC020);
- else
- bcm43xx_phy_write(bcm, 0x080F, 0x8020);
- bcm43xx_phy_write(bcm, 0x0810, 0x0000);
- }
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm, LPD(0, 1, 1)));
- if (phy->rev < 7 || !(bcm->sprom.boardflags
- & BCM43xx_BFL_EXTLNA))
- bcm43xx_phy_write(bcm, 0x0811, 0x01B3);
- else
- bcm43xx_phy_write(bcm, 0x0811, 0x09B3);
- }
- }
- bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO,
- (bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_RADIO) | 0x8000));
- backup[10] = bcm43xx_phy_read(bcm, 0x0035);
- bcm43xx_phy_write(bcm, 0x0035,
- (bcm43xx_phy_read(bcm, 0x0035) & 0xFF7F));
- backup[11] = bcm43xx_read16(bcm, 0x03E6);
- backup[12] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
-
- // Initialization
- if (phy->analog == 0) {
- bcm43xx_write16(bcm, 0x03E6, 0x0122);
- } else {
- if (phy->analog >= 2)
- bcm43xx_phy_write(bcm, 0x0003,
- (bcm43xx_phy_read(bcm, 0x0003)
- & 0xFFBF) | 0x0040);
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
- (bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT)
- | 0x2000));
- }
-
- ret = bcm43xx_radio_calibrationvalue(bcm);
-
- if (phy->type == BCM43xx_PHYTYPE_B)
- bcm43xx_radio_write16(bcm, 0x0078, 0x0026);
-
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm, LPD(0, 1, 1)));
- bcm43xx_phy_write(bcm, 0x0015, 0xBFAF);
- bcm43xx_phy_write(bcm, 0x002B, 0x1403);
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm, LPD(0, 0, 1)));
- bcm43xx_phy_write(bcm, 0x0015, 0xBFA0);
- bcm43xx_radio_write16(bcm, 0x0051,
- (bcm43xx_radio_read16(bcm, 0x0051) | 0x0004));
- if (radio->revision == 8)
- bcm43xx_radio_write16(bcm, 0x0043, 0x001F);
- else {
- bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
- bcm43xx_radio_write16(bcm, 0x0043,
- (bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0)
- | 0x0009);
- }
- bcm43xx_phy_write(bcm, 0x0058, 0x0000);
-
- for (i = 0; i < 16; i++) {
- bcm43xx_phy_write(bcm, 0x005A, 0x0480);
- bcm43xx_phy_write(bcm, 0x0059, 0xC810);
- bcm43xx_phy_write(bcm, 0x0058, 0x000D);
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm, LPD(1, 0, 1)));
- bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
- udelay(10);
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm, LPD(1, 0, 1)));
- bcm43xx_phy_write(bcm, 0x0015, 0xEFB0);
- udelay(10);
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm, LPD(1, 0, 0)));
- bcm43xx_phy_write(bcm, 0x0015, 0xFFF0);
- udelay(20);
- tmp1 += bcm43xx_phy_read(bcm, 0x002D);
- bcm43xx_phy_write(bcm, 0x0058, 0x0000);
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm, LPD(1, 0, 1)));
- bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
- }
-
- tmp1++;
- tmp1 >>= 9;
- udelay(10);
- bcm43xx_phy_write(bcm, 0x0058, 0x0000);
-
- for (i = 0; i < 16; i++) {
- bcm43xx_radio_write16(bcm, 0x0078, (flip_4bit(i) << 1) | 0x0020);
- backup[13] = bcm43xx_radio_read16(bcm, 0x0078);
- udelay(10);
- for (j = 0; j < 16; j++) {
- bcm43xx_phy_write(bcm, 0x005A, 0x0D80);
- bcm43xx_phy_write(bcm, 0x0059, 0xC810);
- bcm43xx_phy_write(bcm, 0x0058, 0x000D);
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm,
- LPD(1, 0, 1)));
- bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
- udelay(10);
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm,
- LPD(1, 0, 1)));
- bcm43xx_phy_write(bcm, 0x0015, 0xEFB0);
- udelay(10);
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm,
- LPD(1, 0, 0)));
- bcm43xx_phy_write(bcm, 0x0015, 0xFFF0);
- udelay(10);
- tmp2 += bcm43xx_phy_read(bcm, 0x002D);
- bcm43xx_phy_write(bcm, 0x0058, 0x0000);
- if (phy->connected)
- bcm43xx_phy_write(bcm, 0x0812,
- bcm43xx_get_812_value(bcm,
- LPD(1, 0, 1)));
- bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
- }
- tmp2++;
- tmp2 >>= 8;
- if (tmp1 < tmp2)
- break;
- }
-
- /* Restore the registers */
- bcm43xx_phy_write(bcm, 0x0015, backup[1]);
- bcm43xx_radio_write16(bcm, 0x0051, backup[14]);
- bcm43xx_radio_write16(bcm, 0x0052, backup[15]);
- bcm43xx_radio_write16(bcm, 0x0043, backup[0]);
- bcm43xx_phy_write(bcm, 0x005A, backup[16]);
- bcm43xx_phy_write(bcm, 0x0059, backup[17]);
- bcm43xx_phy_write(bcm, 0x0058, backup[18]);
- bcm43xx_write16(bcm, 0x03E6, backup[11]);
- if (phy->analog != 0)
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[12]);
- bcm43xx_phy_write(bcm, 0x0035, backup[10]);
- bcm43xx_radio_selectchannel(bcm, radio->channel, 1);
- if (phy->type == BCM43xx_PHYTYPE_B) {
- bcm43xx_phy_write(bcm, 0x0030, backup[2]);
- bcm43xx_write16(bcm, 0x03EC, backup[3]);
- } else {
- if (phy->connected) {
- bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO,
- (bcm43xx_read16(bcm,
- BCM43xx_MMIO_PHY_RADIO) & 0x7FFF));
- bcm43xx_phy_write(bcm, 0x0811, backup[4]);
- bcm43xx_phy_write(bcm, 0x0812, backup[5]);
- bcm43xx_phy_write(bcm, 0x0814, backup[6]);
- bcm43xx_phy_write(bcm, 0x0815, backup[7]);
- bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, backup[8]);
- bcm43xx_phy_write(bcm, 0x0802, backup[9]);
- if (phy->rev > 1) {
- bcm43xx_phy_write(bcm, 0x080F, backup[19]);
- bcm43xx_phy_write(bcm, 0x0810, backup[20]);
- }
- }
- }
- if (i >= 15)
- ret = backup[13];
-
- return ret;
-}
-
-void bcm43xx_radio_init2060(struct bcm43xx_private *bcm)
-{
- int err;
-
- bcm43xx_radio_write16(bcm, 0x0004, 0x00C0);
- bcm43xx_radio_write16(bcm, 0x0005, 0x0008);
- bcm43xx_radio_write16(bcm, 0x0009, 0x0040);
- bcm43xx_radio_write16(bcm, 0x0005, 0x00AA);
- bcm43xx_radio_write16(bcm, 0x0032, 0x008F);
- bcm43xx_radio_write16(bcm, 0x0006, 0x008F);
- bcm43xx_radio_write16(bcm, 0x0034, 0x008F);
- bcm43xx_radio_write16(bcm, 0x002C, 0x0007);
- bcm43xx_radio_write16(bcm, 0x0082, 0x0080);
- bcm43xx_radio_write16(bcm, 0x0080, 0x0000);
- bcm43xx_radio_write16(bcm, 0x003F, 0x00DA);
- bcm43xx_radio_write16(bcm, 0x0005, bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008);
- bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0010);
- bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020);
- bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020);
- udelay(400);
-
- bcm43xx_radio_write16(bcm, 0x0081, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020) | 0x0010);
- udelay(400);
-
- bcm43xx_radio_write16(bcm, 0x0005, (bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008) | 0x0008);
- bcm43xx_radio_write16(bcm, 0x0085, bcm43xx_radio_read16(bcm, 0x0085) & ~0x0010);
- bcm43xx_radio_write16(bcm, 0x0005, bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008);
- bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0040);
- bcm43xx_radio_write16(bcm, 0x0081, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0040) | 0x0040);
- bcm43xx_radio_write16(bcm, 0x0005, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0008) | 0x0008);
- bcm43xx_phy_write(bcm, 0x0063, 0xDDC6);
- bcm43xx_phy_write(bcm, 0x0069, 0x07BE);
- bcm43xx_phy_write(bcm, 0x006A, 0x0000);
-
- err = bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_A, 0);
- assert(err == 0);
- udelay(1000);
-}
-
-static inline
-u16 freq_r3A_value(u16 frequency)
-{
- u16 value;
-
- if (frequency < 5091)
- value = 0x0040;
- else if (frequency < 5321)
- value = 0x0000;
- else if (frequency < 5806)
- value = 0x0080;
- else
- value = 0x0040;
-
- return value;
-}
-
-void bcm43xx_radio_set_tx_iq(struct bcm43xx_private *bcm)
-{
- static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 };
- static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A };
- u16 tmp = bcm43xx_radio_read16(bcm, 0x001E);
- int i, j;
-
- for (i = 0; i < 5; i++) {
- for (j = 0; j < 5; j++) {
- if (tmp == (data_high[i] | data_low[j])) {
- bcm43xx_phy_write(bcm, 0x0069, (i - j) << 8 | 0x00C0);
- return;
- }
- }
- }
-}
-
-int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm,
- u8 channel,
- int synthetic_pu_workaround)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 r8, tmp;
- u16 freq;
-
- if (!ieee80211_is_valid_channel(bcm->ieee, channel))
- return -EINVAL;
- if ((radio->manufact == 0x17F) &&
- (radio->version == 0x2060) &&
- (radio->revision == 1)) {
- freq = channel2freq_a(channel);
-
- r8 = bcm43xx_radio_read16(bcm, 0x0008);
- bcm43xx_write16(bcm, 0x03F0, freq);
- bcm43xx_radio_write16(bcm, 0x0008, r8);
-
- TODO();//TODO: write max channel TX power? to Radio 0x2D
- tmp = bcm43xx_radio_read16(bcm, 0x002E);
- tmp &= 0x0080;
- TODO();//TODO: OR tmp with the Power out estimation for this channel?
- bcm43xx_radio_write16(bcm, 0x002E, tmp);
-
- if (freq >= 4920 && freq <= 5500) {
- /*
- * r8 = (((freq * 15 * 0xE1FC780F) >> 32) / 29) & 0x0F;
- * = (freq * 0.025862069
- */
- r8 = 3 * freq / 116; /* is equal to r8 = freq * 0.025862 */
- }
- bcm43xx_radio_write16(bcm, 0x0007, (r8 << 4) | r8);
- bcm43xx_radio_write16(bcm, 0x0020, (r8 << 4) | r8);
- bcm43xx_radio_write16(bcm, 0x0021, (r8 << 4) | r8);
- bcm43xx_radio_write16(bcm, 0x0022,
- (bcm43xx_radio_read16(bcm, 0x0022)
- & 0x000F) | (r8 << 4));
- bcm43xx_radio_write16(bcm, 0x002A, (r8 << 4));
- bcm43xx_radio_write16(bcm, 0x002B, (r8 << 4));
- bcm43xx_radio_write16(bcm, 0x0008,
- (bcm43xx_radio_read16(bcm, 0x0008)
- & 0x00F0) | (r8 << 4));
- bcm43xx_radio_write16(bcm, 0x0029,
- (bcm43xx_radio_read16(bcm, 0x0029)
- & 0xFF0F) | 0x00B0);
- bcm43xx_radio_write16(bcm, 0x0035, 0x00AA);
- bcm43xx_radio_write16(bcm, 0x0036, 0x0085);
- bcm43xx_radio_write16(bcm, 0x003A,
- (bcm43xx_radio_read16(bcm, 0x003A)
- & 0xFF20) | freq_r3A_value(freq));
- bcm43xx_radio_write16(bcm, 0x003D,
- bcm43xx_radio_read16(bcm, 0x003D) & 0x00FF);
- bcm43xx_radio_write16(bcm, 0x0081,
- (bcm43xx_radio_read16(bcm, 0x0081)
- & 0xFF7F) | 0x0080);
- bcm43xx_radio_write16(bcm, 0x0035,
- bcm43xx_radio_read16(bcm, 0x0035) & 0xFFEF);
- bcm43xx_radio_write16(bcm, 0x0035,
- (bcm43xx_radio_read16(bcm, 0x0035)
- & 0xFFEF) | 0x0010);
- bcm43xx_radio_set_tx_iq(bcm);
- TODO(); //TODO: TSSI2dbm workaround
- bcm43xx_phy_xmitpower(bcm);//FIXME correct?
- } else {
- if (synthetic_pu_workaround)
- bcm43xx_synth_pu_workaround(bcm, channel);
-
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL,
- channel2freq_bg(channel));
-
- if (channel == 14) {
- if (bcm->sprom.locale == BCM43xx_LOCALE_JAPAN) {
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET,
- bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET)
- & ~(1 << 7));
- } else {
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET,
- bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODEFLAGS_OFFSET)
- | (1 << 7));
- }
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
- bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT)
- | (1 << 11));
- } else {
- bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
- bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT)
- & 0xF7BF);
- }
- }
-
- radio->channel = channel;
- //XXX: Using the longer of 2 timeouts (8000 vs 2000 usecs). Specs states
- // that 2000 usecs might suffice.
- udelay(8000);
-
- return 0;
-}
-
-void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val)
-{
- u16 tmp;
-
- val <<= 8;
- tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0022) & 0xFCFF;
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0022, tmp | val);
- tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x03A8) & 0xFCFF;
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x03A8, tmp | val);
- tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0054) & 0xFCFF;
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0054, tmp | val);
-}
-
-/* http://bcm-specs.sipsolutions.net/TX_Gain_Base_Band */
-static u16 bcm43xx_get_txgain_base_band(u16 txpower)
-{
- u16 ret;
-
- assert(txpower <= 63);
-
- if (txpower >= 54)
- ret = 2;
- else if (txpower >= 49)
- ret = 4;
- else if (txpower >= 44)
- ret = 5;
- else
- ret = 6;
-
- return ret;
-}
-
-/* http://bcm-specs.sipsolutions.net/TX_Gain_Radio_Frequency_Power_Amplifier */
-static u16 bcm43xx_get_txgain_freq_power_amp(u16 txpower)
-{
- u16 ret;
-
- assert(txpower <= 63);
-
- if (txpower >= 32)
- ret = 0;
- else if (txpower >= 25)
- ret = 1;
- else if (txpower >= 20)
- ret = 2;
- else if (txpower >= 12)
- ret = 3;
- else
- ret = 4;
-
- return ret;
-}
-
-/* http://bcm-specs.sipsolutions.net/TX_Gain_Digital_Analog_Converter */
-static u16 bcm43xx_get_txgain_dac(u16 txpower)
-{
- u16 ret;
-
- assert(txpower <= 63);
-
- if (txpower >= 54)
- ret = txpower - 53;
- else if (txpower >= 49)
- ret = txpower - 42;
- else if (txpower >= 44)
- ret = txpower - 37;
- else if (txpower >= 32)
- ret = txpower - 32;
- else if (txpower >= 25)
- ret = txpower - 20;
- else if (txpower >= 20)
- ret = txpower - 13;
- else if (txpower >= 12)
- ret = txpower - 8;
- else
- ret = txpower;
-
- return ret;
-}
-
-void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 pamp, base, dac, ilt;
-
- txpower = limit_value(txpower, 0, 63);
-
- pamp = bcm43xx_get_txgain_freq_power_amp(txpower);
- pamp <<= 5;
- pamp &= 0x00E0;
- bcm43xx_phy_write(bcm, 0x0019, pamp);
-
- base = bcm43xx_get_txgain_base_band(txpower);
- base &= 0x000F;
- bcm43xx_phy_write(bcm, 0x0017, base | 0x0020);
-
- ilt = bcm43xx_ilt_read(bcm, 0x3001);
- ilt &= 0x0007;
-
- dac = bcm43xx_get_txgain_dac(txpower);
- dac <<= 3;
- dac |= ilt;
-
- bcm43xx_ilt_write(bcm, 0x3001, dac);
-
- radio->txpwr_offset = txpower;
-
- TODO();
- //TODO: FuncPlaceholder (Adjust BB loft cancel)
-}
-
-void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm,
- u16 baseband_attenuation, u16 radio_attenuation,
- u16 txpower)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-
- if (baseband_attenuation == 0xFFFF)
- baseband_attenuation = radio->baseband_atten;
- if (radio_attenuation == 0xFFFF)
- radio_attenuation = radio->radio_atten;
- if (txpower == 0xFFFF)
- txpower = radio->txctl1;
- radio->baseband_atten = baseband_attenuation;
- radio->radio_atten = radio_attenuation;
- radio->txctl1 = txpower;
-
- assert(/*baseband_attenuation >= 0 &&*/ baseband_attenuation <= 11);
- if (radio->revision < 6)
- assert(/*radio_attenuation >= 0 &&*/ radio_attenuation <= 9);
- else
- assert(/* radio_attenuation >= 0 &&*/ radio_attenuation <= 31);
- assert(/*txpower >= 0 &&*/ txpower <= 7);
-
- bcm43xx_phy_set_baseband_attenuation(bcm, baseband_attenuation);
- bcm43xx_radio_write16(bcm, 0x0043, radio_attenuation);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0064, radio_attenuation);
- if (radio->version == 0x2050) {
- bcm43xx_radio_write16(bcm, 0x0052,
- (bcm43xx_radio_read16(bcm, 0x0052) & ~0x0070)
- | ((txpower << 4) & 0x0070));
- }
- //FIXME: The spec is very weird and unclear here.
- if (phy->type == BCM43xx_PHYTYPE_G)
- bcm43xx_phy_lo_adjust(bcm, 0);
-}
-
-u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
-
- if (radio->version == 0x2050 && radio->revision < 6)
- return 0;
- return 2;
-}
-
-u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- u16 att = 0xFFFF;
-
- if (phy->type == BCM43xx_PHYTYPE_A)
- return 0x60;
-
- switch (radio->version) {
- case 0x2053:
- switch (radio->revision) {
- case 1:
- att = 6;
- break;
- }
- break;
- case 0x2050:
- switch (radio->revision) {
- case 0:
- att = 5;
- break;
- case 1:
- if (phy->type == BCM43xx_PHYTYPE_G) {
- if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
- bcm->board_type == 0x421 &&
- bcm->board_revision >= 30)
- att = 3;
- else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
- bcm->board_type == 0x416)
- att = 3;
- else
- att = 1;
- } else {
- if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
- bcm->board_type == 0x421 &&
- bcm->board_revision >= 30)
- att = 7;
- else
- att = 6;
- }
- break;
- case 2:
- if (phy->type == BCM43xx_PHYTYPE_G) {
- if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
- bcm->board_type == 0x421 &&
- bcm->board_revision >= 30)
- att = 3;
- else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
- bcm->board_type == 0x416)
- att = 5;
- else if (bcm->chip_id == 0x4320)
- att = 4;
- else
- att = 3;
- } else
- att = 6;
- break;
- case 3:
- att = 5;
- break;
- case 4:
- case 5:
- att = 1;
- break;
- case 6:
- case 7:
- att = 5;
- break;
- case 8:
- att = 0x1A;
- break;
- case 9:
- default:
- att = 5;
- }
- }
- if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
- bcm->board_type == 0x421) {
- if (bcm->board_revision < 0x43)
- att = 2;
- else if (bcm->board_revision < 0x51)
- att = 3;
- }
- if (att == 0xFFFF)
- att = 5;
-
- return att;
-}
-
-u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
-
- if (radio->version != 0x2050)
- return 0;
- if (radio->revision == 1)
- return 3;
- if (radio->revision < 6)
- return 2;
- if (radio->revision == 8)
- return 1;
- return 0;
-}
-
-void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- int err;
-
- if (radio->enabled)
- return;
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- bcm43xx_radio_write16(bcm, 0x0004, 0x00C0);
- bcm43xx_radio_write16(bcm, 0x0005, 0x0008);
- bcm43xx_phy_write(bcm, 0x0010, bcm43xx_phy_read(bcm, 0x0010) & 0xFFF7);
- bcm43xx_phy_write(bcm, 0x0011, bcm43xx_phy_read(bcm, 0x0011) & 0xFFF7);
- bcm43xx_radio_init2060(bcm);
- break;
- case BCM43xx_PHYTYPE_B:
- case BCM43xx_PHYTYPE_G:
- bcm43xx_phy_write(bcm, 0x0015, 0x8000);
- bcm43xx_phy_write(bcm, 0x0015, 0xCC00);
- bcm43xx_phy_write(bcm, 0x0015, (phy->connected ? 0x00C0 : 0x0000));
- err = bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 1);
- assert(err == 0);
- break;
- default:
- assert(0);
- }
- radio->enabled = 1;
- dprintk(KERN_INFO PFX "Radio turned on\n");
- bcm43xx_leds_update(bcm, 0);
-}
-
-void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
-
- if (phy->type == BCM43xx_PHYTYPE_A) {
- bcm43xx_radio_write16(bcm, 0x0004, 0x00FF);
- bcm43xx_radio_write16(bcm, 0x0005, 0x00FB);
- bcm43xx_phy_write(bcm, 0x0010, bcm43xx_phy_read(bcm, 0x0010) | 0x0008);
- bcm43xx_phy_write(bcm, 0x0011, bcm43xx_phy_read(bcm, 0x0011) | 0x0008);
- }
- if (phy->type == BCM43xx_PHYTYPE_G && bcm->current_core->rev >= 5) {
- bcm43xx_phy_write(bcm, 0x0811, bcm43xx_phy_read(bcm, 0x0811) | 0x008C);
- bcm43xx_phy_write(bcm, 0x0812, bcm43xx_phy_read(bcm, 0x0812) & 0xFF73);
- } else
- bcm43xx_phy_write(bcm, 0x0015, 0xAA00);
- radio->enabled = 0;
- dprintk(KERN_INFO PFX "Radio initialized\n");
- bcm43xx_leds_update(bcm, 0);
-}
-
-void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0068, 0x7F7F);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x006a, 0x7F7F);
- break;
- case BCM43xx_PHYTYPE_B:
- case BCM43xx_PHYTYPE_G:
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0058, 0x7F7F);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x005a, 0x7F7F);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0070, 0x7F7F);
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0072, 0x7F7F);
- break;
- }
-}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.h b/drivers/net/wireless/bcm43xx/bcm43xx_radio.h
deleted file mode 100644
index 77a98a53a2e2..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
-
- 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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
deleted file mode 100644
index 8ab5f93d192a..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
-
- Broadcom BCM43xx wireless driver
-
- SYSFS support routines
-
- Copyright (c) 2006 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 "bcm43xx_sysfs.h"
-#include "bcm43xx.h"
-#include "bcm43xx_main.h"
-#include "bcm43xx_radio.h"
-
-#include <linux/capability.h>
-
-
-#define GENERIC_FILESIZE 64
-
-
-static int get_integer(const char *buf, size_t count)
-{
- char tmp[10 + 1] = { 0 };
- int ret = -EINVAL;
-
- if (count == 0)
- goto out;
- count = min(count, (size_t)10);
- memcpy(tmp, buf, count);
- ret = simple_strtol(tmp, NULL, 10);
-out:
- return ret;
-}
-
-static int get_boolean(const char *buf, size_t count)
-{
- if (count != 0) {
- if (buf[0] == '1')
- return 1;
- if (buf[0] == '0')
- return 0;
- if (count >= 4 && memcmp(buf, "true", 4) == 0)
- return 1;
- if (count >= 5 && memcmp(buf, "false", 5) == 0)
- return 0;
- if (count >= 3 && memcmp(buf, "yes", 3) == 0)
- return 1;
- if (count >= 2 && memcmp(buf, "no", 2) == 0)
- return 0;
- if (count >= 2 && memcmp(buf, "on", 2) == 0)
- return 1;
- if (count >= 3 && memcmp(buf, "off", 3) == 0)
- return 0;
- }
- return -EINVAL;
-}
-
-static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len)
-{
- int i, pos = 0;
-
- for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
- pos += snprintf(buf + pos, buf_len - pos - 1,
- "%04X", swab16(sprom[i]) & 0xFFFF);
- }
- pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
-
- return pos + 1;
-}
-
-static int hex2sprom(u16 *sprom, const char *dump, size_t len)
-{
- char tmp[5] = { 0 };
- int cnt = 0;
- unsigned long parsed;
-
- if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2)
- return -EINVAL;
-
- while (cnt < BCM43xx_SPROM_SIZE) {
- memcpy(tmp, dump, 4);
- dump += 4;
- parsed = simple_strtoul(tmp, NULL, 16);
- sprom[cnt++] = swab16((u16)parsed);
- }
-
- return 0;
-}
-
-static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct bcm43xx_private *bcm = dev_to_bcm(dev);
- u16 *sprom;
- unsigned long flags;
- int err;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- assert(BCM43xx_SPROM_SIZE * sizeof(u16) <= PAGE_SIZE);
- sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
- GFP_KERNEL);
- if (!sprom)
- return -ENOMEM;
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- err = bcm43xx_sprom_read(bcm, sprom);
- if (!err)
- err = sprom2hex(sprom, buf, PAGE_SIZE);
- mmiowb();
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
- kfree(sprom);
-
- return err;
-}
-
-static ssize_t bcm43xx_attr_sprom_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct bcm43xx_private *bcm = dev_to_bcm(dev);
- u16 *sprom;
- unsigned long flags;
- int err;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
- GFP_KERNEL);
- if (!sprom)
- return -ENOMEM;
- err = hex2sprom(sprom, buf, count);
- if (err)
- goto out_kfree;
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- spin_lock(&bcm->leds_lock);
- err = bcm43xx_sprom_write(bcm, sprom);
- mmiowb();
- spin_unlock(&bcm->leds_lock);
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-out_kfree:
- kfree(sprom);
-
- return err ? err : count;
-
-}
-
-static DEVICE_ATTR(sprom, 0600,
- bcm43xx_attr_sprom_show,
- bcm43xx_attr_sprom_store);
-
-static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct bcm43xx_private *bcm = dev_to_bcm(dev);
- ssize_t count = 0;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- mutex_lock(&bcm->mutex);
-
- switch (bcm43xx_current_radio(bcm)->interfmode) {
- case BCM43xx_RADIO_INTERFMODE_NONE:
- count = snprintf(buf, PAGE_SIZE, "0 (No Interference Mitigation)\n");
- break;
- case BCM43xx_RADIO_INTERFMODE_NONWLAN:
- count = snprintf(buf, PAGE_SIZE, "1 (Non-WLAN Interference Mitigation)\n");
- break;
- case BCM43xx_RADIO_INTERFMODE_MANUALWLAN:
- count = snprintf(buf, PAGE_SIZE, "2 (WLAN Interference Mitigation)\n");
- break;
- default:
- assert(0);
- }
-
- mutex_unlock(&bcm->mutex);
-
- return count;
-
-}
-
-static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct bcm43xx_private *bcm = dev_to_bcm(dev);
- unsigned long flags;
- int err;
- int mode;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- mode = get_integer(buf, count);
- switch (mode) {
- case 0:
- mode = BCM43xx_RADIO_INTERFMODE_NONE;
- break;
- case 1:
- mode = BCM43xx_RADIO_INTERFMODE_NONWLAN;
- break;
- case 2:
- mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN;
- break;
- case 3:
- mode = BCM43xx_RADIO_INTERFMODE_AUTOWLAN;
- break;
- default:
- return -EINVAL;
- }
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
-
- err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
- if (err) {
- printk(KERN_ERR PFX "Interference Mitigation not "
- "supported by device\n");
- }
- mmiowb();
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-
- return err ? err : count;
-}
-
-static DEVICE_ATTR(interference, 0644,
- bcm43xx_attr_interfmode_show,
- bcm43xx_attr_interfmode_store);
-
-static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct bcm43xx_private *bcm = dev_to_bcm(dev);
- ssize_t count;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- mutex_lock(&bcm->mutex);
-
- if (bcm->short_preamble)
- count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n");
- else
- count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");
-
- mutex_unlock(&bcm->mutex);
-
- return count;
-}
-
-static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct bcm43xx_private *bcm = dev_to_bcm(dev);
- unsigned long flags;
- int value;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- value = get_boolean(buf, count);
- if (value < 0)
- return value;
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
-
- bcm->short_preamble = !!value;
-
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-
- return count;
-}
-
-static DEVICE_ATTR(shortpreamble, 0644,
- bcm43xx_attr_preamble_show,
- bcm43xx_attr_preamble_store);
-
-static ssize_t bcm43xx_attr_phymode_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct bcm43xx_private *bcm = dev_to_bcm(dev);
- int phytype;
- int err = -EINVAL;
-
- if (count < 1)
- goto out;
- switch (buf[0]) {
- case 'a': case 'A':
- phytype = BCM43xx_PHYTYPE_A;
- break;
- case 'b': case 'B':
- phytype = BCM43xx_PHYTYPE_B;
- break;
- case 'g': case 'G':
- phytype = BCM43xx_PHYTYPE_G;
- break;
- default:
- goto out;
- }
-
- bcm43xx_cancel_work(bcm);
- mutex_lock(&(bcm)->mutex);
- err = bcm43xx_select_wireless_core(bcm, phytype);
- if (!err)
- bcm43xx_periodic_tasks_setup(bcm);
- mutex_unlock(&(bcm)->mutex);
- if (err == -ESRCH)
- err = -ENODEV;
-
-out:
- return err ? err : count;
-}
-
-static ssize_t bcm43xx_attr_phymode_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct bcm43xx_private *bcm = dev_to_bcm(dev);
- ssize_t count = 0;
-
- mutex_lock(&(bcm)->mutex);
- switch (bcm43xx_current_phy(bcm)->type) {
- case BCM43xx_PHYTYPE_A:
- snprintf(buf, PAGE_SIZE, "A");
- break;
- case BCM43xx_PHYTYPE_B:
- snprintf(buf, PAGE_SIZE, "B");
- break;
- case BCM43xx_PHYTYPE_G:
- snprintf(buf, PAGE_SIZE, "G");
- break;
- default:
- assert(0);
- }
- mutex_unlock(&(bcm)->mutex);
-
- return count;
-}
-
-static DEVICE_ATTR(phymode, 0644,
- bcm43xx_attr_phymode_show,
- bcm43xx_attr_phymode_store);
-
-static ssize_t bcm43xx_attr_microcode_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- unsigned long flags;
- struct bcm43xx_private *bcm = dev_to_bcm(dev);
- ssize_t count = 0;
- u16 status;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- mutex_lock(&(bcm)->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- status = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
- BCM43xx_UCODE_STATUS);
-
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&(bcm)->mutex);
- switch (status) {
- case 0x0000:
- count = snprintf(buf, PAGE_SIZE, "0x%.4x (invalid)\n",
- status);
- break;
- case 0x0001:
- count = snprintf(buf, PAGE_SIZE, "0x%.4x (init)\n",
- status);
- break;
- case 0x0002:
- count = snprintf(buf, PAGE_SIZE, "0x%.4x (active)\n",
- status);
- break;
- case 0x0003:
- count = snprintf(buf, PAGE_SIZE, "0x%.4x (suspended)\n",
- status);
- break;
- case 0x0004:
- count = snprintf(buf, PAGE_SIZE, "0x%.4x (asleep)\n",
- status);
- break;
- default:
- count = snprintf(buf, PAGE_SIZE, "0x%.4x (unknown)\n",
- status);
- break;
- }
-
- return count;
-}
-
-static DEVICE_ATTR(microcodestatus, 0444,
- bcm43xx_attr_microcode_show,
- NULL);
-
-int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
-{
- struct device *dev = &bcm->pci_dev->dev;
- int err;
-
- assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
-
- err = device_create_file(dev, &dev_attr_sprom);
- if (err)
- goto out;
- err = device_create_file(dev, &dev_attr_interference);
- if (err)
- goto err_remove_sprom;
- err = device_create_file(dev, &dev_attr_shortpreamble);
- if (err)
- goto err_remove_interfmode;
- err = device_create_file(dev, &dev_attr_phymode);
- if (err)
- goto err_remove_shortpreamble;
- err = device_create_file(dev, &dev_attr_microcodestatus);
- if (err)
- goto err_remove_phymode;
-
-out:
- return err;
-err_remove_phymode:
- device_remove_file(dev, &dev_attr_phymode);
-err_remove_shortpreamble:
- device_remove_file(dev, &dev_attr_shortpreamble);
-err_remove_interfmode:
- device_remove_file(dev, &dev_attr_interference);
-err_remove_sprom:
- device_remove_file(dev, &dev_attr_sprom);
- goto out;
-}
-
-void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm)
-{
- struct device *dev = &bcm->pci_dev->dev;
-
- device_remove_file(dev, &dev_attr_microcodestatus);
- device_remove_file(dev, &dev_attr_phymode);
- device_remove_file(dev, &dev_attr_shortpreamble);
- device_remove_file(dev, &dev_attr_interference);
- device_remove_file(dev, &dev_attr_sprom);
-}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h
deleted file mode 100644
index cc701df71e2a..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
deleted file mode 100644
index 6acfdc49dccd..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ /dev/null
@@ -1,1035 +0,0 @@
-/*
-
- 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.
-
-*/
-
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <net/ieee80211softmac.h>
-#include <net/ieee80211softmac_wx.h>
-#include <linux/capability.h>
-#include <linux/delay.h>
-
-#include "bcm43xx.h"
-#include "bcm43xx_wx.h"
-#include "bcm43xx_main.h"
-#include "bcm43xx_radio.h"
-#include "bcm43xx_phy.h"
-
-
-/* The WIRELESS_EXT version, which is implemented by this driver. */
-#define BCM43xx_WX_VERSION 18
-
-#define MAX_WX_STRING 80
-
-static int bcm43xx_wx_get_name(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int i;
- struct bcm43xx_phyinfo *phy;
- char suffix[7] = { 0 };
- int have_a = 0, have_b = 0, have_g = 0;
-
- mutex_lock(&bcm->mutex);
- for (i = 0; i < bcm->nr_80211_available; i++) {
- phy = &(bcm->core_80211_ext[i].phy);
- switch (phy->type) {
- case BCM43xx_PHYTYPE_A:
- have_a = 1;
- break;
- case BCM43xx_PHYTYPE_G:
- have_g = 1;
- case BCM43xx_PHYTYPE_B:
- have_b = 1;
- break;
- default:
- assert(0);
- }
- }
- mutex_unlock(&bcm->mutex);
-
- i = 0;
- if (have_a) {
- suffix[i++] = 'a';
- suffix[i++] = '/';
- }
- if (have_b) {
- suffix[i++] = 'b';
- suffix[i++] = '/';
- }
- if (have_g) {
- suffix[i++] = 'g';
- suffix[i++] = '/';
- }
- if (i != 0)
- suffix[i - 1] = '\0';
-
- snprintf(data->name, IFNAMSIZ, "IEEE 802.11%s", suffix);
-
- return 0;
-}
-
-static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
- u8 channel;
- s8 expon;
- int freq;
- int err = -EINVAL;
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
-
- if ((data->freq.e == 0) &&
- (data->freq.m >= 0) && (data->freq.m <= 1000)) {
- channel = data->freq.m;
- freq = bcm43xx_channel_to_freq(bcm, channel);
- } else {
- freq = data->freq.m;
- expon = 6 - data->freq.e;
- while (--expon >= 0) /* scale down the frequency to MHz */
- freq /= 10;
- assert(freq > 1000);
- channel = bcm43xx_freq_to_channel(bcm, freq);
- }
- if (!ieee80211_is_valid_channel(bcm->ieee, channel))
- goto out_unlock;
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
- //ieee80211softmac_disassoc(softmac, $REASON);
- bcm43xx_mac_suspend(bcm);
- err = bcm43xx_radio_selectchannel(bcm, channel, 0);
- bcm43xx_mac_enable(bcm);
- } else {
- bcm43xx_current_radio(bcm)->initial_channel = channel;
- err = 0;
- }
-out_unlock:
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-
- return err;
-}
-
-static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- struct bcm43xx_radioinfo *radio;
- int err = -ENODEV;
- u16 channel;
-
- mutex_lock(&bcm->mutex);
- radio = bcm43xx_current_radio(bcm);
- channel = radio->channel;
- if (channel == 0xFF) {
- channel = radio->initial_channel;
- if (channel == 0xFF)
- goto out_unlock;
- }
- assert(channel > 0 && channel <= 1000);
- data->freq.e = 1;
- data->freq.m = bcm43xx_channel_to_freq(bcm, channel) * 100000;
- data->freq.flags = 1;
-
- err = 0;
-out_unlock:
- mutex_unlock(&bcm->mutex);
-
- return err;
-}
-
-static int bcm43xx_wx_set_mode(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
- int mode;
-
- mode = data->mode;
- if (mode == IW_MODE_AUTO)
- mode = BCM43xx_INITIAL_IWMODE;
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
- if (bcm->ieee->iw_mode != mode)
- bcm43xx_set_iwmode(bcm, mode);
- } else
- bcm->ieee->iw_mode = mode;
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-
- return 0;
-}
-
-static int bcm43xx_wx_get_mode(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-
- mutex_lock(&bcm->mutex);
- data->mode = bcm->ieee->iw_mode;
- mutex_unlock(&bcm->mutex);
-
- return 0;
-}
-
-static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- struct iw_range *range = (struct iw_range *)extra;
- const struct ieee80211_geo *geo;
- int i, j;
- struct bcm43xx_phyinfo *phy;
-
- data->data.length = sizeof(*range);
- memset(range, 0, sizeof(*range));
-
- //TODO: What about 802.11b?
- /* 54Mb/s == ~27Mb/s payload throughput (802.11g) */
- range->throughput = 27 * 1000 * 1000;
-
- range->max_qual.qual = 100;
- range->max_qual.level = 146; /* set floor at -110 dBm (146 - 256) */
- range->max_qual.noise = 146;
- range->max_qual.updated = IW_QUAL_ALL_UPDATED;
-
- range->avg_qual.qual = 50;
- range->avg_qual.level = 0;
- range->avg_qual.noise = 0;
- range->avg_qual.updated = IW_QUAL_ALL_UPDATED;
-
- range->min_rts = BCM43xx_MIN_RTS_THRESHOLD;
- range->max_rts = BCM43xx_MAX_RTS_THRESHOLD;
- range->min_frag = MIN_FRAG_THRESHOLD;
- range->max_frag = MAX_FRAG_THRESHOLD;
-
- range->encoding_size[0] = 5;
- range->encoding_size[1] = 13;
- range->num_encoding_sizes = 2;
- range->max_encoding_tokens = WEP_KEYS;
-
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = BCM43xx_WX_VERSION;
-
- range->enc_capa = IW_ENC_CAPA_WPA |
- IW_ENC_CAPA_WPA2 |
- IW_ENC_CAPA_CIPHER_TKIP |
- IW_ENC_CAPA_CIPHER_CCMP;
-
- mutex_lock(&bcm->mutex);
- phy = bcm43xx_current_phy(bcm);
-
- range->num_bitrates = 0;
- i = 0;
- if (phy->type == BCM43xx_PHYTYPE_A ||
- phy->type == BCM43xx_PHYTYPE_G) {
- range->num_bitrates = 8;
- range->bitrate[i++] = IEEE80211_OFDM_RATE_6MB * 500000;
- range->bitrate[i++] = IEEE80211_OFDM_RATE_9MB * 500000;
- range->bitrate[i++] = IEEE80211_OFDM_RATE_12MB * 500000;
- range->bitrate[i++] = IEEE80211_OFDM_RATE_18MB * 500000;
- range->bitrate[i++] = IEEE80211_OFDM_RATE_24MB * 500000;
- range->bitrate[i++] = IEEE80211_OFDM_RATE_36MB * 500000;
- range->bitrate[i++] = IEEE80211_OFDM_RATE_48MB * 500000;
- range->bitrate[i++] = IEEE80211_OFDM_RATE_54MB * 500000;
- }
- if (phy->type == BCM43xx_PHYTYPE_B ||
- phy->type == BCM43xx_PHYTYPE_G) {
- range->num_bitrates += 4;
- range->bitrate[i++] = IEEE80211_CCK_RATE_1MB * 500000;
- range->bitrate[i++] = IEEE80211_CCK_RATE_2MB * 500000;
- range->bitrate[i++] = IEEE80211_CCK_RATE_5MB * 500000;
- range->bitrate[i++] = IEEE80211_CCK_RATE_11MB * 500000;
- }
-
- geo = ieee80211_get_geo(bcm->ieee);
- range->num_channels = geo->a_channels + geo->bg_channels;
- j = 0;
- for (i = 0; i < geo->a_channels; i++) {
- if (j == IW_MAX_FREQUENCIES)
- break;
- range->freq[j].i = j + 1;
- range->freq[j].m = geo->a[i].freq * 100000;
- range->freq[j].e = 1;
- j++;
- }
- for (i = 0; i < geo->bg_channels; i++) {
- if (j == IW_MAX_FREQUENCIES)
- break;
- range->freq[j].i = j + 1;
- range->freq[j].m = geo->bg[i].freq * 100000;
- range->freq[j].e = 1;
- j++;
- }
- range->num_frequency = j;
-
- mutex_unlock(&bcm->mutex);
-
- return 0;
-}
-
-static int bcm43xx_wx_set_nick(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- size_t len;
-
- mutex_lock(&bcm->mutex);
- len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE);
- memcpy(bcm->nick, extra, len);
- bcm->nick[len] = '\0';
- mutex_unlock(&bcm->mutex);
-
- return 0;
-}
-
-static int bcm43xx_wx_get_nick(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- size_t len;
-
- mutex_lock(&bcm->mutex);
- len = strlen(bcm->nick);
- memcpy(extra, bcm->nick, len);
- data->data.length = (__u16)len;
- data->data.flags = 1;
- mutex_unlock(&bcm->mutex);
-
- return 0;
-}
-
-static int bcm43xx_wx_set_rts(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
- int err = -EINVAL;
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- if (data->rts.disabled) {
- bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD;
- err = 0;
- } else {
- if (data->rts.value >= BCM43xx_MIN_RTS_THRESHOLD &&
- data->rts.value <= BCM43xx_MAX_RTS_THRESHOLD) {
- bcm->rts_threshold = data->rts.value;
- err = 0;
- }
- }
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-
- return err;
-}
-
-static int bcm43xx_wx_get_rts(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-
- mutex_lock(&bcm->mutex);
- data->rts.value = bcm->rts_threshold;
- data->rts.fixed = 0;
- data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD);
- mutex_unlock(&bcm->mutex);
-
- return 0;
-}
-
-static int bcm43xx_wx_set_frag(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
- int err = -EINVAL;
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- if (data->frag.disabled) {
- bcm->ieee->fts = MAX_FRAG_THRESHOLD;
- err = 0;
- } else {
- if (data->frag.value >= MIN_FRAG_THRESHOLD &&
- data->frag.value <= MAX_FRAG_THRESHOLD) {
- bcm->ieee->fts = data->frag.value & ~0x1;
- err = 0;
- }
- }
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-
- return err;
-}
-
-static int bcm43xx_wx_get_frag(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-
- mutex_lock(&bcm->mutex);
- data->frag.value = bcm->ieee->fts;
- data->frag.fixed = 0;
- data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD);
- mutex_unlock(&bcm->mutex);
-
- return 0;
-}
-
-static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- struct bcm43xx_radioinfo *radio;
- struct bcm43xx_phyinfo *phy;
- unsigned long flags;
- int err = -ENODEV;
- u16 maxpower;
-
- if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) {
- printk(KERN_ERR PFX "TX power not in dBm.\n");
- return -EOPNOTSUPP;
- }
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
- goto out_unlock;
- radio = bcm43xx_current_radio(bcm);
- phy = bcm43xx_current_phy(bcm);
- if (data->txpower.disabled != (!(radio->enabled))) {
- if (data->txpower.disabled)
- bcm43xx_radio_turn_off(bcm);
- else
- bcm43xx_radio_turn_on(bcm);
- }
- if (data->txpower.value > 0) {
- /* desired and maxpower dBm values are in Q5.2 */
- if (phy->type == BCM43xx_PHYTYPE_A)
- maxpower = bcm->sprom.maxpower_aphy;
- else
- maxpower = bcm->sprom.maxpower_bgphy;
- radio->txpower_desired = limit_value(data->txpower.value << 2,
- 0, maxpower);
- bcm43xx_phy_xmitpower(bcm);
- }
- err = 0;
-
-out_unlock:
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-
- return err;
-}
-
-static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- struct bcm43xx_radioinfo *radio;
- int err = -ENODEV;
-
- mutex_lock(&bcm->mutex);
- if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
- goto out_unlock;
- radio = bcm43xx_current_radio(bcm);
- /* desired dBm value is in Q5.2 */
- data->txpower.value = radio->txpower_desired >> 2;
- data->txpower.fixed = 1;
- data->txpower.flags = IW_TXPOW_DBM;
- data->txpower.disabled = !(radio->enabled);
-
- err = 0;
-out_unlock:
- mutex_unlock(&bcm->mutex);
-
- return err;
-}
-
-static int bcm43xx_wx_set_encoding(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int err;
-
- err = ieee80211_wx_set_encode(bcm->ieee, info, data, extra);
-
- return err;
-}
-
-static int bcm43xx_wx_set_encodingext(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int err;
-
- err = ieee80211_wx_set_encodeext(bcm->ieee, info, data, extra);
-
- return err;
-}
-
-static int bcm43xx_wx_get_encoding(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int err;
-
- err = ieee80211_wx_get_encode(bcm->ieee, info, data, extra);
-
- return err;
-}
-
-static int bcm43xx_wx_get_encodingext(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int err;
-
- err = ieee80211_wx_get_encodeext(bcm->ieee, info, data, extra);
-
- return err;
-}
-
-static int bcm43xx_wx_set_interfmode(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
- int mode, err = 0;
-
- mode = *((int *)extra);
- switch (mode) {
- case 0:
- mode = BCM43xx_RADIO_INTERFMODE_NONE;
- break;
- case 1:
- mode = BCM43xx_RADIO_INTERFMODE_NONWLAN;
- break;
- case 2:
- mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN;
- break;
- case 3:
- mode = BCM43xx_RADIO_INTERFMODE_AUTOWLAN;
- break;
- default:
- printk(KERN_ERR PFX "set_interfmode allowed parameters are: "
- "0 => None, 1 => Non-WLAN, 2 => WLAN, "
- "3 => Auto-WLAN\n");
- return -EINVAL;
- }
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
- err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
- if (err) {
- printk(KERN_ERR PFX "Interference Mitigation not "
- "supported by device\n");
- }
- } else {
- if (mode == BCM43xx_RADIO_INTERFMODE_AUTOWLAN) {
- printk(KERN_ERR PFX "Interference Mitigation mode Auto-WLAN "
- "not supported while the interface is down.\n");
- err = -ENODEV;
- } else
- bcm43xx_current_radio(bcm)->interfmode = mode;
- }
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-
- return err;
-}
-
-static int bcm43xx_wx_get_interfmode(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int mode;
-
- mutex_lock(&bcm->mutex);
- mode = bcm43xx_current_radio(bcm)->interfmode;
- mutex_unlock(&bcm->mutex);
-
- switch (mode) {
- case BCM43xx_RADIO_INTERFMODE_NONE:
- strncpy(extra, "0 (No Interference Mitigation)", MAX_WX_STRING);
- break;
- case BCM43xx_RADIO_INTERFMODE_NONWLAN:
- strncpy(extra, "1 (Non-WLAN Interference Mitigation)", MAX_WX_STRING);
- break;
- case BCM43xx_RADIO_INTERFMODE_MANUALWLAN:
- strncpy(extra, "2 (WLAN Interference Mitigation)", MAX_WX_STRING);
- break;
- default:
- assert(0);
- }
- data->data.length = strlen(extra) + 1;
-
- return 0;
-}
-
-static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
- int on;
-
- on = *((int *)extra);
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- bcm->short_preamble = !!on;
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-
- return 0;
-}
-
-static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int on;
-
- mutex_lock(&bcm->mutex);
- on = bcm->short_preamble;
- mutex_unlock(&bcm->mutex);
-
- if (on)
- strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING);
- else
- strncpy(extra, "0 (Short Preamble disabled)", MAX_WX_STRING);
- data->data.length = strlen(extra) + 1;
-
- return 0;
-}
-
-static int bcm43xx_wx_set_swencryption(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
- int on;
-
- on = *((int *)extra);
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- bcm->ieee->host_encrypt = !!on;
- bcm->ieee->host_decrypt = !!on;
- bcm->ieee->host_build_iv = !on;
- bcm->ieee->host_strip_iv_icv = !on;
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-
- return 0;
-}
-
-static int bcm43xx_wx_get_swencryption(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int on;
-
- mutex_lock(&bcm->mutex);
- on = bcm->ieee->host_encrypt;
- mutex_unlock(&bcm->mutex);
-
- if (on)
- strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING);
- else
- strncpy(extra, "0 (SW encryption disabled) ", MAX_WX_STRING);
- data->data.length = strlen(extra + 1);
-
- return 0;
-}
-
-/* Enough buffer to hold a hexdump of the sprom data. */
-#define SPROM_BUFFERSIZE 512
-
-static int sprom2hex(const u16 *sprom, char *dump)
-{
- int i, pos = 0;
-
- for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
- pos += snprintf(dump + pos, SPROM_BUFFERSIZE - pos - 1,
- "%04X", swab16(sprom[i]) & 0xFFFF);
- }
-
- return pos + 1;
-}
-
-static int hex2sprom(u16 *sprom, const char *dump, unsigned int len)
-{
- char tmp[5] = { 0 };
- int cnt = 0;
- unsigned long parsed;
-
- if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2)
- return -EINVAL;
- while (cnt < BCM43xx_SPROM_SIZE) {
- memcpy(tmp, dump, 4);
- dump += 4;
- parsed = simple_strtoul(tmp, NULL, 16);
- sprom[cnt++] = swab16((u16)parsed);
- }
-
- return 0;
-}
-
-static int bcm43xx_wx_sprom_read(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int err = -EPERM;
- u16 *sprom;
- unsigned long flags;
-
- if (!capable(CAP_SYS_RAWIO))
- goto out;
-
- err = -ENOMEM;
- sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
- GFP_KERNEL);
- if (!sprom)
- goto out;
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- err = -ENODEV;
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
- err = bcm43xx_sprom_read(bcm, sprom);
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
- if (!err)
- data->data.length = sprom2hex(sprom, extra);
- kfree(sprom);
-out:
- return err;
-}
-
-static int bcm43xx_wx_sprom_write(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- int err = -EPERM;
- u16 *sprom;
- unsigned long flags;
- char *input;
- unsigned int len;
-
- if (!capable(CAP_SYS_RAWIO))
- goto out;
-
- err = -ENOMEM;
- sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
- GFP_KERNEL);
- if (!sprom)
- goto out;
-
- len = data->data.length;
- extra[len - 1] = '\0';
- input = strchr(extra, ':');
- if (input) {
- input++;
- len -= input - extra;
- } else
- input = extra;
- err = hex2sprom(sprom, input, len);
- if (err)
- goto out_kfree;
-
- mutex_lock(&bcm->mutex);
- spin_lock_irqsave(&bcm->irq_lock, flags);
- spin_lock(&bcm->leds_lock);
- err = -ENODEV;
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
- err = bcm43xx_sprom_write(bcm, sprom);
- spin_unlock(&bcm->leds_lock);
- spin_unlock_irqrestore(&bcm->irq_lock, flags);
- mutex_unlock(&bcm->mutex);
-out_kfree:
- kfree(sprom);
-out:
- return err;
-}
-
-/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
-
-static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_dev)
-{
- struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
- struct iw_statistics *wstats;
- struct ieee80211_network *network = NULL;
- static int tmp_level = 0;
- static int tmp_qual = 0;
- unsigned long flags;
-
- wstats = &bcm->stats.wstats;
- if (!mac->associnfo.associated) {
- wstats->miss.beacon = 0;
-// bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here?
- wstats->discard.retries = 0;
-// bcm->ieee->ieee_stats.tx_discards_wrong_sa = 0; // FIXME: same question
- wstats->discard.nwid = 0;
-// bcm->ieee->ieee_stats.rx_discards_undecryptable = 0; // FIXME: ditto
- wstats->discard.code = 0;
-// bcm->ieee->ieee_stats.rx_fragments = 0; // FIXME: same here
- wstats->discard.fragment = 0;
- wstats->discard.misc = 0;
- wstats->qual.qual = 0;
- wstats->qual.level = 0;
- wstats->qual.noise = 0;
- wstats->qual.updated = 7;
- wstats->qual.updated |= IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- return wstats;
- }
- /* fill in the real statistics when iface associated */
- spin_lock_irqsave(&mac->ieee->lock, flags);
- list_for_each_entry(network, &mac->ieee->network_list, list) {
- if (!memcmp(mac->associnfo.bssid, network->bssid, ETH_ALEN)) {
- if (!tmp_level) { /* get initial values */
- tmp_level = network->stats.signal;
- tmp_qual = network->stats.rssi;
- } else { /* smooth results */
- tmp_level = (15 * tmp_level + network->stats.signal)/16;
- tmp_qual = (15 * tmp_qual + network->stats.rssi)/16;
- }
- break;
- }
- }
- spin_unlock_irqrestore(&mac->ieee->lock, flags);
- wstats->qual.level = tmp_level;
- wstats->qual.qual = 100 * tmp_qual / RX_RSSI_MAX;
- wstats->qual.noise = bcm->stats.noise;
- wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable;
- wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded;
- wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa;
- wstats->discard.fragment = bcm->ieee->ieee_stats.rx_fragments;
- wstats->discard.misc = 0; // FIXME
- wstats->miss.beacon = 0; // FIXME
- return wstats;
-}
-
-
-#ifdef WX
-# undef WX
-#endif
-#define WX(ioctl) [(ioctl) - SIOCSIWCOMMIT]
-static const iw_handler bcm43xx_wx_handlers[] = {
- /* Wireless Identification */
- WX(SIOCGIWNAME) = bcm43xx_wx_get_name,
- /* Basic operations */
- WX(SIOCSIWFREQ) = bcm43xx_wx_set_channelfreq,
- WX(SIOCGIWFREQ) = bcm43xx_wx_get_channelfreq,
- WX(SIOCSIWMODE) = bcm43xx_wx_set_mode,
- WX(SIOCGIWMODE) = bcm43xx_wx_get_mode,
- /* Informative stuff */
- WX(SIOCGIWRANGE) = bcm43xx_wx_get_rangeparams,
- /* Access Point manipulation */
- WX(SIOCSIWAP) = ieee80211softmac_wx_set_wap,
- WX(SIOCGIWAP) = ieee80211softmac_wx_get_wap,
- WX(SIOCSIWSCAN) = ieee80211softmac_wx_trigger_scan,
- WX(SIOCGIWSCAN) = ieee80211softmac_wx_get_scan_results,
- /* 802.11 specific support */
- WX(SIOCSIWESSID) = ieee80211softmac_wx_set_essid,
- WX(SIOCGIWESSID) = ieee80211softmac_wx_get_essid,
- WX(SIOCSIWNICKN) = bcm43xx_wx_set_nick,
- WX(SIOCGIWNICKN) = bcm43xx_wx_get_nick,
- /* Other parameters */
- WX(SIOCSIWRATE) = ieee80211softmac_wx_set_rate,
- WX(SIOCGIWRATE) = ieee80211softmac_wx_get_rate,
- WX(SIOCSIWRTS) = bcm43xx_wx_set_rts,
- WX(SIOCGIWRTS) = bcm43xx_wx_get_rts,
- WX(SIOCSIWFRAG) = bcm43xx_wx_set_frag,
- WX(SIOCGIWFRAG) = bcm43xx_wx_get_frag,
- WX(SIOCSIWTXPOW) = bcm43xx_wx_set_xmitpower,
- WX(SIOCGIWTXPOW) = bcm43xx_wx_get_xmitpower,
-//TODO WX(SIOCSIWRETRY) = bcm43xx_wx_set_retry,
-//TODO WX(SIOCGIWRETRY) = bcm43xx_wx_get_retry,
- /* Encoding */
- WX(SIOCSIWENCODE) = bcm43xx_wx_set_encoding,
- WX(SIOCGIWENCODE) = bcm43xx_wx_get_encoding,
- WX(SIOCSIWENCODEEXT) = bcm43xx_wx_set_encodingext,
- WX(SIOCGIWENCODEEXT) = bcm43xx_wx_get_encodingext,
- /* Power saving */
-//TODO WX(SIOCSIWPOWER) = bcm43xx_wx_set_power,
-//TODO WX(SIOCGIWPOWER) = bcm43xx_wx_get_power,
- WX(SIOCSIWGENIE) = ieee80211softmac_wx_set_genie,
- WX(SIOCGIWGENIE) = ieee80211softmac_wx_get_genie,
- WX(SIOCSIWAUTH) = ieee80211_wx_set_auth,
- WX(SIOCGIWAUTH) = ieee80211_wx_get_auth,
-};
-#undef WX
-
-static const iw_handler bcm43xx_priv_wx_handlers[] = {
- /* Set Interference Mitigation Mode. */
- bcm43xx_wx_set_interfmode,
- /* Get Interference Mitigation Mode. */
- bcm43xx_wx_get_interfmode,
- /* Enable/Disable Short Preamble mode. */
- bcm43xx_wx_set_shortpreamble,
- /* Get Short Preamble mode. */
- bcm43xx_wx_get_shortpreamble,
- /* Enable/Disable Software Encryption mode */
- bcm43xx_wx_set_swencryption,
- /* Get Software Encryption mode */
- bcm43xx_wx_get_swencryption,
- /* Write SRPROM data. */
- bcm43xx_wx_sprom_write,
- /* Read SPROM data. */
- bcm43xx_wx_sprom_read,
-};
-
-#define PRIV_WX_SET_INTERFMODE (SIOCIWFIRSTPRIV + 0)
-#define PRIV_WX_GET_INTERFMODE (SIOCIWFIRSTPRIV + 1)
-#define PRIV_WX_SET_SHORTPREAMBLE (SIOCIWFIRSTPRIV + 2)
-#define PRIV_WX_GET_SHORTPREAMBLE (SIOCIWFIRSTPRIV + 3)
-#define PRIV_WX_SET_SWENCRYPTION (SIOCIWFIRSTPRIV + 4)
-#define PRIV_WX_GET_SWENCRYPTION (SIOCIWFIRSTPRIV + 5)
-#define PRIV_WX_SPROM_WRITE (SIOCIWFIRSTPRIV + 6)
-#define PRIV_WX_SPROM_READ (SIOCIWFIRSTPRIV + 7)
-
-#define PRIV_WX_DUMMY(ioctl) \
- { \
- .cmd = (ioctl), \
- .name = "__unused" \
- }
-
-static const struct iw_priv_args bcm43xx_priv_wx_args[] = {
- {
- .cmd = PRIV_WX_SET_INTERFMODE,
- .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- .name = "set_interfmode",
- },
- {
- .cmd = PRIV_WX_GET_INTERFMODE,
- .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
- .name = "get_interfmode",
- },
- {
- .cmd = PRIV_WX_SET_SHORTPREAMBLE,
- .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- .name = "set_shortpreamb",
- },
- {
- .cmd = PRIV_WX_GET_SHORTPREAMBLE,
- .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
- .name = "get_shortpreamb",
- },
- {
- .cmd = PRIV_WX_SET_SWENCRYPTION,
- .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- .name = "set_swencrypt",
- },
- {
- .cmd = PRIV_WX_GET_SWENCRYPTION,
- .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
- .name = "get_swencrypt",
- },
- {
- .cmd = PRIV_WX_SPROM_WRITE,
- .set_args = IW_PRIV_TYPE_CHAR | SPROM_BUFFERSIZE,
- .name = "write_sprom",
- },
- {
- .cmd = PRIV_WX_SPROM_READ,
- .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | SPROM_BUFFERSIZE,
- .name = "read_sprom",
- },
-};
-
-const struct iw_handler_def bcm43xx_wx_handlers_def = {
- .standard = bcm43xx_wx_handlers,
- .num_standard = ARRAY_SIZE(bcm43xx_wx_handlers),
- .num_private = ARRAY_SIZE(bcm43xx_priv_wx_handlers),
- .num_private_args = ARRAY_SIZE(bcm43xx_priv_wx_args),
- .private = bcm43xx_priv_wx_handlers,
- .private_args = bcm43xx_priv_wx_args,
- .get_wireless_stats = bcm43xx_get_wireless_stats,
-};
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.h b/drivers/net/wireless/bcm43xx/bcm43xx_wx.h
deleted file mode 100644
index 1f29ff3aa4c3..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-
- 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_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
deleted file mode 100644
index f79fe11f9e81..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
-
- Broadcom BCM43xx wireless driver
-
- Transmission (TX/RX) related functions.
-
- 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_xmit.h"
-
-#include <linux/etherdevice.h>
-
-
-/* Extract the bitrate out of a CCK PLCP header. */
-static u8 bcm43xx_plcp_get_bitrate_cck(struct bcm43xx_plcp_hdr4 *plcp)
-{
- switch (plcp->raw[0]) {
- case 0x0A:
- return IEEE80211_CCK_RATE_1MB;
- case 0x14:
- return IEEE80211_CCK_RATE_2MB;
- case 0x37:
- return IEEE80211_CCK_RATE_5MB;
- case 0x6E:
- return IEEE80211_CCK_RATE_11MB;
- }
- assert(0);
- return 0;
-}
-
-/* Extract the bitrate out of an OFDM PLCP header. */
-static u8 bcm43xx_plcp_get_bitrate_ofdm(struct bcm43xx_plcp_hdr4 *plcp)
-{
- switch (plcp->raw[0] & 0xF) {
- case 0xB:
- return IEEE80211_OFDM_RATE_6MB;
- case 0xF:
- return IEEE80211_OFDM_RATE_9MB;
- case 0xA:
- return IEEE80211_OFDM_RATE_12MB;
- case 0xE:
- return IEEE80211_OFDM_RATE_18MB;
- case 0x9:
- return IEEE80211_OFDM_RATE_24MB;
- case 0xD:
- return IEEE80211_OFDM_RATE_36MB;
- case 0x8:
- return IEEE80211_OFDM_RATE_48MB;
- case 0xC:
- return IEEE80211_OFDM_RATE_54MB;
- }
- assert(0);
- return 0;
-}
-
-u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate)
-{
- switch (bitrate) {
- case IEEE80211_CCK_RATE_1MB:
- return 0x0A;
- case IEEE80211_CCK_RATE_2MB:
- return 0x14;
- case IEEE80211_CCK_RATE_5MB:
- return 0x37;
- case IEEE80211_CCK_RATE_11MB:
- return 0x6E;
- }
- assert(0);
- return 0;
-}
-
-u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate)
-{
- switch (bitrate) {
- case IEEE80211_OFDM_RATE_6MB:
- return 0xB;
- case IEEE80211_OFDM_RATE_9MB:
- return 0xF;
- case IEEE80211_OFDM_RATE_12MB:
- return 0xA;
- case IEEE80211_OFDM_RATE_18MB:
- return 0xE;
- case IEEE80211_OFDM_RATE_24MB:
- return 0x9;
- case IEEE80211_OFDM_RATE_36MB:
- return 0xD;
- case IEEE80211_OFDM_RATE_48MB:
- return 0x8;
- case IEEE80211_OFDM_RATE_54MB:
- return 0xC;
- }
- assert(0);
- return 0;
-}
-
-static void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
- const u16 octets, const u8 bitrate,
- const int ofdm_modulation)
-{
- __le32 *data = &(plcp->data);
- __u8 *raw = plcp->raw;
-
- if (ofdm_modulation) {
- u32 val = bcm43xx_plcp_get_ratecode_ofdm(bitrate);
- assert(!(octets & 0xF000));
- val |= (octets << 5);
- *data = cpu_to_le32(val);
- } else {
- u32 plen;
-
- plen = octets * 16 / bitrate;
- if ((octets * 16 % bitrate) > 0) {
- plen++;
- if ((bitrate == IEEE80211_CCK_RATE_11MB)
- && ((octets * 8 % 11) < 4)) {
- raw[1] = 0x84;
- } else
- raw[1] = 0x04;
- } else
- raw[1] = 0x04;
- *data |= cpu_to_le32(plen << 16);
- raw[0] = bcm43xx_plcp_get_ratecode_cck(bitrate);
- }
-}
-
-static u8 bcm43xx_calc_fallback_rate(u8 bitrate)
-{
- switch (bitrate) {
- case IEEE80211_CCK_RATE_1MB:
- return IEEE80211_CCK_RATE_1MB;
- case IEEE80211_CCK_RATE_2MB:
- return IEEE80211_CCK_RATE_1MB;
- case IEEE80211_CCK_RATE_5MB:
- return IEEE80211_CCK_RATE_2MB;
- case IEEE80211_CCK_RATE_11MB:
- return IEEE80211_CCK_RATE_5MB;
- case IEEE80211_OFDM_RATE_6MB:
- return IEEE80211_CCK_RATE_5MB;
- case IEEE80211_OFDM_RATE_9MB:
- return IEEE80211_OFDM_RATE_6MB;
- case IEEE80211_OFDM_RATE_12MB:
- return IEEE80211_OFDM_RATE_9MB;
- case IEEE80211_OFDM_RATE_18MB:
- return IEEE80211_OFDM_RATE_12MB;
- case IEEE80211_OFDM_RATE_24MB:
- return IEEE80211_OFDM_RATE_18MB;
- case IEEE80211_OFDM_RATE_36MB:
- return IEEE80211_OFDM_RATE_24MB;
- case IEEE80211_OFDM_RATE_48MB:
- return IEEE80211_OFDM_RATE_36MB;
- case IEEE80211_OFDM_RATE_54MB:
- return IEEE80211_OFDM_RATE_48MB;
- }
- assert(0);
- return 0;
-}
-
-static
-__le16 bcm43xx_calc_duration_id(const struct ieee80211_hdr *wireless_header,
- u8 bitrate)
-{
- const u16 frame_ctl = le16_to_cpu(wireless_header->frame_ctl);
- __le16 duration_id = wireless_header->duration_id;
-
- switch (WLAN_FC_GET_TYPE(frame_ctl)) {
- case IEEE80211_FTYPE_DATA:
- case IEEE80211_FTYPE_MGMT:
- //TODO: Steal the code from ieee80211, once it is completed there.
- break;
- case IEEE80211_FTYPE_CTL:
- /* Use the original duration/id. */
- break;
- default:
- assert(0);
- }
-
- return duration_id;
-}
-
-static inline
-u16 ceiling_div(u16 dividend, u16 divisor)
-{
- return ((dividend + divisor - 1) / divisor);
-}
-
-static void bcm43xx_generate_rts(const struct bcm43xx_phyinfo *phy,
- struct bcm43xx_txhdr *txhdr,
- u16 *flags,
- u8 bitrate,
- const struct ieee80211_hdr_4addr *wlhdr)
-{
- u16 fctl;
- u16 dur;
- u8 fallback_bitrate;
- int ofdm_modulation;
- int fallback_ofdm_modulation;
-// u8 *sa, *da;
- u16 flen;
-
-//FIXME sa = ieee80211_get_SA((struct ieee80211_hdr *)wlhdr);
-//FIXME da = ieee80211_get_DA((struct ieee80211_hdr *)wlhdr);
- fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate);
- ofdm_modulation = !(ieee80211_is_cck_rate(bitrate));
- fallback_ofdm_modulation = !(ieee80211_is_cck_rate(fallback_bitrate));
-
- flen = sizeof(u16) + sizeof(u16) + ETH_ALEN + ETH_ALEN + IEEE80211_FCS_LEN,
- bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_plcp),
- flen, bitrate,
- !ieee80211_is_cck_rate(bitrate));
- bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_fallback_plcp),
- flen, fallback_bitrate,
- !ieee80211_is_cck_rate(fallback_bitrate));
- fctl = IEEE80211_FTYPE_CTL;
- fctl |= IEEE80211_STYPE_RTS;
- dur = le16_to_cpu(wlhdr->duration_id);
-/*FIXME: should we test for dur==0 here and let it unmodified in this case?
- * The following assert checks for this case...
- */
-assert(dur);
-/*FIXME: The duration calculation is not really correct.
- * I am not 100% sure which bitrate to use. We use the RTS rate here,
- * but this is likely to be wrong.
- */
- if (phy->type == BCM43xx_PHYTYPE_A) {
- /* Three times SIFS */
- dur += 16 * 3;
- /* Add ACK duration. */
- dur += ceiling_div((16 + 8 * (14 /*bytes*/) + 6) * 10,
- bitrate * 4);
- /* Add CTS duration. */
- dur += ceiling_div((16 + 8 * (14 /*bytes*/) + 6) * 10,
- bitrate * 4);
- } else {
- /* Three times SIFS */
- dur += 10 * 3;
- /* Add ACK duration. */
- dur += ceiling_div(8 * (14 /*bytes*/) * 10,
- bitrate);
- /* Add CTS duration. */
- dur += ceiling_div(8 * (14 /*bytes*/) * 10,
- bitrate);
- }
-
- txhdr->rts_cts_frame_control = cpu_to_le16(fctl);
- txhdr->rts_cts_dur = cpu_to_le16(dur);
-//printk(BCM43xx_MACFMT " " BCM43xx_MACFMT " " BCM43xx_MACFMT "\n", BCM43xx_MACARG(wlhdr->addr1), BCM43xx_MACARG(wlhdr->addr2), BCM43xx_MACARG(wlhdr->addr3));
-//printk(BCM43xx_MACFMT " " BCM43xx_MACFMT "\n", BCM43xx_MACARG(sa), BCM43xx_MACARG(da));
- memcpy(txhdr->rts_cts_mac1, wlhdr->addr1, ETH_ALEN);//FIXME!
-// memcpy(txhdr->rts_cts_mac2, sa, ETH_ALEN);
-
- *flags |= BCM43xx_TXHDRFLAG_RTSCTS;
- *flags |= BCM43xx_TXHDRFLAG_RTS;
- if (ofdm_modulation)
- *flags |= BCM43xx_TXHDRFLAG_RTSCTS_OFDM;
- if (fallback_ofdm_modulation)
- *flags |= BCM43xx_TXHDRFLAG_RTSCTSFALLBACK_OFDM;
-}
-
-void bcm43xx_generate_txhdr(struct bcm43xx_private *bcm,
- struct bcm43xx_txhdr *txhdr,
- const unsigned char *fragment_data,
- const unsigned int fragment_len,
- const int is_first_fragment,
- const u16 cookie)
-{
- const struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- const struct ieee80211_hdr_4addr *wireless_header = (const struct ieee80211_hdr_4addr *)fragment_data;
- const struct ieee80211_security *secinfo = &bcm->ieee->sec;
- u8 bitrate;
- u8 fallback_bitrate;
- int ofdm_modulation;
- int fallback_ofdm_modulation;
- u16 plcp_fragment_len = fragment_len;
- u16 flags = 0;
- u16 control = 0;
- u16 wsec_rate = 0;
- u16 encrypt_frame;
- const u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(wireless_header->frame_ctl));
- const int is_mgt = (ftype == IEEE80211_FTYPE_MGMT);
-
- /* Now construct the TX header. */
- memset(txhdr, 0, sizeof(*txhdr));
-
- bitrate = ieee80211softmac_suggest_txrate(bcm->softmac,
- is_multicast_ether_addr(wireless_header->addr1), is_mgt);
- ofdm_modulation = !(ieee80211_is_cck_rate(bitrate));
- fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate);
- fallback_ofdm_modulation = !(ieee80211_is_cck_rate(fallback_bitrate));
-
- /* Set Frame Control from 80211 header. */
- txhdr->frame_control = wireless_header->frame_ctl;
- /* Copy address1 from 80211 header. */
- memcpy(txhdr->mac1, wireless_header->addr1, 6);
- /* Set the fallback duration ID. */
- txhdr->fallback_dur_id = bcm43xx_calc_duration_id((const struct ieee80211_hdr *)wireless_header,
- fallback_bitrate);
- /* Set the cookie (used as driver internal ID for the frame) */
- txhdr->cookie = cpu_to_le16(cookie);
-
- /* Hardware appends FCS. */
- plcp_fragment_len += IEEE80211_FCS_LEN;
-
- /* Hardware encryption. */
- encrypt_frame = le16_to_cpup(&wireless_header->frame_ctl) & IEEE80211_FCTL_PROTECTED;
- if (encrypt_frame && !bcm->ieee->host_encrypt) {
- const struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)wireless_header;
- memcpy(txhdr->wep_iv, hdr->payload, 4);
- /* Hardware appends ICV. */
- plcp_fragment_len += 4;
-
- wsec_rate |= (bcm->key[secinfo->active_key].algorithm << BCM43xx_TXHDR_WSEC_ALGO_SHIFT)
- & BCM43xx_TXHDR_WSEC_ALGO_MASK;
- wsec_rate |= (secinfo->active_key << BCM43xx_TXHDR_WSEC_KEYINDEX_SHIFT)
- & BCM43xx_TXHDR_WSEC_KEYINDEX_MASK;
- }
-
- /* Generate the PLCP header and the fallback PLCP header. */
- bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->plcp),
- plcp_fragment_len,
- bitrate, ofdm_modulation);
- bcm43xx_generate_plcp_hdr(&txhdr->fallback_plcp, plcp_fragment_len,
- fallback_bitrate, fallback_ofdm_modulation);
-
- /* Set the CONTROL field */
- if (ofdm_modulation)
- control |= BCM43xx_TXHDRCTL_OFDM;
- if (bcm->short_preamble) //FIXME: could be the other way around, please test
- control |= BCM43xx_TXHDRCTL_SHORT_PREAMBLE;
- control |= (phy->antenna_diversity << BCM43xx_TXHDRCTL_ANTENNADIV_SHIFT)
- & BCM43xx_TXHDRCTL_ANTENNADIV_MASK;
-
- /* Set the FLAGS field */
- if (!is_multicast_ether_addr(wireless_header->addr1) &&
- !is_broadcast_ether_addr(wireless_header->addr1))
- flags |= BCM43xx_TXHDRFLAG_EXPECTACK;
- if (1 /* FIXME: PS poll?? */)
- flags |= 0x10; // FIXME: unknown meaning.
- if (fallback_ofdm_modulation)
- flags |= BCM43xx_TXHDRFLAG_FALLBACKOFDM;
- if (is_first_fragment)
- flags |= BCM43xx_TXHDRFLAG_FIRSTFRAGMENT;
-
- /* Set WSEC/RATE field */
- wsec_rate |= (txhdr->plcp.raw[0] << BCM43xx_TXHDR_RATE_SHIFT)
- & BCM43xx_TXHDR_RATE_MASK;
-
- /* Generate the RTS/CTS packet, if required. */
- /* FIXME: We should first try with CTS-to-self,
- * if we are on 80211g. If we get too many
- * failures (hidden nodes), we should switch back to RTS/CTS.
- */
- if (0/*FIXME txctl->use_rts_cts*/) {
- bcm43xx_generate_rts(phy, txhdr, &flags,
- 0/*FIXME txctl->rts_cts_rate*/,
- wireless_header);
- }
-
- txhdr->flags = cpu_to_le16(flags);
- txhdr->control = cpu_to_le16(control);
- txhdr->wsec_rate = cpu_to_le16(wsec_rate);
-}
-
-static s8 bcm43xx_rssi_postprocess(struct bcm43xx_private *bcm,
- u8 in_rssi, int ofdm,
- int adjust_2053, int adjust_2050)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- s32 tmp;
-
- switch (radio->version) {
- case 0x2050:
- if (ofdm) {
- tmp = in_rssi;
- if (tmp > 127)
- tmp -= 256;
- tmp *= 73;
- tmp /= 64;
- if (adjust_2050)
- tmp += 25;
- else
- tmp -= 3;
- } else {
- if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
- if (in_rssi > 63)
- in_rssi = 63;
- tmp = radio->nrssi_lt[in_rssi];
- tmp = 31 - tmp;
- tmp *= -131;
- tmp /= 128;
- tmp -= 57;
- } else {
- tmp = in_rssi;
- tmp = 31 - tmp;
- tmp *= -149;
- tmp /= 128;
- tmp -= 68;
- }
- if (phy->type == BCM43xx_PHYTYPE_G &&
- adjust_2050)
- tmp += 25;
- }
- break;
- case 0x2060:
- if (in_rssi > 127)
- tmp = in_rssi - 256;
- else
- tmp = in_rssi;
- break;
- default:
- tmp = in_rssi;
- tmp -= 11;
- tmp *= 103;
- tmp /= 64;
- if (adjust_2053)
- tmp -= 109;
- else
- tmp -= 83;
- }
-
- return (s8)tmp;
-}
-
-//TODO
-#if 0
-static s8 bcm43xx_rssinoise_postprocess(struct bcm43xx_private *bcm,
- u8 in_rssi)
-{
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- s8 ret;
-
- if (phy->type == BCM43xx_PHYTYPE_A) {
- //TODO: Incomplete specs.
- ret = 0;
- } else
- ret = bcm43xx_rssi_postprocess(bcm, in_rssi, 0, 1, 1);
-
- return ret;
-}
-#endif
-
-int bcm43xx_rx(struct bcm43xx_private *bcm,
- struct sk_buff *skb,
- struct bcm43xx_rxhdr *rxhdr)
-{
- struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
- struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- struct bcm43xx_plcp_hdr4 *plcp;
- struct ieee80211_rx_stats stats;
- struct ieee80211_hdr_4addr *wlhdr;
- u16 frame_ctl;
- int is_packet_for_us = 0;
- int err = -EINVAL;
- const u16 rxflags1 = le16_to_cpu(rxhdr->flags1);
- const u16 rxflags2 = le16_to_cpu(rxhdr->flags2);
- const u16 rxflags3 = le16_to_cpu(rxhdr->flags3);
- const int is_ofdm = !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_OFDM);
-
- if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) {
- plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data + 2);
- /* Skip two unknown bytes and the PLCP header. */
- skb_pull(skb, 2 + sizeof(struct bcm43xx_plcp_hdr6));
- } else {
- plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data);
- /* Skip the PLCP header. */
- skb_pull(skb, sizeof(struct bcm43xx_plcp_hdr6));
- }
- /* The SKB contains the PAYLOAD (wireless header + data)
- * at this point. The FCS at the end is stripped.
- */
-
- memset(&stats, 0, sizeof(stats));
- stats.mac_time = le16_to_cpu(rxhdr->mactime);
- stats.rssi = rxhdr->rssi;
- stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,
- !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ),
- !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ));
- stats.noise = bcm->stats.noise;
- if (is_ofdm)
- stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp);
- else
- stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp);
- stats.received_channel = radio->channel;
- stats.mask = IEEE80211_STATMASK_SIGNAL |
- IEEE80211_STATMASK_NOISE |
- IEEE80211_STATMASK_RATE |
- IEEE80211_STATMASK_RSSI;
- if (phy->type == BCM43xx_PHYTYPE_A)
- stats.freq = IEEE80211_52GHZ_BAND;
- else
- stats.freq = IEEE80211_24GHZ_BAND;
- stats.len = skb->len;
-
- bcm->stats.last_rx = jiffies;
- if (bcm->ieee->iw_mode == IW_MODE_MONITOR) {
- err = ieee80211_rx(bcm->ieee, skb, &stats);
- return (err == 0) ? -EINVAL : 0;
- }
-
- wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);
-
- switch (bcm->ieee->iw_mode) {
- case IW_MODE_ADHOC:
- if (memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 ||
- memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 ||
- is_broadcast_ether_addr(wlhdr->addr1) ||
- is_multicast_ether_addr(wlhdr->addr1) ||
- bcm->net_dev->flags & IFF_PROMISC)
- is_packet_for_us = 1;
- break;
- case IW_MODE_INFRA:
- default:
- /* When receiving multicast or broadcast packets, filter out
- the packets we send ourself; we shouldn't see those */
- if (memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 ||
- memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 ||
- (memcmp(wlhdr->addr3, bcm->net_dev->dev_addr, ETH_ALEN) &&
- (is_broadcast_ether_addr(wlhdr->addr1) ||
- is_multicast_ether_addr(wlhdr->addr1) ||
- bcm->net_dev->flags & IFF_PROMISC)))
- is_packet_for_us = 1;
- break;
- }
-
- frame_ctl = le16_to_cpu(wlhdr->frame_ctl);
- switch (WLAN_FC_GET_TYPE(frame_ctl)) {
- case IEEE80211_FTYPE_MGMT:
- ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats);
- break;
- case IEEE80211_FTYPE_DATA:
- if (is_packet_for_us) {
- err = ieee80211_rx(bcm->ieee, skb, &stats);
- err = (err == 0) ? -EINVAL : 0;
- }
- break;
- case IEEE80211_FTYPE_CTL:
- break;
- default:
- assert(0);
- return -EINVAL;
- }
-
- return err;
-}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
deleted file mode 100644
index 47c135a7f4dc..000000000000
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
+++ /dev/null
@@ -1,150 +0,0 @@
-#ifndef BCM43xx_XMIT_H_
-#define BCM43xx_XMIT_H_
-
-#include "bcm43xx_main.h"
-
-
-#define _bcm43xx_declare_plcp_hdr(size) \
- struct bcm43xx_plcp_hdr##size { \
- union { \
- __le32 data; \
- __u8 raw[size]; \
- } __attribute__((__packed__)); \
- } __attribute__((__packed__))
-
-/* struct bcm43xx_plcp_hdr4 */
-_bcm43xx_declare_plcp_hdr(4);
-/* struct bcm43xx_plcp_hdr6 */
-_bcm43xx_declare_plcp_hdr(6);
-
-#undef _bcm43xx_declare_plcp_hdr
-
-/* Device specific TX header. To be prepended to TX frames. */
-struct bcm43xx_txhdr {
- union {
- struct {
- __le16 flags;
- __le16 wsec_rate;
- __le16 frame_control;
- u16 unknown_zeroed_0;
- __le16 control;
- u8 wep_iv[10];
- u8 unknown_wsec_tkip_data[3]; //FIXME
- PAD_BYTES(3);
- u8 mac1[6];
- u16 unknown_zeroed_1;
- struct bcm43xx_plcp_hdr4 rts_cts_fallback_plcp;
- __le16 rts_cts_dur_fallback;
- struct bcm43xx_plcp_hdr4 fallback_plcp;
- __le16 fallback_dur_id;
- PAD_BYTES(2);
- __le16 cookie;
- __le16 unknown_scb_stuff; //FIXME
- struct bcm43xx_plcp_hdr6 rts_cts_plcp;
- __le16 rts_cts_frame_control;
- __le16 rts_cts_dur;
- u8 rts_cts_mac1[6];
- u8 rts_cts_mac2[6];
- PAD_BYTES(2);
- struct bcm43xx_plcp_hdr6 plcp;
- } __attribute__((__packed__));
- u8 raw[82];
- } __attribute__((__packed__));
-} __attribute__((__packed__));
-
-/* Values/Masks for the device TX header */
-#define BCM43xx_TXHDRFLAG_EXPECTACK 0x0001
-#define BCM43xx_TXHDRFLAG_RTSCTS 0x0002
-#define BCM43xx_TXHDRFLAG_RTS 0x0004
-#define BCM43xx_TXHDRFLAG_FIRSTFRAGMENT 0x0008
-#define BCM43xx_TXHDRFLAG_DESTPSMODE 0x0020
-#define BCM43xx_TXHDRFLAG_RTSCTS_OFDM 0x0080
-#define BCM43xx_TXHDRFLAG_FALLBACKOFDM 0x0100
-#define BCM43xx_TXHDRFLAG_RTSCTSFALLBACK_OFDM 0x0200
-#define BCM43xx_TXHDRFLAG_CTS 0x0400
-#define BCM43xx_TXHDRFLAG_FRAMEBURST 0x0800
-
-#define BCM43xx_TXHDRCTL_OFDM 0x0001
-#define BCM43xx_TXHDRCTL_SHORT_PREAMBLE 0x0010
-#define BCM43xx_TXHDRCTL_ANTENNADIV_MASK 0x0030
-#define BCM43xx_TXHDRCTL_ANTENNADIV_SHIFT 8
-
-#define BCM43xx_TXHDR_RATE_MASK 0x0F00
-#define BCM43xx_TXHDR_RATE_SHIFT 8
-#define BCM43xx_TXHDR_RTSRATE_MASK 0xF000
-#define BCM43xx_TXHDR_RTSRATE_SHIFT 12
-#define BCM43xx_TXHDR_WSEC_KEYINDEX_MASK 0x00F0
-#define BCM43xx_TXHDR_WSEC_KEYINDEX_SHIFT 4
-#define BCM43xx_TXHDR_WSEC_ALGO_MASK 0x0003
-#define BCM43xx_TXHDR_WSEC_ALGO_SHIFT 0
-
-void bcm43xx_generate_txhdr(struct bcm43xx_private *bcm,
- struct bcm43xx_txhdr *txhdr,
- const unsigned char *fragment_data,
- const unsigned int fragment_len,
- const int is_first_fragment,
- const u16 cookie);
-
-/* RX header as received from the hardware. */
-struct bcm43xx_rxhdr {
- /* Frame Length. Must be generated explicitly in PIO mode. */
- __le16 frame_length;
- PAD_BYTES(2);
- /* Flags field 1 */
- __le16 flags1;
- u8 rssi;
- u8 signal_quality;
- PAD_BYTES(2);
- /* Flags field 3 */
- __le16 flags3;
- /* Flags field 2 */
- __le16 flags2;
- /* Lower 16bits of the TSF at the time the frame started. */
- __le16 mactime;
- PAD_BYTES(14);
-} __attribute__((__packed__));
-
-#define BCM43xx_RXHDR_FLAGS1_OFDM (1 << 0)
-/*#define BCM43xx_RXHDR_FLAGS1_SIGNAL??? (1 << 3) FIXME */
-#define BCM43xx_RXHDR_FLAGS1_SHORTPREAMBLE (1 << 7)
-#define BCM43xx_RXHDR_FLAGS1_2053RSSIADJ (1 << 14)
-
-#define BCM43xx_RXHDR_FLAGS2_INVALIDFRAME (1 << 0)
-#define BCM43xx_RXHDR_FLAGS2_TYPE2FRAME (1 << 2)
-/*FIXME: WEP related flags */
-
-#define BCM43xx_RXHDR_FLAGS3_2050RSSIADJ (1 << 10)
-
-/* Transmit Status as received from the hardware. */
-struct bcm43xx_hwxmitstatus {
- PAD_BYTES(4);
- __le16 cookie;
- u8 flags;
- u8 cnt1:4,
- cnt2:4;
- PAD_BYTES(2);
- __le16 seq;
- __le16 unknown; //FIXME
-} __attribute__((__packed__));
-
-/* Transmit Status in CPU byteorder. */
-struct bcm43xx_xmitstatus {
- u16 cookie;
- u8 flags;
- u8 cnt1:4,
- cnt2:4;
- u16 seq;
- u16 unknown; //FIXME
-};
-
-#define BCM43xx_TXSTAT_FLAG_AMPDU 0x10
-#define BCM43xx_TXSTAT_FLAG_INTER 0x20
-
-u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate);
-u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate);
-
-int bcm43xx_rx(struct bcm43xx_private *bcm,
- struct sk_buff *skb,
- struct bcm43xx_rxhdr *rxhdr);
-
-#endif /* BCM43xx_XMIT_H_ */
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 6b85cca9b3f1..59d9c90d3610 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_IWLCORE) += iwlcore.o
-iwlcore-objs = iwl-core.o
+iwlcore-objs = iwl-core.o iwl-eeprom.o
obj-$(CONFIG_IWL3945) += iwl3945.o
iwl3945-objs = iwl3945-base.o iwl-3945.o iwl-3945-rs.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
index 8b7ef9f1b57b..824a6e532de7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
index 28ecfe8d39a3..f1d002f7b790 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 7dc19136f41a..1ca6fa494e4b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
index 4a1872982027..0b9475114618 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 08604eb8291b..157e572ebc83 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
index b082a093ee26..e88b1d31f56f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 50a641c0c5b7..e116ed77c5ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -980,7 +980,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
priv->stations[sta_id].current_rate.rate_n_flags = rate;
if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
- (sta_id != IWL3945_BROADCAST_ID) &&
+ (sta_id != priv->hw_setting.bcast_sta_id) &&
(sta_id != IWL_MULTICAST_ID))
priv->stations[IWL_STA_ID].current_rate.rate_n_flags = rate;
@@ -2595,7 +2595,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
- tx_beacon_cmd->tx.sta_id = IWL3945_BROADCAST_ID;
+ tx_beacon_cmd->tx.sta_id = priv->hw_setting.bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl3945_fill_beacon_frame(priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 0ab22d366d93..931c465f9e5e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
index 327eabce182c..35f592dc40c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-debug.h b/drivers/net/wireless/iwlwifi/iwl-4965-debug.h
index baf07c715cf8..df329481bb45 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-debug.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 24413a479a3f..c66993eb5b6a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -92,316 +92,6 @@
/* RSSI to dBm */
#define IWL_RSSI_OFFSET 44
-/*
- * EEPROM related constants, enums, and structures.
- */
-
-/*
- * EEPROM access time values:
- *
- * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG,
- * then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit
- * CSR_EEPROM_REG_BIT_CMD (0x2).
- * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1).
- * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec.
- * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
- */
-#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */
-#define IWL_EEPROM_ACCESS_DELAY 10 /* uSec */
-
-/*
- * Regulatory channel usage flags in EEPROM struct iwl4965_eeprom_channel.flags.
- *
- * IBSS and/or AP operation is allowed *only* on those channels with
- * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because
- * RADAR detection is not supported by the 4965 driver, but is a
- * requirement for establishing a new network for legal operation on channels
- * requiring RADAR detection or restricting ACTIVE scanning.
- *
- * NOTE: "WIDE" flag does not indicate anything about "FAT" 40 MHz channels.
- * It only indicates that 20 MHz channel use is supported; FAT channel
- * usage is indicated by a separate set of regulatory flags for each
- * FAT channel pair.
- *
- * NOTE: Using a channel inappropriately will result in a uCode error!
- */
-enum {
- EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */
- EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */
- /* Bit 2 Reserved */
- EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */
- EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */
- EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */
- EEPROM_CHANNEL_NARROW = (1 << 6), /* 10 MHz channel (not used) */
- EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */
-};
-
-/* SKU Capabilities */
-#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
-#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
-
-/* *regulatory* channel data format in eeprom, one for each channel.
- * There are separate entries for FAT (40 MHz) vs. normal (20 MHz) channels. */
-struct iwl4965_eeprom_channel {
- u8 flags; /* EEPROM_CHANNEL_* flags copied from EEPROM */
- s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
-} __attribute__ ((packed));
-
-/* 4965 has two radio transmitters (and 3 radio receivers) */
-#define EEPROM_TX_POWER_TX_CHAINS (2)
-
-/* 4965 has room for up to 8 sets of txpower calibration data */
-#define EEPROM_TX_POWER_BANDS (8)
-
-/* 4965 factory calibration measures txpower gain settings for
- * each of 3 target output levels */
-#define EEPROM_TX_POWER_MEASUREMENTS (3)
-
-/* 4965 driver does not work with txpower calibration version < 5.
- * Look for this in calib_version member of struct iwl4965_eeprom. */
-#define EEPROM_TX_POWER_VERSION_NEW (5)
-
-
-/*
- * 4965 factory calibration data for one txpower level, on one channel,
- * measured on one of the 2 tx chains (radio transmitter and associated
- * antenna). EEPROM contains:
- *
- * 1) Temperature (degrees Celsius) of device when measurement was made.
- *
- * 2) Gain table index used to achieve the target measurement power.
- * This refers to the "well-known" gain tables (see iwl-4965-hw.h).
- *
- * 3) Actual measured output power, in half-dBm ("34" = 17 dBm).
- *
- * 4) RF power amplifier detector level measurement (not used).
- */
-struct iwl4965_eeprom_calib_measure {
- u8 temperature; /* Device temperature (Celsius) */
- u8 gain_idx; /* Index into gain table */
- u8 actual_pow; /* Measured RF output power, half-dBm */
- s8 pa_det; /* Power amp detector level (not used) */
-} __attribute__ ((packed));
-
-
-/*
- * 4965 measurement set for one channel. EEPROM contains:
- *
- * 1) Channel number measured
- *
- * 2) Measurements for each of 3 power levels for each of 2 radio transmitters
- * (a.k.a. "tx chains") (6 measurements altogether)
- */
-struct iwl4965_eeprom_calib_ch_info {
- u8 ch_num;
- struct iwl4965_eeprom_calib_measure measurements[EEPROM_TX_POWER_TX_CHAINS]
- [EEPROM_TX_POWER_MEASUREMENTS];
-} __attribute__ ((packed));
-
-/*
- * 4965 txpower subband info.
- *
- * For each frequency subband, EEPROM contains the following:
- *
- * 1) First and last channels within range of the subband. "0" values
- * indicate that this sample set is not being used.
- *
- * 2) Sample measurement sets for 2 channels close to the range endpoints.
- */
-struct iwl4965_eeprom_calib_subband_info {
- u8 ch_from; /* channel number of lowest channel in subband */
- u8 ch_to; /* channel number of highest channel in subband */
- struct iwl4965_eeprom_calib_ch_info ch1;
- struct iwl4965_eeprom_calib_ch_info ch2;
-} __attribute__ ((packed));
-
-
-/*
- * 4965 txpower calibration info. EEPROM contains:
- *
- * 1) Factory-measured saturation power levels (maximum levels at which
- * tx power amplifier can output a signal without too much distortion).
- * There is one level for 2.4 GHz band and one for 5 GHz band. These
- * values apply to all channels within each of the bands.
- *
- * 2) Factory-measured power supply voltage level. This is assumed to be
- * constant (i.e. same value applies to all channels/bands) while the
- * factory measurements are being made.
- *
- * 3) Up to 8 sets of factory-measured txpower calibration values.
- * These are for different frequency ranges, since txpower gain
- * characteristics of the analog radio circuitry vary with frequency.
- *
- * Not all sets need to be filled with data;
- * struct iwl4965_eeprom_calib_subband_info contains range of channels
- * (0 if unused) for each set of data.
- */
-struct iwl4965_eeprom_calib_info {
- u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */
- u8 saturation_power52; /* half-dBm */
- s16 voltage; /* signed */
- struct iwl4965_eeprom_calib_subband_info band_info[EEPROM_TX_POWER_BANDS];
-} __attribute__ ((packed));
-
-
-/*
- * 4965 EEPROM map
- */
-struct iwl4965_eeprom {
- u8 reserved0[16];
-#define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */
- u16 device_id; /* abs.ofs: 16 */
- u8 reserved1[2];
-#define EEPROM_PMC (2*0x0A) /* 2 bytes */
- u16 pmc; /* abs.ofs: 20 */
- u8 reserved2[20];
-#define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */
- u8 mac_address[6]; /* abs.ofs: 42 */
- u8 reserved3[58];
-#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */
- u16 board_revision; /* abs.ofs: 106 */
- u8 reserved4[11];
-#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */
- u8 board_pba_number[9]; /* abs.ofs: 119 */
- u8 reserved5[8];
-#define EEPROM_VERSION (2*0x44) /* 2 bytes */
- u16 version; /* abs.ofs: 136 */
-#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */
- u8 sku_cap; /* abs.ofs: 138 */
-#define EEPROM_LEDS_MODE (2*0x45+1) /* 1 bytes */
- u8 leds_mode; /* abs.ofs: 139 */
-#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */
- u16 oem_mode;
-#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */
- u16 wowlan_mode; /* abs.ofs: 142 */
-#define EEPROM_LEDS_TIME_INTERVAL (2*0x48) /* 2 bytes */
- u16 leds_time_interval; /* abs.ofs: 144 */
-#define EEPROM_LEDS_OFF_TIME (2*0x49) /* 1 bytes */
- u8 leds_off_time; /* abs.ofs: 146 */
-#define EEPROM_LEDS_ON_TIME (2*0x49+1) /* 1 bytes */
- u8 leds_on_time; /* abs.ofs: 147 */
-#define EEPROM_ALMGOR_M_VERSION (2*0x4A) /* 1 bytes */
- u8 almgor_m_version; /* abs.ofs: 148 */
-#define EEPROM_ANTENNA_SWITCH_TYPE (2*0x4A+1) /* 1 bytes */
- u8 antenna_switch_type; /* abs.ofs: 149 */
- u8 reserved6[8];
-#define EEPROM_4965_BOARD_REVISION (2*0x4F) /* 2 bytes */
- u16 board_revision_4965; /* abs.ofs: 158 */
- u8 reserved7[13];
-#define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */
- u8 board_pba_number_4965[9]; /* abs.ofs: 173 */
- u8 reserved8[10];
-#define EEPROM_REGULATORY_SKU_ID (2*0x60) /* 4 bytes */
- u8 sku_id[4]; /* abs.ofs: 192 */
-
-/*
- * Per-channel regulatory data.
- *
- * Each channel that *might* be supported by 3945 or 4965 has a fixed location
- * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
- * txpower (MSB).
- *
- * Entries immediately below are for 20 MHz channel width. FAT (40 MHz)
- * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
- *
- * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
- */
-#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */
- u16 band_1_count; /* abs.ofs: 196 */
-#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */
- struct iwl4965_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */
-
-/*
- * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
- * 5.0 GHz channels 7, 8, 11, 12, 16
- * (4915-5080MHz) (none of these is ever supported)
- */
-#define EEPROM_REGULATORY_BAND_2 (2*0x71) /* 2 bytes */
- u16 band_2_count; /* abs.ofs: 226 */
-#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */
- struct iwl4965_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */
-
-/*
- * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
- * (5170-5320MHz)
- */
-#define EEPROM_REGULATORY_BAND_3 (2*0x7F) /* 2 bytes */
- u16 band_3_count; /* abs.ofs: 254 */
-#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */
- struct iwl4965_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */
-
-/*
- * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
- * (5500-5700MHz)
- */
-#define EEPROM_REGULATORY_BAND_4 (2*0x8C) /* 2 bytes */
- u16 band_4_count; /* abs.ofs: 280 */
-#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */
- struct iwl4965_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */
-
-/*
- * 5.7 GHz channels 145, 149, 153, 157, 161, 165
- * (5725-5825MHz)
- */
-#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */
- u16 band_5_count; /* abs.ofs: 304 */
-#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */
- struct iwl4965_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */
-
- u8 reserved10[2];
-
-
-/*
- * 2.4 GHz FAT channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11)
- *
- * The channel listed is the center of the lower 20 MHz half of the channel.
- * The overall center frequency is actually 2 channels (10 MHz) above that,
- * and the upper half of each FAT channel is centered 4 channels (20 MHz) away
- * from the lower half; e.g. the upper half of FAT channel 1 is channel 5,
- * and the overall FAT channel width centers on channel 3.
- *
- * NOTE: The RXON command uses 20 MHz channel numbers to specify the
- * control channel to which to tune. RXON also specifies whether the
- * control channel is the upper or lower half of a FAT channel.
- *
- * NOTE: 4965 does not support FAT channels on 2.4 GHz.
- */
-#define EEPROM_REGULATORY_BAND_24_FAT_CHANNELS (2*0xA0) /* 14 bytes */
- struct iwl4965_eeprom_channel band_24_channels[7]; /* abs.ofs: 320 */
- u8 reserved11[2];
-
-/*
- * 5.2 GHz FAT channels 36 (40), 44 (48), 52 (56), 60 (64),
- * 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161)
- */
-#define EEPROM_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8) /* 22 bytes */
- struct iwl4965_eeprom_channel band_52_channels[11]; /* abs.ofs: 336 */
- u8 reserved12[6];
-
-/*
- * 4965 driver requires txpower calibration format version 5 or greater.
- * Driver does not work with txpower calibration version < 5.
- * This value is simply a 16-bit number, no major/minor versions here.
- */
-#define EEPROM_CALIB_VERSION_OFFSET (2*0xB6) /* 2 bytes */
- u16 calib_version; /* abs.ofs: 364 */
- u8 reserved13[2];
- u8 reserved14[96]; /* abs.ofs: 368 */
-
-/*
- * 4965 Txpower calibration data.
- */
-#define EEPROM_IWL_CALIB_TXPOWER_OFFSET (2*0xE8) /* 48 bytes */
- struct iwl4965_eeprom_calib_info calib_info; /* abs.ofs: 464 */
-
- u8 reserved16[140]; /* fill out to full 1024 byte block */
-
-
-} __attribute__ ((packed));
-
-#define IWL_EEPROM_IMAGE_SIZE 1024
-
-/* End of EEPROM */
#include "iwl-4965-commands.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-io.h b/drivers/net/wireless/iwlwifi/iwl-4965-io.h
index 4af0c0175da2..07fca8888f40 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-io.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 25e73864c2a4..4b46226ff350 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
index 911f21396fd0..ae827e1fb0fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 2f01a490c9ee..3401f2a30cc5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -38,6 +38,7 @@
#include <linux/etherdevice.h>
#include <asm/unaligned.h>
+#include "iwl-eeprom.h"
#include "iwl-core.h"
#include "iwl-4965.h"
#include "iwl-helpers.h"
@@ -254,7 +255,7 @@ u8 iwl4965_hw_find_station(struct iwl4965_priv *priv, const u8 *addr)
start = IWL_STA_ID;
if (is_broadcast_ether_addr(addr))
- return IWL4965_BROADCAST_ID;
+ return priv->hw_setting.bcast_sta_id;
spin_lock_irqsave(&priv->sta_lock, flags);
for (i = start; i < priv->hw_setting.max_stations; i++)
@@ -2836,7 +2837,7 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl4965_priv *priv,
tx_beacon_cmd = &frame->u.beacon;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
- tx_beacon_cmd->tx.sta_id = IWL4965_BROADCAST_ID;
+ tx_beacon_cmd->tx.sta_id = priv->hw_setting.bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl4965_fill_beacon_frame(priv,
@@ -4262,7 +4263,7 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv,
"%d, scd_ssn = %d\n",
ba_resp->tid,
ba_resp->seq_ctl,
- (unsigned long long)ba_resp->bitmap,
+ (unsigned long long)le64_to_cpu(ba_resp->bitmap),
ba_resp->scd_flow,
ba_resp->scd_ssn);
IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n",
@@ -4436,7 +4437,7 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap)
link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000);
/* Update the rate scaling for control frame Tx to AP */
- link_cmd.sta_id = is_ap ? IWL_AP_ID : IWL4965_BROADCAST_ID;
+ link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_setting.bcast_sta_id;
iwl4965_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD, sizeof(link_cmd),
&link_cmd);
@@ -4824,10 +4825,23 @@ void iwl4965_hw_cancel_deferred_work(struct iwl4965_priv *priv)
cancel_delayed_work(&priv->init_alive_start);
}
+static struct iwl_lib_ops iwl4965_lib = {
+ .eeprom_ops = {
+ .verify_signature = iwlcore_eeprom_verify_signature,
+ .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
+ .release_semaphore = iwlcore_eeprom_release_semaphore,
+ },
+};
+
+static struct iwl_ops iwl4965_ops = {
+ .lib = &iwl4965_lib,
+};
+
static struct iwl_cfg iwl4965_agn_cfg = {
.name = "4965AGN",
.fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode",
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl4965_ops,
};
struct pci_device_id iwl4965_hw_card_ids[] = {
@@ -4836,35 +4850,4 @@ struct pci_device_id iwl4965_hw_card_ids[] = {
{0}
};
-/*
- * The device's EEPROM semaphore prevents conflicts between driver and uCode
- * when accessing the EEPROM; each access is a series of pulses to/from the
- * EEPROM chip, not a single event, so even reads could conflict if they
- * weren't arbitrated by the semaphore.
- */
-int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv)
-{
- u16 count;
- int rc;
-
- for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
- /* Request semaphore */
- iwl4965_set_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
- /* See if we got it */
- rc = iwl4965_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
- EEPROM_SEM_TIMEOUT);
- if (rc >= 0) {
- IWL_DEBUG_IO("Acquired semaphore after %d tries.\n",
- count+1);
- return rc;
- }
- }
-
- return rc;
-}
-
MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h
index 057fa15d62fd..f4e395fcb807 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -40,6 +40,7 @@
extern struct pci_device_id iwl4965_hw_card_ids[];
#define DRV_NAME "iwl4965"
+#include "iwl-eeprom.h"
#include "iwl-4965-hw.h"
#include "iwl-csr.h"
#include "iwl-prph.h"
@@ -640,7 +641,6 @@ extern u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr,
extern int iwl4965_is_network_packet(struct iwl4965_priv *priv,
struct ieee80211_hdr *header);
extern int iwl4965_power_init_handle(struct iwl4965_priv *priv);
-extern int iwl4965_eeprom_init(struct iwl4965_priv *priv);
extern void iwl4965_handle_data_packet_monitor(struct iwl4965_priv *priv,
struct iwl4965_rx_mem_buffer *rxb,
void *data, short len,
@@ -746,8 +746,6 @@ struct iwl4965_priv;
/*
* Forward declare iwl-4965.c functions for iwl-base.c
*/
-extern int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv);
-
extern int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv,
struct iwl4965_tx_queue *txq,
u16 byte_cnt);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 675b34b696b4..9ca539861db2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1,8 +1,5 @@
/******************************************************************************
*
- * This file is provided under a dual BSD/GPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 Intel Corporation. All rights reserved.
@@ -34,6 +31,7 @@
#include <linux/version.h>
#include "iwl-4965-debug.h"
+#include "iwl-eeprom.h"
#include "iwl-core.h"
MODULE_DESCRIPTION("iwl core");
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index bdd32f891683..88fd49abdabd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -75,10 +75,20 @@
#define IWL_SKU_A 0x2
#define IWL_SKU_N 0x8
+struct iwl_lib_ops {
+ /* eeprom operations (as defined in iwl-eeprom.h) */
+ struct iwl_eeprom_ops eeprom_ops;
+};
+
+struct iwl_ops {
+ const struct iwl_lib_ops *lib;
+};
+
struct iwl_cfg {
const char *name;
const char *fw_name;
unsigned int sku;
+ const struct iwl_ops *ops;
};
#endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 7016e5b41c58..f0a2c8d180f0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 736b88881b03..a443472bea62 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 4ba121634877..ecf651ae2593 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
index b576ff24eb4f..a40a2174df98 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ieee80211 subsystem header files.
*
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index ecf749c2dc0a..093b863ef904 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -93,7 +93,7 @@ int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */
#endif
#define IWLWIFI_VERSION "1.2.26k" VD VS
-#define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation"
+#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
#define DRV_VERSION IWLWIFI_VERSION
@@ -6309,18 +6309,23 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
- if (direct_mask)
+ if (direct_mask) {
IWL_DEBUG_SCAN
("Initiating direct scan for %s.\n",
iwl3945_escape_essid(priv->essid, priv->essid_len));
- else
+ scan->channel_count =
+ iwl3945_get_channels_for_scan(
+ priv, band, 1, /* active */
+ direct_mask,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ } else {
IWL_DEBUG_SCAN("Initiating indirect scan.\n");
-
- scan->channel_count =
- iwl3945_get_channels_for_scan(
- priv, band, 1, /* active */
- direct_mask,
- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ scan->channel_count =
+ iwl3945_get_channels_for_scan(
+ priv, band, 0, /* passive */
+ direct_mask,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ }
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
scan->channel_count * sizeof(struct iwl3945_scan_channel);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 28c64c39ef02..0b7335181719 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -45,6 +45,7 @@
#include <asm/div64.h>
+#include "iwl-eeprom.h"
#include "iwl-core.h"
#include "iwl-4965.h"
#include "iwl-helpers.h"
@@ -1562,85 +1563,6 @@ static int iwl4965_send_beacon_cmd(struct iwl4965_priv *priv)
/******************************************************************************
*
- * EEPROM related functions
- *
- ******************************************************************************/
-
-static void get_eeprom_mac(struct iwl4965_priv *priv, u8 *mac)
-{
- memcpy(mac, priv->eeprom.mac_address, 6);
-}
-
-static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
-{
- iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-}
-
-/**
- * iwl4965_eeprom_init - read EEPROM contents
- *
- * Load the EEPROM contents from adapter into priv->eeprom
- *
- * NOTE: This routine uses the non-debug IO access functions.
- */
-int iwl4965_eeprom_init(struct iwl4965_priv *priv)
-{
- u16 *e = (u16 *)&priv->eeprom;
- u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP);
- u32 r;
- int sz = sizeof(priv->eeprom);
- int rc;
- int i;
- u16 addr;
-
- /* The EEPROM structure has several padding buffers within it
- * and when adding new EEPROM maps is subject to programmer errors
- * which may be very difficult to identify without explicitly
- * checking the resulting size of the eeprom map. */
- BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
-
- if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
- return -ENOENT;
- }
-
- /* Make sure driver (instead of uCode) is allowed to read EEPROM */
- rc = iwl4965_eeprom_acquire_semaphore(priv);
- if (rc < 0) {
- IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
- return -ENOENT;
- }
-
- /* eeprom is an array of 16bit values */
- for (addr = 0; addr < sz; addr += sizeof(u16)) {
- _iwl4965_write32(priv, CSR_EEPROM_REG, addr << 1);
- _iwl4965_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
-
- for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
- i += IWL_EEPROM_ACCESS_DELAY) {
- r = _iwl4965_read_direct32(priv, CSR_EEPROM_REG);
- if (r & CSR_EEPROM_REG_READ_VALID_MSK)
- break;
- udelay(IWL_EEPROM_ACCESS_DELAY);
- }
-
- if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
- IWL_ERROR("Time out reading EEPROM[%d]", addr);
- rc = -ETIMEDOUT;
- goto done;
- }
- e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
- }
- rc = 0;
-
-done:
- iwl4965_eeprom_release_semaphore(priv);
- return rc;
-}
-
-/******************************************************************************
- *
* Misc. internal state and helper functions
*
******************************************************************************/
@@ -5528,8 +5450,9 @@ static void iwl4965_init_hw_rates(struct iwl4965_priv *priv,
/*
* If CCK != 1M then set short preamble rate flag.
*/
- rates[i].flags |= (iwl4965_rates[i].plcp == 10) ?
- 0 : IEEE80211_RATE_SHORT_PREAMBLE;
+ rates[i].flags |=
+ (iwl4965_rates[i].plcp == IWL_RATE_1M_PLCP) ?
+ 0 : IEEE80211_RATE_SHORT_PREAMBLE;
}
}
}
@@ -6821,18 +6744,23 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
- if (direct_mask)
+ if (direct_mask) {
IWL_DEBUG_SCAN
("Initiating direct scan for %s.\n",
iwl4965_escape_essid(priv->essid, priv->essid_len));
- else
+ scan->channel_count =
+ iwl4965_get_channels_for_scan(
+ priv, band, 1, /* active */
+ direct_mask,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ } else {
IWL_DEBUG_SCAN("Initiating indirect scan.\n");
-
- scan->channel_count =
- iwl4965_get_channels_for_scan(
- priv, band, 1, /* active */
- direct_mask,
- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ scan->channel_count =
+ iwl4965_get_channels_for_scan(
+ priv, band, 0, /* passive */
+ direct_mask,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ }
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
scan->channel_count * sizeof(struct iwl4965_scan_channel);
@@ -8765,13 +8693,13 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
goto out_remove_sysfs;
}
/* Read the EEPROM */
- err = iwl4965_eeprom_init(priv);
+ err = iwl_eeprom_init(priv);
if (err) {
IWL_ERROR("Unable to init EEPROM\n");
goto out_remove_sysfs;
}
/* MAC Address location in EEPROM same for 3945/4965 */
- get_eeprom_mac(priv, priv->mac_addr);
+ iwl_eeprom_get_mac(priv, priv->mac_addr);
IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 7fe37bedf313..707b7ff592ec 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -38,7 +38,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
escape_essid(assoc_req->ssid, assoc_req->ssid_len));
if (assoc_req->mode == IW_MODE_INFRA) {
lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
- assoc_req->ssid_len, 0);
+ assoc_req->ssid_len);
bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
@@ -53,7 +53,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
* scan data will cause us to join a non-existant adhoc network
*/
lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
- assoc_req->ssid_len, 1);
+ assoc_req->ssid_len);
/* Search for the requested SSID in the scan table */
bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index b600f2439b57..8f88786b036f 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -164,173 +164,6 @@ out_unlock:
return ret;
}
-static ssize_t lbs_extscan(struct file *file, const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t res, buf_size;
- union iwreq_data wrqu;
- unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *)addr;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_unlock;
- }
-
- lbs_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0);
-
- memset(&wrqu, 0, sizeof(union iwreq_data));
- wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
-
-out_unlock:
- free_page(addr);
- return count;
-}
-
-static void lbs_parse_bssid(char *buf, size_t count,
- struct lbs_ioctl_user_scan_cfg *scan_cfg)
-{
- char *hold;
- unsigned int mac[ETH_ALEN];
-
- hold = strstr(buf, "bssid=");
- if (!hold)
- return;
- hold += 6;
- sscanf(hold, "%02x:%02x:%02x:%02x:%02x:%02x",
- mac, mac+1, mac+2, mac+3, mac+4, mac+5);
- memcpy(scan_cfg->bssid, mac, ETH_ALEN);
-}
-
-static void lbs_parse_ssid(char *buf, size_t count,
- struct lbs_ioctl_user_scan_cfg *scan_cfg)
-{
- char *hold, *end;
- ssize_t size;
-
- hold = strstr(buf, "ssid=");
- if (!hold)
- return;
- hold += 5;
- end = strchr(hold, ' ');
- if (!end)
- end = buf + count - 1;
-
- size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
- strncpy(scan_cfg->ssid, hold, size);
-
- return;
-}
-
-static int lbs_parse_clear(char *buf, size_t count, const char *tag)
-{
- char *hold;
- int val;
-
- hold = strstr(buf, tag);
- if (!hold)
- return 0;
- hold += strlen(tag);
- sscanf(hold, "%d", &val);
-
- if (val != 0)
- val = 1;
-
- return val;
-}
-
-static int lbs_parse_dur(char *buf, size_t count,
- struct lbs_ioctl_user_scan_cfg *scan_cfg)
-{
- char *hold;
- int val;
-
- hold = strstr(buf, "dur=");
- if (!hold)
- return 0;
- hold += 4;
- sscanf(hold, "%d", &val);
-
- return val;
-}
-
-static void lbs_parse_type(char *buf, size_t count,
- struct lbs_ioctl_user_scan_cfg *scan_cfg)
-{
- char *hold;
- int val;
-
- hold = strstr(buf, "type=");
- if (!hold)
- return;
- hold += 5;
- sscanf(hold, "%d", &val);
-
- /* type=1,2 or 3 */
- if (val < 1 || val > 3)
- return;
-
- scan_cfg->bsstype = val;
-
- return;
-}
-
-static ssize_t lbs_setuserscan(struct file *file,
- const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct lbs_private *priv = file->private_data;
- ssize_t res, buf_size;
- struct lbs_ioctl_user_scan_cfg *scan_cfg;
- union iwreq_data wrqu;
- int dur;
- char *buf = (char *)get_zeroed_page(GFP_KERNEL);
-
- if (!buf)
- return -ENOMEM;
-
- buf_size = min(count, len - 1);
- if (copy_from_user(buf, userbuf, buf_size)) {
- res = -EFAULT;
- goto out_buf;
- }
-
- scan_cfg = kzalloc(sizeof(struct lbs_ioctl_user_scan_cfg), GFP_KERNEL);
- if (!scan_cfg) {
- res = -ENOMEM;
- goto out_buf;
- }
- res = count;
-
- scan_cfg->bsstype = LBS_SCAN_BSS_TYPE_ANY;
-
- dur = lbs_parse_dur(buf, count, scan_cfg);
- lbs_parse_bssid(buf, count, scan_cfg);
- scan_cfg->clear_bssid = lbs_parse_clear(buf, count, "clear_bssid=");
- lbs_parse_ssid(buf, count, scan_cfg);
- scan_cfg->clear_ssid = lbs_parse_clear(buf, count, "clear_ssid=");
- lbs_parse_type(buf, count, scan_cfg);
-
- lbs_scan_networks(priv, scan_cfg, 1);
- wait_event_interruptible(priv->cmd_pending,
- priv->surpriseremoved || !priv->scan_channel);
-
- if (priv->surpriseremoved)
- goto out_scan_cfg;
-
- memset(&wrqu, 0x00, sizeof(union iwreq_data));
- wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
-
- out_scan_cfg:
- kfree(scan_cfg);
- out_buf:
- free_page((unsigned long)buf);
- return res;
-}
-
-
/*
* When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might
* get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the
@@ -857,8 +690,6 @@ static struct lbs_debugfs_files debugfs_files[] = {
write_file_dummy), },
{ "sleepparams", 0644, FOPS(lbs_sleepparams_read,
lbs_sleepparams_write), },
- { "extscan", 0600, FOPS(NULL, lbs_extscan), },
- { "setuserscan", 0600, FOPS(NULL, lbs_setuserscan), },
};
static struct lbs_debugfs_files debugfs_events_files[] = {
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index fd1fcc748010..ff2c046ca73f 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -149,6 +149,8 @@ struct lbs_private {
struct work_struct sync_channel;
/* remember which channel was scanned last, != 0 if currently scanning */
int scan_channel;
+ u8 scan_ssid[IW_ESSID_MAX_SIZE + 1];
+ u8 scan_ssid_len;
/** Hardware access */
int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 99f11a56d84e..0598541451d8 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -260,24 +260,12 @@ done:
-
/*********************************************************************/
/* */
/* Main scanning support */
/* */
/*********************************************************************/
-void lbs_scan_worker(struct work_struct *work)
-{
- struct lbs_private *priv =
- container_of(work, struct lbs_private, scan_work.work);
-
- lbs_deb_enter(LBS_DEB_SCAN);
- lbs_scan_networks(priv, NULL, 0);
- lbs_deb_leave(LBS_DEB_SCAN);
-}
-
-
/**
* @brief Create a channel list for the driver to scan based on region info
*
@@ -289,17 +277,11 @@ void lbs_scan_worker(struct work_struct *work)
*
* @param priv A pointer to struct lbs_private structure
* @param scanchanlist Output parameter: resulting channel list to scan
- * @param filteredscan Flag indicating whether or not a BSSID or SSID filter
- * is being sent in the command to firmware. Used to
- * increase the number of channels sent in a scan
- * command and to disable the firmware channel scan
- * filter.
*
* @return void
*/
static int lbs_scan_create_channel_list(struct lbs_private *priv,
- struct chanscanparamset *scanchanlist,
- uint8_t filteredscan)
+ struct chanscanparamset *scanchanlist)
{
struct region_channel *scanregion;
struct chan_freq_power *cfp;
@@ -354,9 +336,6 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv,
}
chan->channumber = cfp->channel;
-
- if (filteredscan)
- chan->chanscanmode.disablechanfilt = 1;
}
}
return chanidx;
@@ -370,15 +349,14 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv,
* length 06 00
* ssid 4d 4e 54 45 53 54
*/
-static int lbs_scan_add_ssid_tlv(uint8_t *tlv,
- const struct lbs_ioctl_user_scan_cfg *user_cfg)
+static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv)
{
struct mrvlietypes_ssidparamset *ssid_tlv = (void *)tlv;
ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
- ssid_tlv->header.len = cpu_to_le16(user_cfg->ssid_len);
- memcpy(ssid_tlv->ssid, user_cfg->ssid, user_cfg->ssid_len);
- return sizeof(ssid_tlv->header) + user_cfg->ssid_len;
+ ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len);
+ memcpy(ssid_tlv->ssid, priv->scan_ssid, priv->scan_ssid_len);
+ return sizeof(ssid_tlv->header) + priv->scan_ssid_len;
}
@@ -461,8 +439,7 @@ static int lbs_scan_add_rates_tlv(uint8_t *tlv)
* for a bunch of channels.
*/
static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype,
- struct chanscanparamset *chan_list, int chan_count,
- const struct lbs_ioctl_user_scan_cfg *user_cfg)
+ struct chanscanparamset *chan_list, int chan_count)
{
int ret = -ENOMEM;
struct cmd_ds_802_11_scan *scan_cmd;
@@ -477,13 +454,13 @@ static int lbs_do_scan(struct lbs_private *priv, uint8_t bsstype,
goto out;
tlv = scan_cmd->tlvbuffer;
- if (user_cfg)
- memcpy(scan_cmd->bssid, user_cfg->bssid, ETH_ALEN);
+ /* TODO: do we need to scan for a specific BSSID?
+ memcpy(scan_cmd->bssid, priv->scan_bssid, ETH_ALEN); */
scan_cmd->bsstype = bsstype;
/* add TLVs */
- if (user_cfg && user_cfg->ssid_len)
- tlv += lbs_scan_add_ssid_tlv(tlv, user_cfg);
+ if (priv->scan_ssid_len)
+ tlv += lbs_scan_add_ssid_tlv(priv, tlv);
if (chan_list && chan_count)
tlv += lbs_scan_add_chanlist_tlv(tlv, chan_list, chan_count);
tlv += lbs_scan_add_rates_tlv(tlv);
@@ -516,14 +493,11 @@ out:
* update the internal driver scan table
*
* @param priv A pointer to struct lbs_private structure
- * @param puserscanin Pointer to the input configuration for the requested
- * scan.
+ * @param full_scan Do a full-scan (blocking)
*
* @return 0 or < 0 if error
*/
-int lbs_scan_networks(struct lbs_private *priv,
- const struct lbs_ioctl_user_scan_cfg *user_cfg,
- int full_scan)
+static int lbs_scan_networks(struct lbs_private *priv, int full_scan)
{
int ret = -ENOMEM;
struct chanscanparamset *chan_list;
@@ -531,7 +505,6 @@ int lbs_scan_networks(struct lbs_private *priv,
int chan_count;
uint8_t bsstype = CMD_BSS_TYPE_ANY;
int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD;
- int filteredscan = 0;
union iwreq_data wrqu;
#ifdef CONFIG_LIBERTAS_DEBUG
struct bss_descriptor *iter;
@@ -547,17 +520,16 @@ int lbs_scan_networks(struct lbs_private *priv,
if (full_scan && delayed_work_pending(&priv->scan_work))
cancel_delayed_work(&priv->scan_work);
- /* Determine same scan parameters */
+ /* User-specified bsstype or channel list
+ TODO: this can be implemented if some user-space application
+ need the feature. Formerly, it was accessible from debugfs,
+ but then nowhere used.
if (user_cfg) {
if (user_cfg->bsstype)
- bsstype = user_cfg->bsstype;
- if (!is_zero_ether_addr(user_cfg->bssid)) {
- numchannels = MRVDRV_MAX_CHANNELS_PER_SCAN;
- filteredscan = 1;
- }
- }
- lbs_deb_scan("numchannels %d, bsstype %d, filteredscan %d\n",
- numchannels, bsstype, filteredscan);
+ bsstype = user_cfg->bsstype;
+ } */
+
+ lbs_deb_scan("numchannels %d, bsstype %d\n", numchannels, bsstype);
/* Create list of channels to scan */
chan_list = kzalloc(sizeof(struct chanscanparamset) *
@@ -568,7 +540,7 @@ int lbs_scan_networks(struct lbs_private *priv,
}
/* We want to scan all channels */
- chan_count = lbs_scan_create_channel_list(priv, chan_list, filteredscan);
+ chan_count = lbs_scan_create_channel_list(priv, chan_list);
netif_stop_queue(priv->dev);
netif_carrier_off(priv->dev);
@@ -597,7 +569,7 @@ int lbs_scan_networks(struct lbs_private *priv,
lbs_deb_scan("scanning %d of %d channels\n",
to_scan, chan_count);
ret = lbs_do_scan(priv, bsstype, curr_chans,
- to_scan, user_cfg);
+ to_scan);
if (ret) {
lbs_pr_err("SCAN_CMD failed\n");
goto out2;
@@ -658,6 +630,17 @@ out:
+void lbs_scan_worker(struct work_struct *work)
+{
+ struct lbs_private *priv =
+ container_of(work, struct lbs_private, scan_work.work);
+
+ lbs_deb_enter(LBS_DEB_SCAN);
+ lbs_scan_networks(priv, 0);
+ lbs_deb_leave(LBS_DEB_SCAN);
+}
+
+
/*********************************************************************/
/* */
/* Result interpretation */
@@ -1068,7 +1051,7 @@ static struct bss_descriptor *lbs_find_best_ssid_in_list(struct lbs_private *pri
}
/**
- * @brief Find the AP with specific ssid in the scan list
+ * @brief Find the best AP
*
* Used from association worker.
*
@@ -1086,7 +1069,8 @@ int lbs_find_best_network_ssid(struct lbs_private *priv, uint8_t *out_ssid,
lbs_deb_enter(LBS_DEB_SCAN);
- lbs_scan_networks(priv, NULL, 1);
+ priv->scan_ssid_len = 0;
+ lbs_scan_networks(priv, 1);
if (priv->surpriseremoved)
goto out;
@@ -1112,29 +1096,24 @@ out:
* @param priv A pointer to struct lbs_private structure
* @param ssid A pointer to the SSID to scan for
* @param ssid_len Length of the SSID
- * @param clear_ssid Should existing scan results with this SSID
- * be cleared?
*
* @return 0-success, otherwise fail
*/
int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid,
- uint8_t ssid_len, uint8_t clear_ssid)
+ uint8_t ssid_len)
{
- struct lbs_ioctl_user_scan_cfg scancfg;
int ret = 0;
- lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s', clear %d",
- escape_essid(ssid, ssid_len), clear_ssid);
+ lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s'\n",
+ escape_essid(ssid, ssid_len));
if (!ssid_len)
goto out;
- memset(&scancfg, 0x00, sizeof(scancfg));
- memcpy(scancfg.ssid, ssid, ssid_len);
- scancfg.ssid_len = ssid_len;
- scancfg.clear_ssid = clear_ssid;
+ memcpy(priv->scan_ssid, ssid, ssid_len);
+ priv->scan_ssid_len = ssid_len;
- lbs_scan_networks(priv, &scancfg, 1);
+ lbs_scan_networks(priv, 1);
if (priv->surpriseremoved) {
ret = -1;
goto out;
@@ -1317,27 +1296,36 @@ out:
* @return 0 --success, otherwise fail
*/
int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *wrqu, char *extra)
+ union iwreq_data *wrqu, char *extra)
{
struct lbs_private *priv = dev->priv;
+ int ret = 0;
- lbs_deb_enter(LBS_DEB_SCAN);
+ lbs_deb_enter(LBS_DEB_WEXT);
- if (!netif_running(dev))
- return -ENETDOWN;
+ if (!netif_running(dev)) {
+ ret = -ENETDOWN;
+ goto out;
+ }
/* mac80211 does this:
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->type != IEEE80211_IF_TYPE_xxx)
- return -EOPNOTSUPP;
+ if (sdata->type != IEEE80211_IF_TYPE_xxx) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+ */
if (wrqu->data.length == sizeof(struct iw_scan_req) &&
wrqu->data.flags & IW_SCAN_THIS_ESSID) {
- req = (struct iw_scan_req *)extra;
- ssid = req->essid;
- ssid_len = req->essid_len;
+ struct iw_scan_req *req = (struct iw_scan_req *)extra;
+ priv->scan_ssid_len = req->essid_len;
+ memcpy(priv->scan_ssid, req->essid, priv->scan_ssid_len);
+ lbs_deb_wext("set_scan, essid '%s'\n",
+ escape_essid(priv->scan_ssid, priv->scan_ssid_len));
+ } else {
+ priv->scan_ssid_len = 0;
}
- */
if (!delayed_work_pending(&priv->scan_work))
queue_delayed_work(priv->work_thread, &priv->scan_work,
@@ -1346,10 +1334,11 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
priv->scan_channel = -1;
if (priv->surpriseremoved)
- return -EIO;
+ ret = -EIO;
- lbs_deb_leave(LBS_DEB_SCAN);
- return 0;
+out:
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+ return ret;
}
@@ -1374,7 +1363,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
struct bss_descriptor *iter_bss;
struct bss_descriptor *safe;
- lbs_deb_enter(LBS_DEB_SCAN);
+ lbs_deb_enter(LBS_DEB_WEXT);
/* iwlist should wait until the current scan is finished */
if (priv->scan_channel)
@@ -1418,7 +1407,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
dwrq->length = (ev - extra);
dwrq->flags = 0;
- lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", err);
+ lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", err);
return err;
}
diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h
index 10d1196acf78..c50c8b74714b 100644
--- a/drivers/net/wireless/libertas/scan.h
+++ b/drivers/net/wireless/libertas/scan.h
@@ -12,8 +12,6 @@
/**
* @brief Maximum number of channels that can be sent in a setuserscan ioctl
- *
- * @sa lbs_ioctl_user_scan_cfg
*/
#define LBS_IOCTL_USER_SCAN_CHAN_MAX 50
@@ -27,60 +25,6 @@
#define LBS_SCAN_BSS_TYPE_ANY 3
/**
- * @brief IOCTL channel sub-structure sent in lbs_ioctl_user_scan_cfg
- *
- * Multiple instances of this structure are included in the IOCTL command
- * to configure a instance of a scan on the specific channel.
- */
-struct lbs_ioctl_user_scan_chan {
- u8 channumber; //!< channel Number to scan
- u8 radiotype; //!< Radio type: 'B/G' band = 0, 'A' band = 1
- u8 scantype; //!< Scan type: Active = 0, Passive = 1
- u16 scantime; //!< Scan duration in milliseconds; if 0 default used
-};
-
-/**
- * @brief IOCTL input structure to configure an immediate scan cmd to firmware
- *
- * Used in the setuserscan (LBS_SET_USER_SCAN) private ioctl. Specifies
- * a number of parameters to be used in general for the scan as well
- * as a channel list (lbs_ioctl_user_scan_chan) for each scan period
- * desired.
- *
- * @sa lbs_set_user_scan_ioctl
- */
-struct lbs_ioctl_user_scan_cfg {
- /**
- * @brief BSS type to be sent in the firmware command
- *
- * Field can be used to restrict the types of networks returned in the
- * scan. valid settings are:
- *
- * - LBS_SCAN_BSS_TYPE_BSS (infrastructure)
- * - LBS_SCAN_BSS_TYPE_IBSS (adhoc)
- * - LBS_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure)
- */
- u8 bsstype;
-
- /**
- * @brief BSSID filter sent in the firmware command to limit the results
- */
- u8 bssid[ETH_ALEN];
-
- /* Clear existing scan results matching this BSSID */
- u8 clear_bssid;
-
- /**
- * @brief SSID filter sent in the firmware command to limit the results
- */
- char ssid[IW_ESSID_MAX_SIZE];
- u8 ssid_len;
-
- /* Clear existing scan results matching this SSID */
- u8 clear_ssid;
-};
-
-/**
* @brief Structure used to store information for each beacon/probe response
*/
struct bss_descriptor {
@@ -136,21 +80,12 @@ int lbs_find_best_network_ssid(struct lbs_private *priv, u8 *out_ssid,
u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode);
int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid,
- u8 ssid_len, u8 clear_ssid);
-
-int lbs_scan_networks(struct lbs_private *priv,
- const struct lbs_ioctl_user_scan_cfg *puserscanin,
- int full_scan);
-
-struct ifreq;
+ u8 ssid_len);
-struct iw_point;
-struct iw_param;
-struct iw_request_info;
int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra);
int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
- struct iw_param *vwrq, char *extra);
+ union iwreq_data *wrqu, char *extra);
void lbs_scan_worker(struct work_struct *work);
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index e8bfc26b10a4..cded4bb69164 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -579,6 +579,9 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info,
range->num_bitrates);
range->num_frequency = 0;
+
+ range->scan_capa = IW_SCAN_CAPA_ESSID;
+
if (priv->enable11d &&
(priv->connect_status == LBS_CONNECTED ||
priv->mesh_connect_status == LBS_CONNECTED)) {
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 10b776c1adc5..977751f372ff 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -154,128 +154,121 @@ MODULE_PARM_DESC(workaround_interval,
#define NDIS_802_11_LENGTH_RATES 8
#define NDIS_802_11_LENGTH_RATES_EX 16
-struct NDIS_802_11_SSID {
- __le32 SsidLength;
- u8 Ssid[NDIS_802_11_LENGTH_SSID];
-} __attribute__((packed));
-
-enum NDIS_802_11_NETWORK_TYPE {
- Ndis802_11FH,
- Ndis802_11DS,
- Ndis802_11OFDM5,
- Ndis802_11OFDM24,
- Ndis802_11NetworkTypeMax
+enum ndis_80211_net_type {
+ ndis_80211_type_freq_hop,
+ ndis_80211_type_direct_seq,
+ ndis_80211_type_ofdm_a,
+ ndis_80211_type_ofdm_g
};
-struct NDIS_802_11_CONFIGURATION_FH {
- __le32 Length;
- __le32 HopPattern;
- __le32 HopSet;
- __le32 DwellTime;
-} __attribute__((packed));
-
-struct NDIS_802_11_CONFIGURATION {
- __le32 Length;
- __le32 BeaconPeriod;
- __le32 ATIMWindow;
- __le32 DSConfig;
- struct NDIS_802_11_CONFIGURATION_FH FHConfig;
-} __attribute__((packed));
-
-enum NDIS_802_11_NETWORK_INFRASTRUCTURE {
- Ndis802_11IBSS,
- Ndis802_11Infrastructure,
- Ndis802_11AutoUnknown,
- Ndis802_11InfrastructureMax
+enum ndis_80211_net_infra {
+ ndis_80211_infra_adhoc,
+ ndis_80211_infra_infra,
+ ndis_80211_infra_auto_unknown
};
-enum NDIS_802_11_AUTHENTICATION_MODE {
- Ndis802_11AuthModeOpen,
- Ndis802_11AuthModeShared,
- Ndis802_11AuthModeAutoSwitch,
- Ndis802_11AuthModeWPA,
- Ndis802_11AuthModeWPAPSK,
- Ndis802_11AuthModeWPANone,
- Ndis802_11AuthModeWPA2,
- Ndis802_11AuthModeWPA2PSK,
- Ndis802_11AuthModeMax
+enum ndis_80211_auth_mode {
+ ndis_80211_auth_open,
+ ndis_80211_auth_shared,
+ ndis_80211_auth_auto_switch,
+ ndis_80211_auth_wpa,
+ ndis_80211_auth_wpa_psk,
+ ndis_80211_auth_wpa_none,
+ ndis_80211_auth_wpa2,
+ ndis_80211_auth_wpa2_psk
};
-enum NDIS_802_11_ENCRYPTION_STATUS {
- Ndis802_11WEPEnabled,
- Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
- Ndis802_11WEPDisabled,
- Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
- Ndis802_11WEPKeyAbsent,
- Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
- Ndis802_11WEPNotSupported,
- Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
- Ndis802_11Encryption2Enabled,
- Ndis802_11Encryption2KeyAbsent,
- Ndis802_11Encryption3Enabled,
- Ndis802_11Encryption3KeyAbsent
+enum ndis_80211_encr_status {
+ ndis_80211_encr_wep_enabled,
+ ndis_80211_encr_disabled,
+ ndis_80211_encr_wep_key_absent,
+ ndis_80211_encr_not_supported,
+ ndis_80211_encr_tkip_enabled,
+ ndis_80211_encr_tkip_key_absent,
+ ndis_80211_encr_ccmp_enabled,
+ ndis_80211_encr_ccmp_key_absent
};
-enum NDIS_802_11_PRIVACY_FILTER {
- Ndis802_11PrivFilterAcceptAll,
- Ndis802_11PrivFilter8021xWEP
+enum ndis_80211_priv_filter {
+ ndis_80211_priv_accept_all,
+ ndis_80211_priv_8021x_wep
};
-struct NDIS_WLAN_BSSID_EX {
- __le32 Length;
- u8 MacAddress[6];
- u8 Padding[2];
- struct NDIS_802_11_SSID Ssid;
- __le32 Privacy;
- __le32 Rssi;
- __le32 NetworkTypeInUse;
- struct NDIS_802_11_CONFIGURATION Configuration;
- __le32 InfrastructureMode;
- u8 SupportedRates[NDIS_802_11_LENGTH_RATES_EX];
- __le32 IELength;
- u8 IEs[0];
+struct ndis_80211_ssid {
+ __le32 length;
+ u8 essid[NDIS_802_11_LENGTH_SSID];
+} __attribute__((packed));
+
+struct ndis_80211_conf_freq_hop {
+ __le32 length;
+ __le32 hop_pattern;
+ __le32 hop_set;
+ __le32 dwell_time;
+} __attribute__((packed));
+
+struct ndis_80211_conf {
+ __le32 length;
+ __le32 beacon_period;
+ __le32 atim_window;
+ __le32 ds_config;
+ struct ndis_80211_conf_freq_hop fh_config;
+} __attribute__((packed));
+
+struct ndis_80211_bssid_ex {
+ __le32 length;
+ u8 mac[6];
+ u8 padding[2];
+ struct ndis_80211_ssid ssid;
+ __le32 privacy;
+ __le32 rssi;
+ __le32 net_type;
+ struct ndis_80211_conf config;
+ __le32 net_infra;
+ u8 rates[NDIS_802_11_LENGTH_RATES_EX];
+ __le32 ie_length;
+ u8 ies[0];
} __attribute__((packed));
-struct NDIS_802_11_BSSID_LIST_EX {
- __le32 NumberOfItems;
- struct NDIS_WLAN_BSSID_EX Bssid[0];
+struct ndis_80211_bssid_list_ex {
+ __le32 num_items;
+ struct ndis_80211_bssid_ex bssid[0];
} __attribute__((packed));
-struct NDIS_802_11_FIXED_IEs {
- u8 Timestamp[8];
- __le16 BeaconInterval;
- __le16 Capabilities;
+struct ndis_80211_fixed_ies {
+ u8 timestamp[8];
+ __le16 beacon_interval;
+ __le16 capabilities;
} __attribute__((packed));
-struct NDIS_802_11_WEP {
- __le32 Length;
- __le32 KeyIndex;
- __le32 KeyLength;
- u8 KeyMaterial[32];
+struct ndis_80211_wep_key {
+ __le32 size;
+ __le32 index;
+ __le32 length;
+ u8 material[32];
} __attribute__((packed));
-struct NDIS_802_11_KEY {
- __le32 Length;
- __le32 KeyIndex;
- __le32 KeyLength;
- u8 Bssid[6];
- u8 Padding[6];
- u8 KeyRSC[8];
- u8 KeyMaterial[32];
+struct ndis_80211_key {
+ __le32 size;
+ __le32 index;
+ __le32 length;
+ u8 bssid[6];
+ u8 padding[6];
+ u8 rsc[8];
+ u8 material[32];
} __attribute__((packed));
-struct NDIS_802_11_REMOVE_KEY {
- __le32 Length;
- __le32 KeyIndex;
- u8 Bssid[6];
+struct ndis_80211_remove_key {
+ __le32 size;
+ __le32 index;
+ u8 bssid[6];
} __attribute__((packed));
-struct RNDIS_CONFIG_PARAMETER_INFOBUFFER {
- __le32 ParameterNameOffset;
- __le32 ParameterNameLength;
- __le32 ParameterType;
- __le32 ParameterValueOffset;
- __le32 ParameterValueLength;
+struct ndis_config_param {
+ __le32 name_offs;
+ __le32 name_length;
+ __le32 type;
+ __le32 value_offs;
+ __le32 value_length;
} __attribute__((packed));
/* these have to match what is in wpa_supplicant */
@@ -334,7 +327,7 @@ struct rndis_wext_private {
/* hardware state */
int radio_on;
int infra_mode;
- struct NDIS_802_11_SSID essid;
+ struct ndis_80211_ssid essid;
/* encryption stuff */
int encr_tx_key_index;
@@ -484,7 +477,7 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
static int rndis_set_config_parameter(struct usbnet *dev, char *param,
int value_type, void *value)
{
- struct RNDIS_CONFIG_PARAMETER_INFOBUFFER *infobuf;
+ struct ndis_config_param *infobuf;
int value_len, info_len, param_len, ret, i;
__le16 *unibuf;
__le32 *dst_value;
@@ -519,12 +512,11 @@ static int rndis_set_config_parameter(struct usbnet *dev, char *param,
devdbg(dev, "setting config parameter: %s, value: %d",
param, *(u32 *)value);
- infobuf->ParameterNameOffset = cpu_to_le32(sizeof(*infobuf));
- infobuf->ParameterNameLength = cpu_to_le32(param_len);
- infobuf->ParameterType = cpu_to_le32(value_type);
- infobuf->ParameterValueOffset = cpu_to_le32(sizeof(*infobuf) +
- param_len);
- infobuf->ParameterValueLength = cpu_to_le32(value_len);
+ infobuf->name_offs = cpu_to_le32(sizeof(*infobuf));
+ infobuf->name_length = cpu_to_le32(param_len);
+ infobuf->type = cpu_to_le32(value_type);
+ infobuf->value_offs = cpu_to_le32(sizeof(*infobuf) + param_len);
+ infobuf->value_length = cpu_to_le32(value_len);
/* simple string to unicode string conversion */
unibuf = (void *)infobuf + sizeof(*infobuf);
@@ -630,7 +622,7 @@ static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
static int
add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index);
-static int get_essid(struct usbnet *usbdev, struct NDIS_802_11_SSID *ssid)
+static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
{
int ret, len;
@@ -638,14 +630,14 @@ static int get_essid(struct usbnet *usbdev, struct NDIS_802_11_SSID *ssid)
ret = rndis_query_oid(usbdev, OID_802_11_SSID, ssid, &len);
if (ret != 0)
- ssid->SsidLength = 0;
+ ssid->length = 0;
#ifdef DEBUG
{
unsigned char tmp[NDIS_802_11_LENGTH_SSID + 1];
- memcpy(tmp, ssid->Ssid, le32_to_cpu(ssid->SsidLength));
- tmp[le32_to_cpu(ssid->SsidLength)] = 0;
+ memcpy(tmp, ssid->essid, le32_to_cpu(ssid->length));
+ tmp[le32_to_cpu(ssid->length)] = 0;
devdbg(usbdev, "get_essid: '%s', ret: %d", tmp, ret);
}
#endif
@@ -653,7 +645,7 @@ static int get_essid(struct usbnet *usbdev, struct NDIS_802_11_SSID *ssid)
}
-static int set_essid(struct usbnet *usbdev, struct NDIS_802_11_SSID *ssid)
+static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
{
struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
int ret;
@@ -697,7 +689,7 @@ static int is_associated(struct usbnet *usbdev)
static int disassociate(struct usbnet *usbdev, int reset_ssid)
{
struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
- struct NDIS_802_11_SSID ssid;
+ struct ndis_80211_ssid ssid;
int i, ret = 0;
if (priv->radio_on) {
@@ -714,12 +706,12 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
/* disassociate causes radio to be turned off; if reset_ssid
* is given, set random ssid to enable radio */
if (reset_ssid) {
- ssid.SsidLength = cpu_to_le32(sizeof(ssid.Ssid));
- get_random_bytes(&ssid.Ssid[2], sizeof(ssid.Ssid)-2);
- ssid.Ssid[0] = 0x1;
- ssid.Ssid[1] = 0xff;
- for (i = 2; i < sizeof(ssid.Ssid); i++)
- ssid.Ssid[i] = 0x1 + (ssid.Ssid[i] * 0xfe / 0xff);
+ ssid.length = cpu_to_le32(sizeof(ssid.essid));
+ get_random_bytes(&ssid.essid[2], sizeof(ssid.essid)-2);
+ ssid.essid[0] = 0x1;
+ ssid.essid[1] = 0xff;
+ for (i = 2; i < sizeof(ssid.essid); i++)
+ ssid.essid[i] = 0x1 + (ssid.essid[i] * 0xfe / 0xff);
ret = set_essid(usbdev, &ssid);
}
return ret;
@@ -737,23 +729,23 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) {
if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
- auth_mode = Ndis802_11AuthModeWPA2;
+ auth_mode = ndis_80211_auth_wpa2;
else
- auth_mode = Ndis802_11AuthModeWPA2PSK;
+ auth_mode = ndis_80211_auth_wpa2_psk;
} else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) {
if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
- auth_mode = Ndis802_11AuthModeWPA;
+ auth_mode = ndis_80211_auth_wpa;
else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK)
- auth_mode = Ndis802_11AuthModeWPAPSK;
+ auth_mode = ndis_80211_auth_wpa_psk;
else
- auth_mode = Ndis802_11AuthModeWPANone;
+ auth_mode = ndis_80211_auth_wpa_none;
} else if (authalg & IW_AUTH_ALG_SHARED_KEY) {
if (authalg & IW_AUTH_ALG_OPEN_SYSTEM)
- auth_mode = Ndis802_11AuthModeAutoSwitch;
+ auth_mode = ndis_80211_auth_auto_switch;
else
- auth_mode = Ndis802_11AuthModeShared;
+ auth_mode = ndis_80211_auth_shared;
} else
- auth_mode = Ndis802_11AuthModeOpen;
+ auth_mode = ndis_80211_auth_open;
tmp = cpu_to_le32(auth_mode);
ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
@@ -778,9 +770,9 @@ static int set_priv_filter(struct usbnet *usbdev)
if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 ||
priv->wpa_version & IW_AUTH_WPA_VERSION_WPA)
- tmp = cpu_to_le32(Ndis802_11PrivFilter8021xWEP);
+ tmp = cpu_to_le32(ndis_80211_priv_8021x_wep);
else
- tmp = cpu_to_le32(Ndis802_11PrivFilterAcceptAll);
+ tmp = cpu_to_le32(ndis_80211_priv_accept_all);
return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp,
sizeof(tmp));
@@ -798,18 +790,18 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
groupwise);
if (pairwise & IW_AUTH_CIPHER_CCMP)
- encr_mode = Ndis802_11Encryption3Enabled;
+ encr_mode = ndis_80211_encr_ccmp_enabled;
else if (pairwise & IW_AUTH_CIPHER_TKIP)
- encr_mode = Ndis802_11Encryption2Enabled;
+ encr_mode = ndis_80211_encr_tkip_enabled;
else if (pairwise &
(IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
- encr_mode = Ndis802_11Encryption1Enabled;
+ encr_mode = ndis_80211_encr_wep_enabled;
else if (groupwise & IW_AUTH_CIPHER_CCMP)
- encr_mode = Ndis802_11Encryption3Enabled;
+ encr_mode = ndis_80211_encr_ccmp_enabled;
else if (groupwise & IW_AUTH_CIPHER_TKIP)
- encr_mode = Ndis802_11Encryption2Enabled;
+ encr_mode = ndis_80211_encr_tkip_enabled;
else
- encr_mode = Ndis802_11EncryptionDisabled;
+ encr_mode = ndis_80211_encr_disabled;
tmp = cpu_to_le32(encr_mode);
ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp,
@@ -877,7 +869,7 @@ static void set_default_iw_params(struct usbnet *usbdev)
priv->wpa_keymgmt = 0;
priv->wpa_version = 0;
- set_infra_mode(usbdev, Ndis802_11Infrastructure);
+ set_infra_mode(usbdev, ndis_80211_infra_infra);
set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
IW_AUTH_ALG_OPEN_SYSTEM);
set_priv_filter(usbdev);
@@ -899,7 +891,7 @@ static int deauthenticate(struct usbnet *usbdev)
static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
{
struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
- struct NDIS_802_11_WEP ndis_key;
+ struct ndis_80211_wep_key ndis_key;
int ret;
if (key_len <= 0 || key_len > 32 || index < 0 || index >= 4)
@@ -907,13 +899,13 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
memset(&ndis_key, 0, sizeof(ndis_key));
- ndis_key.Length = cpu_to_le32(sizeof(ndis_key));
- ndis_key.KeyLength = cpu_to_le32(key_len);
- ndis_key.KeyIndex = cpu_to_le32(index);
- memcpy(&ndis_key.KeyMaterial, key, key_len);
+ ndis_key.size = cpu_to_le32(sizeof(ndis_key));
+ ndis_key.length = cpu_to_le32(key_len);
+ ndis_key.index = cpu_to_le32(index);
+ memcpy(&ndis_key.material, key, key_len);
if (index == priv->encr_tx_key_index) {
- ndis_key.KeyIndex |= cpu_to_le32(1 << 31);
+ ndis_key.index |= cpu_to_le32(1 << 31);
ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104,
IW_AUTH_CIPHER_NONE);
if (ret)
@@ -940,7 +932,7 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
{
struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
- struct NDIS_802_11_REMOVE_KEY remove_key;
+ struct ndis_80211_remove_key remove_key;
__le32 keyindex;
int ret;
@@ -954,17 +946,17 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
priv->wpa_cipher_pair == IW_AUTH_CIPHER_CCMP ||
priv->wpa_cipher_group == IW_AUTH_CIPHER_TKIP ||
priv->wpa_cipher_group == IW_AUTH_CIPHER_CCMP) {
- remove_key.Length = cpu_to_le32(sizeof(remove_key));
- remove_key.KeyIndex = cpu_to_le32(index);
+ remove_key.size = cpu_to_le32(sizeof(remove_key));
+ remove_key.index = cpu_to_le32(index);
if (bssid) {
/* pairwise key */
if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0)
- remove_key.KeyIndex |= cpu_to_le32(1 << 30);
- memcpy(remove_key.Bssid, bssid,
- sizeof(remove_key.Bssid));
+ remove_key.index |= cpu_to_le32(1 << 30);
+ memcpy(remove_key.bssid, bssid,
+ sizeof(remove_key.bssid));
} else
- memset(remove_key.Bssid, 0xff,
- sizeof(remove_key.Bssid));
+ memset(remove_key.bssid, 0xff,
+ sizeof(remove_key.bssid));
ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_KEY, &remove_key,
sizeof(remove_key));
@@ -1184,7 +1176,7 @@ static int rndis_iw_get_name(struct net_device *dev,
static int rndis_iw_set_essid(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
{
- struct NDIS_802_11_SSID ssid;
+ struct ndis_80211_ssid ssid;
int length = wrqu->essid.length;
struct usbnet *usbdev = dev->priv;
@@ -1194,11 +1186,11 @@ static int rndis_iw_set_essid(struct net_device *dev,
if (length > NDIS_802_11_LENGTH_SSID)
length = NDIS_802_11_LENGTH_SSID;
- ssid.SsidLength = cpu_to_le32(length);
+ ssid.length = cpu_to_le32(length);
if (length > 0)
- memcpy(ssid.Ssid, essid, length);
+ memcpy(ssid.essid, essid, length);
else
- memset(ssid.Ssid, 0, NDIS_802_11_LENGTH_SSID);
+ memset(ssid.essid, 0, NDIS_802_11_LENGTH_SSID);
set_assoc_params(usbdev);
@@ -1212,16 +1204,16 @@ static int rndis_iw_set_essid(struct net_device *dev,
static int rndis_iw_get_essid(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
{
- struct NDIS_802_11_SSID ssid;
+ struct ndis_80211_ssid ssid;
struct usbnet *usbdev = dev->priv;
int ret;
ret = get_essid(usbdev, &ssid);
- if (ret == 0 && le32_to_cpu(ssid.SsidLength) > 0) {
+ if (ret == 0 && le32_to_cpu(ssid.length) > 0) {
wrqu->essid.flags = 1;
- wrqu->essid.length = le32_to_cpu(ssid.SsidLength);
- memcpy(essid, ssid.Ssid, wrqu->essid.length);
+ wrqu->essid.length = le32_to_cpu(ssid.length);
+ memcpy(essid, ssid.essid, wrqu->essid.length);
essid[wrqu->essid.length] = 0;
} else {
memset(essid, 0, sizeof(NDIS_802_11_LENGTH_SSID));
@@ -1398,13 +1390,13 @@ static int rndis_iw_get_mode(struct net_device *dev,
struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
switch (priv->infra_mode) {
- case Ndis802_11IBSS:
+ case ndis_80211_infra_adhoc:
wrqu->mode = IW_MODE_ADHOC;
break;
- case Ndis802_11Infrastructure:
+ case ndis_80211_infra_infra:
wrqu->mode = IW_MODE_INFRA;
break;
- /*case Ndis802_11AutoUnknown:*/
+ /*case ndis_80211_infra_auto_unknown:*/
default:
wrqu->mode = IW_MODE_AUTO;
break;
@@ -1424,14 +1416,14 @@ static int rndis_iw_set_mode(struct net_device *dev,
switch (wrqu->mode) {
case IW_MODE_ADHOC:
- mode = Ndis802_11IBSS;
+ mode = ndis_80211_infra_adhoc;
break;
case IW_MODE_INFRA:
- mode = Ndis802_11Infrastructure;
+ mode = ndis_80211_infra_infra;
break;
/*case IW_MODE_AUTO:*/
default:
- mode = Ndis802_11AutoUnknown;
+ mode = ndis_80211_infra_auto_unknown;
break;
}
@@ -1507,7 +1499,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
struct usbnet *usbdev = dev->priv;
struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
- struct NDIS_802_11_KEY ndis_key;
+ struct ndis_80211_key ndis_key;
int keyidx, ret;
u8 *addr;
@@ -1532,54 +1524,54 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
return remove_key(usbdev, keyidx, NULL);
- if (ext->key_len > sizeof(ndis_key.KeyMaterial))
+ if (ext->key_len > sizeof(ndis_key.material))
return -1;
memset(&ndis_key, 0, sizeof(ndis_key));
- ndis_key.Length = cpu_to_le32(sizeof(ndis_key) -
- sizeof(ndis_key.KeyMaterial) + ext->key_len);
- ndis_key.KeyLength = cpu_to_le32(ext->key_len);
- ndis_key.KeyIndex = cpu_to_le32(keyidx);
+ ndis_key.size = cpu_to_le32(sizeof(ndis_key) -
+ sizeof(ndis_key.material) + ext->key_len);
+ ndis_key.length = cpu_to_le32(ext->key_len);
+ ndis_key.index = cpu_to_le32(keyidx);
if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
- memcpy(ndis_key.KeyRSC, ext->rx_seq, 6);
- ndis_key.KeyIndex |= cpu_to_le32(1 << 29);
+ memcpy(ndis_key.rsc, ext->rx_seq, 6);
+ ndis_key.index |= cpu_to_le32(1 << 29);
}
addr = ext->addr.sa_data;
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
/* group key */
- if (priv->infra_mode == Ndis802_11IBSS)
- memset(ndis_key.Bssid, 0xff, ETH_ALEN);
+ if (priv->infra_mode == ndis_80211_infra_adhoc)
+ memset(ndis_key.bssid, 0xff, ETH_ALEN);
else
- get_bssid(usbdev, ndis_key.Bssid);
+ get_bssid(usbdev, ndis_key.bssid);
} else {
/* pairwise key */
- ndis_key.KeyIndex |= cpu_to_le32(1 << 30);
- memcpy(ndis_key.Bssid, addr, ETH_ALEN);
+ ndis_key.index |= cpu_to_le32(1 << 30);
+ memcpy(ndis_key.bssid, addr, ETH_ALEN);
}
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
- ndis_key.KeyIndex |= cpu_to_le32(1 << 31);
+ ndis_key.index |= cpu_to_le32(1 << 31);
if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) {
/* wpa_supplicant gives us the Michael MIC RX/TX keys in
* different order than NDIS spec, so swap the order here. */
- memcpy(ndis_key.KeyMaterial, ext->key, 16);
- memcpy(ndis_key.KeyMaterial + 16, ext->key + 24, 8);
- memcpy(ndis_key.KeyMaterial + 24, ext->key + 16, 8);
+ memcpy(ndis_key.material, ext->key, 16);
+ memcpy(ndis_key.material + 16, ext->key + 24, 8);
+ memcpy(ndis_key.material + 24, ext->key + 16, 8);
} else
- memcpy(ndis_key.KeyMaterial, ext->key, ext->key_len);
+ memcpy(ndis_key.material, ext->key, ext->key_len);
ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
- le32_to_cpu(ndis_key.Length));
+ le32_to_cpu(ndis_key.size));
devdbg(usbdev, "SIOCSIWENCODEEXT: OID_802_11_ADD_KEY -> %08X", ret);
if (ret != 0)
return ret;
priv->encr_key_len[keyidx] = ext->key_len;
- memcpy(&priv->encr_keys[keyidx], ndis_key.KeyMaterial, ext->key_len);
+ memcpy(&priv->encr_keys[keyidx], ndis_key.material, ext->key_len);
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
priv->encr_tx_key_index = keyidx;
@@ -1611,7 +1603,7 @@ static int rndis_iw_set_scan(struct net_device *dev,
static char *rndis_translate_scan(struct net_device *dev,
- char *cev, char *end_buf, struct NDIS_WLAN_BSSID_EX *bssid)
+ char *cev, char *end_buf, struct ndis_80211_bssid_ex *bssid)
{
#ifdef DEBUG
struct usbnet *usbdev = dev->priv;
@@ -1624,60 +1616,55 @@ static char *rndis_translate_scan(struct net_device *dev,
unsigned char sbuf[32];
DECLARE_MAC_BUF(mac);
- bssid_len = le32_to_cpu(bssid->Length);
+ bssid_len = le32_to_cpu(bssid->length);
- devdbg(usbdev, "BSSID %s", print_mac(mac, bssid->MacAddress));
+ devdbg(usbdev, "BSSID %s", print_mac(mac, bssid->mac));
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, bssid->MacAddress, ETH_ALEN);
+ memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
- devdbg(usbdev, "SSID(%d) %s",
- le32_to_cpu(bssid->Ssid.SsidLength),
- bssid->Ssid.Ssid);
+ devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
+ bssid->ssid.essid);
iwe.cmd = SIOCGIWESSID;
- iwe.u.essid.length = le32_to_cpu(bssid->Ssid.SsidLength);
+ iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
iwe.u.essid.flags = 1;
- cev = iwe_stream_add_point(cev, end_buf, &iwe,
- bssid->Ssid.Ssid);
+ cev = iwe_stream_add_point(cev, end_buf, &iwe, bssid->ssid.essid);
- devdbg(usbdev, "MODE %d",
- le32_to_cpu(bssid->InfrastructureMode));
+ devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
iwe.cmd = SIOCGIWMODE;
- switch (le32_to_cpu(bssid->InfrastructureMode)) {
- case Ndis802_11IBSS:
+ switch (le32_to_cpu(bssid->net_infra)) {
+ case ndis_80211_infra_adhoc:
iwe.u.mode = IW_MODE_ADHOC;
break;
- case Ndis802_11Infrastructure:
+ case ndis_80211_infra_infra:
iwe.u.mode = IW_MODE_INFRA;
break;
- /*case Ndis802_11AutoUnknown:*/
+ /*case ndis_80211_infra_auto_unknown:*/
default:
iwe.u.mode = IW_MODE_AUTO;
break;
}
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
- devdbg(usbdev, "FREQ %d kHz",
- le32_to_cpu(bssid->Configuration.DSConfig));
+ devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
iwe.cmd = SIOCGIWFREQ;
- dsconfig_to_freq(le32_to_cpu(bssid->Configuration.DSConfig),
- &iwe.u.freq);
+ dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
- devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->Rssi));
+ devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = level_to_qual(le32_to_cpu(bssid->Rssi));
- iwe.u.qual.level = le32_to_cpu(bssid->Rssi);
+ iwe.u.qual.qual = level_to_qual(le32_to_cpu(bssid->rssi));
+ iwe.u.qual.level = le32_to_cpu(bssid->rssi);
iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
| IW_QUAL_LEVEL_UPDATED
| IW_QUAL_NOISE_INVALID;
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
- devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->Privacy));
+ devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
iwe.cmd = SIOCGIWENCODE;
iwe.u.data.length = 0;
- if (le32_to_cpu(bssid->Privacy) == Ndis802_11PrivFilterAcceptAll)
+ if (le32_to_cpu(bssid->privacy) == ndis_80211_priv_accept_all)
iwe.u.data.flags = IW_ENCODE_DISABLED;
else
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
@@ -1687,10 +1674,10 @@ static char *rndis_translate_scan(struct net_device *dev,
devdbg(usbdev, "RATES:");
current_val = cev + IW_EV_LCP_LEN;
iwe.cmd = SIOCGIWRATE;
- for (i = 0; i < sizeof(bssid->SupportedRates); i++) {
- if (bssid->SupportedRates[i] & 0x7f) {
+ for (i = 0; i < sizeof(bssid->rates); i++) {
+ if (bssid->rates[i] & 0x7f) {
iwe.u.bitrate.value =
- ((bssid->SupportedRates[i] & 0x7f) *
+ ((bssid->rates[i] & 0x7f) *
500000);
devdbg(usbdev, " %d", iwe.u.bitrate.value);
current_val = iwe_stream_add_value(cev,
@@ -1702,24 +1689,24 @@ static char *rndis_translate_scan(struct net_device *dev,
if ((current_val - cev) > IW_EV_LCP_LEN)
cev = current_val;
- beacon = le32_to_cpu(bssid->Configuration.BeaconPeriod);
+ beacon = le32_to_cpu(bssid->config.beacon_period);
devdbg(usbdev, "BCN_INT %d", beacon);
iwe.cmd = IWEVCUSTOM;
snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
iwe.u.data.length = strlen(sbuf);
cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
- atim = le32_to_cpu(bssid->Configuration.ATIMWindow);
+ atim = le32_to_cpu(bssid->config.atim_window);
devdbg(usbdev, "ATIM %d", atim);
iwe.cmd = IWEVCUSTOM;
snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
iwe.u.data.length = strlen(sbuf);
cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
- ie = (void *)(bssid->IEs + sizeof(struct NDIS_802_11_FIXED_IEs));
+ ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
ie_len = min(bssid_len - (int)sizeof(*bssid),
- (int)le32_to_cpu(bssid->IELength));
- ie_len -= sizeof(struct NDIS_802_11_FIXED_IEs);
+ (int)le32_to_cpu(bssid->ie_length));
+ ie_len -= sizeof(struct ndis_80211_fixed_ies);
while (ie_len >= sizeof(*ie) && sizeof(*ie) + ie->len <= ie_len) {
if ((ie->id == MFIE_TYPE_GENERIC && ie->len >= 4 &&
memcmp(ie->data, "\x00\x50\xf2\x01", 4) == 0) ||
@@ -1746,8 +1733,8 @@ static int rndis_iw_get_scan(struct net_device *dev,
struct usbnet *usbdev = dev->priv;
void *buf = NULL;
char *cev = extra;
- struct NDIS_802_11_BSSID_LIST_EX *bssid_list;
- struct NDIS_WLAN_BSSID_EX *bssid;
+ struct ndis_80211_bssid_list_ex *bssid_list;
+ struct ndis_80211_bssid_ex *bssid;
int ret = -EINVAL, len, count, bssid_len;
devdbg(usbdev, "SIOCGIWSCAN");
@@ -1765,16 +1752,16 @@ static int rndis_iw_get_scan(struct net_device *dev,
goto out;
bssid_list = buf;
- bssid = bssid_list->Bssid;
- bssid_len = le32_to_cpu(bssid->Length);
- count = le32_to_cpu(bssid_list->NumberOfItems);
+ bssid = bssid_list->bssid;
+ bssid_len = le32_to_cpu(bssid->length);
+ count = le32_to_cpu(bssid_list->num_items);
devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA,
bssid);
bssid = (void *)bssid + bssid_len;
- bssid_len = le32_to_cpu(bssid->Length);
+ bssid_len = le32_to_cpu(bssid->length);
count--;
}
@@ -1948,7 +1935,7 @@ static int rndis_iw_set_freq(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
struct usbnet *usbdev = dev->priv;
- struct NDIS_802_11_CONFIGURATION config;
+ struct ndis_80211_conf config;
unsigned int dsconfig;
int len, ret;
@@ -1967,7 +1954,7 @@ static int rndis_iw_set_freq(struct net_device *dev,
return 0;
}
- config.DSConfig = cpu_to_le32(dsconfig);
+ config.ds_config = cpu_to_le32(dsconfig);
devdbg(usbdev, "SIOCSIWFREQ: %d * 10^%d", wrqu->freq.m, wrqu->freq.e);
return rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config,
@@ -1979,13 +1966,13 @@ static int rndis_iw_get_freq(struct net_device *dev,
struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
{
struct usbnet *usbdev = dev->priv;
- struct NDIS_802_11_CONFIGURATION config;
+ struct ndis_80211_conf config;
int len, ret;
len = sizeof(config);
ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
if (ret == 0)
- dsconfig_to_freq(le32_to_cpu(config.DSConfig), &wrqu->freq);
+ dsconfig_to_freq(le32_to_cpu(config.ds_config), &wrqu->freq);
devdbg(usbdev, "SIOCGIWFREQ: %d", wrqu->freq.m);
return ret;
@@ -2266,14 +2253,14 @@ static int rndis_wext_get_caps(struct usbnet *dev)
n = 8;
for (i = 0; i < n; i++) {
switch (le32_to_cpu(networks_supported.items[i])) {
- case Ndis802_11FH:
- case Ndis802_11DS:
+ case ndis_80211_type_freq_hop:
+ case ndis_80211_type_direct_seq:
priv->caps |= CAP_MODE_80211B;
break;
- case Ndis802_11OFDM5:
+ case ndis_80211_type_ofdm_a:
priv->caps |= CAP_MODE_80211A;
break;
- case Ndis802_11OFDM24:
+ case ndis_80211_type_ofdm_g:
priv->caps |= CAP_MODE_80211G;
break;
}
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index d5240aa06233..4709c11da419 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -27,8 +27,6 @@ config RT2X00_LIB_USB
config RT2X00_LIB_FIRMWARE
boolean
depends on RT2X00_LIB
- select CRC_CCITT
- select CRC_ITU_T
select FW_LOADER
config RT2X00_LIB_RFKILL
@@ -102,6 +100,7 @@ config RT61PCI
depends on PCI
select RT2X00_LIB_PCI
select RT2X00_LIB_FIRMWARE
+ select CRC_ITU_T
select EEPROM_93CX6
---help---
This is an experimental driver for the Ralink rt61 wireless chip.
@@ -145,6 +144,7 @@ config RT73USB
depends on USB
select RT2X00_LIB_USB
select RT2X00_LIB_FIRMWARE
+ select CRC_ITU_T
---help---
This is an experimental driver for the Ralink rt73 wireless chip.
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 460ef2fb5104..1f49561d3ddc 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -279,8 +279,6 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
u32 reg;
if (flags & CONFIG_UPDATE_TYPE) {
- rt2x00pci_register_write(rt2x00dev, CSR14, 0);
-
/*
* Enable beacon config
*/
@@ -294,10 +292,8 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
*/
rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
- rt2x00_set_field32(&reg, CSR14_TBCN,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
rt2x00_set_field32(&reg, CSR14_TSF_SYNC, conf->sync);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 1);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
@@ -310,10 +306,8 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
conf->bssid, sizeof(conf->bssid));
}
-static int rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev,
- const int short_preamble,
- const int ack_timeout,
- const int ack_consume_time)
+static int rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_erp *erp)
{
int preamble_mask;
u32 reg;
@@ -321,11 +315,13 @@ static int rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev,
/*
* When short preamble is enabled, we should set bit 0x08
*/
- preamble_mask = short_preamble << 3;
+ preamble_mask = erp->short_preamble << 3;
rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
- rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, ack_timeout);
- rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, ack_consume_time);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT,
+ erp->ack_timeout);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME,
+ erp->ack_consume_time);
rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
@@ -423,6 +419,13 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
u8 r1;
u8 r4;
+ /*
+ * We should never come here because rt2x00lib is supposed
+ * to catch this and send us the correct antenna explicitely.
+ */
+ BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
+ ant->tx == ANTENNA_SW_DIVERSITY);
+
rt2400pci_bbp_read(rt2x00dev, 4, &r4);
rt2400pci_bbp_read(rt2x00dev, 1, &r1);
@@ -436,14 +439,8 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
case ANTENNA_A:
rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0);
break;
- case ANTENNA_SW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2);
break;
}
@@ -458,14 +455,8 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0);
break;
- case ANTENNA_SW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
break;
}
@@ -678,7 +669,7 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
priv_rx = rt2x00dev->rx->entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, RXCSR2, &reg);
- rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER, priv_tx->desc_dma);
+ rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma);
rt2x00pci_register_write(rt2x00dev, RXCSR2, reg);
return 0;
@@ -1040,6 +1031,8 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
if (queue == RT2X00_BCN_QUEUE_BEACON) {
rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 1);
rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
@@ -1065,9 +1058,11 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
u32 word0;
u32 word2;
+ u32 word3;
rt2x00_desc_read(priv_rx->desc, 0, &word0);
rt2x00_desc_read(priv_rx->desc, 2, &word2);
+ rt2x00_desc_read(priv_rx->desc, 3, &word3);
rxdesc->flags = 0;
if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
@@ -1077,9 +1072,12 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
/*
* Obtain the status about this packet.
+ * The signal is the PLCP value, and needs to be stripped
+ * of the preamble bit (0x08).
*/
- rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
- rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
+ rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08;
+ rxdesc->signal_plcp = 1;
+ rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) -
entry->queue->rt2x00dev->rssi_offset;
rxdesc->ofdm = 0;
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
@@ -1517,10 +1515,10 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
struct rt2x00_intf *intf = vif_to_intf(control->vif);
struct queue_entry_priv_pci_tx *priv_tx;
struct skb_frame_desc *skbdesc;
+ u32 reg;
if (unlikely(!intf->beacon))
return -ENOBUFS;
-
priv_tx = intf->beacon->priv_data;
/*
@@ -1536,6 +1534,16 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
skbdesc->entry = intf->beacon;
/*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+ rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+
+ /*
* mac80211 doesn't provide the control->queue variable
* for beacons. Set our own queue identification so
* it can be used during descriptor initialization.
@@ -1600,7 +1608,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
.kick_tx_queue = rt2400pci_kick_tx_queue,
.fill_rxdone = rt2400pci_fill_rxdone,
.config_intf = rt2400pci_config_intf,
- .config_preamble = rt2400pci_config_preamble,
+ .config_erp = rt2400pci_config_erp,
.config = rt2400pci_config,
};
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index da178d44660e..a5210f9a3360 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -899,13 +899,13 @@
* Word2
*/
#define RXD_W2_BUFFER_LENGTH FIELD32(0x0000ffff)
-#define RXD_W2_SIGNAL FIELD32(0x00ff0000)
-#define RXD_W2_RSSI FIELD32(0xff000000)
+#define RXD_W2_BBR0 FIELD32(0x00ff0000)
+#define RXD_W2_SIGNAL FIELD32(0xff000000)
/*
* Word3
*/
-#define RXD_W3_BBR2 FIELD32(0x000000ff)
+#define RXD_W3_RSSI FIELD32(0x000000ff)
#define RXD_W3_BBR3 FIELD32(0x0000ff00)
#define RXD_W3_BBR4 FIELD32(0x00ff0000)
#define RXD_W3_BBR5 FIELD32(0xff000000)
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index ffcd996df064..0f5139a2f238 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -281,8 +281,6 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
u32 reg;
if (flags & CONFIG_UPDATE_TYPE) {
- rt2x00pci_register_write(rt2x00dev, CSR14, 0);
-
/*
* Enable beacon config
*/
@@ -297,10 +295,8 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
*/
rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
- rt2x00_set_field32(&reg, CSR14_TBCN,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
rt2x00_set_field32(&reg, CSR14_TSF_SYNC, conf->sync);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 1);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
@@ -313,10 +309,8 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
conf->bssid, sizeof(conf->bssid));
}
-static int rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev,
- const int short_preamble,
- const int ack_timeout,
- const int ack_consume_time)
+static int rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_erp *erp)
{
int preamble_mask;
u32 reg;
@@ -324,11 +318,13 @@ static int rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev,
/*
* When short preamble is enabled, we should set bit 0x08
*/
- preamble_mask = short_preamble << 3;
+ preamble_mask = erp->short_preamble << 3;
rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
- rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, ack_timeout);
- rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, ack_consume_time);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT,
+ erp->ack_timeout);
+ rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME,
+ erp->ack_consume_time);
rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
@@ -450,6 +446,13 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
u8 r14;
u8 r2;
+ /*
+ * We should never come here because rt2x00lib is supposed
+ * to catch this and send us the correct antenna explicitely.
+ */
+ BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
+ ant->tx == ANTENNA_SW_DIVERSITY);
+
rt2x00pci_register_read(rt2x00dev, BBPCSR1, &reg);
rt2500pci_bbp_read(rt2x00dev, 14, &r14);
rt2500pci_bbp_read(rt2x00dev, 2, &r2);
@@ -463,15 +466,8 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, BBPCSR1_CCK, 0);
rt2x00_set_field32(&reg, BBPCSR1_OFDM, 0);
break;
- case ANTENNA_HW_DIVERSITY:
- case ANTENNA_SW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
rt2x00_set_field32(&reg, BBPCSR1_OFDM, 2);
@@ -485,15 +481,8 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
case ANTENNA_A:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
break;
- case ANTENNA_HW_DIVERSITY:
- case ANTENNA_SW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
break;
}
@@ -762,7 +751,7 @@ static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
priv_rx = rt2x00dev->rx->entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, RXCSR2, &reg);
- rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER, priv_tx->desc_dma);
+ rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma);
rt2x00pci_register_write(rt2x00dev, RXCSR2, reg);
return 0;
@@ -1193,6 +1182,8 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
if (queue == RT2X00_BCN_QUEUE_BEACON) {
rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 1);
rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
@@ -1228,10 +1219,17 @@ static void rt2500pci_fill_rxdone(struct queue_entry *entry,
if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
+ /*
+ * Obtain the status about this packet.
+ * When frame was received with an OFDM bitrate,
+ * the signal is the PLCP value. If it was received with
+ * a CCK bitrate the signal is the rate in 100kbit/s.
+ */
+ rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
+ rxdesc->signal_plcp = rxdesc->ofdm;
rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
entry->queue->rt2x00dev->rssi_offset;
- rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
}
@@ -1828,6 +1826,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
struct rt2x00_intf *intf = vif_to_intf(control->vif);
struct queue_entry_priv_pci_tx *priv_tx;
struct skb_frame_desc *skbdesc;
+ u32 reg;
if (unlikely(!intf->beacon))
return -ENOBUFS;
@@ -1847,6 +1846,16 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
skbdesc->entry = intf->beacon;
/*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+ rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+
+ /*
* mac80211 doesn't provide the control->queue variable
* for beacons. Set our own queue identification so
* it can be used during descriptor initialization.
@@ -1911,7 +1920,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
.kick_tx_queue = rt2500pci_kick_tx_queue,
.fill_rxdone = rt2500pci_fill_rxdone,
.config_intf = rt2500pci_config_intf,
- .config_preamble = rt2500pci_config_preamble,
+ .config_erp = rt2500pci_config_erp,
.config = rt2500pci_config,
};
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 9f59db91cfc2..c8216d755835 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -294,7 +294,8 @@ static void rt2500usb_led_brightness(struct led_classdev *led_cdev,
if (in_atomic()) {
NOTICE(led->rt2x00dev,
- "Ignoring LED brightness command for led %d", led->type);
+ "Ignoring LED brightness command for led %d\n",
+ led->type);
return;
}
@@ -324,8 +325,6 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
u16 reg;
if (flags & CONFIG_UPDATE_TYPE) {
- rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0);
-
/*
* Enable beacon config
*/
@@ -345,10 +344,8 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
- rt2x00_set_field16(&reg, TXRX_CSR19_TBCN,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
rt2x00_set_field16(&reg, TXRX_CSR19_TSF_SYNC, conf->sync);
+ rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
}
@@ -361,10 +358,8 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
(3 * sizeof(__le16)));
}
-static int rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev,
- const int short_preamble,
- const int ack_timeout,
- const int ack_consume_time)
+static int rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_erp *erp)
{
u16 reg;
@@ -376,12 +371,12 @@ static int rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev,
return -EAGAIN;
rt2500usb_register_read(rt2x00dev, TXRX_CSR1, &reg);
- rt2x00_set_field16(&reg, TXRX_CSR1_ACK_TIMEOUT, ack_timeout);
+ rt2x00_set_field16(&reg, TXRX_CSR1_ACK_TIMEOUT, erp->ack_timeout);
rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg);
rt2500usb_register_read(rt2x00dev, TXRX_CSR10, &reg);
rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE,
- !!short_preamble);
+ !!erp->short_preamble);
rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg);
return 0;
@@ -442,6 +437,13 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
u16 csr5;
u16 csr6;
+ /*
+ * We should never come here because rt2x00lib is supposed
+ * to catch this and send us the correct antenna explicitely.
+ */
+ BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
+ ant->tx == ANTENNA_SW_DIVERSITY);
+
rt2500usb_bbp_read(rt2x00dev, 2, &r2);
rt2500usb_bbp_read(rt2x00dev, 14, &r14);
rt2500usb_register_read(rt2x00dev, PHY_CSR5, &csr5);
@@ -461,14 +463,8 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 0);
rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 0);
break;
- case ANTENNA_SW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 2);
rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 2);
@@ -485,14 +481,8 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
case ANTENNA_A:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
break;
- case ANTENNA_SW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
break;
}
@@ -1092,6 +1082,8 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) {
+ rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
+ rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);
/*
* Beacon generation will fail initially.
@@ -1117,11 +1109,21 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
__le32 *rxd =
(__le32 *)(entry->skb->data +
(priv_rx->urb->actual_length - entry->queue->desc_size));
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
- int header_size = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
+ unsigned int offset = entry->queue->desc_size + 2;
u32 word0;
u32 word1;
+ /*
+ * Copy descriptor to the available headroom inside the skbuffer.
+ */
+ skb_push(entry->skb, offset);
+ memcpy(entry->skb->data, rxd, entry->queue->desc_size);
+ rxd = (__le32 *)entry->skb->data;
+
+ /*
+ * The descriptor is now aligned to 4 bytes and thus it is
+ * now safe to read it on all architectures.
+ */
rt2x00_desc_read(rxd, 0, &word0);
rt2x00_desc_read(rxd, 1, &word1);
@@ -1133,37 +1135,31 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
/*
* Obtain the status about this packet.
+ * When frame was received with an OFDM bitrate,
+ * the signal is the PLCP value. If it was received with
+ * a CCK bitrate the signal is the rate in 100kbit/s.
*/
+ rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
+ rxdesc->signal_plcp = rxdesc->ofdm;
rxdesc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) -
entry->queue->rt2x00dev->rssi_offset;
- rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
/*
- * The data behind the ieee80211 header must be
- * aligned on a 4 byte boundary.
+ * Adjust the skb memory window to the frame boundaries.
*/
- if (header_size % 4 == 0) {
- skb_push(entry->skb, 2);
- memmove(entry->skb->data, entry->skb->data + 2,
- entry->skb->len - 2);
- }
+ skb_pull(entry->skb, offset);
+ skb_trim(entry->skb, rxdesc->size);
/*
- * Set descriptor pointer.
+ * Set descriptor and data pointer.
*/
skbdesc->data = entry->skb->data;
skbdesc->data_len = rxdesc->size;
- skbdesc->desc = entry->skb->data + rxdesc->size;
+ skbdesc->desc = rxd;
skbdesc->desc_len = entry->queue->desc_size;
-
- /*
- * Remove descriptor from skb buffer and trim the whole thing
- * down to only contain data.
- */
- skb_trim(entry->skb, rxdesc->size);
}
/*
@@ -1740,6 +1736,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
struct skb_frame_desc *skbdesc;
int pipe = usb_sndbulkpipe(usb_dev, 1);
int length;
+ u16 reg;
if (unlikely(!intf->beacon))
return -ENOBUFS;
@@ -1765,6 +1762,16 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
skbdesc->entry = intf->beacon;
/*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 0);
+ rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 0);
+ rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
+
+ /*
* mac80211 doesn't provide the control->queue variable
* for beacons. Set our own queue identification so
* it can be used during descriptor initialization.
@@ -1839,7 +1846,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.kick_tx_queue = rt2500usb_kick_tx_queue,
.fill_rxdone = rt2500usb_fill_rxdone,
.config_intf = rt2500usb_config_intf,
- .config_preamble = rt2500usb_config_preamble,
+ .config_erp = rt2500usb_config_erp,
.config = rt2500usb_config,
};
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index fd65fccbdae7..dfd0af0e0a16 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -44,7 +44,7 @@
/*
* Module information.
*/
-#define DRV_VERSION "2.1.3"
+#define DRV_VERSION "2.1.4"
#define DRV_PROJECT "http://rt2x00.serialmonkey.com"
/*
@@ -384,7 +384,7 @@ struct rt2x00_intf {
*/
unsigned int delayed_flags;
#define DELAYED_UPDATE_BEACON 0x00000001
-#define DELAYED_CONFIG_PREAMBLE 0x00000002
+#define DELAYED_CONFIG_ERP 0x00000002
};
static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
@@ -441,8 +441,8 @@ struct rt2x00lib_conf {
enum ieee80211_band band;
- int basic_rates;
- int slot_time;
+ u32 basic_rates;
+ u32 slot_time;
short sifs;
short pifs;
@@ -451,6 +451,16 @@ struct rt2x00lib_conf {
};
/*
+ * Configuration structure for erp settings.
+ */
+struct rt2x00lib_erp {
+ int short_preamble;
+
+ int ack_timeout;
+ int ack_consume_time;
+};
+
+/*
* Configuration structure wrapper around the
* rt2x00 interface configuration handler.
*/
@@ -495,6 +505,7 @@ struct rt2x00lib_ops {
*/
int (*probe_hw) (struct rt2x00_dev *rt2x00dev);
char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev);
+ u16 (*get_firmware_crc) (void *data, const size_t len);
int (*load_firmware) (struct rt2x00_dev *rt2x00dev, void *data,
const size_t len);
@@ -557,10 +568,8 @@ struct rt2x00lib_ops {
#define CONFIG_UPDATE_MAC ( 1 << 2 )
#define CONFIG_UPDATE_BSSID ( 1 << 3 )
- int (*config_preamble) (struct rt2x00_dev *rt2x00dev,
- const int short_preamble,
- const int ack_timeout,
- const int ack_consume_time);
+ int (*config_erp) (struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_erp *erp);
void (*config) (struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags);
@@ -613,8 +622,6 @@ enum rt2x00_flags {
*/
DRIVER_SUPPORT_MIXED_INTERFACES,
DRIVER_REQUIRE_FIRMWARE,
- DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T,
- DRIVER_REQUIRE_FIRMWARE_CCITT,
DRIVER_REQUIRE_BEACON_GUARD,
DRIVER_REQUIRE_ATIM_QUEUE,
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 69959124d25d..5e2d81a9e438 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -75,43 +75,40 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
rt2x00dev->ops->lib->config_intf(rt2x00dev, intf, &conf, flags);
}
-void rt2x00lib_config_preamble(struct rt2x00_dev *rt2x00dev,
- struct rt2x00_intf *intf,
- const unsigned int short_preamble)
+void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_intf *intf,
+ struct ieee80211_bss_conf *bss_conf)
{
+ struct rt2x00lib_erp erp;
int retval;
- int ack_timeout;
- int ack_consume_time;
- ack_timeout = PLCP + get_duration(ACK_SIZE, 10);
- ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10);
+ memset(&erp, 0, sizeof(erp));
+
+ erp.short_preamble = bss_conf->use_short_preamble;
+ erp.ack_timeout = PLCP + get_duration(ACK_SIZE, 10);
+ erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10);
if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME)
- ack_timeout += SHORT_DIFS;
+ erp.ack_timeout += SHORT_DIFS;
else
- ack_timeout += DIFS;
+ erp.ack_timeout += DIFS;
- if (short_preamble) {
- ack_timeout += SHORT_PREAMBLE;
- ack_consume_time += SHORT_PREAMBLE;
+ if (bss_conf->use_short_preamble) {
+ erp.ack_timeout += SHORT_PREAMBLE;
+ erp.ack_consume_time += SHORT_PREAMBLE;
} else {
- ack_timeout += PREAMBLE;
- ack_consume_time += PREAMBLE;
+ erp.ack_timeout += PREAMBLE;
+ erp.ack_consume_time += PREAMBLE;
}
- retval = rt2x00dev->ops->lib->config_preamble(rt2x00dev,
- short_preamble,
- ack_timeout,
- ack_consume_time);
-
- spin_lock(&intf->lock);
+ retval = rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);
if (retval) {
- intf->delayed_flags |= DELAYED_CONFIG_PREAMBLE;
+ spin_lock(&intf->lock);
+ intf->delayed_flags |= DELAYED_CONFIG_ERP;
queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
+ spin_unlock(&intf->lock);
}
-
- spin_unlock(&intf->lock);
}
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
@@ -148,12 +145,26 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
}
+static u32 rt2x00lib_get_basic_rates(struct ieee80211_supported_band *band)
+{
+ const struct rt2x00_rate *rate;
+ unsigned int i;
+ u32 mask = 0;
+
+ for (i = 0; i < band->n_bitrates; i++) {
+ rate = rt2x00_get_rate(band->bitrates[i].hw_value);
+ if (rate->flags & DEV_RATE_BASIC)
+ mask |= rate->ratemask;
+ }
+
+ return mask;
+}
+
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf, const int force_config)
{
struct rt2x00lib_conf libconf;
struct ieee80211_supported_band *band;
- struct ieee80211_rate *rate;
struct antenna_setup *default_ant = &rt2x00dev->default_ant;
struct antenna_setup *active_ant = &rt2x00dev->link.ant.active;
int flags = 0;
@@ -230,10 +241,9 @@ config:
if (flags & CONFIG_UPDATE_PHYMODE) {
band = &rt2x00dev->bands[conf->channel->band];
- rate = &band->bitrates[band->n_bitrates - 1];
libconf.band = conf->channel->band;
- libconf.basic_rates = rt2x00_get_rate(rate->hw_value)->ratemask;
+ libconf.basic_rates = rt2x00lib_get_basic_rates(band);
}
if (flags & CONFIG_UPDATE_CHANNEL) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 21af11a97334..bfab3b8780d6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -278,6 +278,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
{
struct rt2x00debug_intf *intf = file->private_data;
struct data_queue *queue;
+ unsigned long irqflags;
unsigned int lines = 1 + intf->rt2x00dev->data_queues;
size_t size;
char *data;
@@ -294,7 +295,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n");
queue_for_each(intf->rt2x00dev, queue) {
- spin_lock(&queue->lock);
+ spin_lock_irqsave(&queue->lock, irqflags);
temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid,
queue->count, queue->limit, queue->length,
@@ -302,7 +303,7 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file,
queue->index[Q_INDEX_DONE],
queue->index[Q_INDEX_CRYPTO]);
- spin_unlock(&queue->lock);
+ spin_unlock_irqrestore(&queue->lock, irqflags);
}
size = strlen(data);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index b3a639aa0540..b81efc9b058d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -447,9 +447,8 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
}
}
- if (delayed_flags & DELAYED_CONFIG_PREAMBLE)
- rt2x00lib_config_preamble(rt2x00dev, intf,
- intf->conf.use_short_preamble);
+ if (delayed_flags & DELAYED_CONFIG_ERP)
+ rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf);
}
static void rt2x00lib_intf_scheduled(struct work_struct *work)
@@ -521,7 +520,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
tx_status.ack_signal = 0;
tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY);
tx_status.retry_count = txdesc->retry;
- memcpy(&tx_status.control, txdesc->control, sizeof(txdesc->control));
+ memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control));
if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
if (success)
@@ -581,13 +580,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
for (i = 0; i < sband->n_bitrates; i++) {
rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
- /*
- * When frame was received with an OFDM bitrate,
- * the signal is the PLCP value. If it was received with
- * a CCK bitrate the signal is the rate in 100kbit/s.
- */
- if ((rxdesc->ofdm && rate->plcp == rxdesc->signal) ||
- (!rxdesc->ofdm && rate->bitrate == rxdesc->signal)) {
+ if ((rxdesc->signal_plcp && rate->plcp == rxdesc->signal) ||
+ (!rxdesc->signal_plcp && rate->bitrate == rxdesc->signal)) {
idx = i;
break;
}
@@ -630,7 +624,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
{
struct txentry_desc txdesc;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skbdesc->data;
const struct rt2x00_rate *rate;
int tx_rate;
int length;
@@ -710,7 +704,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
txdesc.signal = rate->plcp;
txdesc.service = 0x04;
- length = skb->len + FCS_LEN;
+ length = skbdesc->data_len + FCS_LEN;
if (rate->flags & DEV_RATE_OFDM) {
__set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags);
@@ -767,75 +761,75 @@ EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc);
*/
const struct rt2x00_rate rt2x00_supported_rates[12] = {
{
- .flags = DEV_RATE_CCK,
+ .flags = DEV_RATE_CCK | DEV_RATE_BASIC,
.bitrate = 10,
- .ratemask = DEV_RATEMASK_1MB,
+ .ratemask = BIT(0),
.plcp = 0x00,
},
{
- .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
+ .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
.bitrate = 20,
- .ratemask = DEV_RATEMASK_2MB,
+ .ratemask = BIT(1),
.plcp = 0x01,
},
{
- .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
+ .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
.bitrate = 55,
- .ratemask = DEV_RATEMASK_5_5MB,
+ .ratemask = BIT(2),
.plcp = 0x02,
},
{
- .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
+ .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
.bitrate = 110,
- .ratemask = DEV_RATEMASK_11MB,
+ .ratemask = BIT(3),
.plcp = 0x03,
},
{
- .flags = DEV_RATE_OFDM,
+ .flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
.bitrate = 60,
- .ratemask = DEV_RATEMASK_6MB,
+ .ratemask = BIT(4),
.plcp = 0x0b,
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 90,
- .ratemask = DEV_RATEMASK_9MB,
+ .ratemask = BIT(5),
.plcp = 0x0f,
},
{
- .flags = DEV_RATE_OFDM,
+ .flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
.bitrate = 120,
- .ratemask = DEV_RATEMASK_12MB,
+ .ratemask = BIT(6),
.plcp = 0x0a,
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 180,
- .ratemask = DEV_RATEMASK_18MB,
+ .ratemask = BIT(7),
.plcp = 0x0e,
},
{
- .flags = DEV_RATE_OFDM,
+ .flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
.bitrate = 240,
- .ratemask = DEV_RATEMASK_24MB,
+ .ratemask = BIT(8),
.plcp = 0x09,
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 360,
- .ratemask = DEV_RATEMASK_36MB,
+ .ratemask = BIT(9),
.plcp = 0x0d,
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 480,
- .ratemask = DEV_RATEMASK_48MB,
+ .ratemask = BIT(10),
.plcp = 0x08,
},
{
.flags = DEV_RATE_OFDM,
.bitrate = 540,
- .ratemask = DEV_RATEMASK_54MB,
+ .ratemask = BIT(11),
.plcp = 0x0c,
},
};
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index 4f9fe56f4f2e..b971bc6e7ee2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -23,8 +23,6 @@
Abstract: rt2x00 firmware loading routines.
*/
-#include <linux/crc-ccitt.h>
-#include <linux/crc-itu-t.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -63,36 +61,7 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
return -ENOENT;
}
- /*
- * Perform crc validation on the firmware.
- * The last 2 bytes in the firmware array are the crc checksum itself,
- * this means that we should never pass those 2 bytes to the crc
- * algorithm.
- */
- if (test_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags)) {
- /*
- * Use the crc itu-t algorithm.
- * Use 0 for the last 2 bytes to complete the checksum.
- */
- crc = crc_itu_t(0, fw->data, fw->size - 2);
- crc = crc_itu_t_byte(crc, 0);
- crc = crc_itu_t_byte(crc, 0);
- } else if (test_bit(DRIVER_REQUIRE_FIRMWARE_CCITT, &rt2x00dev->flags)) {
- /*
- * Use the crc ccitt algorithm.
- * This will return the same value as the legacy driver which
- * used bit ordering reversion on the both the firmware bytes
- * before input input as well as on the final output.
- * Obviously using crc ccitt directly is much more efficient.
- */
- crc = crc_ccitt(~0, fw->data, fw->size - 2);
- } else {
- ERROR(rt2x00dev, "No checksum algorithm selected "
- "for firmware validation.\n");
- retval = -ENOENT;
- goto exit;
- }
-
+ crc = rt2x00dev->ops->lib->get_firmware_crc(fw->data, fw->size);
if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) {
ERROR(rt2x00dev, "Firmware checksum error.\n");
retval = -ENOENT;
@@ -139,4 +108,3 @@ void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev)
release_firmware(rt2x00dev->fw);
rt2x00dev->fw = NULL;
}
-
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c
index 9c29d17e0cc2..ca2d282a9f75 100644
--- a/drivers/net/wireless/rt2x00/rt2x00leds.c
+++ b/drivers/net/wireless/rt2x00/rt2x00leds.c
@@ -109,7 +109,7 @@ static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
return 0;
}
-int rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
+void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
{
char *trigger;
char dev_name[16];
@@ -117,7 +117,7 @@ int rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
int retval;
if (!rt2x00dev->ops->lib->led_brightness)
- return 0;
+ return;
snprintf(dev_name, sizeof(dev_name), "%s-%s",
rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy));
@@ -161,11 +161,10 @@ int rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
goto exit_fail;
}
- return 0;
+ return;
exit_fail:
rt2x00leds_unregister(rt2x00dev);
- return retval;
}
static void rt2x00leds_unregister_trigger(struct rt2x00_trigger *trigger)
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 34ccb3de687e..e4b4dd23d611 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -41,22 +41,10 @@ struct rt2x00_rate {
#define DEV_RATE_CCK 0x0001
#define DEV_RATE_OFDM 0x0002
#define DEV_RATE_SHORT_PREAMBLE 0x0004
+#define DEV_RATE_BASIC 0x0008
unsigned short bitrate; /* In 100kbit/s */
-
unsigned short ratemask;
-#define DEV_RATEMASK_1MB ( (1 << 1) - 1 )
-#define DEV_RATEMASK_2MB ( (1 << 2) - 1 )
-#define DEV_RATEMASK_5_5MB ( (1 << 3) - 1 )
-#define DEV_RATEMASK_11MB ( (1 << 4) - 1 )
-#define DEV_RATEMASK_6MB ( (1 << 5) - 1 )
-#define DEV_RATEMASK_9MB ( (1 << 6) - 1 )
-#define DEV_RATEMASK_12MB ( (1 << 7) - 1 )
-#define DEV_RATEMASK_18MB ( (1 << 8) - 1 )
-#define DEV_RATEMASK_24MB ( (1 << 9) - 1 )
-#define DEV_RATEMASK_36MB ( (1 << 10) - 1 )
-#define DEV_RATEMASK_48MB ( (1 << 11) - 1 )
-#define DEV_RATEMASK_54MB ( (1 << 12) - 1 )
unsigned short plcp;
};
@@ -100,9 +88,9 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
enum ieee80211_if_types type,
u8 *mac, u8 *bssid);
-void rt2x00lib_config_preamble(struct rt2x00_dev *rt2x00dev,
- struct rt2x00_intf *intf,
- const unsigned int short_preamble);
+void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_intf *intf,
+ struct ieee80211_bss_conf *conf);
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
enum antenna rx, enum antenna tx);
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
@@ -189,7 +177,7 @@ static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
*/
#ifdef CONFIG_RT2X00_LIB_LEDS
void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi);
-int rt2x00leds_register(struct rt2x00_dev *rt2x00dev);
+void rt2x00leds_register(struct rt2x00_dev *rt2x00dev);
void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev);
void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev);
void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev);
@@ -199,9 +187,8 @@ static inline void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev,
{
}
-static inline int rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
+static inline void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
{
- return 0;
}
static inline void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index a54f6873e9ea..0a11c27d603b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -99,7 +99,11 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
/*
* Determine which queue to put packet on.
*/
- queue = rt2x00queue_get_queue(rt2x00dev, control->queue);
+ if (control->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM &&
+ test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags))
+ queue = rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_ATIM);
+ else
+ queue = rt2x00queue_get_queue(rt2x00dev, control->queue);
if (unlikely(!queue)) {
ERROR(rt2x00dev,
"Attempt to send packet over invalid queue %d.\n"
@@ -432,17 +436,15 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
}
/*
- * When the preamble mode has changed, we should perform additional
- * configuration steps. For all other changes we are already done.
+ * When the erp information has changed, we should perform
+ * additional configuration steps. For all other changes we are done.
*/
- if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- rt2x00lib_config_preamble(rt2x00dev, intf,
- bss_conf->use_short_preamble);
+ if (changes & BSS_CHANGED_ERP_PREAMBLE)
+ rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
- spin_lock(&intf->lock);
- memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
- spin_unlock(&intf->lock);
- }
+ spin_lock(&intf->lock);
+ memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
+ spin_unlock(&intf->lock);
}
EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 1960d938d73b..7867ec64bd2c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -67,6 +67,7 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
skbdesc->desc_len = queue->desc_size;
skbdesc->entry = entry;
+ memcpy(&priv_tx->control, control, sizeof(priv_tx->control));
memcpy(priv_tx->data, skb->data, skb->len);
rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 9188323f067b..659e9f44c40c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -53,6 +53,7 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
enum queue_index index)
{
struct queue_entry *entry;
+ unsigned long irqflags;
if (unlikely(index >= Q_INDEX_MAX)) {
ERROR(queue->rt2x00dev,
@@ -60,11 +61,11 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
return NULL;
}
- spin_lock(&queue->lock);
+ spin_lock_irqsave(&queue->lock, irqflags);
entry = &queue->entries[queue->index[index]];
- spin_unlock(&queue->lock);
+ spin_unlock_irqrestore(&queue->lock, irqflags);
return entry;
}
@@ -72,13 +73,15 @@ EXPORT_SYMBOL_GPL(rt2x00queue_get_entry);
void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
{
+ unsigned long irqflags;
+
if (unlikely(index >= Q_INDEX_MAX)) {
ERROR(queue->rt2x00dev,
"Index change on invalid index type (%d)\n", index);
return;
}
- spin_lock(&queue->lock);
+ spin_lock_irqsave(&queue->lock, irqflags);
queue->index[index]++;
if (queue->index[index] >= queue->limit)
@@ -91,19 +94,21 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
queue->count ++;
}
- spin_unlock(&queue->lock);
+ spin_unlock_irqrestore(&queue->lock, irqflags);
}
EXPORT_SYMBOL_GPL(rt2x00queue_index_inc);
static void rt2x00queue_reset(struct data_queue *queue)
{
- spin_lock(&queue->lock);
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&queue->lock, irqflags);
queue->count = 0;
queue->length = 0;
memset(queue->index, 0, sizeof(queue->index));
- spin_unlock(&queue->lock);
+ spin_unlock_irqrestore(&queue->lock, irqflags);
}
void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index fbabf389b622..c5f46f234083 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -134,6 +134,8 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
* Summary of information that has been read from the RX frame descriptor.
*
* @signal: Signal of the received frame.
+ * @signal_plcp: Does the signal field contain the plcp value,
+ * or does it contain the bitrate itself.
* @rssi: RSSI of the received frame.
* @ofdm: Was frame send with an OFDM rate.
* @size: Data size of the received frame.
@@ -142,6 +144,7 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
*/
struct rxdone_entry_desc {
int signal;
+ int signal_plcp;
int rssi;
int ofdm;
int size;
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 063b167da31e..5a331674dcb2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -206,6 +206,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
skbdesc->desc_len = queue->desc_size;
skbdesc->entry = entry;
+ memcpy(&priv_tx->control, control, sizeof(priv_tx->control));
rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
/*
@@ -247,11 +248,11 @@ static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue)
* advance.
*/
frame_size = queue->data_size + queue->desc_size;
- skb = dev_alloc_skb(frame_size + 2);
+ skb = dev_alloc_skb(queue->desc_size + frame_size + 2);
if (!skb)
return NULL;
- skb_reserve(skb, 2);
+ skb_reserve(skb, queue->desc_size + 2);
skb_put(skb, frame_size);
return skb;
@@ -264,6 +265,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
struct sk_buff *skb;
struct skb_frame_desc *skbdesc;
struct rxdone_entry_desc rxdesc;
+ int header_size;
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
@@ -288,6 +290,19 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
/*
+ * The data behind the ieee80211 header must be
+ * aligned on a 4 byte boundary.
+ */
+ header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
+ if (header_size % 4 == 0) {
+ skb_push(entry->skb, 2);
+ memmove(entry->skb->data, entry->skb->data + 2,
+ entry->skb->len - 2);
+ skbdesc->data = entry->skb->data;
+ skb_trim(entry->skb,entry->skb->len - 2);
+ }
+
+ /*
* Allocate a new sk buffer to replace the current one.
* If allocation fails, we should drop the current frame
* so we can recycle the existing sk buffer for the new frame.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 9ff7e609cfda..babb240cef3d 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -24,6 +24,7 @@
Supported chipsets: RT2561, RT2561s, RT2661.
*/
+#include <linux/crc-itu-t.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
@@ -336,7 +337,6 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
* bits which (when set to 0) will invalidate the entire beacon.
*/
beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
rt2x00pci_register_write(rt2x00dev, beacon_base, 0);
/*
@@ -344,10 +344,8 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
*/
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
- rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, conf->sync);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
}
@@ -370,20 +368,18 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
}
}
-static int rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev,
- const int short_preamble,
- const int ack_timeout,
- const int ack_consume_time)
+static int rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_erp *erp)
{
u32 reg;
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout);
+ rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
- !!short_preamble);
+ !!erp->short_preamble);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
return 0;
@@ -485,14 +481,8 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
else
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
break;
- case ANTENNA_SW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)
@@ -534,14 +524,8 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
break;
- case ANTENNA_SW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
break;
@@ -579,10 +563,6 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
rt61pci_bbp_read(rt2x00dev, 4, &r4);
rt61pci_bbp_read(rt2x00dev, 77, &r77);
- /* FIXME: Antenna selection for the rf 2529 is very confusing in the
- * legacy driver. The code below should be ok for non-diversity setups.
- */
-
/*
* Configure the RX antenna.
*/
@@ -592,15 +572,14 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
break;
- case ANTENNA_SW_DIVERSITY:
case ANTENNA_HW_DIVERSITY:
/*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
+ * FIXME: Antenna selection for the rf 2529 is very confusing
+ * in the legacy driver. Just default to antenna B until the
+ * legacy code can be properly translated into rt2x00 code.
*/
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
@@ -651,6 +630,13 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
unsigned int i;
u32 reg;
+ /*
+ * We should never come here because rt2x00lib is supposed
+ * to catch this and send us the correct antenna explicitely.
+ */
+ BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
+ ant->tx == ANTENNA_SW_DIVERSITY);
+
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
sel = antenna_sel_a;
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
@@ -861,7 +847,7 @@ dynamic_cca_tune:
}
/*
- * Firmware name function.
+ * Firmware functions
*/
static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
{
@@ -885,9 +871,23 @@ static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
return fw_name;
}
-/*
- * Initialization functions.
- */
+static u16 rt61pci_get_firmware_crc(void *data, const size_t len)
+{
+ u16 crc;
+
+ /*
+ * Use the crc itu-t algorithm.
+ * The last 2 bytes in the firmware array are the crc checksum itself,
+ * this means that we should never pass those 2 bytes to the crc
+ * algorithm.
+ */
+ crc = crc_itu_t(0, data, len - 2);
+ crc = crc_itu_t_byte(crc, 0);
+ crc = crc_itu_t_byte(crc, 0);
+
+ return crc;
+}
+
static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
const size_t len)
{
@@ -968,6 +968,9 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
return 0;
}
+/*
+ * Initialization functions.
+ */
static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
@@ -1562,6 +1565,8 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
+ rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
}
@@ -1640,10 +1645,14 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry,
/*
* Obtain the status about this packet.
+ * When frame was received with an OFDM bitrate,
+ * the signal is the PLCP value. If it was received with
+ * a CCK bitrate the signal is the rate in 100kbit/s.
*/
+ rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
+ rxdesc->signal_plcp = rxdesc->ofdm;
rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1);
- rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
}
@@ -2260,7 +2269,6 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
* This device requires firmware.
*/
__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags);
/*
* Set the rssi offset.
@@ -2373,6 +2381,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
struct rt2x00_intf *intf = vif_to_intf(control->vif);
struct skb_frame_desc *skbdesc;
unsigned int beacon_base;
+ u32 reg;
if (unlikely(!intf->beacon))
return -ENOBUFS;
@@ -2408,6 +2417,16 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
skbdesc->entry = intf->beacon;
/*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+
+ /*
* mac80211 doesn't provide the control->queue variable
* for beacons. Set our own queue identification so
* it can be used during descriptor initialization.
@@ -2449,6 +2468,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.irq_handler = rt61pci_interrupt,
.probe_hw = rt61pci_probe_hw,
.get_firmware_name = rt61pci_get_firmware_name,
+ .get_firmware_crc = rt61pci_get_firmware_crc,
.load_firmware = rt61pci_load_firmware,
.initialize = rt2x00pci_initialize,
.uninitialize = rt2x00pci_uninitialize,
@@ -2465,7 +2485,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.kick_tx_queue = rt61pci_kick_tx_queue,
.fill_rxdone = rt61pci_fill_rxdone,
.config_intf = rt61pci_config_intf,
- .config_preamble = rt61pci_config_preamble,
+ .config_erp = rt61pci_config_erp,
.config = rt61pci_config,
};
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index efc18de16fa1..46b040bf62de 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -24,6 +24,7 @@
Supported chipsets: rt2571W & rt2671.
*/
+#include <linux/crc-itu-t.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
@@ -292,7 +293,8 @@ static void rt73usb_led_brightness(struct led_classdev *led_cdev,
if (in_atomic()) {
NOTICE(led->rt2x00dev,
- "Ignoring LED brightness command for led %d", led->type);
+ "Ignoring LED brightness command for led %d\n",
+ led->type);
return;
}
@@ -347,7 +349,6 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
* bits which (when set to 0) will invalidate the entire beacon.
*/
beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
- rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0);
rt73usb_register_write(rt2x00dev, beacon_base, 0);
/*
@@ -355,10 +356,8 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
*/
rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
- rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE,
- (conf->sync == TSF_SYNC_BEACON));
- rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, conf->sync);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
}
@@ -381,10 +380,8 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
}
}
-static int rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev,
- const int short_preamble,
- const int ack_timeout,
- const int ack_consume_time)
+static int rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_erp *erp)
{
u32 reg;
@@ -396,12 +393,12 @@ static int rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev,
return -EAGAIN;
rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout);
+ rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
rt73usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
- !!short_preamble);
+ !!erp->short_preamble);
rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
return 0;
@@ -500,14 +497,8 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
else
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
break;
- case ANTENNA_SW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)
@@ -548,14 +539,8 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
break;
- case ANTENNA_SW_DIVERSITY:
- /*
- * NOTE: We should never come here because rt2x00lib is
- * supposed to catch this and send us the correct antenna
- * explicitely. However we are nog going to bug about this.
- * Instead, just default to antenna B.
- */
case ANTENNA_B:
+ default:
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
break;
@@ -605,6 +590,13 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
unsigned int i;
u32 reg;
+ /*
+ * We should never come here because rt2x00lib is supposed
+ * to catch this and send us the correct antenna explicitely.
+ */
+ BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
+ ant->tx == ANTENNA_SW_DIVERSITY);
+
if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
sel = antenna_sel_a;
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
@@ -821,16 +813,30 @@ dynamic_cca_tune:
}
/*
- * Firmware name function.
+ * Firmware functions
*/
static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
{
return FIRMWARE_RT2571;
}
-/*
- * Initialization functions.
- */
+static u16 rt73usb_get_firmware_crc(void *data, const size_t len)
+{
+ u16 crc;
+
+ /*
+ * Use the crc itu-t algorithm.
+ * The last 2 bytes in the firmware array are the crc checksum itself,
+ * this means that we should never pass those 2 bytes to the crc
+ * algorithm.
+ */
+ crc = crc_itu_t(0, data, len - 2);
+ crc = crc_itu_t_byte(crc, 0);
+ crc = crc_itu_t_byte(crc, 0);
+
+ return crc;
+}
+
static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
const size_t len)
{
@@ -900,6 +906,9 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
return 0;
}
+/*
+ * Initialization functions.
+ */
static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
{
u32 reg;
@@ -1312,6 +1321,8 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
+ rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
}
@@ -1370,12 +1381,21 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
__le32 *rxd = (__le32 *)entry->skb->data;
- struct ieee80211_hdr *hdr =
- (struct ieee80211_hdr *)entry->skb->data + entry->queue->desc_size;
- int header_size = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
+ unsigned int offset = entry->queue->desc_size + 2;
u32 word0;
u32 word1;
+ /*
+ * Copy descriptor to the available headroom inside the skbuffer.
+ */
+ skb_push(entry->skb, offset);
+ memcpy(entry->skb->data, rxd, entry->queue->desc_size);
+ rxd = (__le32 *)entry->skb->data;
+
+ /*
+ * The descriptor is now aligned to 4 bytes and thus it is
+ * now safe to read it on all architectures.
+ */
rt2x00_desc_read(rxd, 0, &word0);
rt2x00_desc_read(rxd, 1, &word1);
@@ -1385,37 +1405,30 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
/*
* Obtain the status about this packet.
+ * When frame was received with an OFDM bitrate,
+ * the signal is the PLCP value. If it was received with
+ * a CCK bitrate the signal is the rate in 100kbit/s.
*/
+ rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
+ rxdesc->signal_plcp = rxdesc->ofdm;
rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1);
- rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
/*
- * The data behind the ieee80211 header must be
- * aligned on a 4 byte boundary.
+ * Adjust the skb memory window to the frame boundaries.
*/
- if (header_size % 4 == 0) {
- skb_push(entry->skb, 2);
- memmove(entry->skb->data, entry->skb->data + 2,
- entry->skb->len - 2);
- }
+ skb_pull(entry->skb, offset + entry->queue->desc_size);
+ skb_trim(entry->skb, rxdesc->size);
/*
* Set descriptor and data pointer.
*/
- skbdesc->data = entry->skb->data + entry->queue->desc_size;
+ skbdesc->data = entry->skb->data;
skbdesc->data_len = rxdesc->size;
- skbdesc->desc = entry->skb->data;
+ skbdesc->desc = rxd;
skbdesc->desc_len = entry->queue->desc_size;
-
- /*
- * Remove descriptor from skb buffer and trim the whole thing
- * down to only contain data.
- */
- skb_pull(entry->skb, skbdesc->desc_len);
- skb_trim(entry->skb, rxdesc->size);
}
/*
@@ -1856,7 +1869,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
* This device requires firmware.
*/
__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
- __set_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags);
/*
* Set the rssi offset.
@@ -1989,6 +2001,7 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
struct skb_frame_desc *skbdesc;
unsigned int beacon_base;
unsigned int timeout;
+ u32 reg;
if (unlikely(!intf->beacon))
return -ENOBUFS;
@@ -2012,6 +2025,16 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
skbdesc->entry = intf->beacon;
/*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+ rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+
+ /*
* mac80211 doesn't provide the control->queue variable
* for beacons. Set our own queue identification so
* it can be used during descriptor initialization.
@@ -2054,6 +2077,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.probe_hw = rt73usb_probe_hw,
.get_firmware_name = rt73usb_get_firmware_name,
+ .get_firmware_crc = rt73usb_get_firmware_crc,
.load_firmware = rt73usb_load_firmware,
.initialize = rt2x00usb_initialize,
.uninitialize = rt2x00usb_uninitialize,
@@ -2070,7 +2094,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.kick_tx_queue = rt73usb_kick_tx_queue,
.fill_rxdone = rt73usb_fill_rxdone,
.config_intf = rt73usb_config_intf,
- .config_preamble = rt73usb_config_preamble,
+ .config_erp = rt73usb_config_erp,
.config = rt73usb_config,
};
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index f69ef0ba2613..0f7cce2560d1 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -20,6 +20,10 @@ config SSB
If unsure, say N.
+# Common SPROM support routines
+config SSB_SPROM
+ bool
+
config SSB_PCIHOST_POSSIBLE
bool
depends on SSB && (PCI = y || PCI = SSB)
@@ -28,6 +32,7 @@ config SSB_PCIHOST_POSSIBLE
config SSB_PCIHOST
bool "Support for SSB on PCI-bus host"
depends on SSB_PCIHOST_POSSIBLE
+ select SSB_SPROM
default y
help
Support for a Sonics Silicon Backplane on top
@@ -48,6 +53,7 @@ config SSB_PCMCIAHOST_POSSIBLE
config SSB_PCMCIAHOST
bool "Support for SSB on PCMCIA-bus host (EXPERIMENTAL)"
depends on SSB_PCMCIAHOST_POSSIBLE
+ select SSB_SPROM
help
Support for a Sonics Silicon Backplane on top
of a PCMCIA device.
diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile
index 910f35e32fc9..6f255e9c5af9 100644
--- a/drivers/ssb/Makefile
+++ b/drivers/ssb/Makefile
@@ -1,6 +1,7 @@
# core
ssb-y += main.o scan.o
ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o
+ssb-$(CONFIG_SSB_SPROM) += sprom.o
# host support
ssb-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 49d7bbb9bea7..e12371916444 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -69,6 +69,25 @@ found:
}
#endif /* CONFIG_SSB_PCIHOST */
+#ifdef CONFIG_SSB_PCMCIAHOST
+struct ssb_bus *ssb_pcmcia_dev_to_bus(struct pcmcia_device *pdev)
+{
+ struct ssb_bus *bus;
+
+ ssb_buses_lock();
+ list_for_each_entry(bus, &buses, list) {
+ if (bus->bustype == SSB_BUSTYPE_PCMCIA &&
+ bus->host_pcmcia == pdev)
+ goto found;
+ }
+ bus = NULL;
+found:
+ ssb_buses_unlock();
+
+ return bus;
+}
+#endif /* CONFIG_SSB_PCMCIAHOST */
+
int ssb_for_each_bus_call(unsigned long data,
int (*func)(struct ssb_bus *bus, unsigned long data))
{
@@ -398,7 +417,7 @@ void ssb_bus_unregister(struct ssb_bus *bus)
list_del(&bus->list);
ssb_buses_unlock();
- /* ssb_pcmcia_exit(bus); */
+ ssb_pcmcia_exit(bus);
ssb_pci_exit(bus);
ssb_iounmap(bus);
}
@@ -663,7 +682,7 @@ out:
err_dequeue:
list_del(&bus->list);
err_pcmcia_exit:
-/* ssb_pcmcia_exit(bus); */
+ ssb_pcmcia_exit(bus);
err_pci_exit:
ssb_pci_exit(bus);
err_unmap:
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 1facc7620fc8..f1514b33cfae 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -227,7 +227,7 @@ static u8 ssb_sprom_crc(const u16 *sprom, u16 size)
return crc;
}
-static int sprom_check_crc(const u16 *sprom, u16 size)
+static int sprom_check_crc(const u16 *sprom, size_t size)
{
u8 crc;
u8 expected_crc;
@@ -242,12 +242,14 @@ static int sprom_check_crc(const u16 *sprom, u16 size)
return 0;
}
-static void sprom_do_read(struct ssb_bus *bus, u16 *sprom)
+static int sprom_do_read(struct ssb_bus *bus, u16 *sprom)
{
int i;
for (i = 0; i < bus->sprom_size; i++)
sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2));
+
+ return 0;
}
static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
@@ -660,71 +662,18 @@ const struct ssb_bus_ops ssb_pci_ops = {
.write32 = ssb_pci_write32,
};
-static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, u16 size)
-{
- int i, pos = 0;
-
- for (i = 0; i < size; i++)
- pos += snprintf(buf + pos, buf_len - pos - 1,
- "%04X", swab16(sprom[i]) & 0xFFFF);
- pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
-
- return pos + 1;
-}
-
-static int hex2sprom(u16 *sprom, const char *dump, size_t len, u16 size)
-{
- char tmp[5] = { 0 };
- int cnt = 0;
- unsigned long parsed;
-
- if (len < size * 2)
- return -EINVAL;
-
- while (cnt < size) {
- memcpy(tmp, dump, 4);
- dump += 4;
- parsed = simple_strtoul(tmp, NULL, 16);
- sprom[cnt++] = swab16((u16)parsed);
- }
-
- return 0;
-}
-
static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
struct device_attribute *attr,
char *buf)
{
struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
struct ssb_bus *bus;
- u16 *sprom;
- int err = -ENODEV;
- ssize_t count = 0;
bus = ssb_pci_dev_to_bus(pdev);
if (!bus)
- goto out;
- err = -ENOMEM;
- sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL);
- if (!sprom)
- goto out;
+ return -ENODEV;
- /* Use interruptible locking, as the SPROM write might
- * be holding the lock for several seconds. So allow userspace
- * to cancel operation. */
- err = -ERESTARTSYS;
- if (mutex_lock_interruptible(&bus->pci_sprom_mutex))
- goto out_kfree;
- sprom_do_read(bus, sprom);
- mutex_unlock(&bus->pci_sprom_mutex);
-
- count = sprom2hex(sprom, buf, PAGE_SIZE, bus->sprom_size);
- err = 0;
-
-out_kfree:
- kfree(sprom);
-out:
- return err ? err : count;
+ return ssb_attr_sprom_show(bus, buf, sprom_do_read);
}
static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
@@ -733,55 +682,13 @@ static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
{
struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
struct ssb_bus *bus;
- u16 *sprom;
- int res = 0, err = -ENODEV;
bus = ssb_pci_dev_to_bus(pdev);
if (!bus)
- goto out;
- err = -ENOMEM;
- sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL);
- if (!sprom)
- goto out;
- err = hex2sprom(sprom, buf, count, bus->sprom_size);
- if (err) {
- err = -EINVAL;
- goto out_kfree;
- }
- err = sprom_check_crc(sprom, bus->sprom_size);
- if (err) {
- err = -EINVAL;
- goto out_kfree;
- }
+ return -ENODEV;
- /* Use interruptible locking, as the SPROM write might
- * be holding the lock for several seconds. So allow userspace
- * to cancel operation. */
- err = -ERESTARTSYS;
- if (mutex_lock_interruptible(&bus->pci_sprom_mutex))
- goto out_kfree;
- err = ssb_devices_freeze(bus);
- if (err == -EOPNOTSUPP) {
- ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze devices. "
- "No suspend support. Is CONFIG_PM enabled?\n");
- goto out_unlock;
- }
- if (err) {
- ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n");
- goto out_unlock;
- }
- res = sprom_do_write(bus, sprom);
- err = ssb_devices_thaw(bus);
- if (err)
- ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n");
-out_unlock:
- mutex_unlock(&bus->pci_sprom_mutex);
-out_kfree:
- kfree(sprom);
-out:
- if (res)
- return res;
- return err ? err : count;
+ return ssb_attr_sprom_store(bus, buf, count,
+ sprom_check_crc, sprom_do_write);
}
static DEVICE_ATTR(ssb_sprom, 0600,
@@ -808,7 +715,7 @@ int ssb_pci_init(struct ssb_bus *bus)
return 0;
pdev = bus->host_pci;
- mutex_init(&bus->pci_sprom_mutex);
+ mutex_init(&bus->sprom_mutex);
err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);
if (err)
goto out;
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index 84b3a845a8a8..cd49f7c65531 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -3,7 +3,7 @@
* PCMCIA-Hostbus related functions
*
* Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2007 Michael Buesch <mb@bu3sch.de>
+ * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
@@ -11,6 +11,7 @@
#include <linux/ssb/ssb.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/etherdevice.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
@@ -26,59 +27,132 @@
#define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG 0
+/* PCMCIA configuration registers */
+#define SSB_PCMCIA_CORECTL 0x00
+#define SSB_PCMCIA_CORECTL_RESET 0x80 /* Core reset */
+#define SSB_PCMCIA_CORECTL_IRQEN 0x04 /* IRQ enable */
+#define SSB_PCMCIA_CORECTL_FUNCEN 0x01 /* Function enable */
+#define SSB_PCMCIA_CORECTL2 0x80
+#define SSB_PCMCIA_ADDRESS0 0x2E
+#define SSB_PCMCIA_ADDRESS1 0x30
+#define SSB_PCMCIA_ADDRESS2 0x32
+#define SSB_PCMCIA_MEMSEG 0x34
+#define SSB_PCMCIA_SPROMCTL 0x36
+#define SSB_PCMCIA_SPROMCTL_IDLE 0
+#define SSB_PCMCIA_SPROMCTL_WRITE 1
+#define SSB_PCMCIA_SPROMCTL_READ 2
+#define SSB_PCMCIA_SPROMCTL_WRITEEN 4
+#define SSB_PCMCIA_SPROMCTL_WRITEDIS 7
+#define SSB_PCMCIA_SPROMCTL_DONE 8
+#define SSB_PCMCIA_SPROM_DATALO 0x38
+#define SSB_PCMCIA_SPROM_DATAHI 0x3A
+#define SSB_PCMCIA_SPROM_ADDRLO 0x3C
+#define SSB_PCMCIA_SPROM_ADDRHI 0x3E
+
+/* Hardware invariants CIS tuples */
+#define SSB_PCMCIA_CIS 0x80
+#define SSB_PCMCIA_CIS_ID 0x01
+#define SSB_PCMCIA_CIS_BOARDREV 0x02
+#define SSB_PCMCIA_CIS_PA 0x03
+#define SSB_PCMCIA_CIS_PA_PA0B0_LO 0
+#define SSB_PCMCIA_CIS_PA_PA0B0_HI 1
+#define SSB_PCMCIA_CIS_PA_PA0B1_LO 2
+#define SSB_PCMCIA_CIS_PA_PA0B1_HI 3
+#define SSB_PCMCIA_CIS_PA_PA0B2_LO 4
+#define SSB_PCMCIA_CIS_PA_PA0B2_HI 5
+#define SSB_PCMCIA_CIS_PA_ITSSI 6
+#define SSB_PCMCIA_CIS_PA_MAXPOW 7
+#define SSB_PCMCIA_CIS_OEMNAME 0x04
+#define SSB_PCMCIA_CIS_CCODE 0x05
+#define SSB_PCMCIA_CIS_ANTENNA 0x06
+#define SSB_PCMCIA_CIS_ANTGAIN 0x07
+#define SSB_PCMCIA_CIS_BFLAGS 0x08
+#define SSB_PCMCIA_CIS_LEDS 0x09
+
+/* PCMCIA SPROM size. */
+#define SSB_PCMCIA_SPROM_SIZE 256
+#define SSB_PCMCIA_SPROM_SIZE_BYTES (SSB_PCMCIA_SPROM_SIZE * sizeof(u16))
+
+
+/* Write to a PCMCIA configuration register. */
+static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value)
+{
+ conf_reg_t reg;
+ int res;
+
+ memset(&reg, 0, sizeof(reg));
+ reg.Offset = offset;
+ reg.Action = CS_WRITE;
+ reg.Value = value;
+ res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
+ if (unlikely(res != CS_SUCCESS))
+ return -EBUSY;
+
+ return 0;
+}
+
+/* Read from a PCMCIA configuration register. */
+static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value)
+{
+ conf_reg_t reg;
+ int res;
+
+ memset(&reg, 0, sizeof(reg));
+ reg.Offset = offset;
+ reg.Action = CS_READ;
+ res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
+ if (unlikely(res != CS_SUCCESS))
+ return -EBUSY;
+ *value = reg.Value;
+
+ return 0;
+}
+
int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
u8 coreidx)
{
- struct pcmcia_device *pdev = bus->host_pcmcia;
int err;
int attempts = 0;
u32 cur_core;
- conf_reg_t reg;
u32 addr;
u32 read_addr;
+ u8 val;
addr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
while (1) {
- reg.Action = CS_WRITE;
- reg.Offset = 0x2E;
- reg.Value = (addr & 0x0000F000) >> 12;
- err = pcmcia_access_configuration_register(pdev, &reg);
- if (err != CS_SUCCESS)
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS0,
+ (addr & 0x0000F000) >> 12);
+ if (err)
goto error;
- reg.Offset = 0x30;
- reg.Value = (addr & 0x00FF0000) >> 16;
- err = pcmcia_access_configuration_register(pdev, &reg);
- if (err != CS_SUCCESS)
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS1,
+ (addr & 0x00FF0000) >> 16);
+ if (err)
goto error;
- reg.Offset = 0x32;
- reg.Value = (addr & 0xFF000000) >> 24;
- err = pcmcia_access_configuration_register(pdev, &reg);
- if (err != CS_SUCCESS)
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_ADDRESS2,
+ (addr & 0xFF000000) >> 24);
+ if (err)
goto error;
read_addr = 0;
- reg.Action = CS_READ;
- reg.Offset = 0x2E;
- err = pcmcia_access_configuration_register(pdev, &reg);
- if (err != CS_SUCCESS)
+ err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS0, &val);
+ if (err)
goto error;
- read_addr |= ((u32)(reg.Value & 0x0F)) << 12;
- reg.Offset = 0x30;
- err = pcmcia_access_configuration_register(pdev, &reg);
- if (err != CS_SUCCESS)
+ read_addr |= ((u32)(val & 0x0F)) << 12;
+ err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS1, &val);
+ if (err)
goto error;
- read_addr |= ((u32)reg.Value) << 16;
- reg.Offset = 0x32;
- err = pcmcia_access_configuration_register(pdev, &reg);
- if (err != CS_SUCCESS)
+ read_addr |= ((u32)val) << 16;
+ err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_ADDRESS2, &val);
+ if (err)
goto error;
- read_addr |= ((u32)reg.Value) << 24;
+ read_addr |= ((u32)val) << 24;
cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE;
if (cur_core == coreidx)
break;
+ err = -ETIMEDOUT;
if (attempts++ > SSB_BAR0_MAX_RETRIES)
goto error;
udelay(10);
@@ -87,7 +161,7 @@ int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
return 0;
error:
ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
- return -ENODEV;
+ return err;
}
int ssb_pcmcia_switch_core(struct ssb_bus *bus,
@@ -112,27 +186,21 @@ int ssb_pcmcia_switch_core(struct ssb_bus *bus,
int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
{
int attempts = 0;
- conf_reg_t reg;
- int res;
+ int err;
+ u8 val;
SSB_WARN_ON((seg != 0) && (seg != 1));
- reg.Offset = 0x34;
- reg.Function = 0;
while (1) {
- reg.Action = CS_WRITE;
- reg.Value = seg;
- res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
- if (unlikely(res != CS_SUCCESS))
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_MEMSEG, seg);
+ if (err)
goto error;
- reg.Value = 0xFF;
- reg.Action = CS_READ;
- res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
- if (unlikely(res != CS_SUCCESS))
+ err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_MEMSEG, &val);
+ if (err)
goto error;
-
- if (reg.Value == seg)
+ if (val == seg)
break;
+ err = -ETIMEDOUT;
if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
goto error;
udelay(10);
@@ -142,7 +210,7 @@ int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
return 0;
error:
ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n");
- return -ENODEV;
+ return err;
}
static int select_core_and_segment(struct ssb_device *dev,
@@ -276,18 +344,344 @@ const struct ssb_bus_ops ssb_pcmcia_ops = {
.write32 = ssb_pcmcia_write32,
};
-#include <linux/etherdevice.h>
+static int ssb_pcmcia_sprom_command(struct ssb_bus *bus, u8 command)
+{
+ unsigned int i;
+ int err;
+ u8 value;
+
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROMCTL, command);
+ if (err)
+ return err;
+ for (i = 0; i < 1000; i++) {
+ err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROMCTL, &value);
+ if (err)
+ return err;
+ if (value & SSB_PCMCIA_SPROMCTL_DONE)
+ return 0;
+ udelay(10);
+ }
+
+ return -ETIMEDOUT;
+}
+
+/* offset is the 16bit word offset */
+static int ssb_pcmcia_sprom_read(struct ssb_bus *bus, u16 offset, u16 *value)
+{
+ int err;
+ u8 lo, hi;
+
+ offset *= 2; /* Make byte offset */
+
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
+ (offset & 0x00FF));
+ if (err)
+ return err;
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
+ (offset & 0xFF00) >> 8);
+ if (err)
+ return err;
+ err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_READ);
+ if (err)
+ return err;
+ err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATALO, &lo);
+ if (err)
+ return err;
+ err = ssb_pcmcia_cfg_read(bus, SSB_PCMCIA_SPROM_DATAHI, &hi);
+ if (err)
+ return err;
+ *value = (lo | (((u16)hi) << 8));
+
+ return 0;
+}
+
+/* offset is the 16bit word offset */
+static int ssb_pcmcia_sprom_write(struct ssb_bus *bus, u16 offset, u16 value)
+{
+ int err;
+
+ offset *= 2; /* Make byte offset */
+
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRLO,
+ (offset & 0x00FF));
+ if (err)
+ return err;
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_ADDRHI,
+ (offset & 0xFF00) >> 8);
+ if (err)
+ return err;
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATALO,
+ (value & 0x00FF));
+ if (err)
+ return err;
+ err = ssb_pcmcia_cfg_write(bus, SSB_PCMCIA_SPROM_DATAHI,
+ (value & 0xFF00) >> 8);
+ if (err)
+ return err;
+ err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITE);
+ if (err)
+ return err;
+ msleep(20);
+
+ return 0;
+}
+
+/* Read the SPROM image. bufsize is in 16bit words. */
+static int ssb_pcmcia_sprom_read_all(struct ssb_bus *bus, u16 *sprom)
+{
+ int err, i;
+
+ for (i = 0; i < SSB_PCMCIA_SPROM_SIZE; i++) {
+ err = ssb_pcmcia_sprom_read(bus, i, &sprom[i]);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+/* Write the SPROM image. size is in 16bit words. */
+static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom)
+{
+ int i, err;
+ bool failed = 0;
+ size_t size = SSB_PCMCIA_SPROM_SIZE;
+
+ ssb_printk(KERN_NOTICE PFX
+ "Writing SPROM. Do NOT turn off the power! "
+ "Please stand by...\n");
+ err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN);
+ if (err) {
+ ssb_printk(KERN_NOTICE PFX
+ "Could not enable SPROM write access.\n");
+ return -EBUSY;
+ }
+ ssb_printk(KERN_NOTICE PFX "[ 0%%");
+ msleep(500);
+ for (i = 0; i < size; i++) {
+ if (i == size / 4)
+ ssb_printk("25%%");
+ else if (i == size / 2)
+ ssb_printk("50%%");
+ else if (i == (size * 3) / 4)
+ ssb_printk("75%%");
+ else if (i % 2)
+ ssb_printk(".");
+ err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
+ if (err) {
+ ssb_printk("\n" KERN_NOTICE PFX
+ "Failed to write to SPROM.\n");
+ failed = 1;
+ break;
+ }
+ }
+ err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
+ if (err) {
+ ssb_printk("\n" KERN_NOTICE PFX
+ "Could not disable SPROM write access.\n");
+ failed = 1;
+ }
+ msleep(500);
+ if (!failed) {
+ ssb_printk("100%% ]\n");
+ ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
+ }
+
+ return failed ? -EBUSY : 0;
+}
+
+static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
+{
+ //TODO
+ return 0;
+}
+
+#define GOTO_ERROR_ON(condition, description) do { \
+ if (unlikely(condition)) { \
+ error_description = description; \
+ goto error; \
+ } \
+ } while (0)
+
int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
struct ssb_init_invariants *iv)
{
- //TODO
- random_ether_addr(iv->sprom.il0mac);
+ tuple_t tuple;
+ int res;
+ unsigned char buf[32];
+ struct ssb_sprom *sprom = &iv->sprom;
+ struct ssb_boardinfo *bi = &iv->boardinfo;
+ const char *error_description;
+
+ memset(sprom, 0xFF, sizeof(*sprom));
+ sprom->revision = 1;
+ sprom->boardflags_lo = 0;
+ sprom->boardflags_hi = 0;
+
+ /* First fetch the MAC address. */
+ memset(&tuple, 0, sizeof(tuple));
+ tuple.DesiredTuple = CISTPL_FUNCE;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
+ GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl");
+ res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
+ GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl data");
+ while (1) {
+ GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
+ if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
+ break;
+ res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
+ GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl");
+ res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
+ GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl data");
+ }
+ GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
+ memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
+
+ /* Fetch the vendor specific tuples. */
+ memset(&tuple, 0, sizeof(tuple));
+ tuple.DesiredTuple = SSB_PCMCIA_CIS;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
+ GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl");
+ res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
+ GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl data");
+ while (1) {
+ GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
+ switch (tuple.TupleData[0]) {
+ case SSB_PCMCIA_CIS_ID:
+ GOTO_ERROR_ON((tuple.TupleDataLen != 5) &&
+ (tuple.TupleDataLen != 7),
+ "id tpl size");
+ bi->vendor = tuple.TupleData[1] |
+ ((u16)tuple.TupleData[2] << 8);
+ break;
+ case SSB_PCMCIA_CIS_BOARDREV:
+ GOTO_ERROR_ON(tuple.TupleDataLen != 2,
+ "boardrev tpl size");
+ sprom->board_rev = tuple.TupleData[1];
+ break;
+ case SSB_PCMCIA_CIS_PA:
+ GOTO_ERROR_ON(tuple.TupleDataLen != 9,
+ "pa tpl size");
+ sprom->pa0b0 = tuple.TupleData[1] |
+ ((u16)tuple.TupleData[2] << 8);
+ sprom->pa0b1 = tuple.TupleData[3] |
+ ((u16)tuple.TupleData[4] << 8);
+ sprom->pa0b2 = tuple.TupleData[5] |
+ ((u16)tuple.TupleData[6] << 8);
+ sprom->itssi_a = tuple.TupleData[7];
+ sprom->itssi_bg = tuple.TupleData[7];
+ sprom->maxpwr_a = tuple.TupleData[8];
+ sprom->maxpwr_bg = tuple.TupleData[8];
+ break;
+ case SSB_PCMCIA_CIS_OEMNAME:
+ /* We ignore this. */
+ break;
+ case SSB_PCMCIA_CIS_CCODE:
+ GOTO_ERROR_ON(tuple.TupleDataLen != 2,
+ "ccode tpl size");
+ sprom->country_code = tuple.TupleData[1];
+ break;
+ case SSB_PCMCIA_CIS_ANTENNA:
+ GOTO_ERROR_ON(tuple.TupleDataLen != 2,
+ "ant tpl size");
+ sprom->ant_available_a = tuple.TupleData[1];
+ sprom->ant_available_bg = tuple.TupleData[1];
+ break;
+ case SSB_PCMCIA_CIS_ANTGAIN:
+ GOTO_ERROR_ON(tuple.TupleDataLen != 2,
+ "antg tpl size");
+ sprom->antenna_gain.ghz24.a0 = tuple.TupleData[1];
+ sprom->antenna_gain.ghz24.a1 = tuple.TupleData[1];
+ sprom->antenna_gain.ghz24.a2 = tuple.TupleData[1];
+ sprom->antenna_gain.ghz24.a3 = tuple.TupleData[1];
+ sprom->antenna_gain.ghz5.a0 = tuple.TupleData[1];
+ sprom->antenna_gain.ghz5.a1 = tuple.TupleData[1];
+ sprom->antenna_gain.ghz5.a2 = tuple.TupleData[1];
+ sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1];
+ break;
+ case SSB_PCMCIA_CIS_BFLAGS:
+ GOTO_ERROR_ON(tuple.TupleDataLen != 3,
+ "bfl tpl size");
+ sprom->boardflags_lo = tuple.TupleData[1] |
+ ((u16)tuple.TupleData[2] << 8);
+ break;
+ case SSB_PCMCIA_CIS_LEDS:
+ GOTO_ERROR_ON(tuple.TupleDataLen != 5,
+ "leds tpl size");
+ sprom->gpio0 = tuple.TupleData[1];
+ sprom->gpio1 = tuple.TupleData[2];
+ sprom->gpio2 = tuple.TupleData[3];
+ sprom->gpio3 = tuple.TupleData[4];
+ break;
+ }
+ res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
+ if (res == CS_NO_MORE_ITEMS)
+ break;
+ GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl");
+ res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
+ GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl data");
+ }
+
return 0;
+error:
+ ssb_printk(KERN_ERR PFX
+ "PCMCIA: Failed to fetch device invariants: %s\n",
+ error_description);
+ return -ENODEV;
+}
+
+static ssize_t ssb_pcmcia_attr_sprom_show(struct device *pcmciadev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct pcmcia_device *pdev =
+ container_of(pcmciadev, struct pcmcia_device, dev);
+ struct ssb_bus *bus;
+
+ bus = ssb_pcmcia_dev_to_bus(pdev);
+ if (!bus)
+ return -ENODEV;
+
+ return ssb_attr_sprom_show(bus, buf,
+ ssb_pcmcia_sprom_read_all);
+}
+
+static ssize_t ssb_pcmcia_attr_sprom_store(struct device *pcmciadev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct pcmcia_device *pdev =
+ container_of(pcmciadev, struct pcmcia_device, dev);
+ struct ssb_bus *bus;
+
+ bus = ssb_pcmcia_dev_to_bus(pdev);
+ if (!bus)
+ return -ENODEV;
+
+ return ssb_attr_sprom_store(bus, buf, count,
+ ssb_pcmcia_sprom_check_crc,
+ ssb_pcmcia_sprom_write_all);
+}
+
+static DEVICE_ATTR(ssb_sprom, 0600,
+ ssb_pcmcia_attr_sprom_show,
+ ssb_pcmcia_attr_sprom_store);
+
+void ssb_pcmcia_exit(struct ssb_bus *bus)
+{
+ if (bus->bustype != SSB_BUSTYPE_PCMCIA)
+ return;
+
+ device_remove_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
}
int ssb_pcmcia_init(struct ssb_bus *bus)
{
- conf_reg_t reg;
+ u8 val, offset;
int err;
if (bus->bustype != SSB_BUSTYPE_PCMCIA)
@@ -298,22 +692,26 @@ int ssb_pcmcia_init(struct ssb_bus *bus)
ssb_pcmcia_switch_segment(bus, 0);
/* Init IRQ routing */
- reg.Action = CS_READ;
- reg.Function = 0;
if (bus->chip_id == 0x4306)
- reg.Offset = 0x00;
+ offset = SSB_PCMCIA_CORECTL;
else
- reg.Offset = 0x80;
- err = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
- if (err != CS_SUCCESS)
+ offset = SSB_PCMCIA_CORECTL2;
+ err = ssb_pcmcia_cfg_read(bus, offset, &val);
+ if (err)
goto error;
- reg.Action = CS_WRITE;
- reg.Value |= 0x04 | 0x01;
- err = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
- if (err != CS_SUCCESS)
+ val |= SSB_PCMCIA_CORECTL_IRQEN | SSB_PCMCIA_CORECTL_FUNCEN;
+ err = ssb_pcmcia_cfg_write(bus, offset, val);
+ if (err)
+ goto error;
+
+ bus->sprom_size = SSB_PCMCIA_SPROM_SIZE;
+ mutex_init(&bus->sprom_mutex);
+ err = device_create_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
+ if (err)
goto error;
return 0;
error:
- return -ENODEV;
+ ssb_printk(KERN_ERR PFX "Failed to initialize PCMCIA host device\n");
+ return err;
}
diff --git a/drivers/ssb/sprom.c b/drivers/ssb/sprom.c
new file mode 100644
index 000000000000..3668edb39315
--- /dev/null
+++ b/drivers/ssb/sprom.c
@@ -0,0 +1,133 @@
+/*
+ * Sonics Silicon Backplane
+ * Common SPROM support routines
+ *
+ * Copyright (C) 2005-2008 Michael Buesch <mb@bu3sch.de>
+ * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
+ * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
+ * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
+ * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "ssb_private.h"
+
+
+static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
+ size_t sprom_size_words)
+{
+ int i, pos = 0;
+
+ for (i = 0; i < sprom_size_words; i++)
+ pos += snprintf(buf + pos, buf_len - pos - 1,
+ "%04X", swab16(sprom[i]) & 0xFFFF);
+ pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
+
+ return pos + 1;
+}
+
+static int hex2sprom(u16 *sprom, const char *dump, size_t len,
+ size_t sprom_size_words)
+{
+ char tmp[5] = { 0 };
+ int cnt = 0;
+ unsigned long parsed;
+
+ if (len < sprom_size_words * 2)
+ return -EINVAL;
+
+ while (cnt < sprom_size_words) {
+ memcpy(tmp, dump, 4);
+ dump += 4;
+ parsed = simple_strtoul(tmp, NULL, 16);
+ sprom[cnt++] = swab16((u16)parsed);
+ }
+
+ return 0;
+}
+
+/* Common sprom device-attribute show-handler */
+ssize_t ssb_attr_sprom_show(struct ssb_bus *bus, char *buf,
+ int (*sprom_read)(struct ssb_bus *bus, u16 *sprom))
+{
+ u16 *sprom;
+ int err = -ENOMEM;
+ ssize_t count = 0;
+ size_t sprom_size_words = bus->sprom_size;
+
+ sprom = kcalloc(sprom_size_words, sizeof(u16), GFP_KERNEL);
+ if (!sprom)
+ goto out;
+
+ /* Use interruptible locking, as the SPROM write might
+ * be holding the lock for several seconds. So allow userspace
+ * to cancel operation. */
+ err = -ERESTARTSYS;
+ if (mutex_lock_interruptible(&bus->sprom_mutex))
+ goto out_kfree;
+ err = sprom_read(bus, sprom);
+ mutex_unlock(&bus->sprom_mutex);
+
+ if (!err)
+ count = sprom2hex(sprom, buf, PAGE_SIZE, sprom_size_words);
+
+out_kfree:
+ kfree(sprom);
+out:
+ return err ? err : count;
+}
+
+/* Common sprom device-attribute store-handler */
+ssize_t ssb_attr_sprom_store(struct ssb_bus *bus,
+ const char *buf, size_t count,
+ int (*sprom_check_crc)(const u16 *sprom, size_t size),
+ int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom))
+{
+ u16 *sprom;
+ int res = 0, err = -ENOMEM;
+ size_t sprom_size_words = bus->sprom_size;
+
+ sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL);
+ if (!sprom)
+ goto out;
+ err = hex2sprom(sprom, buf, count, sprom_size_words);
+ if (err) {
+ err = -EINVAL;
+ goto out_kfree;
+ }
+ err = sprom_check_crc(sprom, sprom_size_words);
+ if (err) {
+ err = -EINVAL;
+ goto out_kfree;
+ }
+
+ /* Use interruptible locking, as the SPROM write might
+ * be holding the lock for several seconds. So allow userspace
+ * to cancel operation. */
+ err = -ERESTARTSYS;
+ if (mutex_lock_interruptible(&bus->sprom_mutex))
+ goto out_kfree;
+ err = ssb_devices_freeze(bus);
+ if (err == -EOPNOTSUPP) {
+ ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze devices. "
+ "No suspend support. Is CONFIG_PM enabled?\n");
+ goto out_unlock;
+ }
+ if (err) {
+ ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n");
+ goto out_unlock;
+ }
+ res = sprom_write(bus, sprom);
+ err = ssb_devices_thaw(bus);
+ if (err)
+ ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n");
+out_unlock:
+ mutex_unlock(&bus->sprom_mutex);
+out_kfree:
+ kfree(sprom);
+out:
+ if (res)
+ return res;
+ return err ? err : count;
+}
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index d03b20983b1e..a83bf7a4d80b 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -81,6 +81,7 @@ extern int ssb_pcmcia_switch_segment(struct ssb_bus *bus,
u8 seg);
extern int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
struct ssb_init_invariants *iv);
+extern void ssb_pcmcia_exit(struct ssb_bus *bus);
extern int ssb_pcmcia_init(struct ssb_bus *bus);
extern const struct ssb_bus_ops ssb_pcmcia_ops;
#else /* CONFIG_SSB_PCMCIAHOST */
@@ -99,6 +100,9 @@ static inline int ssb_pcmcia_switch_segment(struct ssb_bus *bus,
{
return 0;
}
+static inline void ssb_pcmcia_exit(struct ssb_bus *bus)
+{
+}
static inline int ssb_pcmcia_init(struct ssb_bus *bus)
{
return 0;
@@ -113,6 +117,17 @@ extern int ssb_bus_scan(struct ssb_bus *bus,
extern void ssb_iounmap(struct ssb_bus *ssb);
+/* sprom.c */
+extern
+ssize_t ssb_attr_sprom_show(struct ssb_bus *bus, char *buf,
+ int (*sprom_read)(struct ssb_bus *bus, u16 *sprom));
+extern
+ssize_t ssb_attr_sprom_store(struct ssb_bus *bus,
+ const char *buf, size_t count,
+ int (*sprom_check_crc)(const u16 *sprom, size_t size),
+ int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom));
+
+
/* core.c */
extern u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m);
extern int ssb_devices_freeze(struct ssb_bus *bus);
@@ -120,6 +135,8 @@ extern int ssb_devices_thaw(struct ssb_bus *bus);
extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev);
int ssb_for_each_bus_call(unsigned long data,
int (*func)(struct ssb_bus *bus, unsigned long data));
+extern struct ssb_bus *ssb_pcmcia_dev_to_bus(struct pcmcia_device *pdev);
+
/* b43_pci_bridge.c */
#ifdef CONFIG_SSB_B43_PCI_BRIDGE
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index b7c388972fcf..8644e03cf588 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -245,9 +245,9 @@ struct ssb_bus {
/* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
struct pcmcia_device *host_pcmcia;
-#ifdef CONFIG_SSB_PCIHOST
+#ifdef CONFIG_SSB_SPROM
/* Mutex to protect the SPROM writing. */
- struct mutex pci_sprom_mutex;
+ struct mutex sprom_mutex;
#endif
/* ID information about the Chip. */
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index 285b2adfa648..529816bfbc52 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -183,7 +183,6 @@ const char *escape_essid(const char *essid, u8 essid_len);
#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
#define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
#include <linux/netdevice.h>
-#include <linux/wireless.h>
#include <linux/if_arp.h> /* ARPHRD_ETHER */
#ifndef WIRELESS_SPY
diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h
deleted file mode 100644
index 1ef6282fdded..000000000000
--- a/include/net/ieee80211softmac.h
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * ieee80211softmac.h - public interface to the softmac
- *
- * Copyright (c) 2005 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#ifndef IEEE80211SOFTMAC_H_
-#define IEEE80211SOFTMAC_H_
-
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/list.h>
-#include <net/ieee80211.h>
-
-/* Once the API is considered more or less stable,
- * this should be incremented on API incompatible changes.
- */
-#define IEEE80211SOFTMAC_API 0
-
-#define IEEE80211SOFTMAC_MAX_RATES_LEN 8
-#define IEEE80211SOFTMAC_MAX_EX_RATES_LEN 255
-
-struct ieee80211softmac_ratesinfo {
- u8 count;
- u8 rates[IEEE80211SOFTMAC_MAX_RATES_LEN + IEEE80211SOFTMAC_MAX_EX_RATES_LEN];
-};
-
-/* internal structures */
-struct ieee80211softmac_network;
-struct ieee80211softmac_scaninfo;
-
-struct ieee80211softmac_essid {
- u8 len;
- char data[IW_ESSID_MAX_SIZE+1];
-};
-
-struct ieee80211softmac_wpa {
- char *IE;
- int IElen;
- int IEbuflen;
-};
-
-/*
- * Information about association
- */
-struct ieee80211softmac_assoc_info {
-
- struct mutex mutex;
-
- /*
- * This is the requested ESSID. It is written
- * only by the WX handlers.
- *
- */
- struct ieee80211softmac_essid req_essid;
- /*
- * the ESSID of the network we're currently
- * associated (or trying) to. This is
- * updated to the network's actual ESSID
- * even if the requested ESSID was 'ANY'
- */
- struct ieee80211softmac_essid associate_essid;
-
- /* BSSID we're trying to associate to */
- char bssid[ETH_ALEN];
-
- /* some flags.
- * static_essid is valid if the essid is constant,
- * this is for use by the wx handlers only.
- *
- * associating is true, if the network has been
- * auth'ed on and we are in the process of associating.
- *
- * bssvalid is true if we found a matching network
- * and saved it's BSSID into the bssid above.
- *
- * bssfixed is used for SIOCSIWAP.
- */
- u8 static_essid;
- u8 short_preamble_available;
- u8 associating;
- u8 associated;
- u8 assoc_wait;
- u8 bssvalid;
- u8 bssfixed;
-
- /* Scan retries remaining */
- int scan_retry;
-
- struct delayed_work work;
- struct delayed_work timeout;
-};
-
-struct ieee80211softmac_bss_info {
- /* Rates supported by the network */
- struct ieee80211softmac_ratesinfo supported_rates;
-
- /* This indicates whether frames can currently be transmitted with
- * short preamble (only use this variable during TX at CCK rates) */
- u8 short_preamble:1;
-
- /* This indicates whether protection (e.g. self-CTS) should be used
- * when transmitting with OFDM modulation */
- u8 use_protection:1;
-};
-
-enum {
- IEEE80211SOFTMAC_AUTH_OPEN_REQUEST = 1,
- IEEE80211SOFTMAC_AUTH_OPEN_RESPONSE = 2,
-};
-
-enum {
- IEEE80211SOFTMAC_AUTH_SHARED_REQUEST = 1,
- IEEE80211SOFTMAC_AUTH_SHARED_CHALLENGE = 2,
- IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE = 3,
- IEEE80211SOFTMAC_AUTH_SHARED_PASS = 4,
-};
-
-/* We should make these tunable
- * AUTH_TIMEOUT seems really long, but that's what it is in BSD */
-#define IEEE80211SOFTMAC_AUTH_TIMEOUT (12 * HZ)
-#define IEEE80211SOFTMAC_AUTH_RETRY_LIMIT 5
-#define IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT 3
-
-struct ieee80211softmac_txrates {
- /* The Bit-Rate to be used for multicast frames. */
- u8 mcast_rate;
-
- /* The Bit-Rate to be used for multicast management frames. */
- u8 mgt_mcast_rate;
-
- /* The Bit-Rate to be used for any other (normal) data packet. */
- u8 default_rate;
- /* The Bit-Rate to be used for default fallback
- * (If the device supports fallback and hardware-retry)
- */
- u8 default_fallback;
-
- /* This is the rate that the user asked for */
- u8 user_rate;
-};
-
-/* Bits for txrates_change callback. */
-#define IEEE80211SOFTMAC_TXRATECHG_DEFAULT (1 << 0) /* default_rate */
-#define IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK (1 << 1) /* default_fallback */
-#define IEEE80211SOFTMAC_TXRATECHG_MCAST (1 << 2) /* mcast_rate */
-#define IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST (1 << 3) /* mgt_mcast_rate */
-
-#define IEEE80211SOFTMAC_BSSINFOCHG_RATES (1 << 0) /* supported_rates */
-#define IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE (1 << 1) /* short_preamble */
-#define IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION (1 << 2) /* use_protection */
-
-struct ieee80211softmac_device {
- /* 802.11 structure for data stuff */
- struct ieee80211_device *ieee;
- struct net_device *dev;
-
- /* only valid if associated, then holds the Association ID */
- u16 association_id;
-
- /* the following methods are callbacks that the driver
- * using this framework has to assign
- */
-
- /* always assign these */
- void (*set_bssid_filter)(struct net_device *dev, const u8 *bssid);
- void (*set_channel)(struct net_device *dev, u8 channel);
-
- /* assign if you need it, informational only */
- void (*link_change)(struct net_device *dev);
-
- /* If the hardware can do scanning, assign _all_ three of these callbacks.
- * When the scan finishes, call ieee80211softmac_scan_finished().
- */
-
- /* when called, start_scan is guaranteed to not be called again
- * until you call ieee80211softmac_scan_finished.
- * Return 0 if scanning could start, error otherwise.
- * SOFTMAC AUTHORS: don't call this, use ieee80211softmac_start_scan */
- int (*start_scan)(struct net_device *dev);
- /* this should block until after ieee80211softmac_scan_finished was called
- * SOFTMAC AUTHORS: don't call this, use ieee80211softmac_wait_for_scan */
- void (*wait_for_scan)(struct net_device *dev);
- /* stop_scan aborts a scan, but is asynchronous.
- * if you want to wait for it too, use wait_for_scan
- * SOFTMAC AUTHORS: don't call this, use ieee80211softmac_stop_scan */
- void (*stop_scan)(struct net_device *dev);
-
- /* we'll need something about beacons here too, for AP or ad-hoc modes */
-
- /* Transmission rates to be used by the driver.
- * The SoftMAC figures out the best possible rates.
- * The driver just needs to read them.
- */
- struct ieee80211softmac_txrates txrates;
-
- /* If the driver needs to do stuff on TX rate changes, assign this
- * callback. See IEEE80211SOFTMAC_TXRATECHG for change flags. */
- void (*txrates_change)(struct net_device *dev,
- u32 changes);
-
- /* If the driver needs to do stuff when BSS properties change, assign
- * this callback. see IEEE80211SOFTMAC_BSSINFOCHG for change flags. */
- void (*bssinfo_change)(struct net_device *dev,
- u32 changes);
-
- /* private stuff follows */
- /* this lock protects this structure */
- spinlock_t lock;
-
- struct workqueue_struct *wq;
-
- u8 running; /* SoftMAC started? */
- u8 scanning;
-
- struct ieee80211softmac_scaninfo *scaninfo;
- struct ieee80211softmac_assoc_info associnfo;
- struct ieee80211softmac_bss_info bssinfo;
-
- struct list_head auth_queue;
- struct list_head events;
-
- struct ieee80211softmac_ratesinfo ratesinfo;
- int txrate_badness;
-
- /* WPA stuff */
- struct ieee80211softmac_wpa wpa;
-
- /* we need to keep a list of network structs we copied */
- struct list_head network_list;
-
- /* This must be the last item so that it points to the data
- * allocated beyond this structure by alloc_ieee80211 */
- u8 priv[0];
-};
-
-extern void ieee80211softmac_scan_finished(struct ieee80211softmac_device *sm);
-
-static inline void * ieee80211softmac_priv(struct net_device *dev)
-{
- return ((struct ieee80211softmac_device *)ieee80211_priv(dev))->priv;
-}
-
-extern struct net_device * alloc_ieee80211softmac(int sizeof_priv);
-extern void free_ieee80211softmac(struct net_device *dev);
-
-/* Call this function if you detect a lost TX fragment.
- * (If the device indicates failure of ACK RX, for example.)
- * It is wise to call this function if you are able to detect lost packets,
- * because it contributes to the TX Rates auto adjustment.
- */
-extern void ieee80211softmac_fragment_lost(struct net_device *dev,
- u16 wireless_sequence_number);
-/* Call this function before _start to tell the softmac what rates
- * the hw supports. The rates parameter is copied, so you can
- * free it right after calling this function.
- * Note that the rates need to be sorted. */
-extern void ieee80211softmac_set_rates(struct net_device *dev, u8 count, u8 *rates);
-
-/* Finds the highest rate which is:
- * 1. Present in ri (optionally a basic rate)
- * 2. Supported by the device
- * 3. Less than or equal to the user-defined rate
- */
-extern u8 ieee80211softmac_highest_supported_rate(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_ratesinfo *ri, int basic_only);
-
-/* Helper function which advises you the rate at which a frame should be
- * transmitted at. */
-static inline u8 ieee80211softmac_suggest_txrate(struct ieee80211softmac_device *mac,
- int is_multicast,
- int is_mgt)
-{
- struct ieee80211softmac_txrates *txrates = &mac->txrates;
-
- if (!mac->associnfo.associated)
- return txrates->mgt_mcast_rate;
-
- /* We are associated, sending unicast frame */
- if (!is_multicast)
- return txrates->default_rate;
-
- /* We are associated, sending multicast frame */
- if (is_mgt)
- return txrates->mgt_mcast_rate;
- else
- return txrates->mcast_rate;
-}
-
-/* Helper function which advises you when it is safe to transmit with short
- * preamble.
- * You should only call this function when transmitting at CCK rates. */
-static inline int ieee80211softmac_short_preamble_ok(struct ieee80211softmac_device *mac,
- int is_multicast,
- int is_mgt)
-{
- return (is_multicast && is_mgt) ? 0 : mac->bssinfo.short_preamble;
-}
-
-/* Helper function which advises you whether protection (e.g. self-CTS) is
- * needed. 1 = protection needed, 0 = no protection needed
- * Only use this function when transmitting with OFDM modulation. */
-static inline int ieee80211softmac_protection_needed(struct ieee80211softmac_device *mac)
-{
- return mac->bssinfo.use_protection;
-}
-
-/* Start the SoftMAC. Call this after you initialized the device
- * and it is ready to run.
- */
-extern void ieee80211softmac_start(struct net_device *dev);
-/* Stop the SoftMAC. Call this before you shutdown the device. */
-extern void ieee80211softmac_stop(struct net_device *dev);
-
-/*
- * Event system
- */
-
-/* valid event types */
-#define IEEE80211SOFTMAC_EVENT_ANY -1 /*private use only*/
-#define IEEE80211SOFTMAC_EVENT_SCAN_FINISHED 0
-#define IEEE80211SOFTMAC_EVENT_ASSOCIATED 1
-#define IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED 2
-#define IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT 3
-#define IEEE80211SOFTMAC_EVENT_AUTHENTICATED 4
-#define IEEE80211SOFTMAC_EVENT_AUTH_FAILED 5
-#define IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT 6
-#define IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND 7
-#define IEEE80211SOFTMAC_EVENT_DISASSOCIATED 8
-/* keep this updated! */
-#define IEEE80211SOFTMAC_EVENT_LAST 8
-/*
- * If you want to be notified of certain events, you can call
- * ieee80211softmac_notify[_atomic] with
- * - event set to one of the constants below
- * - fun set to a function pointer of the appropriate type
- * - context set to the context data you want passed
- * The return value is 0, or an error.
- */
-typedef void (*notify_function_ptr)(struct net_device *dev, int event_type, void *context);
-
-#define ieee80211softmac_notify(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_KERNEL);
-#define ieee80211softmac_notify_atomic(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_ATOMIC);
-
-extern int ieee80211softmac_notify_gfp(struct net_device *dev,
- int event, notify_function_ptr fun, void *context, gfp_t gfp_mask);
-
-/* To clear pending work (for ifconfig down, etc.) */
-extern void
-ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm);
-
-#endif /* IEEE80211SOFTMAC_H_ */
diff --git a/include/net/ieee80211softmac_wx.h b/include/net/ieee80211softmac_wx.h
deleted file mode 100644
index 4ee3ad57283f..000000000000
--- a/include/net/ieee80211softmac_wx.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * This file contains the prototypes for the wireless extension
- * handlers that the softmac API provides. Include this file to
- * use the wx handlers, you can assign these directly.
- *
- * Copyright (c) 2005 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#ifndef _IEEE80211SOFTMAC_WX_H
-#define _IEEE80211SOFTMAC_WX_H
-
-#include <net/ieee80211softmac.h>
-#include <net/iw_handler.h>
-
-extern int
-ieee80211softmac_wx_trigger_scan(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra);
-
-extern int
-ieee80211softmac_wx_get_scan_results(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra);
-
-extern int
-ieee80211softmac_wx_set_essid(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra);
-
-extern int
-ieee80211softmac_wx_get_essid(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra);
-
-extern int
-ieee80211softmac_wx_set_rate(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra);
-
-extern int
-ieee80211softmac_wx_get_rate(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra);
-
-extern int
-ieee80211softmac_wx_get_wap(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra);
-
-extern int
-ieee80211softmac_wx_set_wap(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra);
-
-extern int
-ieee80211softmac_wx_set_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra);
-
-extern int
-ieee80211softmac_wx_get_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra);
-extern int
-ieee80211softmac_wx_set_mlme(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra);
-#endif /* _IEEE80211SOFTMAC_WX */
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
index bd501046c9c0..94ed7d3cd9da 100644
--- a/net/ieee80211/Kconfig
+++ b/net/ieee80211/Kconfig
@@ -71,4 +71,3 @@ config IEEE80211_CRYPT_TKIP
This can be compiled as a module and it will be called
"ieee80211_crypt_tkip".
-source "net/ieee80211/softmac/Kconfig"
diff --git a/net/ieee80211/Makefile b/net/ieee80211/Makefile
index 796a7c76ee48..f988417121da 100644
--- a/net/ieee80211/Makefile
+++ b/net/ieee80211/Makefile
@@ -10,4 +10,3 @@ ieee80211-objs := \
ieee80211_wx.o \
ieee80211_geo.o
-obj-$(CONFIG_IEEE80211_SOFTMAC) += softmac/
diff --git a/net/ieee80211/softmac/Kconfig b/net/ieee80211/softmac/Kconfig
deleted file mode 100644
index 2811651cb134..000000000000
--- a/net/ieee80211/softmac/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-config IEEE80211_SOFTMAC
- tristate "Software MAC add-on to the IEEE 802.11 networking stack"
- depends on IEEE80211 && EXPERIMENTAL
- select WIRELESS_EXT
- select IEEE80211_CRYPT_WEP
- ---help---
- This option enables the hardware independent software MAC addon
- for the IEEE 802.11 networking stack.
-
-config IEEE80211_SOFTMAC_DEBUG
- bool "Enable full debugging output"
- depends on IEEE80211_SOFTMAC
diff --git a/net/ieee80211/softmac/Makefile b/net/ieee80211/softmac/Makefile
deleted file mode 100644
index bfcb391bb2c7..000000000000
--- a/net/ieee80211/softmac/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-obj-$(CONFIG_IEEE80211_SOFTMAC) += ieee80211softmac.o
-ieee80211softmac-objs := \
- ieee80211softmac_io.o \
- ieee80211softmac_auth.o \
- ieee80211softmac_module.o \
- ieee80211softmac_scan.o \
- ieee80211softmac_wx.o \
- ieee80211softmac_assoc.o \
- ieee80211softmac_event.o
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
deleted file mode 100644
index c4d122ddd72c..000000000000
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * This file contains the softmac's association logic.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include "ieee80211softmac_priv.h"
-
-/*
- * Overview
- *
- * Before you can associate, you have to authenticate.
- *
- */
-
-/* Sends out an association request to the desired AP */
-static void
-ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
-{
- unsigned long flags;
-
- /* Switch to correct channel for this network */
- mac->set_channel(mac->dev, net->channel);
-
- /* Send association request */
- ieee80211softmac_send_mgt_frame(mac, net, IEEE80211_STYPE_ASSOC_REQ, 0);
-
- dprintk(KERN_INFO PFX "sent association request!\n");
-
- spin_lock_irqsave(&mac->lock, flags);
- mac->associnfo.associated = 0; /* just to make sure */
-
- /* Set a timer for timeout */
- /* FIXME: make timeout configurable */
- if (likely(mac->running))
- queue_delayed_work(mac->wq, &mac->associnfo.timeout, 5 * HZ);
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-void
-ieee80211softmac_assoc_timeout(struct work_struct *work)
-{
- struct ieee80211softmac_device *mac =
- container_of(work, struct ieee80211softmac_device,
- associnfo.timeout.work);
- struct ieee80211softmac_network *n;
-
- mutex_lock(&mac->associnfo.mutex);
- /* we might race against ieee80211softmac_handle_assoc_response,
- * so make sure only one of us does something */
- if (!mac->associnfo.associating)
- goto out;
- mac->associnfo.associating = 0;
- mac->associnfo.bssvalid = 0;
- mac->associnfo.associated = 0;
-
- n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid);
-
- dprintk(KERN_INFO PFX "assoc request timed out!\n");
- ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n);
-out:
- mutex_unlock(&mac->associnfo.mutex);
-}
-
-void
-ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mac->lock, flags);
- if (mac->associnfo.associating)
- cancel_delayed_work(&mac->associnfo.timeout);
-
- netif_carrier_off(mac->dev);
-
- mac->associnfo.associated = 0;
- mac->associnfo.bssvalid = 0;
- mac->associnfo.associating = 0;
- ieee80211softmac_init_bss(mac);
- ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-/* Sends out a disassociation request to the desired AP */
-void
-ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason)
-{
- struct ieee80211softmac_network *found;
-
- if (mac->associnfo.bssvalid && mac->associnfo.associated) {
- found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
- if (found)
- ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason);
- }
-
- ieee80211softmac_disassoc(mac);
-}
-
-static inline int
-we_support_all_basic_rates(struct ieee80211softmac_device *mac, u8 *from, u8 from_len)
-{
- int idx;
- u8 rate;
-
- for (idx = 0; idx < (from_len); idx++) {
- rate = (from)[idx];
- if (!(rate & IEEE80211_BASIC_RATE_MASK))
- continue;
- rate &= ~IEEE80211_BASIC_RATE_MASK;
- if (!ieee80211softmac_ratesinfo_rate_supported(&mac->ratesinfo, rate))
- return 0;
- }
- return 1;
-}
-
-static int
-network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_network *net)
-{
- /* we cannot associate to networks whose name we don't know */
- if (ieee80211_is_empty_essid(net->ssid, net->ssid_len))
- return 0;
- /* do not associate to a network whose BSSBasicRateSet we cannot support */
- if (!we_support_all_basic_rates(mac, net->rates, net->rates_len))
- return 0;
- /* do we really need to check the ex rates? */
- if (!we_support_all_basic_rates(mac, net->rates_ex, net->rates_ex_len))
- return 0;
-
- /* assume that users know what they're doing ...
- * (note we don't let them select a net we're incompatible with) */
- if (mac->associnfo.bssfixed) {
- return !memcmp(mac->associnfo.bssid, net->bssid, ETH_ALEN);
- }
-
- /* if 'ANY' network requested, take any that doesn't have privacy enabled */
- if (mac->associnfo.req_essid.len == 0
- && !(net->capability & WLAN_CAPABILITY_PRIVACY))
- return 1;
- if (net->ssid_len != mac->associnfo.req_essid.len)
- return 0;
- if (!memcmp(net->ssid, mac->associnfo.req_essid.data, mac->associnfo.req_essid.len))
- return 1;
- return 0;
-}
-
-static void
-ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- ieee80211softmac_assoc_work(&mac->associnfo.work.work);
-}
-
-static void
-ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void *context)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- switch (event_type) {
- case IEEE80211SOFTMAC_EVENT_AUTHENTICATED:
- ieee80211softmac_assoc_work(&mac->associnfo.work.work);
- break;
- case IEEE80211SOFTMAC_EVENT_AUTH_FAILED:
- case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT:
- ieee80211softmac_disassoc(mac);
- break;
- }
-}
-
-/* This function is called to handle userspace requests (asynchronously) */
-void
-ieee80211softmac_assoc_work(struct work_struct *work)
-{
- struct ieee80211softmac_device *mac =
- container_of(work, struct ieee80211softmac_device,
- associnfo.work.work);
- struct ieee80211softmac_network *found = NULL;
- struct ieee80211_network *net = NULL, *best = NULL;
- int bssvalid;
- unsigned long flags;
-
- mutex_lock(&mac->associnfo.mutex);
-
- if (!mac->associnfo.associating)
- goto out;
-
- /* ieee80211_disassoc might clear this */
- bssvalid = mac->associnfo.bssvalid;
-
- /* meh */
- if (mac->associnfo.associated)
- ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
-
- /* try to find the requested network in our list, if we found one already */
- if (bssvalid || mac->associnfo.bssfixed)
- found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
-
- /* Search the ieee80211 networks for this network if we didn't find it by bssid,
- * but only if we've scanned at least once (to get a better list of networks to
- * select from). If we have not scanned before, the !found logic below will be
- * invoked and will scan. */
- if (!found && (mac->associnfo.scan_retry < IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT))
- {
- s8 rssi = -128; /* if I don't initialise, gcc emits an invalid warning
- because it cannot follow the best pointer logic. */
- spin_lock_irqsave(&mac->ieee->lock, flags);
- list_for_each_entry(net, &mac->ieee->network_list, list) {
- /* we're supposed to find the network with
- * the best signal here, as we're asked to join
- * any network with a specific ESSID, and many
- * different ones could have that.
- *
- * I'll for now just go with the reported rssi.
- *
- * We also should take into account the rateset
- * here to find the best BSSID to try.
- */
- if (network_matches_request(mac, net)) {
- if (!best) {
- best = net;
- rssi = best->stats.rssi;
- continue;
- }
- /* we already had a matching network, so
- * compare their properties to get the
- * better of the two ... (see above)
- */
- if (rssi < net->stats.rssi) {
- best = net;
- rssi = best->stats.rssi;
- }
- }
- }
- /* if we unlock here, we might get interrupted and the `best'
- * pointer could go stale */
- if (best) {
- found = ieee80211softmac_create_network(mac, best);
- /* if found is still NULL, then we got -ENOMEM somewhere */
- if (found)
- ieee80211softmac_add_network(mac, found);
- }
- spin_unlock_irqrestore(&mac->ieee->lock, flags);
- }
-
- if (!found) {
- if (mac->associnfo.scan_retry > 0) {
- mac->associnfo.scan_retry--;
-
- /* We know of no such network. Let's scan.
- * NB: this also happens if we had no memory to copy the network info...
- * Maybe we can hope to have more memory after scanning finishes ;)
- */
- dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n");
- ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
- if (ieee80211softmac_start_scan(mac)) {
- dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
- }
- goto out;
- } else {
- mac->associnfo.associating = 0;
- mac->associnfo.associated = 0;
-
- dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n");
- /* reset the retry counter for the next user request since we
- * break out and don't reschedule ourselves after this point. */
- mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
- ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL);
- goto out;
- }
- }
-
- /* reset the retry counter for the next user request since we
- * now found a net and will try to associate to it, but not
- * schedule this function again. */
- mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
- mac->associnfo.bssvalid = 1;
- memcpy(mac->associnfo.bssid, found->bssid, ETH_ALEN);
- /* copy the ESSID for displaying it */
- mac->associnfo.associate_essid.len = found->essid.len;
- memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1);
-
- /* we found a network! authenticate (if necessary) and associate to it. */
- if (found->authenticating) {
- dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n");
- if(!mac->associnfo.assoc_wait) {
- mac->associnfo.assoc_wait = 1;
- ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
- }
- goto out;
- }
- if (!found->authenticated && !found->authenticating) {
- /* This relies on the fact that _auth_req only queues the work,
- * otherwise adding the notification would be racy. */
- if (!ieee80211softmac_auth_req(mac, found)) {
- if(!mac->associnfo.assoc_wait) {
- dprintk(KERN_INFO PFX "Cannot associate without being authenticated, requested authentication\n");
- mac->associnfo.assoc_wait = 1;
- ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
- }
- } else {
- printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n");
- mac->associnfo.assoc_wait = 0;
- ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
- }
- goto out;
- }
- /* finally! now we can start associating */
- mac->associnfo.assoc_wait = 0;
- ieee80211softmac_assoc(mac, found);
-
-out:
- mutex_unlock(&mac->associnfo.mutex);
-}
-
-/* call this to do whatever is necessary when we're associated */
-static void
-ieee80211softmac_associated(struct ieee80211softmac_device *mac,
- struct ieee80211_assoc_response * resp,
- struct ieee80211softmac_network *net)
-{
- u16 cap = le16_to_cpu(resp->capability);
- u8 erp_value = net->erp_value;
-
- mac->associnfo.associating = 0;
- mac->bssinfo.supported_rates = net->supported_rates;
- ieee80211softmac_recalc_txrates(mac);
-
- mac->associnfo.associated = 1;
-
- mac->associnfo.short_preamble_available =
- (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0;
- ieee80211softmac_process_erp(mac, erp_value);
-
- if (mac->set_bssid_filter)
- mac->set_bssid_filter(mac->dev, net->bssid);
- memcpy(mac->ieee->bssid, net->bssid, ETH_ALEN);
- netif_carrier_on(mac->dev);
-
- mac->association_id = le16_to_cpup(&resp->aid);
-}
-
-/* received frame handling functions */
-int
-ieee80211softmac_handle_assoc_response(struct net_device * dev,
- struct ieee80211_assoc_response * resp,
- struct ieee80211_network * _ieee80211_network)
-{
- /* NOTE: the network parameter has to be mostly ignored by
- * this code because it is the ieee80211's pointer
- * to the struct, not ours (we made a copy)
- */
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- u16 status = le16_to_cpup(&resp->status);
- struct ieee80211softmac_network *network = NULL;
- unsigned long flags;
- DECLARE_MAC_BUF(mac2);
-
- if (unlikely(!mac->running))
- return -ENODEV;
-
- spin_lock_irqsave(&mac->lock, flags);
-
- if (!mac->associnfo.associating) {
- /* we race against the timeout function, so make sure
- * only one of us can do work */
- spin_unlock_irqrestore(&mac->lock, flags);
- return 0;
- }
- network = ieee80211softmac_get_network_by_bssid_locked(mac, resp->header.addr3);
-
- /* someone sending us things without us knowing him? Ignore. */
- if (!network) {
- dprintk(KERN_INFO PFX "Received unrequested assocation response from %s\n",
- print_mac(mac2, resp->header.addr3));
- spin_unlock_irqrestore(&mac->lock, flags);
- return 0;
- }
-
- /* now that we know it was for us, we can cancel the timeout */
- cancel_delayed_work(&mac->associnfo.timeout);
-
- /* if the association response included an ERP IE, update our saved
- * copy */
- if (_ieee80211_network->flags & NETWORK_HAS_ERP_VALUE)
- network->erp_value = _ieee80211_network->erp_value;
-
- switch (status) {
- case 0:
- dprintk(KERN_INFO PFX "associated!\n");
- ieee80211softmac_associated(mac, resp, network);
- ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATED, network);
- break;
- case WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH:
- if (!network->auth_desynced_once) {
- /* there seem to be a few rare cases where our view of
- * the world is obscured, or buggy APs that don't DEAUTH
- * us properly. So we handle that, but allow it only once.
- */
- printkl(KERN_INFO PFX "We were not authenticated during association, retrying...\n");
- network->authenticated = 0;
- /* we don't want to do this more than once ... */
- network->auth_desynced_once = 1;
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
- break;
- }
- default:
- dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status);
- mac->associnfo.associating = 0;
- mac->associnfo.bssvalid = 0;
- mac->associnfo.associated = 0;
- ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network);
- }
-
- spin_unlock_irqrestore(&mac->lock, flags);
- return 0;
-}
-
-void
-ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mac->lock, flags);
- mac->associnfo.associating = 1;
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-int
-ieee80211softmac_handle_disassoc(struct net_device * dev,
- struct ieee80211_disassoc *disassoc)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- if (unlikely(!mac->running))
- return -ENODEV;
-
- if (memcmp(disassoc->header.addr2, mac->associnfo.bssid, ETH_ALEN))
- return 0;
-
- if (memcmp(disassoc->header.addr1, mac->dev->dev_addr, ETH_ALEN))
- return 0;
-
- dprintk(KERN_INFO PFX "got disassoc frame\n");
- ieee80211softmac_disassoc(mac);
-
- ieee80211softmac_try_reassoc(mac);
-
- return 0;
-}
-
-int
-ieee80211softmac_handle_reassoc_req(struct net_device * dev,
- struct ieee80211_reassoc_request * resp)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- struct ieee80211softmac_network *network;
-
- if (unlikely(!mac->running))
- return -ENODEV;
-
- network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3);
- if (!network) {
- dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
- return 0;
- }
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
-
- return 0;
-}
diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c
deleted file mode 100644
index 1a96c2572578..000000000000
--- a/net/ieee80211/softmac/ieee80211softmac_auth.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * This file contains the softmac's authentication logic.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include "ieee80211softmac_priv.h"
-
-static void ieee80211softmac_auth_queue(struct work_struct *work);
-
-/* Queues an auth request to the desired AP */
-int
-ieee80211softmac_auth_req(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net)
-{
- struct ieee80211softmac_auth_queue_item *auth;
- unsigned long flags;
- DECLARE_MAC_BUF(mac2);
-
- if (net->authenticating || net->authenticated)
- return 0;
- net->authenticating = 1;
-
- /* Add the network if it's not already added */
- ieee80211softmac_add_network(mac, net);
-
- dprintk(KERN_NOTICE PFX "Queueing Authentication Request to %s\n", print_mac(mac2, net->bssid));
- /* Queue the auth request */
- auth = (struct ieee80211softmac_auth_queue_item *)
- kmalloc(sizeof(struct ieee80211softmac_auth_queue_item), GFP_KERNEL);
- if(auth == NULL)
- return -ENOMEM;
-
- auth->net = net;
- auth->mac = mac;
- auth->retry = IEEE80211SOFTMAC_AUTH_RETRY_LIMIT;
- auth->state = IEEE80211SOFTMAC_AUTH_OPEN_REQUEST;
- INIT_DELAYED_WORK(&auth->work, ieee80211softmac_auth_queue);
-
- /* Lock (for list) */
- spin_lock_irqsave(&mac->lock, flags);
-
- /* add to list */
- list_add_tail(&auth->list, &mac->auth_queue);
- queue_delayed_work(mac->wq, &auth->work, 0);
- spin_unlock_irqrestore(&mac->lock, flags);
-
- return 0;
-}
-
-
-/* Sends an auth request to the desired AP and handles timeouts */
-static void
-ieee80211softmac_auth_queue(struct work_struct *work)
-{
- struct ieee80211softmac_device *mac;
- struct ieee80211softmac_auth_queue_item *auth;
- struct ieee80211softmac_network *net;
- unsigned long flags;
- DECLARE_MAC_BUF(mac2);
-
- auth = container_of(work, struct ieee80211softmac_auth_queue_item,
- work.work);
- net = auth->net;
- mac = auth->mac;
-
- if(auth->retry > 0) {
- /* Switch to correct channel for this network */
- mac->set_channel(mac->dev, net->channel);
-
- /* Lock and set flags */
- spin_lock_irqsave(&mac->lock, flags);
- if (unlikely(!mac->running)) {
- /* Prevent reschedule on workqueue flush */
- spin_unlock_irqrestore(&mac->lock, flags);
- return;
- }
- net->authenticated = 0;
- /* add a timeout call so we eventually give up waiting for an auth reply */
- queue_delayed_work(mac->wq, &auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT);
- auth->retry--;
- spin_unlock_irqrestore(&mac->lock, flags);
- if (ieee80211softmac_send_mgt_frame(mac, auth->net, IEEE80211_STYPE_AUTH, auth->state))
- dprintk(KERN_NOTICE PFX "Sending Authentication Request to %s failed (this shouldn't happen, wait for the timeout).\n",
- print_mac(mac2, net->bssid));
- else
- dprintk(KERN_NOTICE PFX "Sent Authentication Request to %s.\n", print_mac(mac2, net->bssid));
- return;
- }
-
- printkl(KERN_WARNING PFX "Authentication timed out with %s\n", print_mac(mac2, net->bssid));
- /* Remove this item from the queue */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticating = 0;
- ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT, net);
- cancel_delayed_work(&auth->work); /* just to make sure... */
- list_del(&auth->list);
- spin_unlock_irqrestore(&mac->lock, flags);
- /* Free it */
- kfree(auth);
-}
-
-/* Sends a response to an auth challenge (for shared key auth). */
-static void
-ieee80211softmac_auth_challenge_response(struct work_struct *work)
-{
- struct ieee80211softmac_auth_queue_item *aq =
- container_of(work, struct ieee80211softmac_auth_queue_item,
- work.work);
-
- /* Send our response */
- ieee80211softmac_send_mgt_frame(aq->mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
-}
-
-/* Handle the auth response from the AP
- * This should be registered with ieee80211 as handle_auth
- */
-int
-ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
-{
-
- struct list_head *list_ptr;
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- struct ieee80211softmac_auth_queue_item *aq = NULL;
- struct ieee80211softmac_network *net = NULL;
- unsigned long flags;
- u8 * data;
- DECLARE_MAC_BUF(mac2);
-
- if (unlikely(!mac->running))
- return -ENODEV;
-
- /* Find correct auth queue item */
- spin_lock_irqsave(&mac->lock, flags);
- list_for_each(list_ptr, &mac->auth_queue) {
- aq = list_entry(list_ptr, struct ieee80211softmac_auth_queue_item, list);
- net = aq->net;
- if (!memcmp(net->bssid, auth->header.addr2, ETH_ALEN))
- break;
- else
- aq = NULL;
- }
- spin_unlock_irqrestore(&mac->lock, flags);
-
- /* Make sure that we've got an auth queue item for this request */
- if(aq == NULL)
- {
- dprintkl(KERN_DEBUG PFX "Authentication response received from %s but no queue item exists.\n", print_mac(mac2, auth->header.addr2));
- /* Error #? */
- return -1;
- }
-
- /* Check for out of order authentication */
- if(!net->authenticating)
- {
- dprintkl(KERN_DEBUG PFX "Authentication response received from %s but did not request authentication.\n",print_mac(mac2, auth->header.addr2));
- return -1;
- }
-
- /* Parse the auth packet */
- switch(le16_to_cpu(auth->algorithm)) {
- case WLAN_AUTH_OPEN:
- /* Check the status code of the response */
-
- switch(le16_to_cpu(auth->status)) {
- case WLAN_STATUS_SUCCESS:
- /* Update the status to Authenticated */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticating = 0;
- net->authenticated = 1;
- spin_unlock_irqrestore(&mac->lock, flags);
-
- /* Send event */
- printkl(KERN_NOTICE PFX "Open Authentication completed with %s\n", print_mac(mac2, net->bssid));
- ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net);
- break;
- default:
- /* Lock and reset flags */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticated = 0;
- net->authenticating = 0;
- spin_unlock_irqrestore(&mac->lock, flags);
-
- printkl(KERN_NOTICE PFX "Open Authentication with %s failed, error code: %i\n",
- print_mac(mac2, net->bssid), le16_to_cpup(&auth->status));
- /* Count the error? */
- break;
- }
- goto free_aq;
- break;
- case WLAN_AUTH_SHARED_KEY:
- /* Figure out where we are in the process */
- switch(le16_to_cpu(auth->transaction)) {
- case IEEE80211SOFTMAC_AUTH_SHARED_CHALLENGE:
- /* Check to make sure we have a challenge IE */
- data = (u8 *)auth->info_element;
- if (*data++ != MFIE_TYPE_CHALLENGE) {
- printkl(KERN_NOTICE PFX "Shared Key Authentication failed due to a missing challenge.\n");
- break;
- }
- /* Save the challenge */
- spin_lock_irqsave(&mac->lock, flags);
- net->challenge_len = *data++;
- if (net->challenge_len > WLAN_AUTH_CHALLENGE_LEN)
- net->challenge_len = WLAN_AUTH_CHALLENGE_LEN;
- kfree(net->challenge);
- net->challenge = kmemdup(data, net->challenge_len,
- GFP_ATOMIC);
- if (net->challenge == NULL) {
- printkl(KERN_NOTICE PFX "Shared Key "
- "Authentication failed due to "
- "memory shortage.\n");
- spin_unlock_irqrestore(&mac->lock, flags);
- break;
- }
- aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE;
-
- /* We reuse the work struct from the auth request here.
- * It is safe to do so as each one is per-request, and
- * at this point (dealing with authentication response)
- * we have obviously already sent the initial auth
- * request. */
- cancel_delayed_work(&aq->work);
- INIT_DELAYED_WORK(&aq->work, &ieee80211softmac_auth_challenge_response);
- queue_delayed_work(mac->wq, &aq->work, 0);
- spin_unlock_irqrestore(&mac->lock, flags);
- return 0;
- case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
- kfree(net->challenge);
- net->challenge = NULL;
- net->challenge_len = 0;
- /* Check the status code of the response */
- switch(auth->status) {
- case WLAN_STATUS_SUCCESS:
- /* Update the status to Authenticated */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticating = 0;
- net->authenticated = 1;
- spin_unlock_irqrestore(&mac->lock, flags);
- printkl(KERN_NOTICE PFX "Shared Key Authentication completed with %s\n",
- print_mac(mac2, net->bssid));
- ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net);
- break;
- default:
- printkl(KERN_NOTICE PFX "Shared Key Authentication with %s failed, error code: %i\n",
- print_mac(mac2, net->bssid), le16_to_cpup(&auth->status));
- /* Lock and reset flags */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticating = 0;
- net->authenticated = 0;
- spin_unlock_irqrestore(&mac->lock, flags);
- /* Count the error? */
- break;
- }
- goto free_aq;
- break;
- default:
- printkl(KERN_WARNING PFX "Unhandled Authentication Step: %i\n", auth->transaction);
- break;
- }
- goto free_aq;
- break;
- default:
- /* ERROR */
- goto free_aq;
- break;
- }
- return 0;
-free_aq:
- /* Cancel the timeout */
- spin_lock_irqsave(&mac->lock, flags);
- cancel_delayed_work(&aq->work);
- /* Remove this item from the queue */
- list_del(&aq->list);
- spin_unlock_irqrestore(&mac->lock, flags);
-
- /* Free it */
- kfree(aq);
- return 0;
-}
-
-/*
- * Handle deauthorization
- */
-static void
-ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net)
-{
- struct ieee80211softmac_auth_queue_item *aq = NULL;
- struct list_head *list_ptr;
- unsigned long flags;
-
- /* deauthentication implies disassociation */
- ieee80211softmac_disassoc(mac);
-
- /* Lock and reset status flags */
- spin_lock_irqsave(&mac->lock, flags);
- net->authenticating = 0;
- net->authenticated = 0;
-
- /* Find correct auth queue item, if it exists */
- list_for_each(list_ptr, &mac->auth_queue) {
- aq = list_entry(list_ptr, struct ieee80211softmac_auth_queue_item, list);
- if (!memcmp(net->bssid, aq->net->bssid, ETH_ALEN))
- break;
- else
- aq = NULL;
- }
-
- /* Cancel pending work */
- if(aq != NULL)
- /* Not entirely safe? What about running work? */
- cancel_delayed_work(&aq->work);
-
- /* Free our network ref */
- ieee80211softmac_del_network_locked(mac, net);
- if(net->challenge != NULL)
- kfree(net->challenge);
- kfree(net);
-
- /* can't transmit data right now... */
- netif_carrier_off(mac->dev);
- spin_unlock_irqrestore(&mac->lock, flags);
-
- ieee80211softmac_try_reassoc(mac);
-}
-
-/*
- * Sends a deauth request to the desired AP
- */
-int
-ieee80211softmac_deauth_req(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net, int reason)
-{
- int ret;
-
- /* Make sure the network is authenticated */
- if (!net->authenticated)
- {
- dprintkl(KERN_DEBUG PFX "Can't send deauthentication packet, network is not authenticated.\n");
- /* Error okay? */
- return -EPERM;
- }
-
- /* Send the de-auth packet */
- if((ret = ieee80211softmac_send_mgt_frame(mac, net, IEEE80211_STYPE_DEAUTH, reason)))
- return ret;
-
- ieee80211softmac_deauth_from_net(mac, net);
- return 0;
-}
-
-/*
- * This should be registered with ieee80211 as handle_deauth
- */
-int
-ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *deauth)
-{
-
- struct ieee80211softmac_network *net = NULL;
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- DECLARE_MAC_BUF(mac2);
-
- if (unlikely(!mac->running))
- return -ENODEV;
-
- if (!deauth) {
- dprintk("deauth without deauth packet. eek!\n");
- return 0;
- }
-
- net = ieee80211softmac_get_network_by_bssid(mac, deauth->header.addr2);
-
- if (net == NULL) {
- dprintkl(KERN_DEBUG PFX "Received deauthentication packet from %s, but that network is unknown.\n",
- print_mac(mac2, deauth->header.addr2));
- return 0;
- }
-
- /* Make sure the network is authenticated */
- if(!net->authenticated)
- {
- dprintkl(KERN_DEBUG PFX "Can't perform deauthentication, network is not authenticated.\n");
- /* Error okay? */
- return -EPERM;
- }
-
- ieee80211softmac_deauth_from_net(mac, net);
-
- /* let's try to re-associate */
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
- return 0;
-}
diff --git a/net/ieee80211/softmac/ieee80211softmac_event.c b/net/ieee80211/softmac/ieee80211softmac_event.c
deleted file mode 100644
index 8cef05b60f16..000000000000
--- a/net/ieee80211/softmac/ieee80211softmac_event.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Event system
- * Also see comments in public header file and longer explanation below.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include "ieee80211softmac_priv.h"
-
-/*
- * Each event has associated to it
- * - an event type (see constants in public header)
- * - an event context (see below)
- * - the function to be called
- * - a context (extra parameter to call the function with)
- * - and the softmac struct
- *
- * The event context is private and can only be used from
- * within this module. Its meaning varies with the event
- * type:
- * SCAN_FINISHED,
- * DISASSOCIATED: NULL
- * ASSOCIATED,
- * ASSOCIATE_FAILED,
- * ASSOCIATE_TIMEOUT,
- * AUTHENTICATED,
- * AUTH_FAILED,
- * AUTH_TIMEOUT: a pointer to the network struct
- * ...
- * Code within this module can use the event context to be only
- * called when the event is true for that specific context
- * as per above table.
- * If the event context is NULL, then the notification is always called,
- * regardless of the event context. The event context is not passed to
- * the callback, it is assumed that the context suffices.
- *
- * You can also use the event context only by setting the event type
- * to -1 (private use only), in which case you'll be notified
- * whenever the event context matches.
- */
-
-static char *event_descriptions[IEEE80211SOFTMAC_EVENT_LAST+1] = {
- NULL, /* scan finished */
- NULL, /* associated */
- "associating failed",
- "associating timed out",
- "authenticated",
- "authenticating failed",
- "authenticating timed out",
- "associating failed because no suitable network was found",
- NULL, /* disassociated */
-};
-
-
-static void
-ieee80211softmac_notify_callback(struct work_struct *work)
-{
- struct ieee80211softmac_event *pevent =
- container_of(work, struct ieee80211softmac_event, work.work);
- struct ieee80211softmac_event event = *pevent;
- kfree(pevent);
-
- event.fun(event.mac->dev, event.event_type, event.context);
-}
-
-int
-ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac,
- int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask)
-{
- struct ieee80211softmac_event *eventptr;
- unsigned long flags;
-
- if (event < -1 || event > IEEE80211SOFTMAC_EVENT_LAST)
- return -ENOSYS;
-
- if (!fun)
- return -EINVAL;
-
- eventptr = kmalloc(sizeof(struct ieee80211softmac_event), gfp_mask);
- if (!eventptr)
- return -ENOMEM;
-
- eventptr->event_type = event;
- INIT_DELAYED_WORK(&eventptr->work, ieee80211softmac_notify_callback);
- eventptr->fun = fun;
- eventptr->context = context;
- eventptr->mac = mac;
- eventptr->event_context = event_context;
-
- spin_lock_irqsave(&mac->lock, flags);
- list_add(&eventptr->list, &mac->events);
- spin_unlock_irqrestore(&mac->lock, flags);
-
- return 0;
-}
-
-int
-ieee80211softmac_notify_gfp(struct net_device *dev,
- int event, notify_function_ptr fun, void *context, gfp_t gfp_mask)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- if (event < 0 || event > IEEE80211SOFTMAC_EVENT_LAST)
- return -ENOSYS;
-
- return ieee80211softmac_notify_internal(mac, event, NULL, fun, context, gfp_mask);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_notify_gfp);
-
-/* private -- calling all callbacks that were specified */
-void
-ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int event, void *event_ctx)
-{
- struct ieee80211softmac_event *eventptr, *tmp;
- struct ieee80211softmac_network *network;
-
- if (event >= 0) {
- union iwreq_data wrqu;
- int we_event;
- char *msg = NULL;
-
- memset(&wrqu, '\0', sizeof (union iwreq_data));
-
- switch(event) {
- case IEEE80211SOFTMAC_EVENT_ASSOCIATED:
- network = (struct ieee80211softmac_network *)event_ctx;
- memcpy(wrqu.ap_addr.sa_data, &network->bssid[0], ETH_ALEN);
- /* fall through */
- case IEEE80211SOFTMAC_EVENT_DISASSOCIATED:
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- we_event = SIOCGIWAP;
- break;
- case IEEE80211SOFTMAC_EVENT_SCAN_FINISHED:
- we_event = SIOCGIWSCAN;
- break;
- default:
- msg = event_descriptions[event];
- if (!msg)
- msg = "SOFTMAC EVENT BUG";
- wrqu.data.length = strlen(msg);
- we_event = IWEVCUSTOM;
- break;
- }
- wireless_send_event(mac->dev, we_event, &wrqu, msg);
- }
-
- if (!list_empty(&mac->events))
- list_for_each_entry_safe(eventptr, tmp, &mac->events, list) {
- if ((eventptr->event_type == event || eventptr->event_type == -1)
- && (eventptr->event_context == NULL || eventptr->event_context == event_ctx)) {
- list_del(&eventptr->list);
- /* User may have subscribed to ANY event, so
- * we tell them which event triggered it. */
- eventptr->event_type = event;
- queue_delayed_work(mac->wq, &eventptr->work, 0);
- }
- }
-}
-
-void
-ieee80211softmac_call_events(struct ieee80211softmac_device *mac, int event, void *event_ctx)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mac->lock, flags);
- ieee80211softmac_call_events_locked(mac, event, event_ctx);
-
- spin_unlock_irqrestore(&mac->lock, flags);
-}
diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c
deleted file mode 100644
index 73b4b13fbd8f..000000000000
--- a/net/ieee80211/softmac/ieee80211softmac_io.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Some parts based on code from net80211
- * Copyright (c) 2001 Atsushi Onoe
- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "ieee80211softmac_priv.h"
-
-/* Helper functions for inserting data into the frames */
-
-/*
- * Adds an ESSID element to the frame
- *
- */
-static u8 *
-ieee80211softmac_add_essid(u8 *dst, struct ieee80211softmac_essid *essid)
-{
- if (essid) {
- *dst++ = MFIE_TYPE_SSID;
- *dst++ = essid->len;
- memcpy(dst, essid->data, essid->len);
- return dst+essid->len;
- } else {
- *dst++ = MFIE_TYPE_SSID;
- *dst++ = 0;
- return dst;
- }
-}
-
-/* Adds Supported Rates and if required Extended Rates Information Element
- * to the frame, ASSUMES WE HAVE A SORTED LIST OF RATES */
-static u8 *
-ieee80211softmac_frame_add_rates(u8 *dst, const struct ieee80211softmac_ratesinfo *r)
-{
- int cck_len, ofdm_len;
- *dst++ = MFIE_TYPE_RATES;
-
- for(cck_len=0; ieee80211_is_cck_rate(r->rates[cck_len]) && (cck_len < r->count);cck_len++);
-
- if(cck_len > IEEE80211SOFTMAC_MAX_RATES_LEN)
- cck_len = IEEE80211SOFTMAC_MAX_RATES_LEN;
- *dst++ = cck_len;
- memcpy(dst, r->rates, cck_len);
- dst += cck_len;
-
- if(cck_len < r->count){
- for (ofdm_len=0; ieee80211_is_ofdm_rate(r->rates[ofdm_len + cck_len]) && (ofdm_len + cck_len < r->count); ofdm_len++);
- if (ofdm_len > 0) {
- if (ofdm_len > IEEE80211SOFTMAC_MAX_EX_RATES_LEN)
- ofdm_len = IEEE80211SOFTMAC_MAX_EX_RATES_LEN;
- *dst++ = MFIE_TYPE_RATES_EX;
- *dst++ = ofdm_len;
- memcpy(dst, r->rates + cck_len, ofdm_len);
- dst += ofdm_len;
- }
- }
- return dst;
-}
-
-/* Allocate a management frame */
-static u8 *
-ieee80211softmac_alloc_mgt(u32 size)
-{
- u8 * data;
-
- /* Add the header and FCS to the size */
- size = size + IEEE80211_3ADDR_LEN;
- if(size > IEEE80211_DATA_LEN)
- return NULL;
- /* Allocate the frame */
- data = kzalloc(size, GFP_ATOMIC);
- return data;
-}
-
-/*
- * Add a 2 Address Header
- */
-static void
-ieee80211softmac_hdr_2addr(struct ieee80211softmac_device *mac,
- struct ieee80211_hdr_2addr *header, u32 type, u8 *dest)
-{
- /* Fill in the frame control flags */
- header->frame_ctl = cpu_to_le16(type);
- /* Control packets always have WEP turned off */
- if(type > IEEE80211_STYPE_CFENDACK && type < IEEE80211_STYPE_PSPOLL)
- header->frame_ctl |= mac->ieee->sec.level ? cpu_to_le16(IEEE80211_FCTL_PROTECTED) : 0;
-
- /* Fill in the duration */
- header->duration_id = 0;
- /* FIXME: How do I find this?
- * calculate. But most drivers just fill in 0 (except if it's a station id of course) */
-
- /* Fill in the Destination Address */
- if(dest == NULL)
- memset(header->addr1, 0xFF, ETH_ALEN);
- else
- memcpy(header->addr1, dest, ETH_ALEN);
- /* Fill in the Source Address */
- memcpy(header->addr2, mac->ieee->dev->dev_addr, ETH_ALEN);
-
-}
-
-
-/* Add a 3 Address Header */
-static void
-ieee80211softmac_hdr_3addr(struct ieee80211softmac_device *mac,
- struct ieee80211_hdr_3addr *header, u32 type, u8 *dest, u8 *bssid)
-{
- /* This is common with 2addr, so use that instead */
- ieee80211softmac_hdr_2addr(mac, (struct ieee80211_hdr_2addr *)header, type, dest);
-
- /* Fill in the BSS ID */
- if(bssid == NULL)
- memset(header->addr3, 0xFF, ETH_ALEN);
- else
- memcpy(header->addr3, bssid, ETH_ALEN);
-
- /* Fill in the sequence # */
- /* FIXME: I need to add this to the softmac struct
- * shouldn't the sequence number be in ieee80211? */
-}
-
-static __le16
-ieee80211softmac_capabilities(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net)
-{
- __le16 capability = 0;
-
- /* ESS and IBSS bits are set according to the current mode */
- switch (mac->ieee->iw_mode) {
- case IW_MODE_INFRA:
- capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
- break;
- case IW_MODE_ADHOC:
- capability = cpu_to_le16(WLAN_CAPABILITY_IBSS);
- break;
- case IW_MODE_AUTO:
- capability = cpu_to_le16(net->capabilities &
- (WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS));
- break;
- default:
- /* bleh. we don't ever go to these modes */
- printk(KERN_ERR PFX "invalid iw_mode!\n");
- break;
- }
-
- /* CF Pollable / CF Poll Request */
- /* Needs to be implemented, for now, the 0's == not supported */
-
- /* Privacy Bit */
- capability |= mac->ieee->sec.level ?
- cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
-
- /* Short Preamble */
- /* Always supported: we probably won't ever be powering devices which
- * dont support this... */
- capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
-
- /* PBCC */
- /* Not widely used */
-
- /* Channel Agility */
- /* Not widely used */
-
- /* Short Slot */
- /* Will be implemented later */
-
- /* DSSS-OFDM */
- /* Not widely used */
-
- return capability;
-}
-
-/*****************************************************************************
- * Create Management packets
- *****************************************************************************/
-
-/* Creates an association request packet */
-static u32
-ieee80211softmac_assoc_req(struct ieee80211_assoc_request **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
-{
- u8 *data;
- (*pkt) = (struct ieee80211_assoc_request *)ieee80211softmac_alloc_mgt(
- 2 + /* Capability Info */
- 2 + /* Listen Interval */
- /* SSID IE */
- 1 + 1 + IW_ESSID_MAX_SIZE +
- /* Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_RATES_LEN +
- /* Extended Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_EX_RATES_LEN +
- /* WPA IE if present */
- mac->wpa.IElen
- /* Other IE's? Optional?
- * Yeah, probably need an extra IE parameter -- lots of vendors like to
- * fill in their own IEs */
- );
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid);
-
- /* Fill in the capabilities */
- (*pkt)->capability = ieee80211softmac_capabilities(mac, net);
-
- /* Fill in Listen Interval (?) */
- (*pkt)->listen_interval = cpu_to_le16(10);
-
- data = (u8 *)(*pkt)->info_element;
- /* Add SSID */
- data = ieee80211softmac_add_essid(data, &net->essid);
- /* Add Rates */
- data = ieee80211softmac_frame_add_rates(data, &mac->ratesinfo);
- /* Add WPA IE */
- if (mac->wpa.IElen && mac->wpa.IE) {
- memcpy(data, mac->wpa.IE, mac->wpa.IElen);
- data += mac->wpa.IElen;
- }
- /* Return the number of used bytes */
- return (data - (u8*)(*pkt));
-}
-
-/* Create a reassociation request packet */
-static u32
-ieee80211softmac_reassoc_req(struct ieee80211_reassoc_request **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
-{
- u8 *data;
- (*pkt) = (struct ieee80211_reassoc_request *)ieee80211softmac_alloc_mgt(
- 2 + /* Capability Info */
- 2 + /* Listen Interval */
- ETH_ALEN + /* AP MAC */
- /* SSID IE */
- 1 + 1 + IW_ESSID_MAX_SIZE +
- /* Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_RATES_LEN +
- /* Extended Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_EX_RATES_LEN
- /* Other IE's? */
- );
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_REASSOC_REQ, net->bssid, net->bssid);
-
- /* Fill in the capabilities */
- (*pkt)->capability = ieee80211softmac_capabilities(mac, net);
-
- /* Fill in Listen Interval (?) */
- (*pkt)->listen_interval = cpu_to_le16(10);
- /* Fill in the current AP MAC */
- memcpy((*pkt)->current_ap, mac->ieee->bssid, ETH_ALEN);
-
- data = (u8 *)(*pkt)->info_element;
- /* Add SSID */
- data = ieee80211softmac_add_essid(data, &net->essid);
- /* Add Rates */
- data = ieee80211softmac_frame_add_rates(data, &mac->ratesinfo);
- /* Return packet size */
- return (data - (u8 *)(*pkt));
-}
-
-/* Create an authentication packet */
-static u32
-ieee80211softmac_auth(struct ieee80211_auth **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
- u16 transaction, u16 status, int *encrypt_mpdu)
-{
- u8 *data;
- int auth_mode = mac->ieee->sec.auth_mode;
- int is_shared_response = (auth_mode == WLAN_AUTH_SHARED_KEY
- && transaction == IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE);
-
- /* Allocate Packet */
- (*pkt) = (struct ieee80211_auth *)ieee80211softmac_alloc_mgt(
- 2 + /* Auth Algorithm */
- 2 + /* Auth Transaction Seq */
- 2 + /* Status Code */
- /* Challenge Text IE */
- (is_shared_response ? 1 + 1 + net->challenge_len : 0)
- );
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_AUTH, net->bssid, net->bssid);
-
- /* Algorithm */
- (*pkt)->algorithm = cpu_to_le16(auth_mode);
- /* Transaction */
- (*pkt)->transaction = cpu_to_le16(transaction);
- /* Status */
- (*pkt)->status = cpu_to_le16(status);
-
- data = (u8 *)(*pkt)->info_element;
- /* Challenge Text */
- if (is_shared_response) {
- *data = MFIE_TYPE_CHALLENGE;
- data++;
-
- /* Copy the challenge in */
- *data = net->challenge_len;
- data++;
- memcpy(data, net->challenge, net->challenge_len);
- data += net->challenge_len;
-
- /* Make sure this frame gets encrypted with the shared key */
- *encrypt_mpdu = 1;
- } else
- *encrypt_mpdu = 0;
-
- /* Return the packet size */
- return (data - (u8 *)(*pkt));
-}
-
-/* Create a disassocation or deauthentication packet */
-static u32
-ieee80211softmac_disassoc_deauth(struct ieee80211_disassoc **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
- u16 type, u16 reason)
-{
- /* Allocate Packet */
- (*pkt) = (struct ieee80211_disassoc *)ieee80211softmac_alloc_mgt(2);
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), type, net->bssid, net->bssid);
- /* Reason */
- (*pkt)->reason = cpu_to_le16(reason);
- /* Return the packet size */
- return (2 + IEEE80211_3ADDR_LEN);
-}
-
-/* Create a probe request packet */
-static u32
-ieee80211softmac_probe_req(struct ieee80211_probe_request **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_essid *essid)
-{
- u8 *data;
- /* Allocate Packet */
- (*pkt) = (struct ieee80211_probe_request *)ieee80211softmac_alloc_mgt(
- /* SSID of requested network */
- 1 + 1 + IW_ESSID_MAX_SIZE +
- /* Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_RATES_LEN +
- /* Extended Rates IE */
- 1 + 1 + IEEE80211SOFTMAC_MAX_EX_RATES_LEN
- );
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_PROBE_REQ, NULL, NULL);
-
- data = (u8 *)(*pkt)->info_element;
- /* Add ESSID (can be NULL) */
- data = ieee80211softmac_add_essid(data, essid);
- /* Add Rates */
- data = ieee80211softmac_frame_add_rates(data, &mac->ratesinfo);
- /* Return packet size */
- return (data - (u8 *)(*pkt));
-}
-
-/* Create a probe response packet */
-/* FIXME: Not complete */
-static u32
-ieee80211softmac_probe_resp(struct ieee80211_probe_response **pkt,
- struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
-{
- u8 *data;
- /* Allocate Packet */
- (*pkt) = (struct ieee80211_probe_response *)ieee80211softmac_alloc_mgt(
- 8 + /* Timestamp */
- 2 + /* Beacon Interval */
- 2 + /* Capability Info */
- /* SSID IE */
- 1 + 1 + IW_ESSID_MAX_SIZE +
- 7 + /* FH Parameter Set */
- 2 + /* DS Parameter Set */
- 8 + /* CF Parameter Set */
- 4 /* IBSS Parameter Set */
- );
- if (unlikely((*pkt) == NULL))
- return 0;
- ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_PROBE_RESP, net->bssid, net->bssid);
- data = (u8 *)(*pkt)->info_element;
-
- /* Return the packet size */
- return (data - (u8 *)(*pkt));
-}
-
-
-/* Sends a manangement packet
- * FIXME: document the use of the arg parameter
- * for _AUTH: (transaction #) | (status << 16)
- */
-int
-ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
- void *ptrarg, u32 type, u32 arg)
-{
- void *pkt = NULL;
- u32 pkt_size = 0;
- int encrypt_mpdu = 0;
-
- switch(type) {
- case IEEE80211_STYPE_ASSOC_REQ:
- pkt_size = ieee80211softmac_assoc_req((struct ieee80211_assoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
- break;
- case IEEE80211_STYPE_REASSOC_REQ:
- pkt_size = ieee80211softmac_reassoc_req((struct ieee80211_reassoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
- break;
- case IEEE80211_STYPE_AUTH:
- pkt_size = ieee80211softmac_auth((struct ieee80211_auth **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, (u16)(arg & 0xFFFF), (u16) (arg >> 16), &encrypt_mpdu);
- break;
- case IEEE80211_STYPE_DISASSOC:
- case IEEE80211_STYPE_DEAUTH:
- pkt_size = ieee80211softmac_disassoc_deauth((struct ieee80211_disassoc **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, type, (u16)(arg & 0xFFFF));
- break;
- case IEEE80211_STYPE_PROBE_REQ:
- pkt_size = ieee80211softmac_probe_req((struct ieee80211_probe_request **)(&pkt), mac, (struct ieee80211softmac_essid *)ptrarg);
- break;
- case IEEE80211_STYPE_PROBE_RESP:
- pkt_size = ieee80211softmac_probe_resp((struct ieee80211_probe_response **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
- break;
- default:
- printkl(KERN_DEBUG PFX "Unsupported Management Frame type: %i\n", type);
- return -EINVAL;
- };
-
- if(pkt_size == 0 || pkt == NULL) {
- printkl(KERN_DEBUG PFX "Error, packet is nonexistant or 0 length\n");
- return -ENOMEM;
- }
-
- /* Send the packet to the ieee80211 layer for tx */
- /* we defined softmac->mgmt_xmit for this. Should we keep it
- * as it is (that means we'd need to wrap this into a txb),
- * modify the prototype (so it matches this function),
- * or get rid of it alltogether?
- * Does this work for you now?
- */
- ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *)pkt,
- IEEE80211_3ADDR_LEN, pkt_size, encrypt_mpdu);
-
- kfree(pkt);
- return 0;
-}
-
-/* Beacon handling */
-int ieee80211softmac_handle_beacon(struct net_device *dev,
- struct ieee80211_beacon *beacon,
- struct ieee80211_network *network)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- /* This might race, but we don't really care and it's not worth
- * adding heavyweight locking in this fastpath.
- */
- if (mac->associnfo.associated) {
- if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
- ieee80211softmac_process_erp(mac, network->erp_value);
- }
-
- return 0;
-}
-
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
deleted file mode 100644
index 07505ca859af..000000000000
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * Contains some basic softmac functions along with module registration code etc.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include "ieee80211softmac_priv.h"
-#include <linux/sort.h>
-#include <linux/etherdevice.h>
-
-struct net_device *alloc_ieee80211softmac(int sizeof_priv)
-{
- struct ieee80211softmac_device *softmac;
- struct net_device *dev;
-
- dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv);
- if (!dev)
- return NULL;
- softmac = ieee80211_priv(dev);
- softmac->wq = create_freezeable_workqueue("softmac");
- if (!softmac->wq) {
- free_ieee80211(dev);
- return NULL;
- }
-
- softmac->dev = dev;
- softmac->ieee = netdev_priv(dev);
- spin_lock_init(&softmac->lock);
-
- softmac->ieee->handle_auth = ieee80211softmac_auth_resp;
- softmac->ieee->handle_deauth = ieee80211softmac_deauth_resp;
- softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response;
- softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req;
- softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc;
- softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon;
- softmac->scaninfo = NULL;
-
- softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
-
- /* TODO: initialise all the other callbacks in the ieee struct
- * (once they're written)
- */
-
- INIT_LIST_HEAD(&softmac->auth_queue);
- INIT_LIST_HEAD(&softmac->network_list);
- INIT_LIST_HEAD(&softmac->events);
-
- mutex_init(&softmac->associnfo.mutex);
- INIT_DELAYED_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work);
- INIT_DELAYED_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout);
- softmac->start_scan = ieee80211softmac_start_scan_implementation;
- softmac->wait_for_scan = ieee80211softmac_wait_for_scan_implementation;
- softmac->stop_scan = ieee80211softmac_stop_scan_implementation;
-
- /* to start with, we can't send anything ... */
- netif_carrier_off(dev);
-
- return dev;
-}
-EXPORT_SYMBOL_GPL(alloc_ieee80211softmac);
-
-/* Clears the pending work queue items, stops all scans, etc. */
-void
-ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm)
-{
- unsigned long flags;
- struct ieee80211softmac_event *eventptr, *eventtmp;
- struct ieee80211softmac_auth_queue_item *authptr, *authtmp;
- struct ieee80211softmac_network *netptr, *nettmp;
-
- ieee80211softmac_stop_scan(sm);
- ieee80211softmac_wait_for_scan(sm);
-
- spin_lock_irqsave(&sm->lock, flags);
- sm->running = 0;
-
- /* Free all pending assoc work items */
- cancel_delayed_work(&sm->associnfo.work);
-
- /* Free all pending scan work items */
- if(sm->scaninfo != NULL)
- cancel_delayed_work(&sm->scaninfo->softmac_scan);
-
- /* Free all pending auth work items */
- list_for_each_entry(authptr, &sm->auth_queue, list)
- cancel_delayed_work(&authptr->work);
-
- /* delete all pending event calls and work items */
- list_for_each_entry_safe(eventptr, eventtmp, &sm->events, list)
- cancel_delayed_work(&eventptr->work);
-
- spin_unlock_irqrestore(&sm->lock, flags);
- flush_workqueue(sm->wq);
-
- /* now we should be save and no longer need locking... */
- spin_lock_irqsave(&sm->lock, flags);
- /* Free all pending auth work items */
- list_for_each_entry_safe(authptr, authtmp, &sm->auth_queue, list) {
- list_del(&authptr->list);
- kfree(authptr);
- }
-
- /* delete all pending event calls and work items */
- list_for_each_entry_safe(eventptr, eventtmp, &sm->events, list) {
- list_del(&eventptr->list);
- kfree(eventptr);
- }
-
- /* Free all networks */
- list_for_each_entry_safe(netptr, nettmp, &sm->network_list, list) {
- ieee80211softmac_del_network_locked(sm, netptr);
- if(netptr->challenge != NULL)
- kfree(netptr->challenge);
- kfree(netptr);
- }
-
- spin_unlock_irqrestore(&sm->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_clear_pending_work);
-
-void free_ieee80211softmac(struct net_device *dev)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(dev);
- ieee80211softmac_clear_pending_work(sm);
- kfree(sm->scaninfo);
- kfree(sm->wpa.IE);
- destroy_workqueue(sm->wq);
- free_ieee80211(dev);
-}
-EXPORT_SYMBOL_GPL(free_ieee80211softmac);
-
-static void ieee80211softmac_start_check_rates(struct ieee80211softmac_device *mac)
-{
- struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
- /* I took out the sorting check, we're seperating by modulation now. */
- if (ri->count)
- return;
- /* otherwise assume we hav'em all! */
- if (mac->ieee->modulation & IEEE80211_CCK_MODULATION) {
- ri->rates[ri->count++] = IEEE80211_CCK_RATE_1MB;
- ri->rates[ri->count++] = IEEE80211_CCK_RATE_2MB;
- ri->rates[ri->count++] = IEEE80211_CCK_RATE_5MB;
- ri->rates[ri->count++] = IEEE80211_CCK_RATE_11MB;
- }
- if (mac->ieee->modulation & IEEE80211_OFDM_MODULATION) {
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_6MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_9MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_12MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_18MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_24MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_36MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_48MB;
- ri->rates[ri->count++] = IEEE80211_OFDM_RATE_54MB;
- }
-}
-
-int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate)
-{
- int search;
- u8 search_rate;
-
- for (search = 0; search < ri->count; search++) {
- search_rate = ri->rates[search];
- search_rate &= ~IEEE80211_BASIC_RATE_MASK;
- if (rate == search_rate)
- return 1;
- }
-
- return 0;
-}
-
-u8 ieee80211softmac_highest_supported_rate(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_ratesinfo *ri, int basic_only)
-{
- u8 user_rate = mac->txrates.user_rate;
- int i;
-
- if (ri->count == 0)
- return IEEE80211_CCK_RATE_1MB;
-
- for (i = ri->count - 1; i >= 0; i--) {
- u8 rate = ri->rates[i];
- if (basic_only && !(rate & IEEE80211_BASIC_RATE_MASK))
- continue;
- rate &= ~IEEE80211_BASIC_RATE_MASK;
- if (rate > user_rate)
- continue;
- if (ieee80211softmac_ratesinfo_rate_supported(&mac->ratesinfo, rate))
- return rate;
- }
-
- /* If we haven't found a suitable rate by now, just trust the user */
- return user_rate;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_highest_supported_rate);
-
-void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
- u8 erp_value)
-{
- int use_protection;
- int short_preamble;
- u32 changes = 0;
-
- /* Barker preamble mode */
- short_preamble = ((erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0
- && mac->associnfo.short_preamble_available) ? 1 : 0;
-
- /* Protection needed? */
- use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
-
- if (mac->bssinfo.short_preamble != short_preamble) {
- changes |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
- mac->bssinfo.short_preamble = short_preamble;
- }
-
- if (mac->bssinfo.use_protection != use_protection) {
- changes |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
- mac->bssinfo.use_protection = use_protection;
- }
-
- if (mac->bssinfo_change && changes)
- mac->bssinfo_change(mac->dev, changes);
-}
-
-void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac)
-{
- struct ieee80211softmac_txrates *txrates = &mac->txrates;
- u32 change = 0;
-
- change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
- txrates->default_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 0);
-
- change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
- txrates->default_fallback = lower_rate(mac, txrates->default_rate);
-
- change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
- txrates->mcast_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 1);
-
- if (mac->txrates_change)
- mac->txrates_change(mac->dev, change);
-
-}
-
-void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac)
-{
- struct ieee80211_device *ieee = mac->ieee;
- u32 change = 0;
- struct ieee80211softmac_txrates *txrates = &mac->txrates;
- struct ieee80211softmac_bss_info *bssinfo = &mac->bssinfo;
-
- /* TODO: We need some kind of state machine to lower the default rates
- * if we loose too many packets.
- */
- /* Change the default txrate to the highest possible value.
- * The txrate machine will lower it, if it is too high.
- */
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- txrates->user_rate = IEEE80211_OFDM_RATE_24MB;
- else
- txrates->user_rate = IEEE80211_CCK_RATE_11MB;
-
- txrates->default_rate = IEEE80211_CCK_RATE_1MB;
- change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
-
- txrates->default_fallback = IEEE80211_CCK_RATE_1MB;
- change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
-
- txrates->mcast_rate = IEEE80211_CCK_RATE_1MB;
- change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
-
- txrates->mgt_mcast_rate = IEEE80211_CCK_RATE_1MB;
- change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST;
-
- if (mac->txrates_change)
- mac->txrates_change(mac->dev, change);
-
- change = 0;
-
- bssinfo->supported_rates.count = 0;
- memset(bssinfo->supported_rates.rates, 0,
- sizeof(bssinfo->supported_rates.rates));
- change |= IEEE80211SOFTMAC_BSSINFOCHG_RATES;
-
- bssinfo->short_preamble = 0;
- change |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
-
- bssinfo->use_protection = 0;
- change |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
-
- if (mac->bssinfo_change)
- mac->bssinfo_change(mac->dev, change);
-
- mac->running = 1;
-}
-
-void ieee80211softmac_start(struct net_device *dev)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- ieee80211softmac_start_check_rates(mac);
- ieee80211softmac_init_bss(mac);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_start);
-
-void ieee80211softmac_stop(struct net_device *dev)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-
- ieee80211softmac_clear_pending_work(mac);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_stop);
-
-void ieee80211softmac_set_rates(struct net_device *dev, u8 count, u8 *rates)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&mac->lock, flags);
- memcpy(mac->ratesinfo.rates, rates, count);
- mac->ratesinfo.count = count;
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_set_rates);
-
-static u8 raise_rate(struct ieee80211softmac_device *mac, u8 rate)
-{
- int i;
- struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
-
- for (i=0; i<ri->count-1; i++) {
- if (ri->rates[i] == rate)
- return ri->rates[i+1];
- }
- /* I guess we can't go any higher... */
- return ri->rates[ri->count];
-}
-
-u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta)
-{
- int i;
- struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
-
- for (i=delta; i<ri->count; i++) {
- if (ri->rates[i] == rate)
- return ri->rates[i-delta];
- }
- /* I guess we can't go any lower... */
- return ri->rates[0];
-}
-
-static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac,
- int amount)
-{
- u8 default_rate = mac->txrates.default_rate;
- u8 default_fallback = mac->txrates.default_fallback;
- u32 changes = 0;
-
- //TODO: This is highly experimental code.
- // Maybe the dynamic rate selection does not work
- // and it has to be removed again.
-
-printk("badness %d\n", mac->txrate_badness);
- mac->txrate_badness += amount;
- if (mac->txrate_badness <= -1000) {
- /* Very small badness. Try a faster bitrate. */
- default_rate = raise_rate(mac, default_rate);
- changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
- default_fallback = get_fallback_rate(mac, default_rate);
- changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
- mac->txrate_badness = 0;
-printk("Bitrate raised to %u\n", default_rate);
- } else if (mac->txrate_badness >= 10000) {
- /* Very high badness. Try a slower bitrate. */
- default_rate = lower_rate(mac, default_rate);
- changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
- default_fallback = get_fallback_rate(mac, default_rate);
- changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
- mac->txrate_badness = 0;
-printk("Bitrate lowered to %u\n", default_rate);
- }
-
- mac->txrates.default_rate = default_rate;
- mac->txrates.default_fallback = default_fallback;
-
- if (changes && mac->txrates_change)
- mac->txrates_change(mac->dev, changes);
-}
-
-void ieee80211softmac_fragment_lost(struct net_device *dev,
- u16 wl_seq)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&mac->lock, flags);
- ieee80211softmac_add_txrates_badness(mac, 1000);
- //TODO
-
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_fragment_lost);
-
-static int rate_cmp(const void *a_, const void *b_) {
- u8 *a, *b;
- a = (u8*)a_;
- b = (u8*)b_;
- return ((*a & ~IEEE80211_BASIC_RATE_MASK) - (*b & ~IEEE80211_BASIC_RATE_MASK));
-}
-
-/* Allocate a softmac network struct and fill it from a network */
-struct ieee80211softmac_network *
-ieee80211softmac_create_network(struct ieee80211softmac_device *mac,
- struct ieee80211_network *net)
-{
- struct ieee80211softmac_network *softnet;
- softnet = kzalloc(sizeof(struct ieee80211softmac_network), GFP_ATOMIC);
- if(softnet == NULL)
- return NULL;
- memcpy(softnet->bssid, net->bssid, ETH_ALEN);
- softnet->channel = net->channel;
- softnet->essid.len = net->ssid_len;
- memcpy(softnet->essid.data, net->ssid, softnet->essid.len);
-
- /* copy rates over */
- softnet->supported_rates.count = net->rates_len;
- memcpy(&softnet->supported_rates.rates[0], net->rates, net->rates_len);
- memcpy(&softnet->supported_rates.rates[softnet->supported_rates.count], net->rates_ex, net->rates_ex_len);
- softnet->supported_rates.count += net->rates_ex_len;
- sort(softnet->supported_rates.rates, softnet->supported_rates.count, sizeof(softnet->supported_rates.rates[0]), rate_cmp, NULL);
-
- /* we save the ERP value because it is needed at association time, and
- * many AP's do not include an ERP IE in the association response. */
- softnet->erp_value = net->erp_value;
-
- softnet->capabilities = net->capability;
- return softnet;
-}
-
-
-/* Add a network to the list, while locked */
-void
-ieee80211softmac_add_network_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *add_net)
-{
- struct ieee80211softmac_network *softmac_net;
-
- list_for_each_entry(softmac_net, &mac->network_list, list) {
- if(!memcmp(softmac_net->bssid, add_net->bssid, ETH_ALEN))
- return;
- }
- list_add(&(add_net->list), &mac->network_list);
-}
-
-/* Add a network to the list, with locking */
-void
-ieee80211softmac_add_network(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *add_net)
-{
- unsigned long flags;
- spin_lock_irqsave(&mac->lock, flags);
- ieee80211softmac_add_network_locked(mac, add_net);
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-
-/* Delete a network from the list, while locked*/
-void
-ieee80211softmac_del_network_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *del_net)
-{
- list_del(&(del_net->list));
-}
-
-/* Delete a network from the list with locking */
-void
-ieee80211softmac_del_network(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *del_net)
-{
- unsigned long flags;
- spin_lock_irqsave(&mac->lock, flags);
- ieee80211softmac_del_network_locked(mac, del_net);
- spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-/* Get a network from the list by MAC while locked */
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_bssid_locked(struct ieee80211softmac_device *mac,
- u8 *bssid)
-{
- struct ieee80211softmac_network *softmac_net;
-
- list_for_each_entry(softmac_net, &mac->network_list, list) {
- if(!memcmp(softmac_net->bssid, bssid, ETH_ALEN))
- return softmac_net;
- }
- return NULL;
-}
-
-/* Get a network from the list by BSSID with locking */
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_bssid(struct ieee80211softmac_device *mac,
- u8 *bssid)
-{
- unsigned long flags;
- struct ieee80211softmac_network *softmac_net;
-
- spin_lock_irqsave(&mac->lock, flags);
- softmac_net = ieee80211softmac_get_network_by_bssid_locked(mac, bssid);
- spin_unlock_irqrestore(&mac->lock, flags);
- return softmac_net;
-}
-
-/* Get a network from the list by ESSID while locked */
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_essid_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_essid *essid)
-{
- struct ieee80211softmac_network *softmac_net;
-
- list_for_each_entry(softmac_net, &mac->network_list, list) {
- if (softmac_net->essid.len == essid->len &&
- !memcmp(softmac_net->essid.data, essid->data, essid->len))
- return softmac_net;
- }
- return NULL;
-}
-
-/* Get a network from the list by ESSID with locking */
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_essid *essid)
-{
- unsigned long flags;
- struct ieee80211softmac_network *softmac_net = NULL;
-
- spin_lock_irqsave(&mac->lock, flags);
- softmac_net = ieee80211softmac_get_network_by_essid_locked(mac, essid);
- spin_unlock_irqrestore(&mac->lock, flags);
- return softmac_net;
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Johannes Berg");
-MODULE_AUTHOR("Joseph Jezak");
-MODULE_AUTHOR("Larry Finger");
-MODULE_AUTHOR("Danny van Dyk");
-MODULE_AUTHOR("Michael Buesch");
-MODULE_DESCRIPTION("802.11 software MAC");
diff --git a/net/ieee80211/softmac/ieee80211softmac_priv.h b/net/ieee80211/softmac/ieee80211softmac_priv.h
deleted file mode 100644
index f9232c8f6bdc..000000000000
--- a/net/ieee80211/softmac/ieee80211softmac_priv.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Internal softmac API definitions.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#ifndef IEEE80211SOFTMAC_PRIV_H_
-#define IEEE80211SOFTMAC_PRIV_H_
-
-#include <net/ieee80211softmac.h>
-#include <net/ieee80211softmac_wx.h>
-#include <linux/kernel.h>
-#include <linux/stringify.h>
-
-
-#define PFX "SoftMAC: "
-
-#ifdef assert
-# undef assert
-#endif
-#ifdef CONFIG_IEEE80211_SOFTMAC_DEBUG
-#define assert(expr) \
- do { \
- if (unlikely(!(expr))) { \
- printkl(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", #expr, \
- __FILE__, __LINE__, __func__); \
- } \
- } while (0)
-#else
-#define assert(expr) do {} while (0)
-#endif
-
-/* rate limited printk(). */
-#ifdef printkl
-# undef printkl
-#endif
-#define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0)
-/* rate limited printk() for debugging */
-#ifdef dprintkl
-# undef dprintkl
-#endif
-#ifdef CONFIG_IEEE80211_SOFTMAC_DEBUG
-# define dprintkl printkl
-#else
-# define dprintkl(f, x...) do { /* nothing */ } while (0)
-#endif
-
-/* debugging printk() */
-#ifdef dprintk
-# undef dprintk
-#endif
-#ifdef CONFIG_IEEE80211_SOFTMAC_DEBUG
-# define dprintk(f, x...) do { printk(f ,##x); } while (0)
-#else
-# define dprintk(f, x...) do { /* nothing */ } while (0)
-#endif
-
-/* private definitions and prototypes */
-
-/*** prototypes from _scan.c */
-void ieee80211softmac_scan(struct work_struct *work);
-/* for internal use if scanning is needed */
-int ieee80211softmac_start_scan(struct ieee80211softmac_device *mac);
-void ieee80211softmac_stop_scan(struct ieee80211softmac_device *mac);
-void ieee80211softmac_wait_for_scan(struct ieee80211softmac_device *mac);
-
-/* for use by _module.c to assign to the callbacks */
-int ieee80211softmac_start_scan_implementation(struct net_device *dev);
-void ieee80211softmac_stop_scan_implementation(struct net_device *dev);
-void ieee80211softmac_wait_for_scan_implementation(struct net_device *dev);
-
-/*** Network prototypes from _module.c */
-struct ieee80211softmac_network * ieee80211softmac_create_network(
- struct ieee80211softmac_device *mac, struct ieee80211_network *net);
-void ieee80211softmac_add_network_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net);
-void ieee80211softmac_add_network(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net);
-void ieee80211softmac_del_network_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net);
-void ieee80211softmac_del_network(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_network *net);
-struct ieee80211softmac_network * ieee80211softmac_get_network_by_bssid_locked(
- struct ieee80211softmac_device *mac, u8 *ea);
-struct ieee80211softmac_network * ieee80211softmac_get_network_by_bssid(
- struct ieee80211softmac_device *mac, u8 *ea);
-struct ieee80211softmac_network * ieee80211softmac_get_network_by_ssid_locked(
- struct ieee80211softmac_device *mac, u8 *ssid, u8 ssid_len);
-struct ieee80211softmac_network * ieee80211softmac_get_network_by_ssid(
- struct ieee80211softmac_device *mac, u8 *ssid, u8 ssid_len);
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_essid_locked(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_essid *essid);
-struct ieee80211softmac_network *
-ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac,
- struct ieee80211softmac_essid *essid);
-
-/* Rates related */
-void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
- u8 erp_value);
-int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate);
-u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta);
-void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac);
-void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac);
-static inline u8 lower_rate(struct ieee80211softmac_device *mac, u8 rate) {
- return ieee80211softmac_lower_rate_delta(mac, rate, 1);
-}
-
-static inline u8 get_fallback_rate(struct ieee80211softmac_device *mac, u8 rate)
-{
- return ieee80211softmac_lower_rate_delta(mac, rate, 2);
-}
-
-
-/*** prototypes from _io.c */
-int ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
- void* ptrarg, u32 type, u32 arg);
-int ieee80211softmac_handle_beacon(struct net_device *dev,
- struct ieee80211_beacon *beacon,
- struct ieee80211_network *network);
-
-/*** prototypes from _auth.c */
-/* do these have to go into the public header? */
-int ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net);
-int ieee80211softmac_deauth_req(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net, int reason);
-
-/* for use by _module.c to assign to the callbacks */
-int ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth);
-int ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *deauth);
-
-/*** prototypes from _assoc.c */
-void ieee80211softmac_assoc_work(struct work_struct *work);
-int ieee80211softmac_handle_assoc_response(struct net_device * dev,
- struct ieee80211_assoc_response * resp,
- struct ieee80211_network * network);
-int ieee80211softmac_handle_disassoc(struct net_device * dev,
- struct ieee80211_disassoc * disassoc);
-int ieee80211softmac_handle_reassoc_req(struct net_device * dev,
- struct ieee80211_reassoc_request * reassoc);
-void ieee80211softmac_assoc_timeout(struct work_struct *work);
-void ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason);
-void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac);
-
-/* some helper functions */
-static inline int ieee80211softmac_scan_handlers_check_self(struct ieee80211softmac_device *sm)
-{
- return (sm->start_scan == ieee80211softmac_start_scan_implementation) &&
- (sm->stop_scan == ieee80211softmac_stop_scan_implementation) &&
- (sm->wait_for_scan == ieee80211softmac_wait_for_scan_implementation);
-}
-
-static inline int ieee80211softmac_scan_sanity_check(struct ieee80211softmac_device *sm)
-{
- return ((sm->start_scan != ieee80211softmac_start_scan_implementation) &&
- (sm->stop_scan != ieee80211softmac_stop_scan_implementation) &&
- (sm->wait_for_scan != ieee80211softmac_wait_for_scan_implementation)
- ) || ieee80211softmac_scan_handlers_check_self(sm);
-}
-
-#define IEEE80211SOFTMAC_PROBE_DELAY HZ/50
-#define IEEE80211SOFTMAC_WORKQUEUE_NAME_LEN (17 + IFNAMSIZ)
-
-struct ieee80211softmac_network {
- struct list_head list; /* List */
- /* Network information copied from ieee80211_network */
- u8 bssid[ETH_ALEN];
- u8 channel;
- struct ieee80211softmac_essid essid;
-
- struct ieee80211softmac_ratesinfo supported_rates;
-
- /* SoftMAC specific */
- u16 authenticating:1, /* Status Flags */
- authenticated:1,
- auth_desynced_once:1;
-
- u8 erp_value; /* Saved ERP value */
- u16 capabilities; /* Capabilities bitfield */
- u8 challenge_len; /* Auth Challenge length */
- char *challenge; /* Challenge Text */
-};
-
-/* structure used to keep track of networks we're auth'ing to */
-struct ieee80211softmac_auth_queue_item {
- struct list_head list; /* List head */
- struct ieee80211softmac_network *net; /* Network to auth */
- struct ieee80211softmac_device *mac; /* SoftMAC device */
- u8 retry; /* Retry limit */
- u8 state; /* Auth State */
- struct delayed_work work; /* Work queue */
-};
-
-/* scanning information */
-struct ieee80211softmac_scaninfo {
- u8 current_channel_idx,
- number_channels;
- struct ieee80211_channel *channels;
- u8 started:1,
- stop:1;
- u8 skip_flags;
- struct completion finished;
- struct delayed_work softmac_scan;
- struct ieee80211softmac_device *mac;
-};
-
-/* private event struct */
-struct ieee80211softmac_event {
- struct list_head list;
- int event_type;
- void *event_context;
- struct delayed_work work;
- notify_function_ptr fun;
- void *context;
- struct ieee80211softmac_device *mac;
-};
-
-void ieee80211softmac_call_events(struct ieee80211softmac_device *mac, int event, void *event_context);
-void ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int event, void *event_context);
-int ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac,
- int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask);
-
-void ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac);
-
-#endif /* IEEE80211SOFTMAC_PRIV_H_ */
diff --git a/net/ieee80211/softmac/ieee80211softmac_scan.c b/net/ieee80211/softmac/ieee80211softmac_scan.c
deleted file mode 100644
index bfab8d7db88f..000000000000
--- a/net/ieee80211/softmac/ieee80211softmac_scan.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Scanning routines.
- *
- * These are not exported because they're assigned to the function pointers.
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include <linux/completion.h>
-#include "ieee80211softmac_priv.h"
-
-/* internal, use to trigger scanning if needed.
- * Returns -EBUSY if already scanning,
- * result of start_scan otherwise */
-int
-ieee80211softmac_start_scan(struct ieee80211softmac_device *sm)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&sm->lock, flags);
- if (sm->scanning)
- {
- spin_unlock_irqrestore(&sm->lock, flags);
- return -EINPROGRESS;
- }
- sm->scanning = 1;
- spin_unlock_irqrestore(&sm->lock, flags);
-
- ret = sm->start_scan(sm->dev);
- if (ret) {
- spin_lock_irqsave(&sm->lock, flags);
- sm->scanning = 0;
- spin_unlock_irqrestore(&sm->lock, flags);
- }
- return ret;
-}
-
-void
-ieee80211softmac_stop_scan(struct ieee80211softmac_device *sm)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sm->lock, flags);
-
- if (!sm->scanning) {
- spin_unlock_irqrestore(&sm->lock, flags);
- return;
- }
-
- spin_unlock_irqrestore(&sm->lock, flags);
- sm->stop_scan(sm->dev);
-}
-
-void
-ieee80211softmac_wait_for_scan(struct ieee80211softmac_device *sm)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sm->lock, flags);
-
- if (!sm->scanning) {
- spin_unlock_irqrestore(&sm->lock, flags);
- return;
- }
-
- spin_unlock_irqrestore(&sm->lock, flags);
- sm->wait_for_scan(sm->dev);
-}
-
-
-/* internal scanning implementation follows */
-void ieee80211softmac_scan(struct work_struct *work)
-{
- int invalid_channel;
- u8 current_channel_idx;
- struct ieee80211softmac_scaninfo *si =
- container_of(work, struct ieee80211softmac_scaninfo,
- softmac_scan.work);
- struct ieee80211softmac_device *sm = si->mac;
- unsigned long flags;
-
- while (!(si->stop) && (si->current_channel_idx < si->number_channels)) {
- current_channel_idx = si->current_channel_idx;
- si->current_channel_idx++; /* go to the next channel */
-
- invalid_channel = (si->skip_flags & si->channels[current_channel_idx].flags);
-
- if (!invalid_channel) {
- sm->set_channel(sm->dev, si->channels[current_channel_idx].channel);
- // FIXME make this user configurable (active/passive)
- if(ieee80211softmac_send_mgt_frame(sm, NULL, IEEE80211_STYPE_PROBE_REQ, 0))
- printkl(KERN_DEBUG PFX "Sending Probe Request Failed\n");
-
- /* also send directed management frame for the network we're looking for */
- // TODO: is this if correct, or should we do this only if scanning from assoc request?
- if (sm->associnfo.req_essid.len)
- ieee80211softmac_send_mgt_frame(sm, &sm->associnfo.req_essid, IEEE80211_STYPE_PROBE_REQ, 0);
-
- spin_lock_irqsave(&sm->lock, flags);
- if (unlikely(!sm->running)) {
- /* Prevent reschedule on workqueue flush */
- spin_unlock_irqrestore(&sm->lock, flags);
- break;
- }
- queue_delayed_work(sm->wq, &si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);
- spin_unlock_irqrestore(&sm->lock, flags);
- return;
- } else {
- dprintk(PFX "Not probing Channel %d (not allowed here)\n", si->channels[current_channel_idx].channel);
- }
- }
-
- spin_lock_irqsave(&sm->lock, flags);
- cancel_delayed_work(&si->softmac_scan);
- si->started = 0;
- spin_unlock_irqrestore(&sm->lock, flags);
-
- dprintk(PFX "Scanning finished: scanned %d channels starting with channel %d\n",
- sm->scaninfo->number_channels, sm->scaninfo->channels[0].channel);
- ieee80211softmac_scan_finished(sm);
- complete_all(&sm->scaninfo->finished);
-}
-
-static inline struct ieee80211softmac_scaninfo *allocate_scaninfo(struct ieee80211softmac_device *mac)
-{
- /* ugh. can we call this without having the spinlock held? */
- struct ieee80211softmac_scaninfo *info = kmalloc(sizeof(struct ieee80211softmac_scaninfo), GFP_ATOMIC);
- if (unlikely(!info))
- return NULL;
- INIT_DELAYED_WORK(&info->softmac_scan, ieee80211softmac_scan);
- info->mac = mac;
- init_completion(&info->finished);
- return info;
-}
-
-int ieee80211softmac_start_scan_implementation(struct net_device *dev)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(dev);
- unsigned long flags;
-
- if (!(dev->flags & IFF_UP))
- return -ENODEV;
-
- assert(ieee80211softmac_scan_handlers_check_self(sm));
- if (!ieee80211softmac_scan_handlers_check_self(sm))
- return -EINVAL;
-
- spin_lock_irqsave(&sm->lock, flags);
- /* it looks like we need to hold the lock here
- * to make sure we don't allocate two of these... */
- if (unlikely(!sm->scaninfo))
- sm->scaninfo = allocate_scaninfo(sm);
- if (unlikely(!sm->scaninfo)) {
- spin_unlock_irqrestore(&sm->lock, flags);
- return -ENOMEM;
- }
-
- sm->scaninfo->skip_flags = IEEE80211_CH_INVALID;
- if (0 /* not scanning in IEEE802.11b */)//TODO
- sm->scaninfo->skip_flags |= IEEE80211_CH_B_ONLY;
- if (0 /* IEEE802.11a */) {//TODO
- sm->scaninfo->channels = sm->ieee->geo.a;
- sm->scaninfo->number_channels = sm->ieee->geo.a_channels;
- } else {
- sm->scaninfo->channels = sm->ieee->geo.bg;
- sm->scaninfo->number_channels = sm->ieee->geo.bg_channels;
- }
- sm->scaninfo->current_channel_idx = 0;
- sm->scaninfo->started = 1;
- sm->scaninfo->stop = 0;
- INIT_COMPLETION(sm->scaninfo->finished);
- queue_delayed_work(sm->wq, &sm->scaninfo->softmac_scan, 0);
- spin_unlock_irqrestore(&sm->lock, flags);
- return 0;
-}
-
-void ieee80211softmac_stop_scan_implementation(struct net_device *dev)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(dev);
- unsigned long flags;
-
- assert(ieee80211softmac_scan_handlers_check_self(sm));
- if (!ieee80211softmac_scan_handlers_check_self(sm))
- return;
-
- spin_lock_irqsave(&sm->lock, flags);
- assert(sm->scaninfo != NULL);
- if (sm->scaninfo) {
- if (sm->scaninfo->started)
- sm->scaninfo->stop = 1;
- else
- complete_all(&sm->scaninfo->finished);
- }
- spin_unlock_irqrestore(&sm->lock, flags);
-}
-
-void ieee80211softmac_wait_for_scan_implementation(struct net_device *dev)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(dev);
- unsigned long flags;
-
- assert(ieee80211softmac_scan_handlers_check_self(sm));
- if (!ieee80211softmac_scan_handlers_check_self(sm))
- return;
-
- spin_lock_irqsave(&sm->lock, flags);
- if (!sm->scaninfo->started) {
- spin_unlock_irqrestore(&sm->lock, flags);
- return;
- }
- spin_unlock_irqrestore(&sm->lock, flags);
- wait_for_completion(&sm->scaninfo->finished);
-}
-
-/* this is what drivers (that do scanning) call when they're done */
-void ieee80211softmac_scan_finished(struct ieee80211softmac_device *sm)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sm->lock, flags);
- sm->scanning = 0;
- spin_unlock_irqrestore(&sm->lock, flags);
-
- if (sm->associnfo.bssvalid) {
- struct ieee80211softmac_network *net;
-
- net = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
- if (net)
- sm->set_channel(sm->dev, net->channel);
- }
- ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished);
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
deleted file mode 100644
index e01b59aedc54..000000000000
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * This file contains our _wx handlers. Make sure you EXPORT_SYMBOL_GPL them
- *
- * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
- * Joseph Jezak <josejx@gentoo.org>
- * Larry Finger <Larry.Finger@lwfinger.net>
- * Danny van Dyk <kugelfang@gentoo.org>
- * Michael Buesch <mbuesch@freenet.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called COPYING.
- */
-
-#include "ieee80211softmac_priv.h"
-
-#include <net/iw_handler.h>
-/* for is_broadcast_ether_addr and is_zero_ether_addr */
-#include <linux/etherdevice.h>
-
-int
-ieee80211softmac_wx_trigger_scan(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
- return ieee80211softmac_start_scan(sm);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_trigger_scan);
-
-
-/* if we're still scanning, return -EAGAIN so that userspace tools
- * can get the complete scan results, otherwise return 0. */
-int
-ieee80211softmac_wx_get_scan_results(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- unsigned long flags;
- struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
-
- spin_lock_irqsave(&sm->lock, flags);
- if (sm->scanning) {
- spin_unlock_irqrestore(&sm->lock, flags);
- return -EAGAIN;
- }
- spin_unlock_irqrestore(&sm->lock, flags);
- return ieee80211_wx_get_scan(sm->ieee, info, data, extra);
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_scan_results);
-
-int
-ieee80211softmac_wx_set_essid(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
- struct ieee80211softmac_auth_queue_item *authptr;
- int length = 0;
- DECLARE_MAC_BUF(mac);
-
-check_assoc_again:
- mutex_lock(&sm->associnfo.mutex);
- if((sm->associnfo.associating || sm->associnfo.associated) &&
- (data->essid.flags && data->essid.length)) {
- dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
- /* Cancel assoc work */
- cancel_delayed_work(&sm->associnfo.work);
- /* We don't have to do this, but it's a little cleaner */
- list_for_each_entry(authptr, &sm->auth_queue, list)
- cancel_delayed_work(&authptr->work);
- sm->associnfo.bssvalid = 0;
- sm->associnfo.bssfixed = 0;
- sm->associnfo.associating = 0;
- sm->associnfo.associated = 0;
- /* We must unlock to avoid deadlocks with the assoc workqueue
- * on the associnfo.mutex */
- mutex_unlock(&sm->associnfo.mutex);
- flush_workqueue(sm->wq);
- /* Avoid race! Check assoc status again. Maybe someone started an
- * association while we flushed. */
- goto check_assoc_again;
- }
-
- sm->associnfo.static_essid = 0;
- sm->associnfo.assoc_wait = 0;
-
- if (data->essid.flags && data->essid.length) {
- length = min((int)data->essid.length, IW_ESSID_MAX_SIZE);
- if (length) {
- memcpy(sm->associnfo.req_essid.data, extra, length);
- sm->associnfo.static_essid = 1;
- }
- }
-
- /* set our requested ESSID length.
- * If applicable, we have already copied the data in */
- sm->associnfo.req_essid.len = length;
-
- sm->associnfo.associating = 1;
- /* queue lower level code to do work (if necessary) */
- queue_delayed_work(sm->wq, &sm->associnfo.work, 0);
-
- mutex_unlock(&sm->associnfo.mutex);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid);
-
-int
-ieee80211softmac_wx_get_essid(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
-
- mutex_lock(&sm->associnfo.mutex);
- /* If all fails, return ANY (empty) */
- data->essid.length = 0;
- data->essid.flags = 0; /* active */
-
- /* If we have a statically configured ESSID then return it */
- if (sm->associnfo.static_essid) {
- data->essid.length = sm->associnfo.req_essid.len;
- data->essid.flags = 1; /* active */
- memcpy(extra, sm->associnfo.req_essid.data, sm->associnfo.req_essid.len);
- dprintk(KERN_INFO PFX "Getting essid from req_essid\n");
- } else if (sm->associnfo.associated || sm->associnfo.associating) {
- /* If we're associating/associated, return that */
- data->essid.length = sm->associnfo.associate_essid.len;
- data->essid.flags = 1; /* active */
- memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len);
- dprintk(KERN_INFO PFX "Getting essid from associate_essid\n");
- }
- mutex_unlock(&sm->associnfo.mutex);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid);
-
-int
-ieee80211softmac_wx_set_rate(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
- struct ieee80211_device *ieee = mac->ieee;
- unsigned long flags;
- s32 in_rate = data->bitrate.value;
- u8 rate;
- int is_ofdm = 0;
- int err = -EINVAL;
-
- if (in_rate == -1) {
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- in_rate = 24000000;
- else
- in_rate = 11000000;
- }
-
- switch (in_rate) {
- case 1000000:
- rate = IEEE80211_CCK_RATE_1MB;
- break;
- case 2000000:
- rate = IEEE80211_CCK_RATE_2MB;
- break;
- case 5500000:
- rate = IEEE80211_CCK_RATE_5MB;
- break;
- case 11000000:
- rate = IEEE80211_CCK_RATE_11MB;
- break;
- case 6000000:
- rate = IEEE80211_OFDM_RATE_6MB;
- is_ofdm = 1;
- break;
- case 9000000:
- rate = IEEE80211_OFDM_RATE_9MB;
- is_ofdm = 1;
- break;
- case 12000000:
- rate = IEEE80211_OFDM_RATE_12MB;
- is_ofdm = 1;
- break;
- case 18000000:
- rate = IEEE80211_OFDM_RATE_18MB;
- is_ofdm = 1;
- break;
- case 24000000:
- rate = IEEE80211_OFDM_RATE_24MB;
- is_ofdm = 1;
- break;
- case 36000000:
- rate = IEEE80211_OFDM_RATE_36MB;
- is_ofdm = 1;
- break;
- case 48000000:
- rate = IEEE80211_OFDM_RATE_48MB;
- is_ofdm = 1;
- break;
- case 54000000:
- rate = IEEE80211_OFDM_RATE_54MB;
- is_ofdm = 1;
- break;
- default:
- goto out;
- }
-
- spin_lock_irqsave(&mac->lock, flags);
-
- /* Check if correct modulation for this PHY. */
- if (is_ofdm && !(ieee->modulation & IEEE80211_OFDM_MODULATION))
- goto out_unlock;
-
- mac->txrates.user_rate = rate;
- ieee80211softmac_recalc_txrates(mac);
- err = 0;
-
-out_unlock:
- spin_unlock_irqrestore(&mac->lock, flags);
-out:
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_rate);
-
-int
-ieee80211softmac_wx_get_rate(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
- unsigned long flags;
- int err = -EINVAL;
-
- spin_lock_irqsave(&mac->lock, flags);
-
- if (unlikely(!mac->running)) {
- err = -ENODEV;
- goto out_unlock;
- }
-
- switch (mac->txrates.default_rate) {
- case IEEE80211_CCK_RATE_1MB:
- data->bitrate.value = 1000000;
- break;
- case IEEE80211_CCK_RATE_2MB:
- data->bitrate.value = 2000000;
- break;
- case IEEE80211_CCK_RATE_5MB:
- data->bitrate.value = 5500000;
- break;
- case IEEE80211_CCK_RATE_11MB:
- data->bitrate.value = 11000000;
- break;
- case IEEE80211_OFDM_RATE_6MB:
- data->bitrate.value = 6000000;
- break;
- case IEEE80211_OFDM_RATE_9MB:
- data->bitrate.value = 9000000;
- break;
- case IEEE80211_OFDM_RATE_12MB:
- data->bitrate.value = 12000000;
- break;
- case IEEE80211_OFDM_RATE_18MB:
- data->bitrate.value = 18000000;
- break;
- case IEEE80211_OFDM_RATE_24MB:
- data->bitrate.value = 24000000;
- break;
- case IEEE80211_OFDM_RATE_36MB:
- data->bitrate.value = 36000000;
- break;
- case IEEE80211_OFDM_RATE_48MB:
- data->bitrate.value = 48000000;
- break;
- case IEEE80211_OFDM_RATE_54MB:
- data->bitrate.value = 54000000;
- break;
- default:
- assert(0);
- goto out_unlock;
- }
- err = 0;
-out_unlock:
- spin_unlock_irqrestore(&mac->lock, flags);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_rate);
-
-int
-ieee80211softmac_wx_get_wap(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
- int err = 0;
-
- mutex_lock(&mac->associnfo.mutex);
- if (mac->associnfo.bssvalid)
- memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN);
- else
- memset(data->ap_addr.sa_data, 0xff, ETH_ALEN);
- data->ap_addr.sa_family = ARPHRD_ETHER;
- mutex_unlock(&mac->associnfo.mutex);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap);
-
-int
-ieee80211softmac_wx_set_wap(struct net_device *net_dev,
- struct iw_request_info *info,
- union iwreq_data *data,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
-
- /* sanity check */
- if (data->ap_addr.sa_family != ARPHRD_ETHER) {
- return -EINVAL;
- }
-
- mutex_lock(&mac->associnfo.mutex);
- if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
- /* the bssid we have is not to be fixed any longer,
- * and we should reassociate to the best AP. */
- mac->associnfo.bssfixed = 0;
- /* force reassociation */
- mac->associnfo.bssvalid = 0;
- if (mac->associnfo.associated)
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
- } else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
- /* the bssid we have is no longer fixed */
- mac->associnfo.bssfixed = 0;
- } else {
- if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) {
- if (mac->associnfo.associating || mac->associnfo.associated) {
- /* bssid unchanged and associated or associating - just return */
- goto out;
- }
- } else {
- /* copy new value in data->ap_addr.sa_data to bssid */
- memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN);
- }
- /* tell the other code that this bssid should be used no matter what */
- mac->associnfo.bssfixed = 1;
- /* queue associate if new bssid or (old one again and not associated) */
- queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
- }
-
- out:
- mutex_unlock(&mac->associnfo.mutex);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap);
-
-int
-ieee80211softmac_wx_set_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- unsigned long flags;
- int err = 0;
- char *buf;
- int i;
-
- mutex_lock(&mac->associnfo.mutex);
- spin_lock_irqsave(&mac->lock, flags);
- /* bleh. shouldn't be locked for that kmalloc... */
-
- if (wrqu->data.length) {
- if ((wrqu->data.length < 2) || (extra[1]+2 != wrqu->data.length)) {
- /* this is an IE, so the length must be
- * correct. Is it possible though that
- * more than one IE is passed in?
- */
- err = -EINVAL;
- goto out;
- }
- if (mac->wpa.IEbuflen <= wrqu->data.length) {
- buf = kmalloc(wrqu->data.length, GFP_ATOMIC);
- if (!buf) {
- err = -ENOMEM;
- goto out;
- }
- kfree(mac->wpa.IE);
- mac->wpa.IE = buf;
- mac->wpa.IEbuflen = wrqu->data.length;
- }
- memcpy(mac->wpa.IE, extra, wrqu->data.length);
- dprintk(KERN_INFO PFX "generic IE set to ");
- for (i=0;i<wrqu->data.length;i++)
- dprintk("%.2x", (u8)mac->wpa.IE[i]);
- dprintk("\n");
- mac->wpa.IElen = wrqu->data.length;
- } else {
- kfree(mac->wpa.IE);
- mac->wpa.IE = NULL;
- mac->wpa.IElen = 0;
- mac->wpa.IEbuflen = 0;
- }
-
- out:
- spin_unlock_irqrestore(&mac->lock, flags);
- mutex_unlock(&mac->associnfo.mutex);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie);
-
-int
-ieee80211softmac_wx_get_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- unsigned long flags;
- int err = 0;
- int space = wrqu->data.length;
-
- mutex_lock(&mac->associnfo.mutex);
- spin_lock_irqsave(&mac->lock, flags);
-
- wrqu->data.length = 0;
-
- if (mac->wpa.IE && mac->wpa.IElen) {
- wrqu->data.length = mac->wpa.IElen;
- if (mac->wpa.IElen <= space)
- memcpy(extra, mac->wpa.IE, mac->wpa.IElen);
- else
- err = -E2BIG;
- }
- spin_unlock_irqrestore(&mac->lock, flags);
- mutex_unlock(&mac->associnfo.mutex);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie);
-
-int
-ieee80211softmac_wx_set_mlme(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct ieee80211softmac_device *mac = ieee80211_priv(dev);
- struct iw_mlme *mlme = (struct iw_mlme *)extra;
- u16 reason = mlme->reason_code;
- struct ieee80211softmac_network *net;
- int err = -EINVAL;
-
- mutex_lock(&mac->associnfo.mutex);
-
- if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) {
- printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n");
- goto out;
- }
-
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data);
- if (!net) {
- printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
- goto out;
- }
- err = ieee80211softmac_deauth_req(mac, net, reason);
- goto out;
- case IW_MLME_DISASSOC:
- ieee80211softmac_send_disassoc_req(mac, reason);
- mac->associnfo.associated = 0;
- mac->associnfo.associating = 0;
- err = 0;
- goto out;
- default:
- err = -EOPNOTSUPP;
- }
-
-out:
- mutex_unlock(&mac->associnfo.mutex);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 3c3f62faae1e..520a5180a4f6 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -32,15 +32,6 @@ config MAC80211_RC_DEFAULT_PID
default rate control algorithm. You should choose
this unless you know what you are doing.
-config MAC80211_RC_DEFAULT_SIMPLE
- bool "Simple rate control algorithm"
- select MAC80211_RC_SIMPLE
- ---help---
- Select the simple rate control as the default rate
- control algorithm. Note that this is a non-responsive,
- dumb algorithm. You should choose the PID rate control
- instead.
-
config MAC80211_RC_DEFAULT_NONE
bool "No default algorithm"
depends on EMBEDDED
@@ -57,7 +48,6 @@ comment "build the algorithm into mac80211."
config MAC80211_RC_DEFAULT
string
default "pid" if MAC80211_RC_DEFAULT_PID
- default "simple" if MAC80211_RC_DEFAULT_SIMPLE
default ""
config MAC80211_RC_PID
@@ -70,15 +60,6 @@ config MAC80211_RC_PID
Say Y or M unless you're sure you want to use a
different rate control algorithm.
-config MAC80211_RC_SIMPLE
- tristate "Simple rate control algorithm (DEPRECATED)"
- ---help---
- This option enables a very simple, non-responsive TX
- rate control algorithm. This algorithm is deprecated
- and will be removed from the kernel in the near future.
- It has been replaced by the PID algorithm.
-
- Say N unless you know what you are doing.
endmenu
config MAC80211_MESH
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 829ce4256b76..70f4b26c2d87 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -44,9 +44,7 @@ mac80211-$(CONFIG_MAC80211_MESH) += \
# Build rate control algorithm(s)
-CFLAGS_rc80211_simple.o += -DRC80211_SIMPLE_COMPILE
CFLAGS_rc80211_pid_algo.o += -DRC80211_PID_COMPILE
-mac80211-$(CONFIG_MAC80211_RC_SIMPLE) += rc80211_simple.o
mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc-pid-$(CONFIG_MAC80211_RC_PID))
# Modular rate algorithms are assigned to mac80211-m - make separate modules
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 484b063a3538..55b63712e48c 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -1803,13 +1803,9 @@ static int __init ieee80211_init(void)
BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb));
- ret = rc80211_simple_init();
- if (ret)
- goto out;
-
ret = rc80211_pid_init();
if (ret)
- goto out_cleanup_simple;
+ goto out;
ret = ieee80211_wme_register();
if (ret) {
@@ -1824,15 +1820,12 @@ static int __init ieee80211_init(void)
out_cleanup_pid:
rc80211_pid_exit();
- out_cleanup_simple:
- rc80211_simple_exit();
out:
return ret;
}
static void __exit ieee80211_exit(void)
{
- rc80211_simple_exit();
rc80211_pid_exit();
if (mesh_allocated)
diff --git a/net/mac80211/ieee80211_rate.h b/net/mac80211/ieee80211_rate.h
index bfd0a1982e4a..5b45f33cb766 100644
--- a/net/mac80211/ieee80211_rate.h
+++ b/net/mac80211/ieee80211_rate.h
@@ -171,21 +171,6 @@ void rate_control_deinitialize(struct ieee80211_local *local);
/* Rate control algorithms */
-#if defined(RC80211_SIMPLE_COMPILE) || \
- (defined(CONFIG_MAC80211_RC_SIMPLE) && \
- !defined(CONFIG_MAC80211_RC_SIMPLE_MODULE))
-extern int rc80211_simple_init(void);
-extern void rc80211_simple_exit(void);
-#else
-static inline int rc80211_simple_init(void)
-{
- return 0;
-}
-static inline void rc80211_simple_exit(void)
-{
-}
-#endif
-
#if defined(RC80211_PID_COMPILE) || \
(defined(CONFIG_MAC80211_RC_PID) && \
!defined(CONFIG_MAC80211_RC_PID_MODULE))
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c
deleted file mode 100644
index 4f72fdca7f12..000000000000
--- a/net/mac80211/rc80211_simple.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright 2002-2005, Instant802 Networks, Inc.
- * Copyright 2005, Devicescape Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/jiffies.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/skbuff.h>
-#include <linux/compiler.h>
-#include <linux/module.h>
-
-#include <net/mac80211.h>
-#include "ieee80211_i.h"
-#include "ieee80211_rate.h"
-#include "debugfs.h"
-
-
-/* This is a minimal implementation of TX rate controlling that can be used
- * as the default when no improved mechanisms are available. */
-
-#define RATE_CONTROL_NUM_DOWN 20
-#define RATE_CONTROL_NUM_UP 15
-
-#define RATE_CONTROL_EMERG_DEC 2
-#define RATE_CONTROL_INTERVAL (HZ / 20)
-#define RATE_CONTROL_MIN_TX 10
-
-static void rate_control_rate_inc(struct ieee80211_local *local,
- struct sta_info *sta)
-{
- struct ieee80211_sub_if_data *sdata;
- struct ieee80211_supported_band *sband;
- int i = sta->txrate_idx;
- int maxrate;
-
- sdata = sta->sdata;
- if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) {
- /* forced unicast rate - do not change STA rate */
- return;
- }
-
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
- maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1;
-
- if (i > sband->n_bitrates)
- i = sband->n_bitrates - 2;
-
- while (i + 1 < sband->n_bitrates) {
- i++;
- if (rate_supported(sta, sband->band, i) &&
- (maxrate < 0 || i <= maxrate)) {
- sta->txrate_idx = i;
- break;
- }
- }
-}
-
-
-static void rate_control_rate_dec(struct ieee80211_local *local,
- struct sta_info *sta)
-{
- struct ieee80211_sub_if_data *sdata;
- struct ieee80211_supported_band *sband;
- int i = sta->txrate_idx;
-
- sdata = sta->sdata;
- if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) {
- /* forced unicast rate - do not change STA rate */
- return;
- }
-
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
- if (i > sband->n_bitrates)
- i = sband->n_bitrates;
-
- while (i > 0) {
- i--;
- if (rate_supported(sta, sband->band, i)) {
- sta->txrate_idx = i;
- break;
- }
- }
-}
-
-struct global_rate_control {
- int dummy;
-};
-
-struct sta_rate_control {
- unsigned long last_rate_change;
- u32 tx_num_failures;
- u32 tx_num_xmit;
-
- unsigned long avg_rate_update;
- u32 tx_avg_rate_sum;
- u32 tx_avg_rate_num;
-
-#ifdef CONFIG_MAC80211_DEBUGFS
- struct dentry *tx_avg_rate_sum_dentry;
- struct dentry *tx_avg_rate_num_dentry;
-#endif
-};
-
-
-static void rate_control_simple_tx_status(void *priv, struct net_device *dev,
- struct sk_buff *skb,
- struct ieee80211_tx_status *status)
-{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct sta_info *sta;
- struct sta_rate_control *srctrl;
-
- rcu_read_lock();
-
- sta = sta_info_get(local, hdr->addr1);
-
- if (!sta)
- goto unlock;
-
- srctrl = sta->rate_ctrl_priv;
- srctrl->tx_num_xmit++;
- if (status->excessive_retries) {
- srctrl->tx_num_failures++;
- sta->tx_retry_failed++;
- sta->tx_num_consecutive_failures++;
- sta->tx_num_mpdu_fail++;
- } else {
- sta->tx_num_consecutive_failures = 0;
- sta->tx_num_mpdu_ok++;
- }
- sta->tx_retry_count += status->retry_count;
- sta->tx_num_mpdu_fail += status->retry_count;
-
- if (time_after(jiffies,
- srctrl->last_rate_change + RATE_CONTROL_INTERVAL) &&
- srctrl->tx_num_xmit > RATE_CONTROL_MIN_TX) {
- u32 per_failed;
- srctrl->last_rate_change = jiffies;
-
- per_failed = (100 * sta->tx_num_mpdu_fail) /
- (sta->tx_num_mpdu_fail + sta->tx_num_mpdu_ok);
- /* TODO: calculate average per_failed to make adjusting
- * parameters easier */
-#if 0
- if (net_ratelimit()) {
- printk(KERN_DEBUG "MPDU fail=%d ok=%d per_failed=%d\n",
- sta->tx_num_mpdu_fail, sta->tx_num_mpdu_ok,
- per_failed);
- }
-#endif
-
- /*
- * XXX: Make these configurable once we have an
- * interface to the rate control algorithms
- */
- if (per_failed > RATE_CONTROL_NUM_DOWN) {
- rate_control_rate_dec(local, sta);
- } else if (per_failed < RATE_CONTROL_NUM_UP) {
- rate_control_rate_inc(local, sta);
- }
- srctrl->tx_avg_rate_sum += status->control.tx_rate->bitrate;
- srctrl->tx_avg_rate_num++;
- srctrl->tx_num_failures = 0;
- srctrl->tx_num_xmit = 0;
- } else if (sta->tx_num_consecutive_failures >=
- RATE_CONTROL_EMERG_DEC) {
- rate_control_rate_dec(local, sta);
- }
-
- if (time_after(jiffies, srctrl->avg_rate_update + 60 * HZ)) {
- srctrl->avg_rate_update = jiffies;
- if (srctrl->tx_avg_rate_num > 0) {
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- DECLARE_MAC_BUF(mac);
- printk(KERN_DEBUG "%s: STA %s Average rate: "
- "%d (%d/%d)\n",
- dev->name, print_mac(mac, sta->addr),
- srctrl->tx_avg_rate_sum /
- srctrl->tx_avg_rate_num,
- srctrl->tx_avg_rate_sum,
- srctrl->tx_avg_rate_num);
-#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
- srctrl->tx_avg_rate_sum = 0;
- srctrl->tx_avg_rate_num = 0;
- }
- }
-
- unlock:
- rcu_read_unlock();
-}
-
-
-static void
-rate_control_simple_get_rate(void *priv, struct net_device *dev,
- struct ieee80211_supported_band *sband,
- struct sk_buff *skb,
- struct rate_selection *sel)
-{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct ieee80211_sub_if_data *sdata;
- struct sta_info *sta;
- int rateidx;
- u16 fc;
-
- rcu_read_lock();
-
- sta = sta_info_get(local, hdr->addr1);
-
- /* Send management frames and broadcast/multicast data using lowest
- * rate. */
- fc = le16_to_cpu(hdr->frame_control);
- if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
- is_multicast_ether_addr(hdr->addr1) || !sta) {
- sel->rate = rate_lowest(local, sband, sta);
- rcu_read_unlock();
- return;
- }
-
- /* If a forced rate is in effect, select it. */
- sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
- sta->txrate_idx = sdata->bss->force_unicast_rateidx;
-
- rateidx = sta->txrate_idx;
-
- if (rateidx >= sband->n_bitrates)
- rateidx = sband->n_bitrates - 1;
-
- sta->last_txrate_idx = rateidx;
-
- rcu_read_unlock();
-
- sel->rate = &sband->bitrates[rateidx];
-}
-
-
-static void rate_control_simple_rate_init(void *priv, void *priv_sta,
- struct ieee80211_local *local,
- struct sta_info *sta)
-{
- struct ieee80211_supported_band *sband;
-
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
- /* TODO: This routine should consider using RSSI from previous packets
- * as we need to have IEEE 802.1X auth succeed immediately after assoc..
- * Until that method is implemented, we will use the lowest supported rate
- * as a workaround, */
- sta->txrate_idx = rate_lowest_index(local, sband, sta);
-}
-
-
-static void * rate_control_simple_alloc(struct ieee80211_local *local)
-{
- struct global_rate_control *rctrl;
-
- rctrl = kzalloc(sizeof(*rctrl), GFP_ATOMIC);
-
- return rctrl;
-}
-
-
-static void rate_control_simple_free(void *priv)
-{
- struct global_rate_control *rctrl = priv;
- kfree(rctrl);
-}
-
-
-static void rate_control_simple_clear(void *priv)
-{
-}
-
-
-static void * rate_control_simple_alloc_sta(void *priv, gfp_t gfp)
-{
- struct sta_rate_control *rctrl;
-
- rctrl = kzalloc(sizeof(*rctrl), gfp);
-
- return rctrl;
-}
-
-
-static void rate_control_simple_free_sta(void *priv, void *priv_sta)
-{
- struct sta_rate_control *rctrl = priv_sta;
- kfree(rctrl);
-}
-
-#ifdef CONFIG_MAC80211_DEBUGFS
-
-static int open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-static ssize_t sta_tx_avg_rate_sum_read(struct file *file,
- char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct sta_rate_control *srctrl = file->private_data;
- char buf[20];
-
- sprintf(buf, "%d\n", srctrl->tx_avg_rate_sum);
- return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
-}
-
-static const struct file_operations sta_tx_avg_rate_sum_ops = {
- .read = sta_tx_avg_rate_sum_read,
- .open = open_file_generic,
-};
-
-static ssize_t sta_tx_avg_rate_num_read(struct file *file,
- char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct sta_rate_control *srctrl = file->private_data;
- char buf[20];
-
- sprintf(buf, "%d\n", srctrl->tx_avg_rate_num);
- return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
-}
-
-static const struct file_operations sta_tx_avg_rate_num_ops = {
- .read = sta_tx_avg_rate_num_read,
- .open = open_file_generic,
-};
-
-static void rate_control_simple_add_sta_debugfs(void *priv, void *priv_sta,
- struct dentry *dir)
-{
- struct sta_rate_control *srctrl = priv_sta;
-
- srctrl->tx_avg_rate_num_dentry =
- debugfs_create_file("rc_simple_sta_tx_avg_rate_num", 0400,
- dir, srctrl, &sta_tx_avg_rate_num_ops);
- srctrl->tx_avg_rate_sum_dentry =
- debugfs_create_file("rc_simple_sta_tx_avg_rate_sum", 0400,
- dir, srctrl, &sta_tx_avg_rate_sum_ops);
-}
-
-static void rate_control_simple_remove_sta_debugfs(void *priv, void *priv_sta)
-{
- struct sta_rate_control *srctrl = priv_sta;
-
- debugfs_remove(srctrl->tx_avg_rate_sum_dentry);
- debugfs_remove(srctrl->tx_avg_rate_num_dentry);
-}
-#endif
-
-static struct rate_control_ops mac80211_rcsimple = {
- .name = "simple",
- .tx_status = rate_control_simple_tx_status,
- .get_rate = rate_control_simple_get_rate,
- .rate_init = rate_control_simple_rate_init,
- .clear = rate_control_simple_clear,
- .alloc = rate_control_simple_alloc,
- .free = rate_control_simple_free,
- .alloc_sta = rate_control_simple_alloc_sta,
- .free_sta = rate_control_simple_free_sta,
-#ifdef CONFIG_MAC80211_DEBUGFS
- .add_sta_debugfs = rate_control_simple_add_sta_debugfs,
- .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs,
-#endif
-};
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Simple rate control algorithm");
-
-int __init rc80211_simple_init(void)
-{
- return ieee80211_rate_control_register(&mac80211_rcsimple);
-}
-
-void rc80211_simple_exit(void)
-{
- ieee80211_rate_control_unregister(&mac80211_rcsimple);
-}
-
-#ifdef CONFIG_MAC80211_RC_SIMPLE_MODULE
-module_init(rc80211_simple_init);
-module_exit(rc80211_simple_exit);
-#endif