Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
commit
6c0bce37ff
|
@ -50,10 +50,6 @@ associates with the AP. hostapd and wpa_supplicant are used to take
|
||||||
care of WPA2-PSK authentication. In addition, hostapd is also
|
care of WPA2-PSK authentication. In addition, hostapd is also
|
||||||
processing access point side of association.
|
processing access point side of association.
|
||||||
|
|
||||||
Please note that the current Linux kernel does not enable AP mode, so a
|
|
||||||
simple patch is needed to enable AP mode selection:
|
|
||||||
http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch
|
|
||||||
|
|
||||||
|
|
||||||
# Build mac80211_hwsim as part of kernel configuration
|
# Build mac80211_hwsim as part of kernel configuration
|
||||||
|
|
||||||
|
@ -65,3 +61,8 @@ hostapd hostapd.conf
|
||||||
|
|
||||||
# Run wpa_supplicant (station) for wlan1
|
# Run wpa_supplicant (station) for wlan1
|
||||||
wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf
|
wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf
|
||||||
|
|
||||||
|
|
||||||
|
More test cases are available in hostap.git:
|
||||||
|
git://w1.fi/srv/git/hostap.git and mac80211_hwsim/tests subdirectory
|
||||||
|
(http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=tree;f=mac80211_hwsim/tests)
|
||||||
|
|
22
MAINTAINERS
22
MAINTAINERS
|
@ -3608,16 +3608,26 @@ L: linux-hams@vger.kernel.org
|
||||||
W: http://www.linux-ax25.org/
|
W: http://www.linux-ax25.org/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
RTL818X WIRELESS DRIVER
|
RTL8180 WIRELESS DRIVER
|
||||||
P: Michael Wu
|
P: John W. Linville
|
||||||
M: flamingice@sourmilk.net
|
M: linville@tuxdriver.com
|
||||||
P: Andrea Merello
|
|
||||||
M: andreamrl@tiscali.it
|
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
W: http://linuxwireless.org/
|
W: http://linuxwireless.org/
|
||||||
T: git kernel.org:/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git
|
T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-testing.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
RTL8187 WIRELESS DRIVER
|
||||||
|
P: Herton Ronaldo Krzesinski
|
||||||
|
M: herton@mandriva.com.br
|
||||||
|
P: Hin-Tak Leung
|
||||||
|
M htl10@users.sourceforge.net
|
||||||
|
P: Larry Finger
|
||||||
|
M: Larry.Finger@lwfinger.net
|
||||||
|
L: linux-wireless@vger.kernel.org
|
||||||
|
W: http://linuxwireless.org/
|
||||||
|
T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-testing.git
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
S3 SAVAGE FRAMEBUFFER DRIVER
|
S3 SAVAGE FRAMEBUFFER DRIVER
|
||||||
P: Antonino Daplas
|
P: Antonino Daplas
|
||||||
M: adaplas@gmail.com
|
M: adaplas@gmail.com
|
||||||
|
|
|
@ -123,150 +123,6 @@ config PCMCIA_RAYCS
|
||||||
To compile this driver as a module, choose M here: the module will be
|
To compile this driver as a module, choose M here: the module will be
|
||||||
called ray_cs. If unsure, say N.
|
called ray_cs. If unsure, say N.
|
||||||
|
|
||||||
config IPW2100
|
|
||||||
tristate "Intel PRO/Wireless 2100 Network Connection"
|
|
||||||
depends on PCI && WLAN_80211
|
|
||||||
select WIRELESS_EXT
|
|
||||||
select FW_LOADER
|
|
||||||
select IEEE80211
|
|
||||||
---help---
|
|
||||||
A driver for the Intel PRO/Wireless 2100 Network
|
|
||||||
Connection 802.11b wireless network adapter.
|
|
||||||
|
|
||||||
See <file:Documentation/networking/README.ipw2100> for information on
|
|
||||||
the capabilities currently enabled in this driver and for tips
|
|
||||||
for debugging issues and problems.
|
|
||||||
|
|
||||||
In order to use this driver, you will need a firmware image for it.
|
|
||||||
You can obtain the firmware from
|
|
||||||
<http://ipw2100.sf.net/>. Once you have the firmware image, you
|
|
||||||
will need to place it in /lib/firmware.
|
|
||||||
|
|
||||||
You will also very likely need the Wireless Tools in order to
|
|
||||||
configure your card:
|
|
||||||
|
|
||||||
<http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
|
|
||||||
|
|
||||||
It is recommended that you compile this driver as a module (M)
|
|
||||||
rather than built-in (Y). This driver requires firmware at device
|
|
||||||
initialization time, and when built-in this typically happens
|
|
||||||
before the filesystem is accessible (hence firmware will be
|
|
||||||
unavailable and initialization will fail). If you do choose to build
|
|
||||||
this driver into your kernel image, you can avoid this problem by
|
|
||||||
including the firmware and a firmware loader in an initramfs.
|
|
||||||
|
|
||||||
config IPW2100_MONITOR
|
|
||||||
bool "Enable promiscuous mode"
|
|
||||||
depends on IPW2100
|
|
||||||
---help---
|
|
||||||
Enables promiscuous/monitor mode support for the ipw2100 driver.
|
|
||||||
With this feature compiled into the driver, you can switch to
|
|
||||||
promiscuous mode via the Wireless Tool's Monitor mode. While in this
|
|
||||||
mode, no packets can be sent.
|
|
||||||
|
|
||||||
config IPW2100_DEBUG
|
|
||||||
bool "Enable full debugging output in IPW2100 module."
|
|
||||||
depends on IPW2100
|
|
||||||
---help---
|
|
||||||
This option will enable debug tracing output for the IPW2100.
|
|
||||||
|
|
||||||
This will result in the kernel module being ~60k larger. You can
|
|
||||||
control which debug output is sent to the kernel log by setting the
|
|
||||||
value in
|
|
||||||
|
|
||||||
/sys/bus/pci/drivers/ipw2100/debug_level
|
|
||||||
|
|
||||||
This entry will only exist if this option is enabled.
|
|
||||||
|
|
||||||
If you are not trying to debug or develop the IPW2100 driver, you
|
|
||||||
most likely want to say N here.
|
|
||||||
|
|
||||||
config IPW2200
|
|
||||||
tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
|
|
||||||
depends on PCI && WLAN_80211
|
|
||||||
select WIRELESS_EXT
|
|
||||||
select FW_LOADER
|
|
||||||
select IEEE80211
|
|
||||||
---help---
|
|
||||||
A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
|
|
||||||
Connection adapters.
|
|
||||||
|
|
||||||
See <file:Documentation/networking/README.ipw2200> for
|
|
||||||
information on the capabilities currently enabled in this
|
|
||||||
driver and for tips for debugging issues and problems.
|
|
||||||
|
|
||||||
In order to use this driver, you will need a firmware image for it.
|
|
||||||
You can obtain the firmware from
|
|
||||||
<http://ipw2200.sf.net/>. See the above referenced README.ipw2200
|
|
||||||
for information on where to install the firmware images.
|
|
||||||
|
|
||||||
You will also very likely need the Wireless Tools in order to
|
|
||||||
configure your card:
|
|
||||||
|
|
||||||
<http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
|
|
||||||
|
|
||||||
It is recommended that you compile this driver as a module (M)
|
|
||||||
rather than built-in (Y). This driver requires firmware at device
|
|
||||||
initialization time, and when built-in this typically happens
|
|
||||||
before the filesystem is accessible (hence firmware will be
|
|
||||||
unavailable and initialization will fail). If you do choose to build
|
|
||||||
this driver into your kernel image, you can avoid this problem by
|
|
||||||
including the firmware and a firmware loader in an initramfs.
|
|
||||||
|
|
||||||
config IPW2200_MONITOR
|
|
||||||
bool "Enable promiscuous mode"
|
|
||||||
depends on IPW2200
|
|
||||||
---help---
|
|
||||||
Enables promiscuous/monitor mode support for the ipw2200 driver.
|
|
||||||
With this feature compiled into the driver, you can switch to
|
|
||||||
promiscuous mode via the Wireless Tool's Monitor mode. While in this
|
|
||||||
mode, no packets can be sent.
|
|
||||||
|
|
||||||
config IPW2200_RADIOTAP
|
|
||||||
bool "Enable radiotap format 802.11 raw packet support"
|
|
||||||
depends on IPW2200_MONITOR
|
|
||||||
|
|
||||||
config IPW2200_PROMISCUOUS
|
|
||||||
bool "Enable creation of a RF radiotap promiscuous interface"
|
|
||||||
depends on IPW2200_MONITOR
|
|
||||||
select IPW2200_RADIOTAP
|
|
||||||
---help---
|
|
||||||
Enables the creation of a second interface prefixed 'rtap'.
|
|
||||||
This second interface will provide every received in radiotap
|
|
||||||
format.
|
|
||||||
|
|
||||||
This is useful for performing wireless network analysis while
|
|
||||||
maintaining an active association.
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
|
|
||||||
% modprobe ipw2200 rtap_iface=1
|
|
||||||
% ifconfig rtap0 up
|
|
||||||
% tethereal -i rtap0
|
|
||||||
|
|
||||||
If you do not specify 'rtap_iface=1' as a module parameter then
|
|
||||||
the rtap interface will not be created and you will need to turn
|
|
||||||
it on via sysfs:
|
|
||||||
|
|
||||||
% echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
|
|
||||||
|
|
||||||
config IPW2200_QOS
|
|
||||||
bool "Enable QoS support"
|
|
||||||
depends on IPW2200 && EXPERIMENTAL
|
|
||||||
|
|
||||||
config IPW2200_DEBUG
|
|
||||||
bool "Enable full debugging output in IPW2200 module."
|
|
||||||
depends on IPW2200
|
|
||||||
---help---
|
|
||||||
This option will enable low level debug tracing output for IPW2200.
|
|
||||||
|
|
||||||
Note, normal debug code is already compiled in. This low level
|
|
||||||
debug option enables debug on hot paths (e.g Tx, Rx, ISR) and
|
|
||||||
will result in the kernel module being ~70 larger. Most users
|
|
||||||
will typically not need this high verbosity debug information.
|
|
||||||
|
|
||||||
If you are not sure, say N here.
|
|
||||||
|
|
||||||
config LIBERTAS
|
config LIBERTAS
|
||||||
tristate "Marvell 8xxx Libertas WLAN driver support"
|
tristate "Marvell 8xxx Libertas WLAN driver support"
|
||||||
depends on WLAN_80211
|
depends on WLAN_80211
|
||||||
|
@ -712,6 +568,7 @@ config MAC80211_HWSIM
|
||||||
source "drivers/net/wireless/p54/Kconfig"
|
source "drivers/net/wireless/p54/Kconfig"
|
||||||
source "drivers/net/wireless/ath5k/Kconfig"
|
source "drivers/net/wireless/ath5k/Kconfig"
|
||||||
source "drivers/net/wireless/ath9k/Kconfig"
|
source "drivers/net/wireless/ath9k/Kconfig"
|
||||||
|
source "drivers/net/wireless/ipw2x00/Kconfig"
|
||||||
source "drivers/net/wireless/iwlwifi/Kconfig"
|
source "drivers/net/wireless/iwlwifi/Kconfig"
|
||||||
source "drivers/net/wireless/hostap/Kconfig"
|
source "drivers/net/wireless/hostap/Kconfig"
|
||||||
source "drivers/net/wireless/b43/Kconfig"
|
source "drivers/net/wireless/b43/Kconfig"
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
# Makefile for the Linux Wireless network device drivers.
|
# Makefile for the Linux Wireless network device drivers.
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-$(CONFIG_IPW2100) += ipw2100.o
|
obj-$(CONFIG_IPW2100) += ipw2x00/
|
||||||
|
obj-$(CONFIG_IPW2200) += ipw2x00/
|
||||||
obj-$(CONFIG_IPW2200) += ipw2200.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_STRIP) += strip.o
|
obj-$(CONFIG_STRIP) += strip.o
|
||||||
obj-$(CONFIG_ARLAN) += arlan.o
|
obj-$(CONFIG_ARLAN) += arlan.o
|
||||||
|
@ -31,6 +30,8 @@ obj-$(CONFIG_HOSTAP) += hostap/
|
||||||
obj-$(CONFIG_B43) += b43/
|
obj-$(CONFIG_B43) += b43/
|
||||||
obj-$(CONFIG_B43LEGACY) += b43legacy/
|
obj-$(CONFIG_B43LEGACY) += b43legacy/
|
||||||
obj-$(CONFIG_ZD1211RW) += zd1211rw/
|
obj-$(CONFIG_ZD1211RW) += zd1211rw/
|
||||||
|
obj-$(CONFIG_RTL8180) += rtl818x/
|
||||||
|
obj-$(CONFIG_RTL8187) += rtl818x/
|
||||||
|
|
||||||
# 16-bit wireless PCMCIA client drivers
|
# 16-bit wireless PCMCIA client drivers
|
||||||
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
|
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
|
||||||
|
@ -43,12 +44,6 @@ obj-$(CONFIG_LIBERTAS) += libertas/
|
||||||
|
|
||||||
obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/
|
obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/
|
||||||
|
|
||||||
rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
|
|
||||||
rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_RTL8180) += rtl8180.o
|
|
||||||
obj-$(CONFIG_RTL8187) += rtl8187.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_ADM8211) += adm8211.o
|
obj-$(CONFIG_ADM8211) += adm8211.o
|
||||||
|
|
||||||
obj-$(CONFIG_IWLWIFI) += iwlwifi/
|
obj-$(CONFIG_IWLWIFI) += iwlwifi/
|
||||||
|
|
|
@ -2219,9 +2219,9 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume)
|
||||||
*/
|
*/
|
||||||
sc->curchan = sc->hw->conf.channel;
|
sc->curchan = sc->hw->conf.channel;
|
||||||
sc->curband = &sc->sbands[sc->curchan->band];
|
sc->curband = &sc->sbands[sc->curchan->band];
|
||||||
sc->imask = AR5K_INT_RXOK | AR5K_INT_TXOK | AR5K_INT_RXEOL |
|
sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
|
||||||
AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL |
|
AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
|
||||||
AR5K_INT_MIB;
|
AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
|
||||||
ret = ath5k_reset(sc, false, false);
|
ret = ath5k_reset(sc, false, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -2953,9 +2953,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
|
||||||
test_bit(ATH_STAT_PROMISC, sc->status))
|
test_bit(ATH_STAT_PROMISC, sc->status))
|
||||||
rfilt |= AR5K_RX_FILTER_PROM;
|
rfilt |= AR5K_RX_FILTER_PROM;
|
||||||
if (sc->opmode == NL80211_IFTYPE_STATION ||
|
if (sc->opmode == NL80211_IFTYPE_STATION ||
|
||||||
sc->opmode == NL80211_IFTYPE_ADHOC) {
|
sc->opmode == NL80211_IFTYPE_ADHOC ||
|
||||||
|
sc->opmode == NL80211_IFTYPE_AP)
|
||||||
rfilt |= AR5K_RX_FILTER_BEACON;
|
rfilt |= AR5K_RX_FILTER_BEACON;
|
||||||
}
|
|
||||||
if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
|
if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
|
||||||
rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
|
rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
|
||||||
AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
|
AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
|
||||||
|
|
|
@ -2196,9 +2196,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Re-enable RX/TX and beacons
|
* Re-enable RX/TX and beacons
|
||||||
|
|
|
@ -842,9 +842,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
|
||||||
*
|
*
|
||||||
* XXX: Find an interval that's OK for all cards...
|
* XXX: Find an interval that's OK for all cards...
|
||||||
*/
|
*/
|
||||||
ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset queues and start beacon timers at the end of the reset routine
|
* Reset queues and start beacon timers at the end of the reset routine
|
||||||
|
|
|
@ -382,8 +382,9 @@ static const char *ath9k_hw_devname(u16 devid)
|
||||||
{
|
{
|
||||||
switch (devid) {
|
switch (devid) {
|
||||||
case AR5416_DEVID_PCI:
|
case AR5416_DEVID_PCI:
|
||||||
case AR5416_DEVID_PCIE:
|
|
||||||
return "Atheros 5416";
|
return "Atheros 5416";
|
||||||
|
case AR5416_DEVID_PCIE:
|
||||||
|
return "Atheros 5418";
|
||||||
case AR9160_DEVID_PCI:
|
case AR9160_DEVID_PCI:
|
||||||
return "Atheros 9160";
|
return "Atheros 9160";
|
||||||
case AR9280_DEVID_PCI:
|
case AR9280_DEVID_PCI:
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <linux/nl80211.h>
|
#include <linux/nl80211.h>
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
#include "reg.h"
|
||||||
|
|
||||||
#define ATH_PCI_VERSION "0.1"
|
#define ATH_PCI_VERSION "0.1"
|
||||||
|
|
||||||
|
@ -1519,15 +1520,74 @@ static struct ieee80211_ops ath9k_ops = {
|
||||||
.set_frag_threshold = ath9k_no_fragmentation,
|
.set_frag_threshold = ath9k_no_fragmentation,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
u32 version;
|
||||||
|
const char * name;
|
||||||
|
} ath_mac_bb_names[] = {
|
||||||
|
{ AR_SREV_VERSION_5416_PCI, "5416" },
|
||||||
|
{ AR_SREV_VERSION_5416_PCIE, "5418" },
|
||||||
|
{ AR_SREV_VERSION_9100, "9100" },
|
||||||
|
{ AR_SREV_VERSION_9160, "9160" },
|
||||||
|
{ AR_SREV_VERSION_9280, "9280" },
|
||||||
|
{ AR_SREV_VERSION_9285, "9285" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
u16 version;
|
||||||
|
const char * name;
|
||||||
|
} ath_rf_names[] = {
|
||||||
|
{ 0, "5133" },
|
||||||
|
{ AR_RAD5133_SREV_MAJOR, "5133" },
|
||||||
|
{ AR_RAD5122_SREV_MAJOR, "5122" },
|
||||||
|
{ AR_RAD2133_SREV_MAJOR, "2133" },
|
||||||
|
{ AR_RAD2122_SREV_MAJOR, "2122" }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
ath_mac_bb_name(u32 mac_bb_version)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
|
||||||
|
if (ath_mac_bb_names[i].version == mac_bb_version) {
|
||||||
|
return ath_mac_bb_names[i].name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "????";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the RF name. "????" is returned if the RF is unknown.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
ath_rf_name(u16 rf_version)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
|
||||||
|
if (ath_rf_names[i].version == rf_version) {
|
||||||
|
return ath_rf_names[i].name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "????";
|
||||||
|
}
|
||||||
|
|
||||||
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
void __iomem *mem;
|
void __iomem *mem;
|
||||||
struct ath_softc *sc;
|
struct ath_softc *sc;
|
||||||
struct ieee80211_hw *hw;
|
struct ieee80211_hw *hw;
|
||||||
const char *athname;
|
|
||||||
u8 csz;
|
u8 csz;
|
||||||
u32 val;
|
u32 val;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
struct ath_hal *ah;
|
||||||
|
|
||||||
if (pci_enable_device(pdev))
|
if (pci_enable_device(pdev))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
@ -1614,11 +1674,15 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
goto bad4;
|
goto bad4;
|
||||||
}
|
}
|
||||||
|
|
||||||
athname = ath9k_hw_probe(id->vendor, id->device);
|
ah = sc->sc_ah;
|
||||||
|
printk(KERN_INFO
|
||||||
printk(KERN_INFO "%s: %s: mem=0x%lx, irq=%d\n",
|
"%s: Atheros AR%s MAC/BB Rev:%x "
|
||||||
|
"AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
|
||||||
wiphy_name(hw->wiphy),
|
wiphy_name(hw->wiphy),
|
||||||
athname ? athname : "Atheros ???",
|
ath_mac_bb_name(ah->ah_macVersion),
|
||||||
|
ah->ah_macRev,
|
||||||
|
ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
|
||||||
|
ah->ah_phyRev,
|
||||||
(unsigned long)mem, pdev->irq);
|
(unsigned long)mem, pdev->irq);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1272,8 +1272,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
|
||||||
rate_ctrl->state[tx_rate].per = 100;
|
rate_ctrl->state[tx_rate].per = 100;
|
||||||
} else {
|
} else {
|
||||||
/* xretries == 2 */
|
/* xretries == 2 */
|
||||||
count = sizeof(nretry_to_per_lookup) /
|
count = ARRAY_SIZE(nretry_to_per_lookup);
|
||||||
sizeof(nretry_to_per_lookup[0]);
|
|
||||||
if (retries >= count)
|
if (retries >= count)
|
||||||
retries = count - 1;
|
retries = count - 1;
|
||||||
/* new_PER = 7/8*old_PER + 1/8*(currentPER) */
|
/* new_PER = 7/8*old_PER + 1/8*(currentPER) */
|
||||||
|
@ -1291,8 +1290,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
|
||||||
} else { /* xretries == 0 */
|
} else { /* xretries == 0 */
|
||||||
/* Update the PER. */
|
/* Update the PER. */
|
||||||
/* Make sure it doesn't index out of array's bounds. */
|
/* Make sure it doesn't index out of array's bounds. */
|
||||||
count = sizeof(nretry_to_per_lookup) /
|
count = ARRAY_SIZE(nretry_to_per_lookup);
|
||||||
sizeof(nretry_to_per_lookup[0]);
|
|
||||||
if (retries >= count)
|
if (retries >= count)
|
||||||
retries = count - 1;
|
retries = count - 1;
|
||||||
if (info_priv->n_bad_frames) {
|
if (info_priv->n_bad_frames) {
|
||||||
|
|
|
@ -296,9 +296,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
|
||||||
rfilt &= ~ATH9K_RX_FILTER_UCAST;
|
rfilt &= ~ATH9K_RX_FILTER_UCAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((sc->sc_ah->ah_opmode == ATH9K_M_STA) &&
|
if (sc->sc_ah->ah_opmode == ATH9K_M_STA ||
|
||||||
(sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)) ||
|
sc->sc_ah->ah_opmode == ATH9K_M_IBSS)
|
||||||
(sc->sc_ah->ah_opmode == ATH9K_M_IBSS))
|
|
||||||
rfilt |= ATH9K_RX_FILTER_BEACON;
|
rfilt |= ATH9K_RX_FILTER_BEACON;
|
||||||
|
|
||||||
/* If in HOSTAP mode, want to enable reception of PSPOLL frames
|
/* If in HOSTAP mode, want to enable reception of PSPOLL frames
|
||||||
|
|
|
@ -46,7 +46,6 @@ static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
|
||||||
case 0x6E:
|
case 0x6E:
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
B43_WARN_ON(1);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +72,6 @@ static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
|
||||||
case 0xC:
|
case 0xC:
|
||||||
return base + 7;
|
return base + 7;
|
||||||
}
|
}
|
||||||
B43_WARN_ON(1);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,6 +606,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
||||||
phytype == B43_PHYTYPE_A);
|
phytype == B43_PHYTYPE_A);
|
||||||
else
|
else
|
||||||
status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
|
status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
|
||||||
|
if (unlikely(status.rate_idx == -1))
|
||||||
|
goto drop;
|
||||||
status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
|
status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -145,6 +145,10 @@
|
||||||
#define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */
|
#define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */
|
||||||
#define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */
|
#define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */
|
||||||
/* SHM_SHARED rate tables */
|
/* SHM_SHARED rate tables */
|
||||||
|
#define B43legacy_SHM_SH_OFDMDIRECT 0x0480 /* Pointer to OFDM direct map */
|
||||||
|
#define B43legacy_SHM_SH_OFDMBASIC 0x04A0 /* Pointer to OFDM basic rate map */
|
||||||
|
#define B43legacy_SHM_SH_CCKDIRECT 0x04C0 /* Pointer to CCK direct map */
|
||||||
|
#define B43legacy_SHM_SH_CCKBASIC 0x04E0 /* Pointer to CCK basic rate map */
|
||||||
/* SHM_SHARED microcode soft registers */
|
/* SHM_SHARED microcode soft registers */
|
||||||
#define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */
|
#define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */
|
||||||
#define B43legacy_SHM_SH_UCODEPATCH 0x0002 /* Microcode patchlevel */
|
#define B43legacy_SHM_SH_UCODEPATCH 0x0002 /* Microcode patchlevel */
|
||||||
|
@ -663,7 +667,6 @@ struct b43legacy_wldev {
|
||||||
bool bad_frames_preempt;/* Use "Bad Frames Preemption". */
|
bool bad_frames_preempt;/* Use "Bad Frames Preemption". */
|
||||||
bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM). */
|
bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM). */
|
||||||
bool short_preamble; /* TRUE if using short preamble. */
|
bool short_preamble; /* TRUE if using short preamble. */
|
||||||
bool short_slot; /* TRUE if using short slot timing. */
|
|
||||||
bool radio_hw_enable; /* State of radio hardware enable bit. */
|
bool radio_hw_enable; /* State of radio hardware enable bit. */
|
||||||
|
|
||||||
/* PHY/Radio device. */
|
/* PHY/Radio device. */
|
||||||
|
|
|
@ -576,13 +576,11 @@ static void b43legacy_set_slot_time(struct b43legacy_wldev *dev,
|
||||||
static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev)
|
static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev)
|
||||||
{
|
{
|
||||||
b43legacy_set_slot_time(dev, 9);
|
b43legacy_set_slot_time(dev, 9);
|
||||||
dev->short_slot = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
|
static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
|
||||||
{
|
{
|
||||||
b43legacy_set_slot_time(dev, 20);
|
b43legacy_set_slot_time(dev, 20);
|
||||||
dev->short_slot = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
|
/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
|
||||||
|
@ -2608,16 +2606,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
|
||||||
if (conf->channel->hw_value != phy->channel)
|
if (conf->channel->hw_value != phy->channel)
|
||||||
b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
|
b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
|
||||||
|
|
||||||
/* Enable/Disable ShortSlot timing. */
|
|
||||||
if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME))
|
|
||||||
!= dev->short_slot) {
|
|
||||||
B43legacy_WARN_ON(phy->type != B43legacy_PHYTYPE_G);
|
|
||||||
if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)
|
|
||||||
b43legacy_short_slot_timing_enable(dev);
|
|
||||||
else
|
|
||||||
b43legacy_short_slot_timing_disable(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
|
dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
|
||||||
|
|
||||||
/* Adjust the desired TX power level. */
|
/* Adjust the desired TX power level. */
|
||||||
|
@ -2662,6 +2650,104 @@ out_unlock_mutex:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u64 brates)
|
||||||
|
{
|
||||||
|
struct ieee80211_supported_band *sband =
|
||||||
|
dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
|
||||||
|
struct ieee80211_rate *rate;
|
||||||
|
int i;
|
||||||
|
u16 basic, direct, offset, basic_offset, rateptr;
|
||||||
|
|
||||||
|
for (i = 0; i < sband->n_bitrates; i++) {
|
||||||
|
rate = &sband->bitrates[i];
|
||||||
|
|
||||||
|
if (b43legacy_is_cck_rate(rate->hw_value)) {
|
||||||
|
direct = B43legacy_SHM_SH_CCKDIRECT;
|
||||||
|
basic = B43legacy_SHM_SH_CCKBASIC;
|
||||||
|
offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
|
||||||
|
offset &= 0xF;
|
||||||
|
} else {
|
||||||
|
direct = B43legacy_SHM_SH_OFDMDIRECT;
|
||||||
|
basic = B43legacy_SHM_SH_OFDMBASIC;
|
||||||
|
offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
|
||||||
|
offset &= 0xF;
|
||||||
|
}
|
||||||
|
|
||||||
|
rate = ieee80211_get_response_rate(sband, brates, rate->bitrate);
|
||||||
|
|
||||||
|
if (b43legacy_is_cck_rate(rate->hw_value)) {
|
||||||
|
basic_offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
|
||||||
|
basic_offset &= 0xF;
|
||||||
|
} else {
|
||||||
|
basic_offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
|
||||||
|
basic_offset &= 0xF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the pointer that we need to point to
|
||||||
|
* from the direct map
|
||||||
|
*/
|
||||||
|
rateptr = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
|
||||||
|
direct + 2 * basic_offset);
|
||||||
|
/* and write it to the basic map */
|
||||||
|
b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
|
||||||
|
basic + 2 * offset, rateptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
|
||||||
|
struct ieee80211_vif *vif,
|
||||||
|
struct ieee80211_bss_conf *conf,
|
||||||
|
u32 changed)
|
||||||
|
{
|
||||||
|
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
|
||||||
|
struct b43legacy_wldev *dev;
|
||||||
|
struct b43legacy_phy *phy;
|
||||||
|
unsigned long flags;
|
||||||
|
u32 savedirqs;
|
||||||
|
|
||||||
|
mutex_lock(&wl->mutex);
|
||||||
|
|
||||||
|
dev = wl->current_dev;
|
||||||
|
phy = &dev->phy;
|
||||||
|
|
||||||
|
/* Disable IRQs while reconfiguring the device.
|
||||||
|
* This makes it possible to drop the spinlock throughout
|
||||||
|
* the reconfiguration process. */
|
||||||
|
spin_lock_irqsave(&wl->irq_lock, flags);
|
||||||
|
if (b43legacy_status(dev) < B43legacy_STAT_STARTED) {
|
||||||
|
spin_unlock_irqrestore(&wl->irq_lock, flags);
|
||||||
|
goto out_unlock_mutex;
|
||||||
|
}
|
||||||
|
savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
|
||||||
|
spin_unlock_irqrestore(&wl->irq_lock, flags);
|
||||||
|
b43legacy_synchronize_irq(dev);
|
||||||
|
|
||||||
|
b43legacy_mac_suspend(dev);
|
||||||
|
|
||||||
|
if (changed & BSS_CHANGED_BASIC_RATES)
|
||||||
|
b43legacy_update_basic_rates(dev, conf->basic_rates);
|
||||||
|
|
||||||
|
if (changed & BSS_CHANGED_ERP_SLOT) {
|
||||||
|
if (conf->use_short_slot)
|
||||||
|
b43legacy_short_slot_timing_enable(dev);
|
||||||
|
else
|
||||||
|
b43legacy_short_slot_timing_disable(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
b43legacy_mac_enable(dev);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&wl->irq_lock, flags);
|
||||||
|
b43legacy_interrupt_enable(dev, savedirqs);
|
||||||
|
/* XXX: why? */
|
||||||
|
mmiowb();
|
||||||
|
spin_unlock_irqrestore(&wl->irq_lock, flags);
|
||||||
|
out_unlock_mutex:
|
||||||
|
mutex_unlock(&wl->mutex);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
|
static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
|
||||||
unsigned int changed,
|
unsigned int changed,
|
||||||
unsigned int *fflags,
|
unsigned int *fflags,
|
||||||
|
@ -3370,6 +3456,7 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
|
||||||
.add_interface = b43legacy_op_add_interface,
|
.add_interface = b43legacy_op_add_interface,
|
||||||
.remove_interface = b43legacy_op_remove_interface,
|
.remove_interface = b43legacy_op_remove_interface,
|
||||||
.config = b43legacy_op_dev_config,
|
.config = b43legacy_op_dev_config,
|
||||||
|
.bss_info_changed = b43legacy_op_bss_info_changed,
|
||||||
.config_interface = b43legacy_op_config_interface,
|
.config_interface = b43legacy_op_config_interface,
|
||||||
.configure_filter = b43legacy_op_configure_filter,
|
.configure_filter = b43legacy_op_configure_filter,
|
||||||
.get_stats = b43legacy_op_get_stats,
|
.get_stats = b43legacy_op_get_stats,
|
||||||
|
|
|
@ -2,8 +2,10 @@ config HOSTAP
|
||||||
tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)"
|
tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)"
|
||||||
depends on WLAN_80211
|
depends on WLAN_80211
|
||||||
select WIRELESS_EXT
|
select WIRELESS_EXT
|
||||||
select IEEE80211
|
select LIB80211
|
||||||
select IEEE80211_CRYPT_WEP
|
select LIB80211_CRYPT_WEP
|
||||||
|
select LIB80211_CRYPT_TKIP
|
||||||
|
select LIB80211_CRYPT_CCMP
|
||||||
---help---
|
---help---
|
||||||
Shared driver code for IEEE 802.11b wireless cards based on
|
Shared driver code for IEEE 802.11b wireless cards based on
|
||||||
Intersil Prism2/2.5/3 chipset. This driver supports so called
|
Intersil Prism2/2.5/3 chipset. This driver supports so called
|
||||||
|
|
|
@ -63,7 +63,7 @@ void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
|
||||||
int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac);
|
int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac);
|
||||||
void ap_control_kickall(struct ap_data *ap);
|
void ap_control_kickall(struct ap_data *ap);
|
||||||
void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
|
void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
|
||||||
struct ieee80211_crypt_data ***crypt);
|
struct lib80211_crypt_data ***crypt);
|
||||||
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
|
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
|
||||||
struct iw_quality qual[], int buf_size,
|
struct iw_quality qual[], int buf_size,
|
||||||
int aplist);
|
int aplist);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define HOSTAP_80211_H
|
#define HOSTAP_80211_H
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <net/ieee80211_crypt.h>
|
#include <net/ieee80211.h>
|
||||||
|
|
||||||
struct hostap_ieee80211_mgmt {
|
struct hostap_ieee80211_mgmt {
|
||||||
__le16 frame_control;
|
__le16 frame_control;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <net/ieee80211_crypt.h>
|
#include <net/lib80211.h>
|
||||||
|
|
||||||
#include "hostap_80211.h"
|
#include "hostap_80211.h"
|
||||||
#include "hostap.h"
|
#include "hostap.h"
|
||||||
|
@ -649,7 +649,7 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
|
||||||
/* Called only as a tasklet (software IRQ) */
|
/* Called only as a tasklet (software IRQ) */
|
||||||
static int
|
static int
|
||||||
hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
|
hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
|
||||||
struct ieee80211_crypt_data *crypt)
|
struct lib80211_crypt_data *crypt)
|
||||||
{
|
{
|
||||||
struct ieee80211_hdr_4addr *hdr;
|
struct ieee80211_hdr_4addr *hdr;
|
||||||
int res, hdrlen;
|
int res, hdrlen;
|
||||||
|
@ -687,7 +687,7 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
|
||||||
/* Called only as a tasklet (software IRQ) */
|
/* Called only as a tasklet (software IRQ) */
|
||||||
static int
|
static int
|
||||||
hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
|
hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
|
||||||
int keyidx, struct ieee80211_crypt_data *crypt)
|
int keyidx, struct lib80211_crypt_data *crypt)
|
||||||
{
|
{
|
||||||
struct ieee80211_hdr_4addr *hdr;
|
struct ieee80211_hdr_4addr *hdr;
|
||||||
int res, hdrlen;
|
int res, hdrlen;
|
||||||
|
@ -733,7 +733,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
|
||||||
int from_assoc_ap = 0;
|
int from_assoc_ap = 0;
|
||||||
u8 dst[ETH_ALEN];
|
u8 dst[ETH_ALEN];
|
||||||
u8 src[ETH_ALEN];
|
u8 src[ETH_ALEN];
|
||||||
struct ieee80211_crypt_data *crypt = NULL;
|
struct lib80211_crypt_data *crypt = NULL;
|
||||||
void *sta = NULL;
|
void *sta = NULL;
|
||||||
int keyidx = 0;
|
int keyidx = 0;
|
||||||
|
|
||||||
|
@ -785,7 +785,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
if (skb->len >= hdrlen + 3)
|
if (skb->len >= hdrlen + 3)
|
||||||
idx = skb->data[hdrlen + 3] >> 6;
|
idx = skb->data[hdrlen + 3] >> 6;
|
||||||
crypt = local->crypt[idx];
|
crypt = local->crypt_info.crypt[idx];
|
||||||
sta = NULL;
|
sta = NULL;
|
||||||
|
|
||||||
/* Use station specific key to override default keys if the
|
/* Use station specific key to override default keys if the
|
||||||
|
|
|
@ -306,7 +306,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
/* Called only from software IRQ */
|
/* Called only from software IRQ */
|
||||||
static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
|
static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
|
||||||
struct ieee80211_crypt_data *crypt)
|
struct lib80211_crypt_data *crypt)
|
||||||
{
|
{
|
||||||
struct hostap_interface *iface;
|
struct hostap_interface *iface;
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
|
@ -405,7 +405,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
if (local->host_encrypt) {
|
if (local->host_encrypt) {
|
||||||
/* Set crypt to default algorithm and key; will be replaced in
|
/* Set crypt to default algorithm and key; will be replaced in
|
||||||
* AP code if STA has own alg/key */
|
* AP code if STA has own alg/key */
|
||||||
tx.crypt = local->crypt[local->tx_keyidx];
|
tx.crypt = local->crypt_info.crypt[local->crypt_info.tx_keyidx];
|
||||||
tx.host_encrypt = 1;
|
tx.host_encrypt = 1;
|
||||||
} else {
|
} else {
|
||||||
tx.crypt = NULL;
|
tx.crypt = NULL;
|
||||||
|
@ -487,7 +487,9 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu))
|
if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu))
|
||||||
tx.crypt = NULL;
|
tx.crypt = NULL;
|
||||||
else if ((tx.crypt || local->crypt[local->tx_keyidx]) && !no_encrypt) {
|
else if ((tx.crypt ||
|
||||||
|
local->crypt_info.crypt[local->crypt_info.tx_keyidx]) &&
|
||||||
|
!no_encrypt) {
|
||||||
/* Add ISWEP flag both for firmware and host based encryption
|
/* Add ISWEP flag both for firmware and host based encryption
|
||||||
*/
|
*/
|
||||||
fc |= IEEE80211_FCTL_PROTECTED;
|
fc |= IEEE80211_FCTL_PROTECTED;
|
||||||
|
|
|
@ -1206,7 +1206,7 @@ static void prism2_check_tx_rates(struct sta_info *sta)
|
||||||
|
|
||||||
static void ap_crypt_init(struct ap_data *ap)
|
static void ap_crypt_init(struct ap_data *ap)
|
||||||
{
|
{
|
||||||
ap->crypt = ieee80211_get_crypto_ops("WEP");
|
ap->crypt = lib80211_get_crypto_ops("WEP");
|
||||||
|
|
||||||
if (ap->crypt) {
|
if (ap->crypt) {
|
||||||
if (ap->crypt->init) {
|
if (ap->crypt->init) {
|
||||||
|
@ -1224,7 +1224,7 @@ static void ap_crypt_init(struct ap_data *ap)
|
||||||
|
|
||||||
if (ap->crypt == NULL) {
|
if (ap->crypt == NULL) {
|
||||||
printk(KERN_WARNING "AP could not initialize WEP: load module "
|
printk(KERN_WARNING "AP could not initialize WEP: load module "
|
||||||
"ieee80211_crypt_wep.ko\n");
|
"lib80211_crypt_wep.ko\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1293,7 +1293,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
|
||||||
__le16 *pos;
|
__le16 *pos;
|
||||||
u16 resp = WLAN_STATUS_SUCCESS, fc;
|
u16 resp = WLAN_STATUS_SUCCESS, fc;
|
||||||
struct sta_info *sta = NULL;
|
struct sta_info *sta = NULL;
|
||||||
struct ieee80211_crypt_data *crypt;
|
struct lib80211_crypt_data *crypt;
|
||||||
char *txt = "";
|
char *txt = "";
|
||||||
|
|
||||||
len = skb->len - IEEE80211_MGMT_HDR_LEN;
|
len = skb->len - IEEE80211_MGMT_HDR_LEN;
|
||||||
|
@ -1319,7 +1319,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
if (skb->len >= hdrlen + 3)
|
if (skb->len >= hdrlen + 3)
|
||||||
idx = skb->data[hdrlen + 3] >> 6;
|
idx = skb->data[hdrlen + 3] >> 6;
|
||||||
crypt = local->crypt[idx];
|
crypt = local->crypt_info.crypt[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
|
pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
|
||||||
|
@ -3065,7 +3065,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
|
||||||
/* Called only as a tasklet (software IRQ) */
|
/* Called only as a tasklet (software IRQ) */
|
||||||
int hostap_handle_sta_crypto(local_info_t *local,
|
int hostap_handle_sta_crypto(local_info_t *local,
|
||||||
struct ieee80211_hdr_4addr *hdr,
|
struct ieee80211_hdr_4addr *hdr,
|
||||||
struct ieee80211_crypt_data **crypt,
|
struct lib80211_crypt_data **crypt,
|
||||||
void **sta_ptr)
|
void **sta_ptr)
|
||||||
{
|
{
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
|
@ -3213,7 +3213,7 @@ void hostap_update_rates(local_info_t *local)
|
||||||
|
|
||||||
|
|
||||||
void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
|
void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
|
||||||
struct ieee80211_crypt_data ***crypt)
|
struct lib80211_crypt_data ***crypt)
|
||||||
{
|
{
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ struct sta_info {
|
||||||
u32 tx_since_last_failure;
|
u32 tx_since_last_failure;
|
||||||
u32 tx_consecutive_exc;
|
u32 tx_consecutive_exc;
|
||||||
|
|
||||||
struct ieee80211_crypt_data *crypt;
|
struct lib80211_crypt_data *crypt;
|
||||||
|
|
||||||
int ap; /* whether this station is an AP */
|
int ap; /* whether this station is an AP */
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ struct ap_data {
|
||||||
|
|
||||||
/* WEP operations for generating challenges to be used with shared key
|
/* WEP operations for generating challenges to be used with shared key
|
||||||
* authentication */
|
* authentication */
|
||||||
struct ieee80211_crypto_ops *crypt;
|
struct lib80211_crypto_ops *crypt;
|
||||||
void *crypt_priv;
|
void *crypt_priv;
|
||||||
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
|
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
|
||||||
};
|
};
|
||||||
|
@ -229,7 +229,7 @@ typedef enum {
|
||||||
struct hostap_tx_data {
|
struct hostap_tx_data {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int host_encrypt;
|
int host_encrypt;
|
||||||
struct ieee80211_crypt_data *crypt;
|
struct lib80211_crypt_data *crypt;
|
||||||
void *sta_ptr;
|
void *sta_ptr;
|
||||||
};
|
};
|
||||||
ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
|
ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
|
||||||
|
@ -244,7 +244,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
|
||||||
struct hostap_80211_rx_status *rx_stats,
|
struct hostap_80211_rx_status *rx_stats,
|
||||||
int wds);
|
int wds);
|
||||||
int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
|
int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
|
||||||
struct ieee80211_crypt_data **crypt,
|
struct lib80211_crypt_data **crypt,
|
||||||
void **sta_ptr);
|
void **sta_ptr);
|
||||||
int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
|
int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
|
||||||
int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
|
int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
#include <linux/wireless.h>
|
#include <linux/wireless.h>
|
||||||
#include <net/iw_handler.h>
|
#include <net/iw_handler.h>
|
||||||
#include <net/ieee80211.h>
|
#include <net/ieee80211.h>
|
||||||
#include <net/ieee80211_crypt.h>
|
#include <net/lib80211.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
||||||
#include "hostap_80211.h"
|
#include "hostap_80211.h"
|
||||||
|
@ -2788,45 +2788,6 @@ static void prism2_check_sta_fw_version(local_info_t *local)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void prism2_crypt_deinit_entries(local_info_t *local, int force)
|
|
||||||
{
|
|
||||||
struct list_head *ptr, *n;
|
|
||||||
struct ieee80211_crypt_data *entry;
|
|
||||||
|
|
||||||
for (ptr = local->crypt_deinit_list.next, n = ptr->next;
|
|
||||||
ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) {
|
|
||||||
entry = list_entry(ptr, struct ieee80211_crypt_data, list);
|
|
||||||
|
|
||||||
if (atomic_read(&entry->refcnt) != 0 && !force)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
list_del(ptr);
|
|
||||||
|
|
||||||
if (entry->ops)
|
|
||||||
entry->ops->deinit(entry->priv);
|
|
||||||
kfree(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void prism2_crypt_deinit_handler(unsigned long data)
|
|
||||||
{
|
|
||||||
local_info_t *local = (local_info_t *) data;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&local->lock, flags);
|
|
||||||
prism2_crypt_deinit_entries(local, 0);
|
|
||||||
if (!list_empty(&local->crypt_deinit_list)) {
|
|
||||||
printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
|
|
||||||
"deletion list\n", local->dev->name);
|
|
||||||
local->crypt_deinit_timer.expires = jiffies + HZ;
|
|
||||||
add_timer(&local->crypt_deinit_timer);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&local->lock, flags);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void hostap_passive_scan(unsigned long data)
|
static void hostap_passive_scan(unsigned long data)
|
||||||
{
|
{
|
||||||
local_info_t *local = (local_info_t *) data;
|
local_info_t *local = (local_info_t *) data;
|
||||||
|
@ -3250,10 +3211,8 @@ while (0)
|
||||||
|
|
||||||
INIT_LIST_HEAD(&local->cmd_queue);
|
INIT_LIST_HEAD(&local->cmd_queue);
|
||||||
init_waitqueue_head(&local->hostscan_wq);
|
init_waitqueue_head(&local->hostscan_wq);
|
||||||
INIT_LIST_HEAD(&local->crypt_deinit_list);
|
|
||||||
init_timer(&local->crypt_deinit_timer);
|
lib80211_crypt_info_init(&local->crypt_info, dev->name, &local->lock);
|
||||||
local->crypt_deinit_timer.data = (unsigned long) local;
|
|
||||||
local->crypt_deinit_timer.function = prism2_crypt_deinit_handler;
|
|
||||||
|
|
||||||
init_timer(&local->passive_scan_timer);
|
init_timer(&local->passive_scan_timer);
|
||||||
local->passive_scan_timer.data = (unsigned long) local;
|
local->passive_scan_timer.data = (unsigned long) local;
|
||||||
|
@ -3354,9 +3313,7 @@ static void prism2_free_local_data(struct net_device *dev)
|
||||||
|
|
||||||
flush_scheduled_work();
|
flush_scheduled_work();
|
||||||
|
|
||||||
if (timer_pending(&local->crypt_deinit_timer))
|
lib80211_crypt_info_free(&local->crypt_info);
|
||||||
del_timer(&local->crypt_deinit_timer);
|
|
||||||
prism2_crypt_deinit_entries(local, 1);
|
|
||||||
|
|
||||||
if (timer_pending(&local->passive_scan_timer))
|
if (timer_pending(&local->passive_scan_timer))
|
||||||
del_timer(&local->passive_scan_timer);
|
del_timer(&local->passive_scan_timer);
|
||||||
|
@ -3373,16 +3330,6 @@ static void prism2_free_local_data(struct net_device *dev)
|
||||||
if (local->dev_enabled)
|
if (local->dev_enabled)
|
||||||
prism2_callback(local, PRISM2_CALLBACK_DISABLE);
|
prism2_callback(local, PRISM2_CALLBACK_DISABLE);
|
||||||
|
|
||||||
for (i = 0; i < WEP_KEYS; i++) {
|
|
||||||
struct ieee80211_crypt_data *crypt = local->crypt[i];
|
|
||||||
if (crypt) {
|
|
||||||
if (crypt->ops)
|
|
||||||
crypt->ops->deinit(crypt->priv);
|
|
||||||
kfree(crypt);
|
|
||||||
local->crypt[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (local->ap != NULL)
|
if (local->ap != NULL)
|
||||||
hostap_free_data(local->ap);
|
hostap_free_data(local->ap);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
#include <net/ieee80211_crypt.h>
|
#include <net/lib80211.h>
|
||||||
|
|
||||||
#include "hostap_wlan.h"
|
#include "hostap_wlan.h"
|
||||||
#include "hostap.h"
|
#include "hostap.h"
|
||||||
|
@ -116,32 +116,6 @@ static int prism2_get_name(struct net_device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void prism2_crypt_delayed_deinit(local_info_t *local,
|
|
||||||
struct ieee80211_crypt_data **crypt)
|
|
||||||
{
|
|
||||||
struct ieee80211_crypt_data *tmp;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
tmp = *crypt;
|
|
||||||
*crypt = NULL;
|
|
||||||
|
|
||||||
if (tmp == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* must not run ops->deinit() while there may be pending encrypt or
|
|
||||||
* decrypt operations. Use a list of delayed deinits to avoid needing
|
|
||||||
* locking. */
|
|
||||||
|
|
||||||
spin_lock_irqsave(&local->lock, flags);
|
|
||||||
list_add(&tmp->list, &local->crypt_deinit_list);
|
|
||||||
if (!timer_pending(&local->crypt_deinit_timer)) {
|
|
||||||
local->crypt_deinit_timer.expires = jiffies + HZ;
|
|
||||||
add_timer(&local->crypt_deinit_timer);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&local->lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int prism2_ioctl_siwencode(struct net_device *dev,
|
static int prism2_ioctl_siwencode(struct net_device *dev,
|
||||||
struct iw_request_info *info,
|
struct iw_request_info *info,
|
||||||
struct iw_point *erq, char *keybuf)
|
struct iw_point *erq, char *keybuf)
|
||||||
|
@ -149,47 +123,47 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
|
||||||
struct hostap_interface *iface;
|
struct hostap_interface *iface;
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
int i;
|
int i;
|
||||||
struct ieee80211_crypt_data **crypt;
|
struct lib80211_crypt_data **crypt;
|
||||||
|
|
||||||
iface = netdev_priv(dev);
|
iface = netdev_priv(dev);
|
||||||
local = iface->local;
|
local = iface->local;
|
||||||
|
|
||||||
i = erq->flags & IW_ENCODE_INDEX;
|
i = erq->flags & IW_ENCODE_INDEX;
|
||||||
if (i < 1 || i > 4)
|
if (i < 1 || i > 4)
|
||||||
i = local->tx_keyidx;
|
i = local->crypt_info.tx_keyidx;
|
||||||
else
|
else
|
||||||
i--;
|
i--;
|
||||||
if (i < 0 || i >= WEP_KEYS)
|
if (i < 0 || i >= WEP_KEYS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
crypt = &local->crypt[i];
|
crypt = &local->crypt_info.crypt[i];
|
||||||
|
|
||||||
if (erq->flags & IW_ENCODE_DISABLED) {
|
if (erq->flags & IW_ENCODE_DISABLED) {
|
||||||
if (*crypt)
|
if (*crypt)
|
||||||
prism2_crypt_delayed_deinit(local, crypt);
|
lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*crypt != NULL && (*crypt)->ops != NULL &&
|
if (*crypt != NULL && (*crypt)->ops != NULL &&
|
||||||
strcmp((*crypt)->ops->name, "WEP") != 0) {
|
strcmp((*crypt)->ops->name, "WEP") != 0) {
|
||||||
/* changing to use WEP; deinit previously used algorithm */
|
/* changing to use WEP; deinit previously used algorithm */
|
||||||
prism2_crypt_delayed_deinit(local, crypt);
|
lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*crypt == NULL) {
|
if (*crypt == NULL) {
|
||||||
struct ieee80211_crypt_data *new_crypt;
|
struct lib80211_crypt_data *new_crypt;
|
||||||
|
|
||||||
/* take WEP into use */
|
/* take WEP into use */
|
||||||
new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
|
new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (new_crypt == NULL)
|
if (new_crypt == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
|
new_crypt->ops = lib80211_get_crypto_ops("WEP");
|
||||||
if (!new_crypt->ops) {
|
if (!new_crypt->ops) {
|
||||||
request_module("ieee80211_crypt_wep");
|
request_module("lib80211_crypt_wep");
|
||||||
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
|
new_crypt->ops = lib80211_get_crypto_ops("WEP");
|
||||||
}
|
}
|
||||||
if (new_crypt->ops)
|
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
|
||||||
new_crypt->priv = new_crypt->ops->init(i);
|
new_crypt->priv = new_crypt->ops->init(i);
|
||||||
if (!new_crypt->ops || !new_crypt->priv) {
|
if (!new_crypt->ops || !new_crypt->priv) {
|
||||||
kfree(new_crypt);
|
kfree(new_crypt);
|
||||||
|
@ -210,16 +184,16 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
|
||||||
memset(keybuf + erq->length, 0, len - erq->length);
|
memset(keybuf + erq->length, 0, len - erq->length);
|
||||||
(*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);
|
(*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);
|
||||||
for (j = 0; j < WEP_KEYS; j++) {
|
for (j = 0; j < WEP_KEYS; j++) {
|
||||||
if (j != i && local->crypt[j]) {
|
if (j != i && local->crypt_info.crypt[j]) {
|
||||||
first = 0;
|
first = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (first)
|
if (first)
|
||||||
local->tx_keyidx = i;
|
local->crypt_info.tx_keyidx = i;
|
||||||
} else {
|
} else {
|
||||||
/* No key data - just set the default TX key index */
|
/* No key data - just set the default TX key index */
|
||||||
local->tx_keyidx = i;
|
local->crypt_info.tx_keyidx = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -252,20 +226,20 @@ static int prism2_ioctl_giwencode(struct net_device *dev,
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
int i, len;
|
int i, len;
|
||||||
u16 val;
|
u16 val;
|
||||||
struct ieee80211_crypt_data *crypt;
|
struct lib80211_crypt_data *crypt;
|
||||||
|
|
||||||
iface = netdev_priv(dev);
|
iface = netdev_priv(dev);
|
||||||
local = iface->local;
|
local = iface->local;
|
||||||
|
|
||||||
i = erq->flags & IW_ENCODE_INDEX;
|
i = erq->flags & IW_ENCODE_INDEX;
|
||||||
if (i < 1 || i > 4)
|
if (i < 1 || i > 4)
|
||||||
i = local->tx_keyidx;
|
i = local->crypt_info.tx_keyidx;
|
||||||
else
|
else
|
||||||
i--;
|
i--;
|
||||||
if (i < 0 || i >= WEP_KEYS)
|
if (i < 0 || i >= WEP_KEYS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
crypt = local->crypt[i];
|
crypt = local->crypt_info.crypt[i];
|
||||||
erq->flags = i + 1;
|
erq->flags = i + 1;
|
||||||
|
|
||||||
if (crypt == NULL || crypt->ops == NULL) {
|
if (crypt == NULL || crypt->ops == NULL) {
|
||||||
|
@ -3227,8 +3201,8 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||||
local_info_t *local = iface->local;
|
local_info_t *local = iface->local;
|
||||||
struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
|
struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
struct ieee80211_crypto_ops *ops;
|
struct lib80211_crypto_ops *ops;
|
||||||
struct ieee80211_crypt_data **crypt;
|
struct lib80211_crypt_data **crypt;
|
||||||
void *sta_ptr;
|
void *sta_ptr;
|
||||||
u8 *addr;
|
u8 *addr;
|
||||||
const char *alg, *module;
|
const char *alg, *module;
|
||||||
|
@ -3237,7 +3211,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||||
if (i > WEP_KEYS)
|
if (i > WEP_KEYS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (i < 1 || i > WEP_KEYS)
|
if (i < 1 || i > WEP_KEYS)
|
||||||
i = local->tx_keyidx;
|
i = local->crypt_info.tx_keyidx;
|
||||||
else
|
else
|
||||||
i--;
|
i--;
|
||||||
if (i < 0 || i >= WEP_KEYS)
|
if (i < 0 || i >= WEP_KEYS)
|
||||||
|
@ -3247,7 +3221,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||||
if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
|
if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
|
||||||
addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
|
addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
|
||||||
sta_ptr = NULL;
|
sta_ptr = NULL;
|
||||||
crypt = &local->crypt[i];
|
crypt = &local->crypt_info.crypt[i];
|
||||||
} else {
|
} else {
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -3260,7 +3234,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||||
* is emulated by using default key idx 0.
|
* is emulated by using default key idx 0.
|
||||||
*/
|
*/
|
||||||
i = 0;
|
i = 0;
|
||||||
crypt = &local->crypt[i];
|
crypt = &local->crypt_info.crypt[i];
|
||||||
} else
|
} else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -3269,22 +3243,22 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||||
if ((erq->flags & IW_ENCODE_DISABLED) ||
|
if ((erq->flags & IW_ENCODE_DISABLED) ||
|
||||||
ext->alg == IW_ENCODE_ALG_NONE) {
|
ext->alg == IW_ENCODE_ALG_NONE) {
|
||||||
if (*crypt)
|
if (*crypt)
|
||||||
prism2_crypt_delayed_deinit(local, crypt);
|
lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ext->alg) {
|
switch (ext->alg) {
|
||||||
case IW_ENCODE_ALG_WEP:
|
case IW_ENCODE_ALG_WEP:
|
||||||
alg = "WEP";
|
alg = "WEP";
|
||||||
module = "ieee80211_crypt_wep";
|
module = "lib80211_crypt_wep";
|
||||||
break;
|
break;
|
||||||
case IW_ENCODE_ALG_TKIP:
|
case IW_ENCODE_ALG_TKIP:
|
||||||
alg = "TKIP";
|
alg = "TKIP";
|
||||||
module = "ieee80211_crypt_tkip";
|
module = "lib80211_crypt_tkip";
|
||||||
break;
|
break;
|
||||||
case IW_ENCODE_ALG_CCMP:
|
case IW_ENCODE_ALG_CCMP:
|
||||||
alg = "CCMP";
|
alg = "CCMP";
|
||||||
module = "ieee80211_crypt_ccmp";
|
module = "lib80211_crypt_ccmp";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk(KERN_DEBUG "%s: unsupported algorithm %d\n",
|
printk(KERN_DEBUG "%s: unsupported algorithm %d\n",
|
||||||
|
@ -3293,10 +3267,10 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ops = ieee80211_get_crypto_ops(alg);
|
ops = lib80211_get_crypto_ops(alg);
|
||||||
if (ops == NULL) {
|
if (ops == NULL) {
|
||||||
request_module(module);
|
request_module(module);
|
||||||
ops = ieee80211_get_crypto_ops(alg);
|
ops = lib80211_get_crypto_ops(alg);
|
||||||
}
|
}
|
||||||
if (ops == NULL) {
|
if (ops == NULL) {
|
||||||
printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
|
printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
|
||||||
|
@ -3315,18 +3289,19 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*crypt == NULL || (*crypt)->ops != ops) {
|
if (*crypt == NULL || (*crypt)->ops != ops) {
|
||||||
struct ieee80211_crypt_data *new_crypt;
|
struct lib80211_crypt_data *new_crypt;
|
||||||
|
|
||||||
prism2_crypt_delayed_deinit(local, crypt);
|
lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
|
||||||
|
|
||||||
new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
|
new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (new_crypt == NULL) {
|
if (new_crypt == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
new_crypt->ops = ops;
|
new_crypt->ops = ops;
|
||||||
new_crypt->priv = new_crypt->ops->init(i);
|
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
|
||||||
|
new_crypt->priv = new_crypt->ops->init(i);
|
||||||
if (new_crypt->priv == NULL) {
|
if (new_crypt->priv == NULL) {
|
||||||
kfree(new_crypt);
|
kfree(new_crypt);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -3354,20 +3329,20 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||||
|
|
||||||
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
|
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
|
||||||
if (!sta_ptr)
|
if (!sta_ptr)
|
||||||
local->tx_keyidx = i;
|
local->crypt_info.tx_keyidx = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (sta_ptr == NULL && ext->key_len > 0) {
|
if (sta_ptr == NULL && ext->key_len > 0) {
|
||||||
int first = 1, j;
|
int first = 1, j;
|
||||||
for (j = 0; j < WEP_KEYS; j++) {
|
for (j = 0; j < WEP_KEYS; j++) {
|
||||||
if (j != i && local->crypt[j]) {
|
if (j != i && local->crypt_info.crypt[j]) {
|
||||||
first = 0;
|
first = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (first)
|
if (first)
|
||||||
local->tx_keyidx = i;
|
local->crypt_info.tx_keyidx = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -3399,7 +3374,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
|
||||||
{
|
{
|
||||||
struct hostap_interface *iface = netdev_priv(dev);
|
struct hostap_interface *iface = netdev_priv(dev);
|
||||||
local_info_t *local = iface->local;
|
local_info_t *local = iface->local;
|
||||||
struct ieee80211_crypt_data **crypt;
|
struct lib80211_crypt_data **crypt;
|
||||||
void *sta_ptr;
|
void *sta_ptr;
|
||||||
int max_key_len, i;
|
int max_key_len, i;
|
||||||
struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
|
struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
|
||||||
|
@ -3411,7 +3386,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
|
||||||
|
|
||||||
i = erq->flags & IW_ENCODE_INDEX;
|
i = erq->flags & IW_ENCODE_INDEX;
|
||||||
if (i < 1 || i > WEP_KEYS)
|
if (i < 1 || i > WEP_KEYS)
|
||||||
i = local->tx_keyidx;
|
i = local->crypt_info.tx_keyidx;
|
||||||
else
|
else
|
||||||
i--;
|
i--;
|
||||||
|
|
||||||
|
@ -3419,7 +3394,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
|
||||||
if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
|
if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
|
||||||
addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
|
addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
|
||||||
sta_ptr = NULL;
|
sta_ptr = NULL;
|
||||||
crypt = &local->crypt[i];
|
crypt = &local->crypt_info.crypt[i];
|
||||||
} else {
|
} else {
|
||||||
i = 0;
|
i = 0;
|
||||||
sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
|
sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
|
||||||
|
@ -3468,8 +3443,8 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
|
||||||
int param_len)
|
int param_len)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct ieee80211_crypto_ops *ops;
|
struct lib80211_crypto_ops *ops;
|
||||||
struct ieee80211_crypt_data **crypt;
|
struct lib80211_crypt_data **crypt;
|
||||||
void *sta_ptr;
|
void *sta_ptr;
|
||||||
|
|
||||||
param->u.crypt.err = 0;
|
param->u.crypt.err = 0;
|
||||||
|
@ -3486,7 +3461,7 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
|
||||||
if (param->u.crypt.idx >= WEP_KEYS)
|
if (param->u.crypt.idx >= WEP_KEYS)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
sta_ptr = NULL;
|
sta_ptr = NULL;
|
||||||
crypt = &local->crypt[param->u.crypt.idx];
|
crypt = &local->crypt_info.crypt[param->u.crypt.idx];
|
||||||
} else {
|
} else {
|
||||||
if (param->u.crypt.idx)
|
if (param->u.crypt.idx)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -3503,20 +3478,20 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
|
||||||
|
|
||||||
if (strcmp(param->u.crypt.alg, "none") == 0) {
|
if (strcmp(param->u.crypt.alg, "none") == 0) {
|
||||||
if (crypt)
|
if (crypt)
|
||||||
prism2_crypt_delayed_deinit(local, crypt);
|
lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
|
ops = lib80211_get_crypto_ops(param->u.crypt.alg);
|
||||||
if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
|
if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
|
||||||
request_module("ieee80211_crypt_wep");
|
request_module("lib80211_crypt_wep");
|
||||||
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
|
ops = lib80211_get_crypto_ops(param->u.crypt.alg);
|
||||||
} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
|
} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
|
||||||
request_module("ieee80211_crypt_tkip");
|
request_module("lib80211_crypt_tkip");
|
||||||
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
|
ops = lib80211_get_crypto_ops(param->u.crypt.alg);
|
||||||
} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
|
} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
|
||||||
request_module("ieee80211_crypt_ccmp");
|
request_module("lib80211_crypt_ccmp");
|
||||||
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
|
ops = lib80211_get_crypto_ops(param->u.crypt.alg);
|
||||||
}
|
}
|
||||||
if (ops == NULL) {
|
if (ops == NULL) {
|
||||||
printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
|
printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
|
||||||
|
@ -3531,11 +3506,11 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
|
||||||
local->host_decrypt = local->host_encrypt = 1;
|
local->host_decrypt = local->host_encrypt = 1;
|
||||||
|
|
||||||
if (*crypt == NULL || (*crypt)->ops != ops) {
|
if (*crypt == NULL || (*crypt)->ops != ops) {
|
||||||
struct ieee80211_crypt_data *new_crypt;
|
struct lib80211_crypt_data *new_crypt;
|
||||||
|
|
||||||
prism2_crypt_delayed_deinit(local, crypt);
|
lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
|
||||||
|
|
||||||
new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
|
new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (new_crypt == NULL) {
|
if (new_crypt == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
@ -3568,7 +3543,7 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
|
||||||
|
|
||||||
if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
|
if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
|
||||||
if (!sta_ptr)
|
if (!sta_ptr)
|
||||||
local->tx_keyidx = param->u.crypt.idx;
|
local->crypt_info.tx_keyidx = param->u.crypt.idx;
|
||||||
else if (param->u.crypt.idx) {
|
else if (param->u.crypt.idx) {
|
||||||
printk(KERN_DEBUG "%s: TX key idx setting failed\n",
|
printk(KERN_DEBUG "%s: TX key idx setting failed\n",
|
||||||
local->dev->name);
|
local->dev->name);
|
||||||
|
@ -3604,7 +3579,7 @@ static int prism2_ioctl_get_encryption(local_info_t *local,
|
||||||
struct prism2_hostapd_param *param,
|
struct prism2_hostapd_param *param,
|
||||||
int param_len)
|
int param_len)
|
||||||
{
|
{
|
||||||
struct ieee80211_crypt_data **crypt;
|
struct lib80211_crypt_data **crypt;
|
||||||
void *sta_ptr;
|
void *sta_ptr;
|
||||||
int max_key_len;
|
int max_key_len;
|
||||||
|
|
||||||
|
@ -3620,8 +3595,8 @@ static int prism2_ioctl_get_encryption(local_info_t *local,
|
||||||
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
|
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
|
||||||
sta_ptr = NULL;
|
sta_ptr = NULL;
|
||||||
if (param->u.crypt.idx >= WEP_KEYS)
|
if (param->u.crypt.idx >= WEP_KEYS)
|
||||||
param->u.crypt.idx = local->tx_keyidx;
|
param->u.crypt.idx = local->crypt_info.tx_keyidx;
|
||||||
crypt = &local->crypt[param->u.crypt.idx];
|
crypt = &local->crypt_info.crypt[param->u.crypt.idx];
|
||||||
} else {
|
} else {
|
||||||
param->u.crypt.idx = 0;
|
param->u.crypt.idx = 0;
|
||||||
sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,
|
sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <net/net_namespace.h>
|
#include <net/net_namespace.h>
|
||||||
#include <net/iw_handler.h>
|
#include <net/iw_handler.h>
|
||||||
#include <net/ieee80211.h>
|
#include <net/ieee80211.h>
|
||||||
#include <net/ieee80211_crypt.h>
|
#include <net/lib80211.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
#include "hostap_wlan.h"
|
#include "hostap_wlan.h"
|
||||||
|
@ -343,10 +343,11 @@ int hostap_set_encryption(local_info_t *local)
|
||||||
char keybuf[WEP_KEY_LEN + 1];
|
char keybuf[WEP_KEY_LEN + 1];
|
||||||
enum { NONE, WEP, OTHER } encrypt_type;
|
enum { NONE, WEP, OTHER } encrypt_type;
|
||||||
|
|
||||||
idx = local->tx_keyidx;
|
idx = local->crypt_info.tx_keyidx;
|
||||||
if (local->crypt[idx] == NULL || local->crypt[idx]->ops == NULL)
|
if (local->crypt_info.crypt[idx] == NULL ||
|
||||||
|
local->crypt_info.crypt[idx]->ops == NULL)
|
||||||
encrypt_type = NONE;
|
encrypt_type = NONE;
|
||||||
else if (strcmp(local->crypt[idx]->ops->name, "WEP") == 0)
|
else if (strcmp(local->crypt_info.crypt[idx]->ops->name, "WEP") == 0)
|
||||||
encrypt_type = WEP;
|
encrypt_type = WEP;
|
||||||
else
|
else
|
||||||
encrypt_type = OTHER;
|
encrypt_type = OTHER;
|
||||||
|
@ -394,17 +395,17 @@ int hostap_set_encryption(local_info_t *local)
|
||||||
/* 104-bit support seems to require that all the keys are set to the
|
/* 104-bit support seems to require that all the keys are set to the
|
||||||
* same keylen */
|
* same keylen */
|
||||||
keylen = 6; /* first 5 octets */
|
keylen = 6; /* first 5 octets */
|
||||||
len = local->crypt[idx]->ops->get_key(keybuf, sizeof(keybuf),
|
len = local->crypt_info.crypt[idx]->ops->get_key(keybuf, sizeof(keybuf), NULL,
|
||||||
NULL, local->crypt[idx]->priv);
|
local->crypt_info.crypt[idx]->priv);
|
||||||
if (idx >= 0 && idx < WEP_KEYS && len > 5)
|
if (idx >= 0 && idx < WEP_KEYS && len > 5)
|
||||||
keylen = WEP_KEY_LEN + 1; /* first 13 octets */
|
keylen = WEP_KEY_LEN + 1; /* first 13 octets */
|
||||||
|
|
||||||
for (i = 0; i < WEP_KEYS; i++) {
|
for (i = 0; i < WEP_KEYS; i++) {
|
||||||
memset(keybuf, 0, sizeof(keybuf));
|
memset(keybuf, 0, sizeof(keybuf));
|
||||||
if (local->crypt[i]) {
|
if (local->crypt_info.crypt[i]) {
|
||||||
(void) local->crypt[i]->ops->get_key(
|
(void) local->crypt_info.crypt[i]->ops->get_key(
|
||||||
keybuf, sizeof(keybuf),
|
keybuf, sizeof(keybuf),
|
||||||
NULL, local->crypt[i]->priv);
|
NULL, local->crypt_info.crypt[i]->priv);
|
||||||
}
|
}
|
||||||
if (local->func->set_rid(local->dev,
|
if (local->func->set_rid(local->dev,
|
||||||
HFA384X_RID_CNFDEFAULTKEY0 + i,
|
HFA384X_RID_CNFDEFAULTKEY0 + i,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <net/ieee80211_crypt.h>
|
#include <net/lib80211.h>
|
||||||
|
|
||||||
#include "hostap_wlan.h"
|
#include "hostap_wlan.h"
|
||||||
#include "hostap.h"
|
#include "hostap.h"
|
||||||
|
@ -36,9 +36,10 @@ static int prism2_debug_proc_read(char *page, char **start, off_t off,
|
||||||
p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled);
|
p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled);
|
||||||
p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck);
|
p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck);
|
||||||
for (i = 0; i < WEP_KEYS; i++) {
|
for (i = 0; i < WEP_KEYS; i++) {
|
||||||
if (local->crypt[i] && local->crypt[i]->ops) {
|
if (local->crypt_info.crypt[i] &&
|
||||||
p += sprintf(p, "crypt[%d]=%s\n",
|
local->crypt_info.crypt[i]->ops) {
|
||||||
i, local->crypt[i]->ops->name);
|
p += sprintf(p, "crypt[%d]=%s\n", i,
|
||||||
|
local->crypt_info.crypt[i]->ops->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p += sprintf(p, "pri_only=%d\n", local->pri_only);
|
p += sprintf(p, "pri_only=%d\n", local->pri_only);
|
||||||
|
@ -206,12 +207,13 @@ static int prism2_crypt_proc_read(char *page, char **start, off_t off,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
p += sprintf(p, "tx_keyidx=%d\n", local->tx_keyidx);
|
p += sprintf(p, "tx_keyidx=%d\n", local->crypt_info.tx_keyidx);
|
||||||
for (i = 0; i < WEP_KEYS; i++) {
|
for (i = 0; i < WEP_KEYS; i++) {
|
||||||
if (local->crypt[i] && local->crypt[i]->ops &&
|
if (local->crypt_info.crypt[i] &&
|
||||||
local->crypt[i]->ops->print_stats) {
|
local->crypt_info.crypt[i]->ops &&
|
||||||
p = local->crypt[i]->ops->print_stats(
|
local->crypt_info.crypt[i]->ops->print_stats) {
|
||||||
p, local->crypt[i]->priv);
|
p = local->crypt_info.crypt[i]->ops->print_stats(
|
||||||
|
p, local->crypt_info.crypt[i]->priv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <net/iw_handler.h>
|
#include <net/iw_handler.h>
|
||||||
#include <net/ieee80211_radiotap.h>
|
#include <net/ieee80211_radiotap.h>
|
||||||
|
#include <net/lib80211.h>
|
||||||
|
|
||||||
#include "hostap_config.h"
|
#include "hostap_config.h"
|
||||||
#include "hostap_common.h"
|
#include "hostap_common.h"
|
||||||
|
@ -763,10 +764,7 @@ struct local_info {
|
||||||
|
|
||||||
#define WEP_KEYS 4
|
#define WEP_KEYS 4
|
||||||
#define WEP_KEY_LEN 13
|
#define WEP_KEY_LEN 13
|
||||||
struct ieee80211_crypt_data *crypt[WEP_KEYS];
|
struct lib80211_crypt_info crypt_info;
|
||||||
int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
|
|
||||||
struct timer_list crypt_deinit_timer;
|
|
||||||
struct list_head crypt_deinit_list;
|
|
||||||
|
|
||||||
int open_wep; /* allow unencrypted frames */
|
int open_wep; /* allow unencrypted frames */
|
||||||
int host_encrypt;
|
int host_encrypt;
|
||||||
|
|
|
@ -0,0 +1,191 @@
|
||||||
|
#
|
||||||
|
# Intel Centrino wireless drivers
|
||||||
|
#
|
||||||
|
|
||||||
|
config IPW2100
|
||||||
|
tristate "Intel PRO/Wireless 2100 Network Connection"
|
||||||
|
depends on PCI && WLAN_80211
|
||||||
|
select WIRELESS_EXT
|
||||||
|
select FW_LOADER
|
||||||
|
select LIB80211
|
||||||
|
select LIBIPW
|
||||||
|
---help---
|
||||||
|
A driver for the Intel PRO/Wireless 2100 Network
|
||||||
|
Connection 802.11b wireless network adapter.
|
||||||
|
|
||||||
|
See <file:Documentation/networking/README.ipw2100> for information on
|
||||||
|
the capabilities currently enabled in this driver and for tips
|
||||||
|
for debugging issues and problems.
|
||||||
|
|
||||||
|
In order to use this driver, you will need a firmware image for it.
|
||||||
|
You can obtain the firmware from
|
||||||
|
<http://ipw2100.sf.net/>. Once you have the firmware image, you
|
||||||
|
will need to place it in /lib/firmware.
|
||||||
|
|
||||||
|
You will also very likely need the Wireless Tools in order to
|
||||||
|
configure your card:
|
||||||
|
|
||||||
|
<http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
|
||||||
|
|
||||||
|
It is recommended that you compile this driver as a module (M)
|
||||||
|
rather than built-in (Y). This driver requires firmware at device
|
||||||
|
initialization time, and when built-in this typically happens
|
||||||
|
before the filesystem is accessible (hence firmware will be
|
||||||
|
unavailable and initialization will fail). If you do choose to build
|
||||||
|
this driver into your kernel image, you can avoid this problem by
|
||||||
|
including the firmware and a firmware loader in an initramfs.
|
||||||
|
|
||||||
|
config IPW2100_MONITOR
|
||||||
|
bool "Enable promiscuous mode"
|
||||||
|
depends on IPW2100
|
||||||
|
---help---
|
||||||
|
Enables promiscuous/monitor mode support for the ipw2100 driver.
|
||||||
|
With this feature compiled into the driver, you can switch to
|
||||||
|
promiscuous mode via the Wireless Tool's Monitor mode. While in this
|
||||||
|
mode, no packets can be sent.
|
||||||
|
|
||||||
|
config IPW2100_DEBUG
|
||||||
|
bool "Enable full debugging output in IPW2100 module."
|
||||||
|
depends on IPW2100
|
||||||
|
---help---
|
||||||
|
This option will enable debug tracing output for the IPW2100.
|
||||||
|
|
||||||
|
This will result in the kernel module being ~60k larger. You can
|
||||||
|
control which debug output is sent to the kernel log by setting the
|
||||||
|
value in
|
||||||
|
|
||||||
|
/sys/bus/pci/drivers/ipw2100/debug_level
|
||||||
|
|
||||||
|
This entry will only exist if this option is enabled.
|
||||||
|
|
||||||
|
If you are not trying to debug or develop the IPW2100 driver, you
|
||||||
|
most likely want to say N here.
|
||||||
|
|
||||||
|
config IPW2200
|
||||||
|
tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
|
||||||
|
depends on PCI && WLAN_80211
|
||||||
|
select WIRELESS_EXT
|
||||||
|
select FW_LOADER
|
||||||
|
select LIB80211
|
||||||
|
select LIBIPW
|
||||||
|
---help---
|
||||||
|
A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
|
||||||
|
Connection adapters.
|
||||||
|
|
||||||
|
See <file:Documentation/networking/README.ipw2200> for
|
||||||
|
information on the capabilities currently enabled in this
|
||||||
|
driver and for tips for debugging issues and problems.
|
||||||
|
|
||||||
|
In order to use this driver, you will need a firmware image for it.
|
||||||
|
You can obtain the firmware from
|
||||||
|
<http://ipw2200.sf.net/>. See the above referenced README.ipw2200
|
||||||
|
for information on where to install the firmware images.
|
||||||
|
|
||||||
|
You will also very likely need the Wireless Tools in order to
|
||||||
|
configure your card:
|
||||||
|
|
||||||
|
<http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
|
||||||
|
|
||||||
|
It is recommended that you compile this driver as a module (M)
|
||||||
|
rather than built-in (Y). This driver requires firmware at device
|
||||||
|
initialization time, and when built-in this typically happens
|
||||||
|
before the filesystem is accessible (hence firmware will be
|
||||||
|
unavailable and initialization will fail). If you do choose to build
|
||||||
|
this driver into your kernel image, you can avoid this problem by
|
||||||
|
including the firmware and a firmware loader in an initramfs.
|
||||||
|
|
||||||
|
config IPW2200_MONITOR
|
||||||
|
bool "Enable promiscuous mode"
|
||||||
|
depends on IPW2200
|
||||||
|
---help---
|
||||||
|
Enables promiscuous/monitor mode support for the ipw2200 driver.
|
||||||
|
With this feature compiled into the driver, you can switch to
|
||||||
|
promiscuous mode via the Wireless Tool's Monitor mode. While in this
|
||||||
|
mode, no packets can be sent.
|
||||||
|
|
||||||
|
config IPW2200_RADIOTAP
|
||||||
|
bool "Enable radiotap format 802.11 raw packet support"
|
||||||
|
depends on IPW2200_MONITOR
|
||||||
|
|
||||||
|
config IPW2200_PROMISCUOUS
|
||||||
|
bool "Enable creation of a RF radiotap promiscuous interface"
|
||||||
|
depends on IPW2200_MONITOR
|
||||||
|
select IPW2200_RADIOTAP
|
||||||
|
---help---
|
||||||
|
Enables the creation of a second interface prefixed 'rtap'.
|
||||||
|
This second interface will provide every received in radiotap
|
||||||
|
format.
|
||||||
|
|
||||||
|
This is useful for performing wireless network analysis while
|
||||||
|
maintaining an active association.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
% modprobe ipw2200 rtap_iface=1
|
||||||
|
% ifconfig rtap0 up
|
||||||
|
% tethereal -i rtap0
|
||||||
|
|
||||||
|
If you do not specify 'rtap_iface=1' as a module parameter then
|
||||||
|
the rtap interface will not be created and you will need to turn
|
||||||
|
it on via sysfs:
|
||||||
|
|
||||||
|
% echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
|
||||||
|
|
||||||
|
config IPW2200_QOS
|
||||||
|
bool "Enable QoS support"
|
||||||
|
depends on IPW2200 && EXPERIMENTAL
|
||||||
|
|
||||||
|
config IPW2200_DEBUG
|
||||||
|
bool "Enable full debugging output in IPW2200 module."
|
||||||
|
depends on IPW2200
|
||||||
|
---help---
|
||||||
|
This option will enable low level debug tracing output for IPW2200.
|
||||||
|
|
||||||
|
Note, normal debug code is already compiled in. This low level
|
||||||
|
debug option enables debug on hot paths (e.g Tx, Rx, ISR) and
|
||||||
|
will result in the kernel module being ~70 larger. Most users
|
||||||
|
will typically not need this high verbosity debug information.
|
||||||
|
|
||||||
|
If you are not sure, say N here.
|
||||||
|
|
||||||
|
config LIBIPW
|
||||||
|
tristate
|
||||||
|
select WIRELESS_EXT
|
||||||
|
select CRYPTO
|
||||||
|
select CRYPTO_ARC4
|
||||||
|
select CRYPTO_ECB
|
||||||
|
select CRYPTO_AES
|
||||||
|
select CRYPTO_MICHAEL_MIC
|
||||||
|
select CRYPTO_ECB
|
||||||
|
select CRC32
|
||||||
|
select LIB80211
|
||||||
|
select LIB80211_CRYPT_WEP
|
||||||
|
select LIB80211_CRYPT_TKIP
|
||||||
|
select LIB80211_CRYPT_CCMP
|
||||||
|
---help---
|
||||||
|
This option enables the hardware independent IEEE 802.11
|
||||||
|
networking stack. This component is deprecated in favor of the
|
||||||
|
mac80211 component.
|
||||||
|
|
||||||
|
config LIBIPW_DEBUG
|
||||||
|
bool "Full debugging output for the LIBIPW component"
|
||||||
|
depends on LIBIPW
|
||||||
|
---help---
|
||||||
|
This option will enable debug tracing output for the
|
||||||
|
libipw component.
|
||||||
|
|
||||||
|
This will result in the kernel module being ~70k larger. You
|
||||||
|
can control which debug output is sent to the kernel log by
|
||||||
|
setting the value in
|
||||||
|
|
||||||
|
/proc/net/ieee80211/debug_level
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
% echo 0x00000FFO > /proc/net/ieee80211/debug_level
|
||||||
|
|
||||||
|
For a list of values you can assign to debug_level, you
|
||||||
|
can look at the bit mask values in <net/ieee80211.h>
|
||||||
|
|
||||||
|
If you are not trying to debug or develop the libipw
|
||||||
|
component, you most likely want to say N here.
|
|
@ -0,0 +1,14 @@
|
||||||
|
#
|
||||||
|
# Makefile for the Intel Centrino wireless drivers
|
||||||
|
#
|
||||||
|
|
||||||
|
obj-$(CONFIG_IPW2100) += ipw2100.o
|
||||||
|
obj-$(CONFIG_IPW2200) += ipw2200.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_LIBIPW) += libipw.o
|
||||||
|
libipw-objs := \
|
||||||
|
libipw_module.o \
|
||||||
|
libipw_tx.o \
|
||||||
|
libipw_rx.o \
|
||||||
|
libipw_wx.o \
|
||||||
|
libipw_geo.o
|
|
@ -4010,7 +4010,7 @@ static ssize_t show_internals(struct device *d, struct device_attribute *attr,
|
||||||
else
|
else
|
||||||
len += sprintf(buf + len, "not connected\n");
|
len += sprintf(buf + len, "not connected\n");
|
||||||
|
|
||||||
DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], "p");
|
DUMP_VAR(ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx], "p");
|
||||||
DUMP_VAR(status, "08lx");
|
DUMP_VAR(status, "08lx");
|
||||||
DUMP_VAR(config, "08lx");
|
DUMP_VAR(config, "08lx");
|
||||||
DUMP_VAR(capability, "08lx");
|
DUMP_VAR(capability, "08lx");
|
||||||
|
@ -5514,7 +5514,7 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ipw2100_set_key_index(priv, priv->ieee->tx_keyidx, 1);
|
ipw2100_set_key_index(priv, priv->ieee->crypt_info.tx_keyidx, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Always enable privacy so the Host can filter WEP packets if
|
/* Always enable privacy so the Host can filter WEP packets if
|
||||||
|
@ -7620,7 +7620,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
|
||||||
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
||||||
struct ieee80211_device *ieee = priv->ieee;
|
struct ieee80211_device *ieee = priv->ieee;
|
||||||
struct iw_param *param = &wrqu->param;
|
struct iw_param *param = &wrqu->param;
|
||||||
struct ieee80211_crypt_data *crypt;
|
struct lib80211_crypt_data *crypt;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -7635,7 +7635,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IW_AUTH_TKIP_COUNTERMEASURES:
|
case IW_AUTH_TKIP_COUNTERMEASURES:
|
||||||
crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
|
crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
|
||||||
if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
|
if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -7712,7 +7712,7 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
|
||||||
{
|
{
|
||||||
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
struct ipw2100_priv *priv = ieee80211_priv(dev);
|
||||||
struct ieee80211_device *ieee = priv->ieee;
|
struct ieee80211_device *ieee = priv->ieee;
|
||||||
struct ieee80211_crypt_data *crypt;
|
struct lib80211_crypt_data *crypt;
|
||||||
struct iw_param *param = &wrqu->param;
|
struct iw_param *param = &wrqu->param;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -7728,7 +7728,7 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IW_AUTH_TKIP_COUNTERMEASURES:
|
case IW_AUTH_TKIP_COUNTERMEASURES:
|
||||||
crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
|
crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
|
||||||
if (!crypt || !crypt->ops->get_flags) {
|
if (!crypt || !crypt->ops->get_flags) {
|
||||||
IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
|
IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
|
||||||
"crypt not set!\n");
|
"crypt not set!\n");
|
|
@ -6600,7 +6600,7 @@ static int ipw_wx_set_auth(struct net_device *dev,
|
||||||
struct ipw_priv *priv = ieee80211_priv(dev);
|
struct ipw_priv *priv = ieee80211_priv(dev);
|
||||||
struct ieee80211_device *ieee = priv->ieee;
|
struct ieee80211_device *ieee = priv->ieee;
|
||||||
struct iw_param *param = &wrqu->param;
|
struct iw_param *param = &wrqu->param;
|
||||||
struct ieee80211_crypt_data *crypt;
|
struct lib80211_crypt_data *crypt;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -6622,7 +6622,7 @@ static int ipw_wx_set_auth(struct net_device *dev,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IW_AUTH_TKIP_COUNTERMEASURES:
|
case IW_AUTH_TKIP_COUNTERMEASURES:
|
||||||
crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
|
crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
|
||||||
if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
|
if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6699,7 +6699,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
|
||||||
{
|
{
|
||||||
struct ipw_priv *priv = ieee80211_priv(dev);
|
struct ipw_priv *priv = ieee80211_priv(dev);
|
||||||
struct ieee80211_device *ieee = priv->ieee;
|
struct ieee80211_device *ieee = priv->ieee;
|
||||||
struct ieee80211_crypt_data *crypt;
|
struct lib80211_crypt_data *crypt;
|
||||||
struct iw_param *param = &wrqu->param;
|
struct iw_param *param = &wrqu->param;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -6715,7 +6715,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IW_AUTH_TKIP_COUNTERMEASURES:
|
case IW_AUTH_TKIP_COUNTERMEASURES:
|
||||||
crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
|
crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
|
||||||
if (!crypt || !crypt->ops->get_flags)
|
if (!crypt || !crypt->ops->get_flags)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -7575,8 +7575,7 @@ static int ipw_associate(void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(priv->config & CFG_ASSOCIATE) &&
|
if (!(priv->config & CFG_ASSOCIATE) &&
|
||||||
!(priv->config & (CFG_STATIC_ESSID |
|
!(priv->config & (CFG_STATIC_ESSID | CFG_STATIC_BSSID))) {
|
||||||
CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
|
|
||||||
IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
|
IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -10252,8 +10251,8 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
|
||||||
case SEC_LEVEL_1:
|
case SEC_LEVEL_1:
|
||||||
tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
|
tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
|
||||||
cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||||
tfd->u.data.key_index = priv->ieee->tx_keyidx;
|
tfd->u.data.key_index = priv->ieee->crypt_info.tx_keyidx;
|
||||||
if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
|
if (priv->ieee->sec.key_sizes[priv->ieee->crypt_info.tx_keyidx] <=
|
||||||
40)
|
40)
|
||||||
tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
|
tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
|
||||||
else
|
else
|
|
@ -180,13 +180,10 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
|
||||||
ieee->host_open_frag = 1;
|
ieee->host_open_frag = 1;
|
||||||
ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
|
ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
|
||||||
|
|
||||||
INIT_LIST_HEAD(&ieee->crypt_deinit_list);
|
|
||||||
setup_timer(&ieee->crypt_deinit_timer, ieee80211_crypt_deinit_handler,
|
|
||||||
(unsigned long)ieee);
|
|
||||||
ieee->crypt_quiesced = 0;
|
|
||||||
|
|
||||||
spin_lock_init(&ieee->lock);
|
spin_lock_init(&ieee->lock);
|
||||||
|
|
||||||
|
lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
|
||||||
|
|
||||||
ieee->wpa_enabled = 0;
|
ieee->wpa_enabled = 0;
|
||||||
ieee->drop_unencrypted = 0;
|
ieee->drop_unencrypted = 0;
|
||||||
ieee->privacy_invoked = 0;
|
ieee->privacy_invoked = 0;
|
||||||
|
@ -203,23 +200,7 @@ void free_ieee80211(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct ieee80211_device *ieee = netdev_priv(dev);
|
struct ieee80211_device *ieee = netdev_priv(dev);
|
||||||
|
|
||||||
int i;
|
lib80211_crypt_info_free(&ieee->crypt_info);
|
||||||
|
|
||||||
ieee80211_crypt_quiescing(ieee);
|
|
||||||
del_timer_sync(&ieee->crypt_deinit_timer);
|
|
||||||
ieee80211_crypt_deinit_entries(ieee, 1);
|
|
||||||
|
|
||||||
for (i = 0; i < WEP_KEYS; i++) {
|
|
||||||
struct ieee80211_crypt_data *crypt = ieee->crypt[i];
|
|
||||||
if (crypt) {
|
|
||||||
if (crypt->ops) {
|
|
||||||
crypt->ops->deinit(crypt->priv);
|
|
||||||
module_put(crypt->ops->owner);
|
|
||||||
}
|
|
||||||
kfree(crypt);
|
|
||||||
ieee->crypt[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ieee80211_networks_free(ieee);
|
ieee80211_networks_free(ieee);
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
|
@ -268,7 +268,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
|
||||||
/* Called only as a tasklet (software IRQ), by ieee80211_rx */
|
/* Called only as a tasklet (software IRQ), by ieee80211_rx */
|
||||||
static int
|
static int
|
||||||
ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
|
ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
|
||||||
struct ieee80211_crypt_data *crypt)
|
struct lib80211_crypt_data *crypt)
|
||||||
{
|
{
|
||||||
struct ieee80211_hdr_3addr *hdr;
|
struct ieee80211_hdr_3addr *hdr;
|
||||||
int res, hdrlen;
|
int res, hdrlen;
|
||||||
|
@ -300,7 +300,7 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
|
||||||
static int
|
static int
|
||||||
ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
|
ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
|
||||||
struct sk_buff *skb, int keyidx,
|
struct sk_buff *skb, int keyidx,
|
||||||
struct ieee80211_crypt_data *crypt)
|
struct lib80211_crypt_data *crypt)
|
||||||
{
|
{
|
||||||
struct ieee80211_hdr_3addr *hdr;
|
struct ieee80211_hdr_3addr *hdr;
|
||||||
int res, hdrlen;
|
int res, hdrlen;
|
||||||
|
@ -348,7 +348,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
|
||||||
#endif
|
#endif
|
||||||
u8 dst[ETH_ALEN];
|
u8 dst[ETH_ALEN];
|
||||||
u8 src[ETH_ALEN];
|
u8 src[ETH_ALEN];
|
||||||
struct ieee80211_crypt_data *crypt = NULL;
|
struct lib80211_crypt_data *crypt = NULL;
|
||||||
int keyidx = 0;
|
int keyidx = 0;
|
||||||
int can_be_decrypted = 0;
|
int can_be_decrypted = 0;
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
|
||||||
* is only allowed 2-bits of storage, no value of keyidx can
|
* is only allowed 2-bits of storage, no value of keyidx can
|
||||||
* be provided via above code that would result in keyidx
|
* be provided via above code that would result in keyidx
|
||||||
* being out of range */
|
* being out of range */
|
||||||
crypt = ieee->crypt[keyidx];
|
crypt = ieee->crypt_info.crypt[keyidx];
|
||||||
|
|
||||||
#ifdef NOT_YET
|
#ifdef NOT_YET
|
||||||
sta = NULL;
|
sta = NULL;
|
|
@ -152,7 +152,8 @@ static int ieee80211_copy_snap(u8 * data, __be16 h_proto)
|
||||||
static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
|
static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
|
||||||
struct sk_buff *frag, int hdr_len)
|
struct sk_buff *frag, int hdr_len)
|
||||||
{
|
{
|
||||||
struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
|
struct lib80211_crypt_data *crypt =
|
||||||
|
ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (crypt == NULL)
|
if (crypt == NULL)
|
||||||
|
@ -270,7 +271,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
.qos_ctl = 0
|
.qos_ctl = 0
|
||||||
};
|
};
|
||||||
u8 dest[ETH_ALEN], src[ETH_ALEN];
|
u8 dest[ETH_ALEN], src[ETH_ALEN];
|
||||||
struct ieee80211_crypt_data *crypt;
|
struct lib80211_crypt_data *crypt;
|
||||||
int priority = skb->priority;
|
int priority = skb->priority;
|
||||||
int snapped = 0;
|
int snapped = 0;
|
||||||
|
|
||||||
|
@ -294,7 +295,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
ether_type = ((struct ethhdr *)skb->data)->h_proto;
|
ether_type = ((struct ethhdr *)skb->data)->h_proto;
|
||||||
|
|
||||||
crypt = ieee->crypt[ieee->tx_keyidx];
|
crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
|
||||||
|
|
||||||
encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) &&
|
encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) &&
|
||||||
ieee->sec.encrypt;
|
ieee->sec.encrypt;
|
|
@ -307,7 +307,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
|
||||||
.flags = 0
|
.flags = 0
|
||||||
};
|
};
|
||||||
int i, key, key_provided, len;
|
int i, key, key_provided, len;
|
||||||
struct ieee80211_crypt_data **crypt;
|
struct lib80211_crypt_data **crypt;
|
||||||
int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
|
int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
|
||||||
DECLARE_SSID_BUF(ssid);
|
DECLARE_SSID_BUF(ssid);
|
||||||
|
|
||||||
|
@ -321,30 +321,30 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
|
||||||
key_provided = 1;
|
key_provided = 1;
|
||||||
} else {
|
} else {
|
||||||
key_provided = 0;
|
key_provided = 0;
|
||||||
key = ieee->tx_keyidx;
|
key = ieee->crypt_info.tx_keyidx;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
|
IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
|
||||||
"provided" : "default");
|
"provided" : "default");
|
||||||
|
|
||||||
crypt = &ieee->crypt[key];
|
crypt = &ieee->crypt_info.crypt[key];
|
||||||
|
|
||||||
if (erq->flags & IW_ENCODE_DISABLED) {
|
if (erq->flags & IW_ENCODE_DISABLED) {
|
||||||
if (key_provided && *crypt) {
|
if (key_provided && *crypt) {
|
||||||
IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
|
IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
|
||||||
key);
|
key);
|
||||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||||
} else
|
} else
|
||||||
IEEE80211_DEBUG_WX("Disabling encryption.\n");
|
IEEE80211_DEBUG_WX("Disabling encryption.\n");
|
||||||
|
|
||||||
/* Check all the keys to see if any are still configured,
|
/* Check all the keys to see if any are still configured,
|
||||||
* and if no key index was provided, de-init them all */
|
* and if no key index was provided, de-init them all */
|
||||||
for (i = 0; i < WEP_KEYS; i++) {
|
for (i = 0; i < WEP_KEYS; i++) {
|
||||||
if (ieee->crypt[i] != NULL) {
|
if (ieee->crypt_info.crypt[i] != NULL) {
|
||||||
if (key_provided)
|
if (key_provided)
|
||||||
break;
|
break;
|
||||||
ieee80211_crypt_delayed_deinit(ieee,
|
lib80211_crypt_delayed_deinit(&ieee->crypt_info,
|
||||||
&ieee->crypt[i]);
|
&ieee->crypt_info.crypt[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,21 +366,21 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
|
||||||
strcmp((*crypt)->ops->name, "WEP") != 0) {
|
strcmp((*crypt)->ops->name, "WEP") != 0) {
|
||||||
/* changing to use WEP; deinit previously used algorithm
|
/* changing to use WEP; deinit previously used algorithm
|
||||||
* on this key */
|
* on this key */
|
||||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*crypt == NULL && host_crypto) {
|
if (*crypt == NULL && host_crypto) {
|
||||||
struct ieee80211_crypt_data *new_crypt;
|
struct lib80211_crypt_data *new_crypt;
|
||||||
|
|
||||||
/* take WEP into use */
|
/* take WEP into use */
|
||||||
new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
|
new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (new_crypt == NULL)
|
if (new_crypt == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
|
new_crypt->ops = lib80211_get_crypto_ops("WEP");
|
||||||
if (!new_crypt->ops) {
|
if (!new_crypt->ops) {
|
||||||
request_module("ieee80211_crypt_wep");
|
request_module("lib80211_crypt_wep");
|
||||||
new_crypt->ops = ieee80211_get_crypto_ops("WEP");
|
new_crypt->ops = lib80211_get_crypto_ops("WEP");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
|
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
|
||||||
|
@ -391,7 +391,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
|
||||||
new_crypt = NULL;
|
new_crypt = NULL;
|
||||||
|
|
||||||
printk(KERN_WARNING "%s: could not initialize WEP: "
|
printk(KERN_WARNING "%s: could not initialize WEP: "
|
||||||
"load module ieee80211_crypt_wep\n", dev->name);
|
"load module lib80211_crypt_wep\n", dev->name);
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
*crypt = new_crypt;
|
*crypt = new_crypt;
|
||||||
|
@ -440,7 +440,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
|
||||||
if (key_provided) {
|
if (key_provided) {
|
||||||
IEEE80211_DEBUG_WX("Setting key %d to default Tx "
|
IEEE80211_DEBUG_WX("Setting key %d to default Tx "
|
||||||
"key.\n", key);
|
"key.\n", key);
|
||||||
ieee->tx_keyidx = key;
|
ieee->crypt_info.tx_keyidx = key;
|
||||||
sec.active_key = key;
|
sec.active_key = key;
|
||||||
sec.flags |= SEC_ACTIVE_KEY;
|
sec.flags |= SEC_ACTIVE_KEY;
|
||||||
}
|
}
|
||||||
|
@ -485,7 +485,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
|
||||||
{
|
{
|
||||||
struct iw_point *erq = &(wrqu->encoding);
|
struct iw_point *erq = &(wrqu->encoding);
|
||||||
int len, key;
|
int len, key;
|
||||||
struct ieee80211_crypt_data *crypt;
|
struct lib80211_crypt_data *crypt;
|
||||||
struct ieee80211_security *sec = &ieee->sec;
|
struct ieee80211_security *sec = &ieee->sec;
|
||||||
|
|
||||||
IEEE80211_DEBUG_WX("GET_ENCODE\n");
|
IEEE80211_DEBUG_WX("GET_ENCODE\n");
|
||||||
|
@ -496,9 +496,9 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
key--;
|
key--;
|
||||||
} else
|
} else
|
||||||
key = ieee->tx_keyidx;
|
key = ieee->crypt_info.tx_keyidx;
|
||||||
|
|
||||||
crypt = ieee->crypt[key];
|
crypt = ieee->crypt_info.crypt[key];
|
||||||
erq->flags = key + 1;
|
erq->flags = key + 1;
|
||||||
|
|
||||||
if (!sec->enabled) {
|
if (!sec->enabled) {
|
||||||
|
@ -531,8 +531,8 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||||
int i, idx, ret = 0;
|
int i, idx, ret = 0;
|
||||||
int group_key = 0;
|
int group_key = 0;
|
||||||
const char *alg, *module;
|
const char *alg, *module;
|
||||||
struct ieee80211_crypto_ops *ops;
|
struct lib80211_crypto_ops *ops;
|
||||||
struct ieee80211_crypt_data **crypt;
|
struct lib80211_crypt_data **crypt;
|
||||||
|
|
||||||
struct ieee80211_security sec = {
|
struct ieee80211_security sec = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
|
@ -544,17 +544,17 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
idx--;
|
idx--;
|
||||||
} else
|
} else
|
||||||
idx = ieee->tx_keyidx;
|
idx = ieee->crypt_info.tx_keyidx;
|
||||||
|
|
||||||
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
|
if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
|
||||||
crypt = &ieee->crypt[idx];
|
crypt = &ieee->crypt_info.crypt[idx];
|
||||||
group_key = 1;
|
group_key = 1;
|
||||||
} else {
|
} else {
|
||||||
/* some Cisco APs use idx>0 for unicast in dynamic WEP */
|
/* some Cisco APs use idx>0 for unicast in dynamic WEP */
|
||||||
if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
|
if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ieee->iw_mode == IW_MODE_INFRA)
|
if (ieee->iw_mode == IW_MODE_INFRA)
|
||||||
crypt = &ieee->crypt[idx];
|
crypt = &ieee->crypt_info.crypt[idx];
|
||||||
else
|
else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -563,10 +563,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||||
if ((encoding->flags & IW_ENCODE_DISABLED) ||
|
if ((encoding->flags & IW_ENCODE_DISABLED) ||
|
||||||
ext->alg == IW_ENCODE_ALG_NONE) {
|
ext->alg == IW_ENCODE_ALG_NONE) {
|
||||||
if (*crypt)
|
if (*crypt)
|
||||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||||
|
|
||||||
for (i = 0; i < WEP_KEYS; i++)
|
for (i = 0; i < WEP_KEYS; i++)
|
||||||
if (ieee->crypt[i] != NULL)
|
if (ieee->crypt_info.crypt[i] != NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (i == WEP_KEYS) {
|
if (i == WEP_KEYS) {
|
||||||
|
@ -589,15 +589,15 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||||
switch (ext->alg) {
|
switch (ext->alg) {
|
||||||
case IW_ENCODE_ALG_WEP:
|
case IW_ENCODE_ALG_WEP:
|
||||||
alg = "WEP";
|
alg = "WEP";
|
||||||
module = "ieee80211_crypt_wep";
|
module = "lib80211_crypt_wep";
|
||||||
break;
|
break;
|
||||||
case IW_ENCODE_ALG_TKIP:
|
case IW_ENCODE_ALG_TKIP:
|
||||||
alg = "TKIP";
|
alg = "TKIP";
|
||||||
module = "ieee80211_crypt_tkip";
|
module = "lib80211_crypt_tkip";
|
||||||
break;
|
break;
|
||||||
case IW_ENCODE_ALG_CCMP:
|
case IW_ENCODE_ALG_CCMP:
|
||||||
alg = "CCMP";
|
alg = "CCMP";
|
||||||
module = "ieee80211_crypt_ccmp";
|
module = "lib80211_crypt_ccmp";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
|
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
|
||||||
|
@ -606,10 +606,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ops = ieee80211_get_crypto_ops(alg);
|
ops = lib80211_get_crypto_ops(alg);
|
||||||
if (ops == NULL) {
|
if (ops == NULL) {
|
||||||
request_module(module);
|
request_module(module);
|
||||||
ops = ieee80211_get_crypto_ops(alg);
|
ops = lib80211_get_crypto_ops(alg);
|
||||||
}
|
}
|
||||||
if (ops == NULL) {
|
if (ops == NULL) {
|
||||||
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
|
IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
|
||||||
|
@ -619,9 +619,9 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*crypt == NULL || (*crypt)->ops != ops) {
|
if (*crypt == NULL || (*crypt)->ops != ops) {
|
||||||
struct ieee80211_crypt_data *new_crypt;
|
struct lib80211_crypt_data *new_crypt;
|
||||||
|
|
||||||
ieee80211_crypt_delayed_deinit(ieee, crypt);
|
lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
|
||||||
|
|
||||||
new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
|
new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
|
||||||
if (new_crypt == NULL) {
|
if (new_crypt == NULL) {
|
||||||
|
@ -649,7 +649,7 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
|
||||||
|
|
||||||
skip_host_crypt:
|
skip_host_crypt:
|
||||||
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
|
if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
|
||||||
ieee->tx_keyidx = idx;
|
ieee->crypt_info.tx_keyidx = idx;
|
||||||
sec.active_key = idx;
|
sec.active_key = idx;
|
||||||
sec.flags |= SEC_ACTIVE_KEY;
|
sec.flags |= SEC_ACTIVE_KEY;
|
||||||
}
|
}
|
||||||
|
@ -715,7 +715,7 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
idx--;
|
idx--;
|
||||||
} else
|
} else
|
||||||
idx = ieee->tx_keyidx;
|
idx = ieee->crypt_info.tx_keyidx;
|
||||||
|
|
||||||
if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
|
if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
|
||||||
ext->alg != IW_ENCODE_ALG_WEP)
|
ext->alg != IW_ENCODE_ALG_WEP)
|
|
@ -5,6 +5,7 @@ iwlcore-objs += iwl-scan.o
|
||||||
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
|
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
|
||||||
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
|
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
|
||||||
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
|
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
|
||||||
|
iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
|
||||||
|
|
||||||
obj-$(CONFIG_IWLAGN) += iwlagn.o
|
obj-$(CONFIG_IWLAGN) += iwlagn.o
|
||||||
iwlagn-objs := iwl-agn.o iwl-agn-rs.o
|
iwlagn-objs := iwl-agn.o iwl-agn-rs.o
|
||||||
|
|
|
@ -819,64 +819,6 @@ enum {
|
||||||
#define IWL49_NUM_QUEUES 16
|
#define IWL49_NUM_QUEUES 16
|
||||||
#define IWL49_NUM_AMPDU_QUEUES 8
|
#define IWL49_NUM_AMPDU_QUEUES 8
|
||||||
|
|
||||||
#define IWL_TX_DMA_MASK (DMA_BIT_MASK(36) & ~0x3)
|
|
||||||
#define IWL_NUM_OF_TBS 20
|
|
||||||
|
|
||||||
static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr)
|
|
||||||
{
|
|
||||||
return (sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0) & 0xF;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* struct iwl_tfd_tb transmit buffer descriptor within transmit frame descriptor
|
|
||||||
*
|
|
||||||
* This structure contains dma address and length of transmission address
|
|
||||||
*
|
|
||||||
* @lo: low [31:0] portion of the dma address of TX buffer
|
|
||||||
* every even is unaligned on 16 bit boundary
|
|
||||||
* @hi_n_len 0-3 [35:32] portion of dma
|
|
||||||
* 4-16 length of the tx buffer
|
|
||||||
*/
|
|
||||||
struct iwl_tfd_tb {
|
|
||||||
__le32 lo;
|
|
||||||
__le16 hi_n_len;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct iwl_tfd
|
|
||||||
*
|
|
||||||
* Transmit Frame Descriptor (TFD)
|
|
||||||
*
|
|
||||||
* @ __reserved1[3] reserved
|
|
||||||
* @ num_tbs 0-5 number of active tbs
|
|
||||||
* 6-7 padding (not used)
|
|
||||||
* @ tbs[20] transmit frame buffer descriptors
|
|
||||||
* @ __pad padding
|
|
||||||
*
|
|
||||||
* Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM.
|
|
||||||
* Both driver and device share these circular buffers, each of which must be
|
|
||||||
* contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes
|
|
||||||
*
|
|
||||||
* Driver must indicate the physical address of the base of each
|
|
||||||
* circular buffer via the FH_MEM_CBBC_QUEUE registers.
|
|
||||||
*
|
|
||||||
* Each TFD contains pointer/size information for up to 20 data buffers
|
|
||||||
* in host DRAM. These buffers collectively contain the (one) frame described
|
|
||||||
* by the TFD. Each buffer must be a single contiguous block of memory within
|
|
||||||
* itself, but buffers may be scattered in host DRAM. Each buffer has max size
|
|
||||||
* of (4K - 4). The concatenates all of a TFD's buffers into a single
|
|
||||||
* Tx frame, up to 8 KBytes in size.
|
|
||||||
*
|
|
||||||
* A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
|
|
||||||
*
|
|
||||||
* Bit fields in the control dword (val0):
|
|
||||||
*/
|
|
||||||
struct iwl_tfd {
|
|
||||||
u8 __reserved1[3];
|
|
||||||
u8 num_tbs;
|
|
||||||
struct iwl_tfd_tb tbs[IWL_NUM_OF_TBS];
|
|
||||||
__le32 __pad;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl4965_schedq_bc_tbl
|
* struct iwl4965_schedq_bc_tbl
|
||||||
|
@ -896,64 +838,9 @@ struct iwl_tfd {
|
||||||
* padding puts each byte count table on a 1024-byte boundary;
|
* padding puts each byte count table on a 1024-byte boundary;
|
||||||
* 4965 assumes tables are separated by 1024 bytes.
|
* 4965 assumes tables are separated by 1024 bytes.
|
||||||
*/
|
*/
|
||||||
struct iwl4965_schedq_bc_tbl {
|
struct iwl4965_scd_bc_tbl {
|
||||||
__le16 tfd_offset[TFD_QUEUE_BC_SIZE];
|
__le16 tfd_offset[TFD_QUEUE_BC_SIZE];
|
||||||
u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)];
|
u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
#endif /* !__iwl_4965_hw_h__ */
|
||||||
/**
|
|
||||||
* struct iwl4965_shared - handshake area for Tx and Rx
|
|
||||||
*
|
|
||||||
* For convenience in allocating memory, this structure combines 2 areas of
|
|
||||||
* DRAM which must be shared between driver and 4965. These do not need to
|
|
||||||
* be combined, if better allocation would result from keeping them separate:
|
|
||||||
*
|
|
||||||
* 1) The Tx byte count tables occupy 1024 bytes each (16 KBytes total for
|
|
||||||
* 16 queues). Driver uses SCD_DRAM_BASE_ADDR to tell 4965 where to find
|
|
||||||
* the first of these tables. 4965 assumes tables are 1024 bytes apart.
|
|
||||||
*
|
|
||||||
* 2) The Rx status (val0 and val1) occupies only 8 bytes. Driver uses
|
|
||||||
* FH_RSCSR_CHNL0_STTS_WPTR_REG to tell 4965 where to find this area.
|
|
||||||
* Driver reads val0 to determine the latest Receive Buffer Descriptor (RBD)
|
|
||||||
* that has been filled by the 4965.
|
|
||||||
*
|
|
||||||
* Bit fields val0:
|
|
||||||
* 31-12: Not used
|
|
||||||
* 11- 0: Index of last filled Rx buffer descriptor (4965 writes, driver reads)
|
|
||||||
*
|
|
||||||
* Bit fields val1:
|
|
||||||
* 31- 0: Not used
|
|
||||||
*/
|
|
||||||
struct iwl4965_shared {
|
|
||||||
struct iwl4965_schedq_bc_tbl queues_bc_tbls[IWL49_NUM_QUEUES];
|
|
||||||
__le32 rb_closed;
|
|
||||||
|
|
||||||
/* __le32 rb_closed_stts_rb_num:12; */
|
|
||||||
#define IWL_rb_closed_stts_rb_num_POS 0
|
|
||||||
#define IWL_rb_closed_stts_rb_num_LEN 12
|
|
||||||
#define IWL_rb_closed_stts_rb_num_SYM rb_closed
|
|
||||||
/* __le32 rsrv1:4; */
|
|
||||||
/* __le32 rb_closed_stts_rx_frame_num:12; */
|
|
||||||
#define IWL_rb_closed_stts_rx_frame_num_POS 16
|
|
||||||
#define IWL_rb_closed_stts_rx_frame_num_LEN 12
|
|
||||||
#define IWL_rb_closed_stts_rx_frame_num_SYM rb_closed
|
|
||||||
/* __le32 rsrv2:4; */
|
|
||||||
|
|
||||||
__le32 frm_finished;
|
|
||||||
/* __le32 frame_finished_stts_rb_num:12; */
|
|
||||||
#define IWL_frame_finished_stts_rb_num_POS 0
|
|
||||||
#define IWL_frame_finished_stts_rb_num_LEN 12
|
|
||||||
#define IWL_frame_finished_stts_rb_num_SYM frm_finished
|
|
||||||
/* __le32 rsrv3:4; */
|
|
||||||
/* __le32 frame_finished_stts_rx_frame_num:12; */
|
|
||||||
#define IWL_frame_finished_stts_rx_frame_num_POS 16
|
|
||||||
#define IWL_frame_finished_stts_rx_frame_num_LEN 12
|
|
||||||
#define IWL_frame_finished_stts_rx_frame_num_SYM frm_finished
|
|
||||||
/* __le32 rsrv4:4; */
|
|
||||||
|
|
||||||
__le32 padding1; /* so that allocation will be aligned to 16B */
|
|
||||||
__le32 padding2;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
#endif /* __iwl4965_4965_hw_h__ */
|
|
||||||
|
|
|
@ -715,8 +715,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
|
||||||
|
|
||||||
/* Tel 4965 where to find Tx byte count tables */
|
/* Tel 4965 where to find Tx byte count tables */
|
||||||
iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
|
iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
|
||||||
(priv->shared_phys +
|
priv->scd_bc_tbls.dma >> 10);
|
||||||
offsetof(struct iwl4965_shared, queues_bc_tbls)) >> 10);
|
|
||||||
|
|
||||||
/* Disable chain mode for all queues */
|
/* Disable chain mode for all queues */
|
||||||
iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0);
|
iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0);
|
||||||
|
@ -804,6 +803,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
|
priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
|
||||||
|
priv->hw_params.scd_bc_tbls_size =
|
||||||
|
IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
|
||||||
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
|
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
|
||||||
priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
|
priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
|
||||||
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
|
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
|
||||||
|
@ -1631,36 +1632,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
struct iwl4965_shared *s = priv->shared_virt;
|
|
||||||
return le32_to_cpu(s->rb_closed) & 0xFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
|
|
||||||
sizeof(struct iwl4965_shared),
|
|
||||||
&priv->shared_phys);
|
|
||||||
if (!priv->shared_virt)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared));
|
|
||||||
|
|
||||||
priv->rb_closed_offset = offsetof(struct iwl4965_shared, rb_closed);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iwl4965_free_shared_mem(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
if (priv->shared_virt)
|
|
||||||
pci_free_consistent(priv->pci_dev,
|
|
||||||
sizeof(struct iwl4965_shared),
|
|
||||||
priv->shared_virt,
|
|
||||||
priv->shared_phys);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
|
* iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
|
||||||
*/
|
*/
|
||||||
|
@ -1668,7 +1639,7 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
|
||||||
struct iwl_tx_queue *txq,
|
struct iwl_tx_queue *txq,
|
||||||
u16 byte_cnt)
|
u16 byte_cnt)
|
||||||
{
|
{
|
||||||
struct iwl4965_shared *shared_data = priv->shared_virt;
|
struct iwl4965_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
|
||||||
int txq_id = txq->q.id;
|
int txq_id = txq->q.id;
|
||||||
int write_ptr = txq->q.write_ptr;
|
int write_ptr = txq->q.write_ptr;
|
||||||
int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
|
int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
|
||||||
|
@ -1678,11 +1649,11 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
|
||||||
|
|
||||||
bc_ent = cpu_to_le16(len & 0xFFF);
|
bc_ent = cpu_to_le16(len & 0xFFF);
|
||||||
/* Set up byte count within first 256 entries */
|
/* Set up byte count within first 256 entries */
|
||||||
shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent;
|
scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
|
||||||
|
|
||||||
/* If within first 64 entries, duplicate at end */
|
/* If within first 64 entries, duplicate at end */
|
||||||
if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
|
if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
|
||||||
shared_data->queues_bc_tbls[txq_id].
|
scd_bc_tbl[txq_id].
|
||||||
tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
|
tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2304,9 +2275,6 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
|
||||||
|
|
||||||
static struct iwl_lib_ops iwl4965_lib = {
|
static struct iwl_lib_ops iwl4965_lib = {
|
||||||
.set_hw_params = iwl4965_hw_set_hw_params,
|
.set_hw_params = iwl4965_hw_set_hw_params,
|
||||||
.alloc_shared_mem = iwl4965_alloc_shared_mem,
|
|
||||||
.free_shared_mem = iwl4965_free_shared_mem,
|
|
||||||
.shared_mem_rx_idx = iwl4965_shared_mem_rx_idx,
|
|
||||||
.txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,
|
.txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,
|
||||||
.txq_set_sched = iwl4965_txq_set_sched,
|
.txq_set_sched = iwl4965_txq_set_sched,
|
||||||
.txq_agg_enable = iwl4965_txq_agg_enable,
|
.txq_agg_enable = iwl4965_txq_agg_enable,
|
||||||
|
|
|
@ -90,45 +90,10 @@
|
||||||
* @tfd_offset 0-12 - tx command byte count
|
* @tfd_offset 0-12 - tx command byte count
|
||||||
* 12-16 - station index
|
* 12-16 - station index
|
||||||
*/
|
*/
|
||||||
struct iwl5000_schedq_bc_tbl {
|
struct iwl5000_scd_bc_tbl {
|
||||||
__le16 tfd_offset[TFD_QUEUE_BC_SIZE];
|
__le16 tfd_offset[TFD_QUEUE_BC_SIZE];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/**
|
|
||||||
* struct iwl5000_shared
|
|
||||||
* @rb_closed
|
|
||||||
* address is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG
|
|
||||||
*/
|
|
||||||
struct iwl5000_shared {
|
|
||||||
struct iwl5000_schedq_bc_tbl queues_bc_tbls[IWL50_NUM_QUEUES];
|
|
||||||
__le32 rb_closed;
|
|
||||||
|
|
||||||
/* __le32 rb_closed_stts_rb_num:12; */
|
|
||||||
#define IWL_rb_closed_stts_rb_num_POS 0
|
|
||||||
#define IWL_rb_closed_stts_rb_num_LEN 12
|
|
||||||
#define IWL_rb_closed_stts_rb_num_SYM rb_closed
|
|
||||||
/* __le32 rsrv1:4; */
|
|
||||||
/* __le32 rb_closed_stts_rx_frame_num:12; */
|
|
||||||
#define IWL_rb_closed_stts_rx_frame_num_POS 16
|
|
||||||
#define IWL_rb_closed_stts_rx_frame_num_LEN 12
|
|
||||||
#define IWL_rb_closed_stts_rx_frame_num_SYM rb_closed
|
|
||||||
/* __le32 rsrv2:4; */
|
|
||||||
|
|
||||||
__le32 frm_finished;
|
|
||||||
/* __le32 frame_finished_stts_rb_num:12; */
|
|
||||||
#define IWL_frame_finished_stts_rb_num_POS 0
|
|
||||||
#define IWL_frame_finished_stts_rb_num_LEN 12
|
|
||||||
#define IWL_frame_finished_stts_rb_num_SYM frm_finished
|
|
||||||
/* __le32 rsrv3:4; */
|
|
||||||
/* __le32 frame_finished_stts_rx_frame_num:12; */
|
|
||||||
#define IWL_frame_finished_stts_rx_frame_num_POS 16
|
|
||||||
#define IWL_frame_finished_stts_rx_frame_num_LEN 12
|
|
||||||
#define IWL_frame_finished_stts_rx_frame_num_SYM frm_finished
|
|
||||||
/* __le32 rsrv4:4; */
|
|
||||||
|
|
||||||
__le32 padding1; /* so that allocation will be aligned to 16B */
|
|
||||||
__le32 padding2;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
#endif /* __iwl_5000_hw_h__ */
|
#endif /* __iwl_5000_hw_h__ */
|
||||||
|
|
||||||
|
|
|
@ -721,11 +721,9 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
|
||||||
iwl_write_targ_mem(priv, a, 0);
|
iwl_write_targ_mem(priv, a, 0);
|
||||||
|
|
||||||
iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
|
iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
|
||||||
(priv->shared_phys +
|
priv->scd_bc_tbls.dma >> 10);
|
||||||
offsetof(struct iwl5000_shared, queues_bc_tbls)) >> 10);
|
|
||||||
iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
|
iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
|
||||||
IWL50_SCD_QUEUECHAIN_SEL_ALL(
|
IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
|
||||||
priv->hw_params.max_txq_num));
|
|
||||||
iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
|
iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
|
||||||
|
|
||||||
/* initiate the queues */
|
/* initiate the queues */
|
||||||
|
@ -788,6 +786,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
|
priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
|
||||||
|
priv->hw_params.scd_bc_tbls_size =
|
||||||
|
IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
|
||||||
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
|
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
|
||||||
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
|
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
|
||||||
priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
|
priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
|
||||||
|
@ -853,36 +853,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwl5000_alloc_shared_mem(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
|
|
||||||
sizeof(struct iwl5000_shared),
|
|
||||||
&priv->shared_phys);
|
|
||||||
if (!priv->shared_virt)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memset(priv->shared_virt, 0, sizeof(struct iwl5000_shared));
|
|
||||||
|
|
||||||
priv->rb_closed_offset = offsetof(struct iwl5000_shared, rb_closed);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iwl5000_free_shared_mem(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
if (priv->shared_virt)
|
|
||||||
pci_free_consistent(priv->pci_dev,
|
|
||||||
sizeof(struct iwl5000_shared),
|
|
||||||
priv->shared_virt,
|
|
||||||
priv->shared_phys);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int iwl5000_shared_mem_rx_idx(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
struct iwl5000_shared *s = priv->shared_virt;
|
|
||||||
return le32_to_cpu(s->rb_closed) & 0xFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
|
* iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
|
||||||
*/
|
*/
|
||||||
|
@ -890,7 +860,7 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
|
||||||
struct iwl_tx_queue *txq,
|
struct iwl_tx_queue *txq,
|
||||||
u16 byte_cnt)
|
u16 byte_cnt)
|
||||||
{
|
{
|
||||||
struct iwl5000_shared *shared_data = priv->shared_virt;
|
struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
|
||||||
int write_ptr = txq->q.write_ptr;
|
int write_ptr = txq->q.write_ptr;
|
||||||
int txq_id = txq->q.id;
|
int txq_id = txq->q.id;
|
||||||
u8 sec_ctl = 0;
|
u8 sec_ctl = 0;
|
||||||
|
@ -919,17 +889,17 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
|
||||||
|
|
||||||
bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
|
bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
|
||||||
|
|
||||||
shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent;
|
scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
|
||||||
|
|
||||||
if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
|
if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
|
||||||
shared_data->queues_bc_tbls[txq_id].
|
scd_bc_tbl[txq_id].
|
||||||
tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
|
tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
|
static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
|
||||||
struct iwl_tx_queue *txq)
|
struct iwl_tx_queue *txq)
|
||||||
{
|
{
|
||||||
struct iwl5000_shared *shared_data = priv->shared_virt;
|
struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
|
||||||
int txq_id = txq->q.id;
|
int txq_id = txq->q.id;
|
||||||
int read_ptr = txq->q.read_ptr;
|
int read_ptr = txq->q.read_ptr;
|
||||||
u8 sta_id = 0;
|
u8 sta_id = 0;
|
||||||
|
@ -941,11 +911,10 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
|
||||||
sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
|
sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
|
||||||
|
|
||||||
bc_ent = cpu_to_le16(1 | (sta_id << 12));
|
bc_ent = cpu_to_le16(1 | (sta_id << 12));
|
||||||
shared_data->queues_bc_tbls[txq_id].
|
scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
|
||||||
tfd_offset[read_ptr] = bc_ent;
|
|
||||||
|
|
||||||
if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
|
if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
|
||||||
shared_data->queues_bc_tbls[txq_id].
|
scd_bc_tbl[txq_id].
|
||||||
tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
|
tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1458,9 +1427,6 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
|
||||||
|
|
||||||
static struct iwl_lib_ops iwl5000_lib = {
|
static struct iwl_lib_ops iwl5000_lib = {
|
||||||
.set_hw_params = iwl5000_hw_set_hw_params,
|
.set_hw_params = iwl5000_hw_set_hw_params,
|
||||||
.alloc_shared_mem = iwl5000_alloc_shared_mem,
|
|
||||||
.free_shared_mem = iwl5000_free_shared_mem,
|
|
||||||
.shared_mem_rx_idx = iwl5000_shared_mem_rx_idx,
|
|
||||||
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
|
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
|
||||||
.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
|
.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
|
||||||
.txq_set_sched = iwl5000_txq_set_sched,
|
.txq_set_sched = iwl5000_txq_set_sched,
|
||||||
|
|
|
@ -871,138 +871,6 @@ static void iwl_set_rate(struct iwl_priv *priv)
|
||||||
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
|
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
|
||||||
|
|
||||||
#include "iwl-spectrum.h"
|
|
||||||
|
|
||||||
#define BEACON_TIME_MASK_LOW 0x00FFFFFF
|
|
||||||
#define BEACON_TIME_MASK_HIGH 0xFF000000
|
|
||||||
#define TIME_UNIT 1024
|
|
||||||
|
|
||||||
/*
|
|
||||||
* extended beacon time format
|
|
||||||
* time in usec will be changed into a 32-bit value in 8:24 format
|
|
||||||
* the high 1 byte is the beacon counts
|
|
||||||
* the lower 3 bytes is the time in usec within one beacon interval
|
|
||||||
*/
|
|
||||||
|
|
||||||
static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
|
|
||||||
{
|
|
||||||
u32 quot;
|
|
||||||
u32 rem;
|
|
||||||
u32 interval = beacon_interval * 1024;
|
|
||||||
|
|
||||||
if (!interval || !usec)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
|
|
||||||
rem = (usec % interval) & BEACON_TIME_MASK_LOW;
|
|
||||||
|
|
||||||
return (quot << 24) + rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* base is usually what we get from ucode with each received frame,
|
|
||||||
* the same as HW timer counter counting down
|
|
||||||
*/
|
|
||||||
|
|
||||||
static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
|
|
||||||
{
|
|
||||||
u32 base_low = base & BEACON_TIME_MASK_LOW;
|
|
||||||
u32 addon_low = addon & BEACON_TIME_MASK_LOW;
|
|
||||||
u32 interval = beacon_interval * TIME_UNIT;
|
|
||||||
u32 res = (base & BEACON_TIME_MASK_HIGH) +
|
|
||||||
(addon & BEACON_TIME_MASK_HIGH);
|
|
||||||
|
|
||||||
if (base_low > addon_low)
|
|
||||||
res += base_low - addon_low;
|
|
||||||
else if (base_low < addon_low) {
|
|
||||||
res += interval + base_low - addon_low;
|
|
||||||
res += (1 << 24);
|
|
||||||
} else
|
|
||||||
res += (1 << 24);
|
|
||||||
|
|
||||||
return cpu_to_le32(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int iwl_get_measurement(struct iwl_priv *priv,
|
|
||||||
struct ieee80211_measurement_params *params,
|
|
||||||
u8 type)
|
|
||||||
{
|
|
||||||
struct iwl4965_spectrum_cmd spectrum;
|
|
||||||
struct iwl_rx_packet *res;
|
|
||||||
struct iwl_host_cmd cmd = {
|
|
||||||
.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
|
|
||||||
.data = (void *)&spectrum,
|
|
||||||
.meta.flags = CMD_WANT_SKB,
|
|
||||||
};
|
|
||||||
u32 add_time = le64_to_cpu(params->start_time);
|
|
||||||
int rc;
|
|
||||||
int spectrum_resp_status;
|
|
||||||
int duration = le16_to_cpu(params->duration);
|
|
||||||
|
|
||||||
if (iwl_is_associated(priv))
|
|
||||||
add_time =
|
|
||||||
iwl_usecs_to_beacons(
|
|
||||||
le64_to_cpu(params->start_time) - priv->last_tsf,
|
|
||||||
le16_to_cpu(priv->rxon_timing.beacon_interval));
|
|
||||||
|
|
||||||
memset(&spectrum, 0, sizeof(spectrum));
|
|
||||||
|
|
||||||
spectrum.channel_count = cpu_to_le16(1);
|
|
||||||
spectrum.flags =
|
|
||||||
RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
|
|
||||||
spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
|
|
||||||
cmd.len = sizeof(spectrum);
|
|
||||||
spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
|
|
||||||
|
|
||||||
if (iwl_is_associated(priv))
|
|
||||||
spectrum.start_time =
|
|
||||||
iwl_add_beacon_time(priv->last_beacon_time,
|
|
||||||
add_time,
|
|
||||||
le16_to_cpu(priv->rxon_timing.beacon_interval));
|
|
||||||
else
|
|
||||||
spectrum.start_time = 0;
|
|
||||||
|
|
||||||
spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
|
|
||||||
spectrum.channels[0].channel = params->channel;
|
|
||||||
spectrum.channels[0].type = type;
|
|
||||||
if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
|
|
||||||
spectrum.flags |= RXON_FLG_BAND_24G_MSK |
|
|
||||||
RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
|
|
||||||
|
|
||||||
rc = iwl_send_cmd_sync(priv, &cmd);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
|
|
||||||
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
|
|
||||||
IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
|
|
||||||
rc = -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
|
|
||||||
switch (spectrum_resp_status) {
|
|
||||||
case 0: /* Command will be handled */
|
|
||||||
if (res->u.spectrum.id != 0xff) {
|
|
||||||
IWL_DEBUG_INFO
|
|
||||||
("Replaced existing measurement: %d\n",
|
|
||||||
res->u.spectrum.id);
|
|
||||||
priv->measurement_status &= ~MEASUREMENT_READY;
|
|
||||||
}
|
|
||||||
priv->measurement_status |= MEASUREMENT_ACTIVE;
|
|
||||||
rc = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: /* Command will not be handled */
|
|
||||||
rc = -EAGAIN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_kfree_skb_any(cmd.meta.u.skb);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
|
@ -1072,24 +940,6 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||||
priv->staging_rxon.channel = csa->channel;
|
priv->staging_rxon.channel = csa->channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
|
|
||||||
struct iwl_rx_mem_buffer *rxb)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
|
||||||
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
|
||||||
struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
|
|
||||||
|
|
||||||
if (!report->state) {
|
|
||||||
IWL_DEBUG(IWL_DL_11H,
|
|
||||||
"Spectrum Measure Notification: Start\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&priv->measure_report, report, sizeof(*report));
|
|
||||||
priv->measurement_status |= MEASUREMENT_READY;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
|
static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
|
||||||
struct iwl_rx_mem_buffer *rxb)
|
struct iwl_rx_mem_buffer *rxb)
|
||||||
{
|
{
|
||||||
|
@ -1298,8 +1148,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
|
||||||
priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
|
priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
|
||||||
priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
|
priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
|
||||||
priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
|
priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
|
||||||
priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
|
|
||||||
iwl_rx_spectrum_measure_notif;
|
|
||||||
priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
|
priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
|
||||||
priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
|
priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
|
||||||
iwl_rx_pm_debug_statistics_notif;
|
iwl_rx_pm_debug_statistics_notif;
|
||||||
|
@ -1313,6 +1161,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
|
||||||
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
|
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
|
||||||
priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
|
priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
|
||||||
|
|
||||||
|
iwl_setup_spectrum_handlers(priv);
|
||||||
iwl_setup_rx_scan_handlers(priv);
|
iwl_setup_rx_scan_handlers(priv);
|
||||||
|
|
||||||
/* status change handler */
|
/* status change handler */
|
||||||
|
@ -1359,7 +1208,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
|
||||||
|
|
||||||
/* uCode's read index (stored in shared DRAM) indicates the last Rx
|
/* uCode's read index (stored in shared DRAM) indicates the last Rx
|
||||||
* buffer that the driver may process (last buffer filled by ucode). */
|
* buffer that the driver may process (last buffer filled by ucode). */
|
||||||
r = priv->cfg->ops->lib->shared_mem_rx_idx(priv);
|
r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
|
||||||
i = rxq->read;
|
i = rxq->read;
|
||||||
|
|
||||||
/* Rx interrupt, but nothing sent from uCode */
|
/* Rx interrupt, but nothing sent from uCode */
|
||||||
|
@ -2002,6 +1851,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* temporary */
|
||||||
|
static int iwl_mac_beacon_update(struct ieee80211_hw *hw,
|
||||||
|
struct sk_buff *skb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iwl_alive_start - called after REPLY_ALIVE notification received
|
* iwl_alive_start - called after REPLY_ALIVE notification received
|
||||||
* from protocol/runtime uCode (initialization uCode's
|
* from protocol/runtime uCode (initialization uCode's
|
||||||
|
@ -2084,6 +1937,15 @@ static void iwl_alive_start(struct iwl_priv *priv)
|
||||||
|
|
||||||
iwl_power_update_mode(priv, 1);
|
iwl_power_update_mode(priv, 1);
|
||||||
|
|
||||||
|
/* reassociate for ADHOC mode */
|
||||||
|
if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
|
||||||
|
struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
|
||||||
|
priv->vif);
|
||||||
|
if (beacon)
|
||||||
|
iwl_mac_beacon_update(priv->hw, beacon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
|
if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
|
||||||
iwl_set_mode(priv, priv->iw_mode);
|
iwl_set_mode(priv, priv->iw_mode);
|
||||||
|
|
||||||
|
@ -2183,8 +2045,6 @@ static void __iwl_down(struct iwl_priv *priv)
|
||||||
priv->cfg->ops->lib->apm_ops.stop(priv);
|
priv->cfg->ops->lib->apm_ops.stop(priv);
|
||||||
else
|
else
|
||||||
priv->cfg->ops->lib->apm_ops.reset(priv);
|
priv->cfg->ops->lib->apm_ops.reset(priv);
|
||||||
priv->cfg->ops->lib->free_shared_mem(priv);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
|
memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
|
||||||
|
|
||||||
|
@ -2237,12 +2097,6 @@ static int __iwl_up(struct iwl_priv *priv)
|
||||||
|
|
||||||
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
|
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
|
||||||
|
|
||||||
ret = priv->cfg->ops->lib->alloc_shared_mem(priv);
|
|
||||||
if (ret) {
|
|
||||||
IWL_ERROR("Unable to allocate shared memory\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = iwl_hw_nic_init(priv);
|
ret = iwl_hw_nic_init(priv);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
IWL_ERROR("Unable to init nic\n");
|
IWL_ERROR("Unable to init nic\n");
|
||||||
|
@ -2930,8 +2784,6 @@ static void iwl_config_ap(struct iwl_priv *priv)
|
||||||
* clear sta table, add BCAST sta... */
|
* clear sta table, add BCAST sta... */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* temporary */
|
|
||||||
static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
|
|
||||||
|
|
||||||
static int iwl_mac_config_interface(struct ieee80211_hw *hw,
|
static int iwl_mac_config_interface(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_vif *vif,
|
struct ieee80211_vif *vif,
|
||||||
|
@ -2953,7 +2805,9 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
|
||||||
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
|
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
|
||||||
if (!beacon)
|
if (!beacon)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
mutex_lock(&priv->mutex);
|
||||||
rc = iwl_mac_beacon_update(hw, beacon);
|
rc = iwl_mac_beacon_update(hw, beacon);
|
||||||
|
mutex_unlock(&priv->mutex);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -3529,18 +3383,15 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
__le64 timestamp;
|
__le64 timestamp;
|
||||||
|
|
||||||
mutex_lock(&priv->mutex);
|
|
||||||
IWL_DEBUG_MAC80211("enter\n");
|
IWL_DEBUG_MAC80211("enter\n");
|
||||||
|
|
||||||
if (!iwl_is_ready_rf(priv)) {
|
if (!iwl_is_ready_rf(priv)) {
|
||||||
IWL_DEBUG_MAC80211("leave - RF not ready\n");
|
IWL_DEBUG_MAC80211("leave - RF not ready\n");
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
|
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
|
||||||
IWL_DEBUG_MAC80211("leave - not IBSS\n");
|
IWL_DEBUG_MAC80211("leave - not IBSS\n");
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3562,7 +3413,6 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||||
|
|
||||||
iwl_post_associate(priv);
|
iwl_post_associate(priv);
|
||||||
|
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3766,79 +3616,6 @@ static ssize_t store_filter_flags(struct device *d,
|
||||||
static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
|
static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
|
||||||
store_filter_flags);
|
store_filter_flags);
|
||||||
|
|
||||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
|
||||||
|
|
||||||
static ssize_t show_measurement(struct device *d,
|
|
||||||
struct device_attribute *attr, char *buf)
|
|
||||||
{
|
|
||||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
|
||||||
struct iwl4965_spectrum_notification measure_report;
|
|
||||||
u32 size = sizeof(measure_report), len = 0, ofs = 0;
|
|
||||||
u8 *data = (u8 *)&measure_report;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
|
||||||
if (!(priv->measurement_status & MEASUREMENT_READY)) {
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memcpy(&measure_report, &priv->measure_report, size);
|
|
||||||
priv->measurement_status = 0;
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
|
||||||
|
|
||||||
while (size && (PAGE_SIZE - len)) {
|
|
||||||
hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
|
|
||||||
PAGE_SIZE - len, 1);
|
|
||||||
len = strlen(buf);
|
|
||||||
if (PAGE_SIZE - len)
|
|
||||||
buf[len++] = '\n';
|
|
||||||
|
|
||||||
ofs += 16;
|
|
||||||
size -= min(size, 16U);
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t store_measurement(struct device *d,
|
|
||||||
struct device_attribute *attr,
|
|
||||||
const char *buf, size_t count)
|
|
||||||
{
|
|
||||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
|
||||||
struct ieee80211_measurement_params params = {
|
|
||||||
.channel = le16_to_cpu(priv->active_rxon.channel),
|
|
||||||
.start_time = cpu_to_le64(priv->last_tsf),
|
|
||||||
.duration = cpu_to_le16(1),
|
|
||||||
};
|
|
||||||
u8 type = IWL_MEASURE_BASIC;
|
|
||||||
u8 buffer[32];
|
|
||||||
u8 channel;
|
|
||||||
|
|
||||||
if (count) {
|
|
||||||
char *p = buffer;
|
|
||||||
strncpy(buffer, buf, min(sizeof(buffer), count));
|
|
||||||
channel = simple_strtoul(p, NULL, 0);
|
|
||||||
if (channel)
|
|
||||||
params.channel = channel;
|
|
||||||
|
|
||||||
p = buffer;
|
|
||||||
while (*p && *p != ' ')
|
|
||||||
p++;
|
|
||||||
if (*p)
|
|
||||||
type = simple_strtoul(p + 1, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
IWL_DEBUG_INFO("Invoking measurement of type %d on "
|
|
||||||
"channel %d (for '%s')\n", type, params.channel, buf);
|
|
||||||
iwl_get_measurement(priv, ¶ms, type);
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
|
|
||||||
show_measurement, store_measurement);
|
|
||||||
#endif /* CONFIG_IWLAGN_SPECTRUM_MEASUREMENT */
|
|
||||||
|
|
||||||
static ssize_t store_retry_rate(struct device *d,
|
static ssize_t store_retry_rate(struct device *d,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
|
@ -4091,9 +3868,6 @@ static struct attribute *iwl_sysfs_entries[] = {
|
||||||
&dev_attr_channels.attr,
|
&dev_attr_channels.attr,
|
||||||
&dev_attr_flags.attr,
|
&dev_attr_flags.attr,
|
||||||
&dev_attr_filter_flags.attr,
|
&dev_attr_filter_flags.attr,
|
||||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
|
||||||
&dev_attr_measurement.attr,
|
|
||||||
#endif
|
|
||||||
&dev_attr_power_level.attr,
|
&dev_attr_power_level.attr,
|
||||||
&dev_attr_retry_rate.attr,
|
&dev_attr_retry_rate.attr,
|
||||||
&dev_attr_statistics.attr,
|
&dev_attr_statistics.attr,
|
||||||
|
|
|
@ -213,10 +213,11 @@ struct iwl_cmd_header {
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 4965 rate_n_flags bit fields
|
* iwlagn rate_n_flags bit fields
|
||||||
*
|
*
|
||||||
* rate_n_flags format is used in following 4965 commands:
|
* rate_n_flags format is used in following iwlagn commands:
|
||||||
* REPLY_RX (response only)
|
* REPLY_RX (response only)
|
||||||
|
* REPLY_RX_MPDU (response only)
|
||||||
* REPLY_TX (both command and response)
|
* REPLY_TX (both command and response)
|
||||||
* REPLY_TX_LINK_QUALITY_CMD
|
* REPLY_TX_LINK_QUALITY_CMD
|
||||||
*
|
*
|
||||||
|
@ -230,8 +231,9 @@ struct iwl_cmd_header {
|
||||||
* 6) 54 Mbps
|
* 6) 54 Mbps
|
||||||
* 7) 60 Mbps
|
* 7) 60 Mbps
|
||||||
*
|
*
|
||||||
* 3: 0) Single stream (SISO)
|
* 4-3: 0) Single stream (SISO)
|
||||||
* 1) Dual stream (MIMO)
|
* 1) Dual stream (MIMO)
|
||||||
|
* 2) Triple stream (MIMO)
|
||||||
*
|
*
|
||||||
* 5: Value of 0x20 in bits 7:0 indicates 6 Mbps FAT duplicate data
|
* 5: Value of 0x20 in bits 7:0 indicates 6 Mbps FAT duplicate data
|
||||||
*
|
*
|
||||||
|
@ -252,8 +254,8 @@ struct iwl_cmd_header {
|
||||||
* 110) 11 Mbps
|
* 110) 11 Mbps
|
||||||
*/
|
*/
|
||||||
#define RATE_MCS_CODE_MSK 0x7
|
#define RATE_MCS_CODE_MSK 0x7
|
||||||
#define RATE_MCS_MIMO_POS 3
|
#define RATE_MCS_SPATIAL_POS 3
|
||||||
#define RATE_MCS_MIMO_MSK 0x8
|
#define RATE_MCS_SPATIAL_MSK 0x18
|
||||||
#define RATE_MCS_HT_DUP_POS 5
|
#define RATE_MCS_HT_DUP_POS 5
|
||||||
#define RATE_MCS_HT_DUP_MSK 0x20
|
#define RATE_MCS_HT_DUP_MSK 0x20
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,9 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <net/mac80211.h>
|
#include <net/mac80211.h>
|
||||||
|
|
||||||
struct iwl_priv; /* FIXME: remove */
|
|
||||||
#include "iwl-debug.h"
|
|
||||||
#include "iwl-eeprom.h"
|
#include "iwl-eeprom.h"
|
||||||
#include "iwl-dev.h" /* FIXME: remove */
|
#include "iwl-dev.h" /* FIXME: remove */
|
||||||
|
#include "iwl-debug.h"
|
||||||
#include "iwl-core.h"
|
#include "iwl-core.h"
|
||||||
#include "iwl-io.h"
|
#include "iwl-io.h"
|
||||||
#include "iwl-rfkill.h"
|
#include "iwl-rfkill.h"
|
||||||
|
@ -190,52 +189,6 @@ void iwl_hw_detect(struct iwl_priv *priv)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iwl_hw_detect);
|
EXPORT_SYMBOL(iwl_hw_detect);
|
||||||
|
|
||||||
/* Tell nic where to find the "keep warm" buffer */
|
|
||||||
int iwl_kw_init(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&priv->lock, flags);
|
|
||||||
ret = iwl_grab_nic_access(priv);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG,
|
|
||||||
priv->kw.dma_addr >> 4);
|
|
||||||
iwl_release_nic_access(priv);
|
|
||||||
out:
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int iwl_kw_alloc(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
struct pci_dev *dev = priv->pci_dev;
|
|
||||||
struct iwl_kw *kw = &priv->kw;
|
|
||||||
|
|
||||||
kw->size = IWL_KW_SIZE;
|
|
||||||
kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr);
|
|
||||||
if (!kw->v_addr)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* iwl_kw_free - Free the "keep warm" buffer
|
|
||||||
*/
|
|
||||||
void iwl_kw_free(struct iwl_priv *priv)
|
|
||||||
{
|
|
||||||
struct pci_dev *dev = priv->pci_dev;
|
|
||||||
struct iwl_kw *kw = &priv->kw;
|
|
||||||
|
|
||||||
if (kw->v_addr) {
|
|
||||||
pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr);
|
|
||||||
memset(kw, 0, sizeof(*kw));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int iwl_hw_nic_init(struct iwl_priv *priv)
|
int iwl_hw_nic_init(struct iwl_priv *priv)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
|
@ -102,10 +102,6 @@ struct iwl_hcmd_utils_ops {
|
||||||
struct iwl_lib_ops {
|
struct iwl_lib_ops {
|
||||||
/* set hw dependent parameters */
|
/* set hw dependent parameters */
|
||||||
int (*set_hw_params)(struct iwl_priv *priv);
|
int (*set_hw_params)(struct iwl_priv *priv);
|
||||||
/* ucode shared memory */
|
|
||||||
int (*alloc_shared_mem)(struct iwl_priv *priv);
|
|
||||||
void (*free_shared_mem)(struct iwl_priv *priv);
|
|
||||||
int (*shared_mem_rx_idx)(struct iwl_priv *priv);
|
|
||||||
/* Handling TX */
|
/* Handling TX */
|
||||||
void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
|
void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
|
||||||
struct iwl_tx_queue *txq,
|
struct iwl_tx_queue *txq,
|
||||||
|
@ -198,10 +194,6 @@ int iwl_setup_mac(struct iwl_priv *priv);
|
||||||
int iwl_set_hw_params(struct iwl_priv *priv);
|
int iwl_set_hw_params(struct iwl_priv *priv);
|
||||||
int iwl_init_drv(struct iwl_priv *priv);
|
int iwl_init_drv(struct iwl_priv *priv);
|
||||||
void iwl_uninit_drv(struct iwl_priv *priv);
|
void iwl_uninit_drv(struct iwl_priv *priv);
|
||||||
/* "keep warm" functions */
|
|
||||||
int iwl_kw_init(struct iwl_priv *priv);
|
|
||||||
int iwl_kw_alloc(struct iwl_priv *priv);
|
|
||||||
void iwl_kw_free(struct iwl_priv *priv);
|
|
||||||
|
|
||||||
/*****************************************************
|
/*****************************************************
|
||||||
* RX
|
* RX
|
||||||
|
@ -297,6 +289,14 @@ int iwl_send_calib_results(struct iwl_priv *priv);
|
||||||
int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
|
int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
|
||||||
void iwl_calib_free_results(struct iwl_priv *priv);
|
void iwl_calib_free_results(struct iwl_priv *priv);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Spectrum Measureemtns in iwl-spectrum.c
|
||||||
|
******************************************************************************/
|
||||||
|
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||||
|
void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
|
||||||
|
#else
|
||||||
|
static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
|
||||||
|
#endif
|
||||||
/*****************************************************
|
/*****************************************************
|
||||||
* S e n d i n g H o s t C o m m a n d s *
|
* S e n d i n g H o s t C o m m a n d s *
|
||||||
*****************************************************/
|
*****************************************************/
|
||||||
|
|
|
@ -40,6 +40,13 @@ do { if ((priv->debug_level & (level)) && net_ratelimit()) \
|
||||||
dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
|
dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
|
||||||
in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
|
in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
|
||||||
|
|
||||||
|
#define iwl_print_hex_dump(priv, level, p, len) \
|
||||||
|
do { \
|
||||||
|
if (priv->debug_level & level) \
|
||||||
|
print_hex_dump(KERN_DEBUG, "iwl data: ", \
|
||||||
|
DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||||
struct iwl_debugfs {
|
struct iwl_debugfs {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -70,6 +77,9 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv);
|
||||||
#else
|
#else
|
||||||
#define IWL_DEBUG(level, fmt, args...)
|
#define IWL_DEBUG(level, fmt, args...)
|
||||||
#define IWL_DEBUG_LIMIT(level, fmt, args...)
|
#define IWL_DEBUG_LIMIT(level, fmt, args...)
|
||||||
|
static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
|
||||||
|
void *p, u32 len)
|
||||||
|
{}
|
||||||
#endif /* CONFIG_IWLWIFI_DEBUG */
|
#endif /* CONFIG_IWLWIFI_DEBUG */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,6 @@ struct iwl_host_cmd {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct iwl_rx_queue - Rx queue
|
* struct iwl_rx_queue - Rx queue
|
||||||
* @processed: Internal index to last handled Rx packet
|
|
||||||
* @read: Shared index to newest available Rx buffer
|
* @read: Shared index to newest available Rx buffer
|
||||||
* @write: Shared index to oldest written Rx packet
|
* @write: Shared index to oldest written Rx packet
|
||||||
* @free_count: Number of pre-allocated buffers in rx_free
|
* @free_count: Number of pre-allocated buffers in rx_free
|
||||||
|
@ -316,13 +315,14 @@ struct iwl_rx_queue {
|
||||||
dma_addr_t dma_addr;
|
dma_addr_t dma_addr;
|
||||||
struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
|
struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
|
||||||
struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE];
|
struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE];
|
||||||
u32 processed;
|
|
||||||
u32 read;
|
u32 read;
|
||||||
u32 write;
|
u32 write;
|
||||||
u32 free_count;
|
u32 free_count;
|
||||||
struct list_head rx_free;
|
struct list_head rx_free;
|
||||||
struct list_head rx_used;
|
struct list_head rx_used;
|
||||||
int need_update;
|
int need_update;
|
||||||
|
struct iwl_rb_status *rb_stts;
|
||||||
|
dma_addr_t rb_stts_dma;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -507,6 +507,7 @@ struct iwl_sensitivity_ranges {
|
||||||
/**
|
/**
|
||||||
* struct iwl_hw_params
|
* struct iwl_hw_params
|
||||||
* @max_txq_num: Max # Tx queues supported
|
* @max_txq_num: Max # Tx queues supported
|
||||||
|
* @scd_bc_tbls_size: size of scheduler byte count tables
|
||||||
* @tx/rx_chains_num: Number of TX/RX chains
|
* @tx/rx_chains_num: Number of TX/RX chains
|
||||||
* @valid_tx/rx_ant: usable antennas
|
* @valid_tx/rx_ant: usable antennas
|
||||||
* @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
|
* @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
|
||||||
|
@ -524,6 +525,7 @@ struct iwl_sensitivity_ranges {
|
||||||
*/
|
*/
|
||||||
struct iwl_hw_params {
|
struct iwl_hw_params {
|
||||||
u16 max_txq_num;
|
u16 max_txq_num;
|
||||||
|
u16 scd_bc_tbls_size;
|
||||||
u8 tx_chains_num;
|
u8 tx_chains_num;
|
||||||
u8 rx_chains_num;
|
u8 rx_chains_num;
|
||||||
u8 valid_tx_ant;
|
u8 valid_tx_ant;
|
||||||
|
@ -605,13 +607,9 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
|
||||||
struct iwl_priv;
|
struct iwl_priv;
|
||||||
|
|
||||||
|
|
||||||
/* Structures, enum, and defines specific to the 4965 */
|
struct iwl_dma_ptr {
|
||||||
|
dma_addr_t dma;
|
||||||
#define IWL_KW_SIZE 0x1000 /*4k */
|
void *addr;
|
||||||
|
|
||||||
struct iwl_kw {
|
|
||||||
dma_addr_t dma_addr;
|
|
||||||
void *v_addr;
|
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -907,7 +905,9 @@ struct iwl_priv {
|
||||||
struct iwl_rx_queue rxq;
|
struct iwl_rx_queue rxq;
|
||||||
struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES];
|
struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES];
|
||||||
unsigned long txq_ctx_active_msk;
|
unsigned long txq_ctx_active_msk;
|
||||||
struct iwl_kw kw; /* keep warm address */
|
struct iwl_dma_ptr kw; /* keep warm address */
|
||||||
|
struct iwl_dma_ptr scd_bc_tbls;
|
||||||
|
|
||||||
u32 scd_base_addr; /* scheduler sram base address */
|
u32 scd_base_addr; /* scheduler sram base address */
|
||||||
|
|
||||||
unsigned long status;
|
unsigned long status;
|
||||||
|
@ -967,11 +967,7 @@ struct iwl_priv {
|
||||||
struct ieee80211_vif *vif;
|
struct ieee80211_vif *vif;
|
||||||
|
|
||||||
struct iwl_hw_params hw_params;
|
struct iwl_hw_params hw_params;
|
||||||
/* driver/uCode shared Tx Byte Counts and Rx status */
|
|
||||||
void *shared_virt;
|
|
||||||
int rb_closed_offset;
|
|
||||||
/* Physical Pointer to Tx Byte Counts and Rx status */
|
|
||||||
dma_addr_t shared_phys;
|
|
||||||
|
|
||||||
/* Current association information needed to configure the
|
/* Current association information needed to configure the
|
||||||
* hardware */
|
* hardware */
|
||||||
|
@ -1093,23 +1089,6 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch)
|
||||||
return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
|
return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
|
||||||
static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
|
|
||||||
void *p, u32 len)
|
|
||||||
{
|
|
||||||
if (!(priv->debug_level & level))
|
|
||||||
return;
|
|
||||||
|
|
||||||
print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
|
|
||||||
p, len, 1);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
|
|
||||||
void *p, u32 len)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern const struct iwl_channel_info *iwl_get_channel_info(
|
extern const struct iwl_channel_info *iwl_get_channel_info(
|
||||||
const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
|
const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
|
||||||
|
|
||||||
|
|
|
@ -266,6 +266,8 @@
|
||||||
#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000)
|
#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000)
|
||||||
#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000)
|
#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000)
|
||||||
|
|
||||||
|
#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME (0x00008000)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rx Shared Status Registers (RSSR)
|
* Rx Shared Status Registers (RSSR)
|
||||||
|
@ -403,5 +405,86 @@
|
||||||
#define TFD_QUEUE_SIZE_BC_DUP (64)
|
#define TFD_QUEUE_SIZE_BC_DUP (64)
|
||||||
#define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP)
|
#define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct iwl_rb_status - reseve buffer status
|
||||||
|
* host memory mapped FH registers
|
||||||
|
* @closed_rb_num [0:11] - Indicates the index of the RB which was closed
|
||||||
|
* @closed_fr_num [0:11] - Indicates the index of the RX Frame which was closed
|
||||||
|
* @finished_rb_num [0:11] - Indicates the index of the current RB
|
||||||
|
* in which the last frame was written to
|
||||||
|
* @finished_fr_num [0:11] - Indicates the index of the RX Frame
|
||||||
|
* which was transfered
|
||||||
|
*/
|
||||||
|
struct iwl_rb_status {
|
||||||
|
__le16 closed_rb_num;
|
||||||
|
__le16 closed_fr_num;
|
||||||
|
__le16 finished_rb_num;
|
||||||
|
__le16 finished_fr_nam;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define IWL_TX_DMA_MASK DMA_BIT_MASK(36)
|
||||||
|
|
||||||
|
#define IWL_NUM_OF_TBS 20
|
||||||
|
|
||||||
|
static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr)
|
||||||
|
{
|
||||||
|
return (sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0) & 0xF;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* struct iwl_tfd_tb transmit buffer descriptor within transmit frame descriptor
|
||||||
|
*
|
||||||
|
* This structure contains dma address and length of transmission address
|
||||||
|
*
|
||||||
|
* @lo: low [31:0] portion of the dma address of TX buffer
|
||||||
|
* every even is unaligned on 16 bit boundary
|
||||||
|
* @hi_n_len 0-3 [35:32] portion of dma
|
||||||
|
* 4-16 length of the tx buffer
|
||||||
|
*/
|
||||||
|
struct iwl_tfd_tb {
|
||||||
|
__le32 lo;
|
||||||
|
__le16 hi_n_len;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct iwl_tfd
|
||||||
|
*
|
||||||
|
* Transmit Frame Descriptor (TFD)
|
||||||
|
*
|
||||||
|
* @ __reserved1[3] reserved
|
||||||
|
* @ num_tbs 0-5 number of active tbs
|
||||||
|
* 6-7 padding (not used)
|
||||||
|
* @ tbs[20] transmit frame buffer descriptors
|
||||||
|
* @ __pad padding
|
||||||
|
*
|
||||||
|
* Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM.
|
||||||
|
* Both driver and device share these circular buffers, each of which must be
|
||||||
|
* contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes
|
||||||
|
*
|
||||||
|
* Driver must indicate the physical address of the base of each
|
||||||
|
* circular buffer via the FH_MEM_CBBC_QUEUE registers.
|
||||||
|
*
|
||||||
|
* Each TFD contains pointer/size information for up to 20 data buffers
|
||||||
|
* in host DRAM. These buffers collectively contain the (one) frame described
|
||||||
|
* by the TFD. Each buffer must be a single contiguous block of memory within
|
||||||
|
* itself, but buffers may be scattered in host DRAM. Each buffer has max size
|
||||||
|
* of (4K - 4). The concatenates all of a TFD's buffers into a single
|
||||||
|
* Tx frame, up to 8 KBytes in size.
|
||||||
|
*
|
||||||
|
* A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
|
||||||
|
*
|
||||||
|
* Bit fields in the control dword (val0):
|
||||||
|
*/
|
||||||
|
struct iwl_tfd {
|
||||||
|
u8 __reserved1[3];
|
||||||
|
u8 num_tbs;
|
||||||
|
struct iwl_tfd_tb tbs[IWL_NUM_OF_TBS];
|
||||||
|
__le32 __pad;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|
||||||
|
/* Keep Warm Size */
|
||||||
|
#define IWL_KW_SIZE 0x1000 /*4k */
|
||||||
|
|
||||||
#endif /* !__iwl_fh_h__ */
|
#endif /* !__iwl_fh_h__ */
|
||||||
|
|
|
@ -257,15 +257,11 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
|
||||||
struct iwl_power_mgr *setting = &(priv->power_data);
|
struct iwl_power_mgr *setting = &(priv->power_data);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u16 uninitialized_var(final_mode);
|
u16 uninitialized_var(final_mode);
|
||||||
|
bool update_chains;
|
||||||
|
|
||||||
/* Don't update the RX chain when chain noise calibration is running */
|
/* Don't update the RX chain when chain noise calibration is running */
|
||||||
if (priv->chain_noise_data.state != IWL_CHAIN_NOISE_DONE &&
|
update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
|
||||||
priv->chain_noise_data.state != IWL_CHAIN_NOISE_ALIVE) {
|
priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
|
||||||
IWL_DEBUG_POWER("Cannot update the power, chain noise "
|
|
||||||
"calibration running: %d\n",
|
|
||||||
priv->chain_noise_data.state);
|
|
||||||
return -EAGAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If on battery, set to 3,
|
/* If on battery, set to 3,
|
||||||
* if plugged into AC power, set to CAM ("continuously aware mode"),
|
* if plugged into AC power, set to CAM ("continuously aware mode"),
|
||||||
|
@ -313,9 +309,12 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
|
||||||
else
|
else
|
||||||
set_bit(STATUS_POWER_PMI, &priv->status);
|
set_bit(STATUS_POWER_PMI, &priv->status);
|
||||||
|
|
||||||
if (priv->cfg->ops->lib->update_chain_flags)
|
if (priv->cfg->ops->lib->update_chain_flags && update_chains)
|
||||||
priv->cfg->ops->lib->update_chain_flags(priv);
|
priv->cfg->ops->lib->update_chain_flags(priv);
|
||||||
|
else
|
||||||
|
IWL_DEBUG_POWER("Cannot update the power, chain noise "
|
||||||
|
"calibration running: %d\n",
|
||||||
|
priv->chain_noise_data.state);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
setting->power_mode = final_mode;
|
setting->power_mode = final_mode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,8 +218,7 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
|
||||||
|
|
||||||
/* If we've added more space for the firmware to place data, tell it.
|
/* If we've added more space for the firmware to place data, tell it.
|
||||||
* Increment device's write pointer in multiples of 8. */
|
* Increment device's write pointer in multiples of 8. */
|
||||||
if ((write != (rxq->write & ~0x7))
|
if (write != (rxq->write & ~0x7)) {
|
||||||
|| (abs(rxq->write - rxq->read) > 7)) {
|
|
||||||
spin_lock_irqsave(&rxq->lock, flags);
|
spin_lock_irqsave(&rxq->lock, flags);
|
||||||
rxq->need_update = 1;
|
rxq->need_update = 1;
|
||||||
spin_unlock_irqrestore(&rxq->lock, flags);
|
spin_unlock_irqrestore(&rxq->lock, flags);
|
||||||
|
@ -317,7 +316,10 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
|
||||||
|
|
||||||
pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
|
pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
|
||||||
rxq->dma_addr);
|
rxq->dma_addr);
|
||||||
|
pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status),
|
||||||
|
rxq->rb_stts, rxq->rb_stts_dma);
|
||||||
rxq->bd = NULL;
|
rxq->bd = NULL;
|
||||||
|
rxq->rb_stts = NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iwl_rx_queue_free);
|
EXPORT_SYMBOL(iwl_rx_queue_free);
|
||||||
|
|
||||||
|
@ -334,7 +336,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
|
||||||
/* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
|
/* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
|
||||||
rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
|
rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
|
||||||
if (!rxq->bd)
|
if (!rxq->bd)
|
||||||
return -ENOMEM;
|
goto err_bd;
|
||||||
|
|
||||||
|
rxq->rb_stts = pci_alloc_consistent(dev, sizeof(struct iwl_rb_status),
|
||||||
|
&rxq->rb_stts_dma);
|
||||||
|
if (!rxq->rb_stts)
|
||||||
|
goto err_rb;
|
||||||
|
|
||||||
/* Fill the rx_used queue with _all_ of the Rx buffers */
|
/* Fill the rx_used queue with _all_ of the Rx buffers */
|
||||||
for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
|
for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
|
||||||
|
@ -346,6 +353,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
|
||||||
rxq->free_count = 0;
|
rxq->free_count = 0;
|
||||||
rxq->need_update = 0;
|
rxq->need_update = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_rb:
|
||||||
|
pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
|
||||||
|
rxq->dma_addr);
|
||||||
|
err_bd:
|
||||||
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iwl_rx_queue_alloc);
|
EXPORT_SYMBOL(iwl_rx_queue_alloc);
|
||||||
|
|
||||||
|
@ -412,7 +425,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
|
||||||
|
|
||||||
/* Tell device where in DRAM to update its Rx status */
|
/* Tell device where in DRAM to update its Rx status */
|
||||||
iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
|
iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
|
||||||
(priv->shared_phys + priv->rb_closed_offset) >> 4);
|
rxq->rb_stts_dma >> 4);
|
||||||
|
|
||||||
/* Enable Rx DMA
|
/* Enable Rx DMA
|
||||||
* FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
|
* FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
|
||||||
|
@ -426,6 +439,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
|
||||||
FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
|
FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
|
||||||
FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
|
FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
|
||||||
FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
|
FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
|
||||||
|
FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME |
|
||||||
rb_size|
|
rb_size|
|
||||||
(rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
|
(rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
|
||||||
(rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
|
(rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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 Street, Fifth Floor, Boston, MA 02110, USA
|
||||||
|
*
|
||||||
|
* The full GNU General Public License is included in this distribution in the
|
||||||
|
* file called LICENSE.
|
||||||
|
*
|
||||||
|
* Contact Information:
|
||||||
|
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||||
|
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/wireless.h>
|
||||||
|
|
||||||
|
#include <net/mac80211.h>
|
||||||
|
|
||||||
|
#include "iwl-eeprom.h"
|
||||||
|
#include "iwl-dev.h"
|
||||||
|
#include "iwl-core.h"
|
||||||
|
#include "iwl-io.h"
|
||||||
|
#include "iwl-spectrum.h"
|
||||||
|
|
||||||
|
#define BEACON_TIME_MASK_LOW 0x00FFFFFF
|
||||||
|
#define BEACON_TIME_MASK_HIGH 0xFF000000
|
||||||
|
#define TIME_UNIT 1024
|
||||||
|
|
||||||
|
/*
|
||||||
|
* extended beacon time format
|
||||||
|
* time in usec will be changed into a 32-bit value in 8:24 format
|
||||||
|
* the high 1 byte is the beacon counts
|
||||||
|
* the lower 3 bytes is the time in usec within one beacon interval
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* TOOD: was used in sysfs debug interface need to add to mac */
|
||||||
|
#if 0
|
||||||
|
static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
|
||||||
|
{
|
||||||
|
u32 quot;
|
||||||
|
u32 rem;
|
||||||
|
u32 interval = beacon_interval * 1024;
|
||||||
|
|
||||||
|
if (!interval || !usec)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
|
||||||
|
rem = (usec % interval) & BEACON_TIME_MASK_LOW;
|
||||||
|
|
||||||
|
return (quot << 24) + rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* base is usually what we get from ucode with each received frame,
|
||||||
|
* the same as HW timer counter counting down
|
||||||
|
*/
|
||||||
|
|
||||||
|
static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
|
||||||
|
{
|
||||||
|
u32 base_low = base & BEACON_TIME_MASK_LOW;
|
||||||
|
u32 addon_low = addon & BEACON_TIME_MASK_LOW;
|
||||||
|
u32 interval = beacon_interval * TIME_UNIT;
|
||||||
|
u32 res = (base & BEACON_TIME_MASK_HIGH) +
|
||||||
|
(addon & BEACON_TIME_MASK_HIGH);
|
||||||
|
|
||||||
|
if (base_low > addon_low)
|
||||||
|
res += base_low - addon_low;
|
||||||
|
else if (base_low < addon_low) {
|
||||||
|
res += interval + base_low - addon_low;
|
||||||
|
res += (1 << 24);
|
||||||
|
} else
|
||||||
|
res += (1 << 24);
|
||||||
|
|
||||||
|
return cpu_to_le32(res);
|
||||||
|
}
|
||||||
|
static int iwl_get_measurement(struct iwl_priv *priv,
|
||||||
|
struct ieee80211_measurement_params *params,
|
||||||
|
u8 type)
|
||||||
|
{
|
||||||
|
struct iwl4965_spectrum_cmd spectrum;
|
||||||
|
struct iwl_rx_packet *res;
|
||||||
|
struct iwl_host_cmd cmd = {
|
||||||
|
.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
|
||||||
|
.data = (void *)&spectrum,
|
||||||
|
.meta.flags = CMD_WANT_SKB,
|
||||||
|
};
|
||||||
|
u32 add_time = le64_to_cpu(params->start_time);
|
||||||
|
int rc;
|
||||||
|
int spectrum_resp_status;
|
||||||
|
int duration = le16_to_cpu(params->duration);
|
||||||
|
|
||||||
|
if (iwl_is_associated(priv))
|
||||||
|
add_time =
|
||||||
|
iwl_usecs_to_beacons(
|
||||||
|
le64_to_cpu(params->start_time) - priv->last_tsf,
|
||||||
|
le16_to_cpu(priv->rxon_timing.beacon_interval));
|
||||||
|
|
||||||
|
memset(&spectrum, 0, sizeof(spectrum));
|
||||||
|
|
||||||
|
spectrum.channel_count = cpu_to_le16(1);
|
||||||
|
spectrum.flags =
|
||||||
|
RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
|
||||||
|
spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
|
||||||
|
cmd.len = sizeof(spectrum);
|
||||||
|
spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
|
||||||
|
|
||||||
|
if (iwl_is_associated(priv))
|
||||||
|
spectrum.start_time =
|
||||||
|
iwl_add_beacon_time(priv->last_beacon_time,
|
||||||
|
add_time,
|
||||||
|
le16_to_cpu(priv->rxon_timing.beacon_interval));
|
||||||
|
else
|
||||||
|
spectrum.start_time = 0;
|
||||||
|
|
||||||
|
spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
|
||||||
|
spectrum.channels[0].channel = params->channel;
|
||||||
|
spectrum.channels[0].type = type;
|
||||||
|
if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
|
||||||
|
spectrum.flags |= RXON_FLG_BAND_24G_MSK |
|
||||||
|
RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
|
||||||
|
|
||||||
|
rc = iwl_send_cmd_sync(priv, &cmd);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
|
||||||
|
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
|
||||||
|
IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
|
||||||
|
rc = -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
|
||||||
|
switch (spectrum_resp_status) {
|
||||||
|
case 0: /* Command will be handled */
|
||||||
|
if (res->u.spectrum.id != 0xff) {
|
||||||
|
IWL_DEBUG_INFO
|
||||||
|
("Replaced existing measurement: %d\n",
|
||||||
|
res->u.spectrum.id);
|
||||||
|
priv->measurement_status &= ~MEASUREMENT_READY;
|
||||||
|
}
|
||||||
|
priv->measurement_status |= MEASUREMENT_ACTIVE;
|
||||||
|
rc = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: /* Command will not be handled */
|
||||||
|
rc = -EAGAIN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_kfree_skb_any(cmd.meta.u.skb);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
|
||||||
|
struct iwl_rx_mem_buffer *rxb)
|
||||||
|
{
|
||||||
|
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
||||||
|
struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
|
||||||
|
|
||||||
|
if (!report->state) {
|
||||||
|
IWL_DEBUG(IWL_DL_11H,
|
||||||
|
"Spectrum Measure Notification: Start\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&priv->measure_report, report, sizeof(*report));
|
||||||
|
priv->measurement_status |= MEASUREMENT_READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void iwl_setup_spectrum_handlers(struct iwl_priv *priv)
|
||||||
|
{
|
||||||
|
priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
|
||||||
|
iwl_rx_spectrum_measure_notif;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(iwl_setup_spectrum_handlers);
|
|
@ -88,4 +88,5 @@ struct ieee80211_measurement_report {
|
||||||
struct ieee80211_basic_report basic[0];
|
struct ieee80211_basic_report basic[0];
|
||||||
} u;
|
} u;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -56,6 +56,26 @@ static const u16 default_tid_to_tx_fifo[] = {
|
||||||
IWL_TX_FIFO_AC3
|
IWL_TX_FIFO_AC3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv,
|
||||||
|
struct iwl_dma_ptr *ptr, size_t size)
|
||||||
|
{
|
||||||
|
ptr->addr = pci_alloc_consistent(priv->pci_dev, size, &ptr->dma);
|
||||||
|
if (!ptr->addr)
|
||||||
|
return -ENOMEM;
|
||||||
|
ptr->size = size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void iwl_free_dma_ptr(struct iwl_priv *priv,
|
||||||
|
struct iwl_dma_ptr *ptr)
|
||||||
|
{
|
||||||
|
if (unlikely(!ptr->addr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pci_free_consistent(priv->pci_dev, ptr->size, ptr->addr, ptr->dma);
|
||||||
|
memset(ptr, 0, sizeof(*ptr));
|
||||||
|
}
|
||||||
|
|
||||||
static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
|
static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
|
||||||
{
|
{
|
||||||
struct iwl_tfd_tb *tb = &tfd->tbs[idx];
|
struct iwl_tfd_tb *tb = &tfd->tbs[idx];
|
||||||
|
@ -517,8 +537,9 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
|
||||||
else
|
else
|
||||||
iwl_tx_queue_free(priv, txq_id);
|
iwl_tx_queue_free(priv, txq_id);
|
||||||
|
|
||||||
/* Keep-warm buffer */
|
iwl_free_dma_ptr(priv, &priv->kw);
|
||||||
iwl_kw_free(priv);
|
|
||||||
|
iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
|
EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
|
||||||
|
|
||||||
|
@ -535,13 +556,17 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
|
||||||
int txq_id, slots_num;
|
int txq_id, slots_num;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
iwl_kw_free(priv);
|
|
||||||
|
|
||||||
/* Free all tx/cmd queues and keep-warm buffer */
|
/* Free all tx/cmd queues and keep-warm buffer */
|
||||||
iwl_hw_txq_ctx_free(priv);
|
iwl_hw_txq_ctx_free(priv);
|
||||||
|
|
||||||
|
ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
|
||||||
|
priv->hw_params.scd_bc_tbls_size);
|
||||||
|
if (ret) {
|
||||||
|
IWL_ERROR("Scheduler BC Table allocation failed\n");
|
||||||
|
goto error_bc_tbls;
|
||||||
|
}
|
||||||
/* Alloc keep-warm buffer */
|
/* Alloc keep-warm buffer */
|
||||||
ret = iwl_kw_alloc(priv);
|
ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
IWL_ERROR("Keep Warm allocation failed\n");
|
IWL_ERROR("Keep Warm allocation failed\n");
|
||||||
goto error_kw;
|
goto error_kw;
|
||||||
|
@ -556,16 +581,13 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
|
||||||
/* Turn off all Tx DMA fifos */
|
/* Turn off all Tx DMA fifos */
|
||||||
priv->cfg->ops->lib->txq_set_sched(priv, 0);
|
priv->cfg->ops->lib->txq_set_sched(priv, 0);
|
||||||
|
|
||||||
|
/* Tell NIC where to find the "keep warm" buffer */
|
||||||
|
iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
|
||||||
|
|
||||||
iwl_release_nic_access(priv);
|
iwl_release_nic_access(priv);
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
|
||||||
|
|
||||||
/* Tell nic where to find the keep-warm buffer */
|
|
||||||
ret = iwl_kw_init(priv);
|
|
||||||
if (ret) {
|
|
||||||
IWL_ERROR("kw_init failed\n");
|
|
||||||
goto error_reset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Alloc and init all Tx queues, including the command queue (#4) */
|
/* Alloc and init all Tx queues, including the command queue (#4) */
|
||||||
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
|
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
|
||||||
|
@ -584,8 +606,10 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
|
||||||
error:
|
error:
|
||||||
iwl_hw_txq_ctx_free(priv);
|
iwl_hw_txq_ctx_free(priv);
|
||||||
error_reset:
|
error_reset:
|
||||||
iwl_kw_free(priv);
|
iwl_free_dma_ptr(priv, &priv->kw);
|
||||||
error_kw:
|
error_kw:
|
||||||
|
iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
|
||||||
|
error_bc_tbls:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1236,8 +1260,13 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||||
* command queue then there a command routing bug has been introduced
|
* command queue then there a command routing bug has been introduced
|
||||||
* in the queue management code. */
|
* in the queue management code. */
|
||||||
if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
|
if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
|
||||||
"wrong command queue %d, command id 0x%X\n", txq_id, pkt->hdr.cmd))
|
"wrong command queue %d, sequence 0x%X readp=%d writep=%d\n",
|
||||||
|
txq_id, sequence,
|
||||||
|
priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr,
|
||||||
|
priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) {
|
||||||
|
iwl_print_hex_dump(priv, IWL_DL_INFO , rxb, 32);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
|
cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
|
||||||
cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
|
cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
|
||||||
|
|
|
@ -1418,9 +1418,16 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
|
||||||
return priv->ibss_beacon->len;
|
return priv->ibss_beacon->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
|
static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
|
||||||
{
|
{
|
||||||
u8 i;
|
u8 i;
|
||||||
|
int rate_mask;
|
||||||
|
|
||||||
|
/* Set rate mask*/
|
||||||
|
if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
|
||||||
|
rate_mask = priv->active_rate_basic & 0xF;
|
||||||
|
else
|
||||||
|
rate_mask = priv->active_rate_basic & 0xFF0;
|
||||||
|
|
||||||
for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
|
for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
|
||||||
i = iwl3945_rates[i].next_ieee) {
|
i = iwl3945_rates[i].next_ieee) {
|
||||||
|
@ -1428,7 +1435,11 @@ static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
|
||||||
return iwl3945_rates[i].plcp;
|
return iwl3945_rates[i].plcp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IWL_RATE_INVALID;
|
/* No valid rate was found. Assign the lowest one */
|
||||||
|
if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
|
||||||
|
return IWL_RATE_1M_PLCP;
|
||||||
|
else
|
||||||
|
return IWL_RATE_6M_PLCP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
|
static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
|
||||||
|
@ -1446,16 +1457,7 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) {
|
rate = iwl3945_rate_get_lowest_plcp(priv);
|
||||||
rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic &
|
|
||||||
0xFF0);
|
|
||||||
if (rate == IWL_INVALID_RATE)
|
|
||||||
rate = IWL_RATE_6M_PLCP;
|
|
||||||
} else {
|
|
||||||
rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
|
|
||||||
if (rate == IWL_INVALID_RATE)
|
|
||||||
rate = IWL_RATE_1M_PLCP;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
|
frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
|
||||||
|
|
||||||
|
@ -4741,7 +4743,7 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
|
||||||
#define IWL_PASSIVE_DWELL_BASE (100)
|
#define IWL_PASSIVE_DWELL_BASE (100)
|
||||||
#define IWL_CHANNEL_TUNE_TIME 5
|
#define IWL_CHANNEL_TUNE_TIME 5
|
||||||
|
|
||||||
#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
|
#define IWL_SCAN_PROBE_MASK(n) (BIT(n) | (BIT(n) - BIT(1)))
|
||||||
|
|
||||||
static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
|
static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
|
||||||
enum ieee80211_band band,
|
enum ieee80211_band band,
|
||||||
|
@ -5601,6 +5603,10 @@ static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* temporary */
|
||||||
|
static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
|
||||||
|
struct sk_buff *skb);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iwl3945_alive_start - called after REPLY_ALIVE notification received
|
* iwl3945_alive_start - called after REPLY_ALIVE notification received
|
||||||
* from protocol/runtime uCode (initialization uCode's
|
* from protocol/runtime uCode (initialization uCode's
|
||||||
|
@ -5704,6 +5710,14 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
|
||||||
if (priv->error_recovering)
|
if (priv->error_recovering)
|
||||||
iwl3945_error_recovery(priv);
|
iwl3945_error_recovery(priv);
|
||||||
|
|
||||||
|
/* reassociate for ADHOC mode */
|
||||||
|
if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
|
||||||
|
struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
|
||||||
|
priv->vif);
|
||||||
|
if (beacon)
|
||||||
|
iwl3945_mac_beacon_update(priv->hw, beacon);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
|
@ -6710,9 +6724,6 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
|
||||||
* clear sta table, add BCAST sta... */
|
* clear sta table, add BCAST sta... */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* temporary */
|
|
||||||
static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
|
|
||||||
|
|
||||||
static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
|
static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_vif *vif,
|
struct ieee80211_vif *vif,
|
||||||
struct ieee80211_if_conf *conf)
|
struct ieee80211_if_conf *conf)
|
||||||
|
@ -6734,7 +6745,9 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
|
||||||
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
|
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
|
||||||
if (!beacon)
|
if (!beacon)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
mutex_lock(&priv->mutex);
|
||||||
rc = iwl3945_mac_beacon_update(hw, beacon);
|
rc = iwl3945_mac_beacon_update(hw, beacon);
|
||||||
|
mutex_unlock(&priv->mutex);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -7188,18 +7201,15 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
|
||||||
struct iwl3945_priv *priv = hw->priv;
|
struct iwl3945_priv *priv = hw->priv;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
mutex_lock(&priv->mutex);
|
|
||||||
IWL_DEBUG_MAC80211("enter\n");
|
IWL_DEBUG_MAC80211("enter\n");
|
||||||
|
|
||||||
if (!iwl3945_is_ready_rf(priv)) {
|
if (!iwl3945_is_ready_rf(priv)) {
|
||||||
IWL_DEBUG_MAC80211("leave - RF not ready\n");
|
IWL_DEBUG_MAC80211("leave - RF not ready\n");
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
|
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
|
||||||
IWL_DEBUG_MAC80211("leave - not IBSS\n");
|
IWL_DEBUG_MAC80211("leave - not IBSS\n");
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7219,7 +7229,6 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
|
||||||
|
|
||||||
iwl3945_post_associate(priv);
|
iwl3945_post_associate(priv);
|
||||||
|
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,8 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
|
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
|
||||||
|
struct wol_config *p_wol_config)
|
||||||
{
|
{
|
||||||
struct cmd_ds_host_sleep cmd_config;
|
struct cmd_ds_host_sleep cmd_config;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -169,10 +170,21 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
|
||||||
cmd_config.gpio = priv->wol_gpio;
|
cmd_config.gpio = priv->wol_gpio;
|
||||||
cmd_config.gap = priv->wol_gap;
|
cmd_config.gap = priv->wol_gap;
|
||||||
|
|
||||||
|
if (p_wol_config != NULL)
|
||||||
|
memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
|
||||||
|
sizeof(struct wol_config));
|
||||||
|
else
|
||||||
|
cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
|
||||||
|
|
||||||
ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
|
ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
|
if (criteria) {
|
||||||
priv->wol_criteria = criteria;
|
lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
|
||||||
|
priv->wol_criteria = criteria;
|
||||||
|
} else
|
||||||
|
memcpy((uint8_t *) p_wol_config,
|
||||||
|
(uint8_t *)&cmd_config.wol_conf,
|
||||||
|
sizeof(struct wol_config));
|
||||||
} else {
|
} else {
|
||||||
lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
|
lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,8 @@ int lbs_mesh_config_send(struct lbs_private *priv,
|
||||||
uint16_t action, uint16_t type);
|
uint16_t action, uint16_t type);
|
||||||
int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
|
int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
|
||||||
|
|
||||||
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
|
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
|
||||||
|
struct wol_config *p_wol_config);
|
||||||
int lbs_suspend(struct lbs_private *priv);
|
int lbs_suspend(struct lbs_private *priv);
|
||||||
void lbs_resume(struct lbs_private *priv);
|
void lbs_resume(struct lbs_private *priv);
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,18 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
|
||||||
#define EHS_WAKE_ON_MAC_EVENT 0x0004
|
#define EHS_WAKE_ON_MAC_EVENT 0x0004
|
||||||
#define EHS_WAKE_ON_MULTICAST_DATA 0x0008
|
#define EHS_WAKE_ON_MULTICAST_DATA 0x0008
|
||||||
#define EHS_REMOVE_WAKEUP 0xFFFFFFFF
|
#define EHS_REMOVE_WAKEUP 0xFFFFFFFF
|
||||||
|
/* Wake rules for Host_Sleep_CFG command */
|
||||||
|
#define WOL_RULE_NET_TYPE_INFRA_OR_IBSS 0x00
|
||||||
|
#define WOL_RULE_NET_TYPE_MESH 0x10
|
||||||
|
#define WOL_RULE_ADDR_TYPE_BCAST 0x01
|
||||||
|
#define WOL_RULE_ADDR_TYPE_MCAST 0x08
|
||||||
|
#define WOL_RULE_ADDR_TYPE_UCAST 0x02
|
||||||
|
#define WOL_RULE_OP_AND 0x01
|
||||||
|
#define WOL_RULE_OP_OR 0x02
|
||||||
|
#define WOL_RULE_OP_INVALID 0xFF
|
||||||
|
#define WOL_RESULT_VALID_CMD 0
|
||||||
|
#define WOL_RESULT_NOSPC_ERR 1
|
||||||
|
#define WOL_RESULT_EEXIST_ERR 2
|
||||||
|
|
||||||
/** Misc constants */
|
/** Misc constants */
|
||||||
/* This section defines 802.11 specific contants */
|
/* This section defines 802.11 specific contants */
|
||||||
|
|
|
@ -180,7 +180,7 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
|
||||||
if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
|
if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
|
||||||
if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT;
|
if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT;
|
||||||
|
|
||||||
return lbs_host_sleep_cfg(priv, criteria);
|
return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ethtool_ops lbs_ethtool_ops = {
|
struct ethtool_ops lbs_ethtool_ops = {
|
||||||
|
|
|
@ -220,6 +220,14 @@ enum cmd_fwt_access_opts {
|
||||||
CMD_ACT_FWT_ACCESS_TIME,
|
CMD_ACT_FWT_ACCESS_TIME,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Define action or option for CMD_802_11_HOST_SLEEP_CFG */
|
||||||
|
enum cmd_wol_cfg_opts {
|
||||||
|
CMD_ACT_ACTION_NONE = 0,
|
||||||
|
CMD_ACT_SET_WOL_RULE,
|
||||||
|
CMD_ACT_GET_WOL_RULE,
|
||||||
|
CMD_ACT_RESET_WOL_RULE,
|
||||||
|
};
|
||||||
|
|
||||||
/* Define action or option for CMD_MESH_ACCESS */
|
/* Define action or option for CMD_MESH_ACCESS */
|
||||||
enum cmd_mesh_access_opts {
|
enum cmd_mesh_access_opts {
|
||||||
CMD_ACT_MESH_GET_TTL = 1,
|
CMD_ACT_MESH_GET_TTL = 1,
|
||||||
|
|
|
@ -580,13 +580,37 @@ struct MrvlIEtype_keyParamSet {
|
||||||
u8 key[32];
|
u8 key[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_WOL_RULES 16
|
||||||
|
|
||||||
|
struct host_wol_rule {
|
||||||
|
uint8_t rule_no;
|
||||||
|
uint8_t rule_ops;
|
||||||
|
__le16 sig_offset;
|
||||||
|
__le16 sig_length;
|
||||||
|
__le16 reserve;
|
||||||
|
__be32 sig_mask;
|
||||||
|
__be32 signature;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wol_config {
|
||||||
|
uint8_t action;
|
||||||
|
uint8_t pattern;
|
||||||
|
uint8_t no_rules_in_cmd;
|
||||||
|
uint8_t result;
|
||||||
|
struct host_wol_rule rule[MAX_WOL_RULES];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct cmd_ds_host_sleep {
|
struct cmd_ds_host_sleep {
|
||||||
struct cmd_header hdr;
|
struct cmd_header hdr;
|
||||||
__le32 criteria;
|
__le32 criteria;
|
||||||
uint8_t gpio;
|
uint8_t gpio;
|
||||||
uint8_t gap;
|
uint16_t gap;
|
||||||
|
struct wol_config wol_conf;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct cmd_ds_802_11_key_material {
|
struct cmd_ds_802_11_key_material {
|
||||||
struct cmd_header hdr;
|
struct cmd_header hdr;
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,8 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
|
||||||
|
|
||||||
priv->wol_gpio = 2; /* Wake via GPIO2... */
|
priv->wol_gpio = 2; /* Wake via GPIO2... */
|
||||||
priv->wol_gap = 20; /* ... after 20ms */
|
priv->wol_gap = 20; /* ... after 20ms */
|
||||||
lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
|
lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA,
|
||||||
|
(struct wol_config *) NULL);
|
||||||
|
|
||||||
wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
|
wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
|
||||||
wake_method.action = cpu_to_le16(CMD_ACT_GET);
|
wake_method.action = cpu_to_le16(CMD_ACT_GET);
|
||||||
|
|
|
@ -368,7 +368,8 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
|
||||||
|
|
||||||
hwsim_check_magic(vif);
|
hwsim_check_magic(vif);
|
||||||
|
|
||||||
if (vif->type != NL80211_IFTYPE_AP)
|
if (vif->type != NL80211_IFTYPE_AP &&
|
||||||
|
vif->type != NL80211_IFTYPE_MESH_POINT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
skb = ieee80211_beacon_get(hw, vif);
|
skb = ieee80211_beacon_get(hw, vif);
|
||||||
|
@ -774,7 +775,8 @@ static int __init init_mac80211_hwsim(void)
|
||||||
hw->queues = 4;
|
hw->queues = 4;
|
||||||
hw->wiphy->interface_modes =
|
hw->wiphy->interface_modes =
|
||||||
BIT(NL80211_IFTYPE_STATION) |
|
BIT(NL80211_IFTYPE_STATION) |
|
||||||
BIT(NL80211_IFTYPE_AP);
|
BIT(NL80211_IFTYPE_AP) |
|
||||||
|
BIT(NL80211_IFTYPE_MESH_POINT);
|
||||||
hw->ampdu_queues = 1;
|
hw->ampdu_queues = 1;
|
||||||
|
|
||||||
/* ask mac80211 to reserve space for magic */
|
/* ask mac80211 to reserve space for magic */
|
||||||
|
|
|
@ -5444,7 +5444,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
|
||||||
char *current_ev,
|
char *current_ev,
|
||||||
char *end_buf,
|
char *end_buf,
|
||||||
union hermes_scan_info *bss,
|
union hermes_scan_info *bss,
|
||||||
unsigned int last_scanned)
|
unsigned long last_scanned)
|
||||||
{
|
{
|
||||||
struct orinoco_private *priv = netdev_priv(dev);
|
struct orinoco_private *priv = netdev_priv(dev);
|
||||||
u16 capabilities;
|
u16 capabilities;
|
||||||
|
@ -5591,7 +5591,7 @@ static inline char *orinoco_translate_ext_scan(struct net_device *dev,
|
||||||
char *current_ev,
|
char *current_ev,
|
||||||
char *end_buf,
|
char *end_buf,
|
||||||
struct agere_ext_scan_info *bss,
|
struct agere_ext_scan_info *bss,
|
||||||
unsigned int last_scanned)
|
unsigned long last_scanned)
|
||||||
{
|
{
|
||||||
u16 capabilities;
|
u16 capabilities;
|
||||||
u16 channel;
|
u16 channel;
|
||||||
|
|
|
@ -69,14 +69,14 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
*/
|
*/
|
||||||
reg = rt2400pci_bbp_check(rt2x00dev);
|
reg = rt2400pci_bbp_check(rt2x00dev);
|
||||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||||
ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
|
goto exit_fail;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the data into the BBP.
|
* Write the data into the BBP.
|
||||||
|
@ -88,6 +88,15 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||||
rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1);
|
rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1);
|
||||||
|
|
||||||
rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
|
rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
exit_fail:
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
|
@ -95,14 +104,14 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
*/
|
*/
|
||||||
reg = rt2400pci_bbp_check(rt2x00dev);
|
reg = rt2400pci_bbp_check(rt2x00dev);
|
||||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||||
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
|
goto exit_fail;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the request into the BBP.
|
* Write the request into the BBP.
|
||||||
|
@ -118,13 +127,20 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
*/
|
*/
|
||||||
reg = rt2400pci_bbp_check(rt2x00dev);
|
reg = rt2400pci_bbp_check(rt2x00dev);
|
||||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||||
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
|
goto exit_fail;
|
||||||
*value = 0xff;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*value = rt2x00_get_field32(reg, BBPCSR_VALUE);
|
*value = rt2x00_get_field32(reg, BBPCSR_VALUE);
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
exit_fail:
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
|
||||||
|
*value = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
|
@ -136,6 +152,8 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
if (!word)
|
if (!word)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||||
rt2x00pci_register_read(rt2x00dev, RFCSR, ®);
|
rt2x00pci_register_read(rt2x00dev, RFCSR, ®);
|
||||||
if (!rt2x00_get_field32(reg, RFCSR_BUSY))
|
if (!rt2x00_get_field32(reg, RFCSR_BUSY))
|
||||||
|
@ -143,6 +161,7 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
udelay(REGISTER_BUSY_DELAY);
|
udelay(REGISTER_BUSY_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
|
ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -155,6 +174,8 @@ rf_write:
|
||||||
|
|
||||||
rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
|
rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
|
||||||
rt2x00_rf_write(rt2x00dev, word, value);
|
rt2x00_rf_write(rt2x00dev, word, value);
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
|
static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
|
||||||
|
@ -322,7 +343,7 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
|
||||||
/*
|
/*
|
||||||
* Enable beacon config
|
* Enable beacon config
|
||||||
*/
|
*/
|
||||||
bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20);
|
bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
|
||||||
rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®);
|
rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®);
|
||||||
rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload);
|
rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload);
|
||||||
rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg);
|
rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg);
|
||||||
|
@ -367,25 +388,25 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
|
||||||
rt2x00pci_register_read(rt2x00dev, ARCSR2, ®);
|
rt2x00pci_register_read(rt2x00dev, ARCSR2, ®);
|
||||||
rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00);
|
rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00);
|
||||||
rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04);
|
rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04);
|
||||||
rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10));
|
rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
|
||||||
rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
|
rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
|
||||||
|
|
||||||
rt2x00pci_register_read(rt2x00dev, ARCSR3, ®);
|
rt2x00pci_register_read(rt2x00dev, ARCSR3, ®);
|
||||||
rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask);
|
rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask);
|
||||||
rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04);
|
rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04);
|
||||||
rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20));
|
rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
|
||||||
rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
|
rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
|
||||||
|
|
||||||
rt2x00pci_register_read(rt2x00dev, ARCSR4, ®);
|
rt2x00pci_register_read(rt2x00dev, ARCSR4, ®);
|
||||||
rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask);
|
rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask);
|
||||||
rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04);
|
rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04);
|
||||||
rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55));
|
rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
|
||||||
rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
|
rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
|
||||||
|
|
||||||
rt2x00pci_register_read(rt2x00dev, ARCSR5, ®);
|
rt2x00pci_register_read(rt2x00dev, ARCSR5, ®);
|
||||||
rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask);
|
rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask);
|
||||||
rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84);
|
rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84);
|
||||||
rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
|
rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110));
|
||||||
rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
|
rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
|
||||||
|
|
||||||
rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
|
rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
|
||||||
|
@ -626,36 +647,47 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
|
||||||
/*
|
/*
|
||||||
* Initialization functions.
|
* Initialization functions.
|
||||||
*/
|
*/
|
||||||
static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
|
static bool rt2400pci_get_entry_state(struct queue_entry *entry)
|
||||||
struct queue_entry *entry)
|
{
|
||||||
|
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
||||||
|
u32 word;
|
||||||
|
|
||||||
|
if (entry->queue->qid == QID_RX) {
|
||||||
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
|
|
||||||
|
return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
|
||||||
|
} else {
|
||||||
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
|
|
||||||
|
return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
|
||||||
|
rt2x00_get_field32(word, TXD_W0_VALID));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rt2400pci_clear_entry(struct queue_entry *entry)
|
||||||
{
|
{
|
||||||
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
||||||
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||||
u32 word;
|
u32 word;
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 2, &word);
|
if (entry->queue->qid == QID_RX) {
|
||||||
rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
|
rt2x00_desc_read(entry_priv->desc, 2, &word);
|
||||||
rt2x00_desc_write(entry_priv->desc, 2, word);
|
rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
|
||||||
|
rt2x00_desc_write(entry_priv->desc, 2, word);
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 1, &word);
|
rt2x00_desc_read(entry_priv->desc, 1, &word);
|
||||||
rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
|
rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
|
||||||
rt2x00_desc_write(entry_priv->desc, 1, word);
|
rt2x00_desc_write(entry_priv->desc, 1, word);
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
||||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||||
}
|
} else {
|
||||||
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev,
|
rt2x00_set_field32(&word, TXD_W0_VALID, 0);
|
||||||
struct queue_entry *entry)
|
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
|
||||||
{
|
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||||
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
}
|
||||||
u32 word;
|
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
|
||||||
rt2x00_set_field32(&word, TXD_W0_VALID, 0);
|
|
||||||
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
|
|
||||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
|
static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
|
||||||
|
@ -1570,8 +1602,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
|
||||||
.probe_hw = rt2400pci_probe_hw,
|
.probe_hw = rt2400pci_probe_hw,
|
||||||
.initialize = rt2x00pci_initialize,
|
.initialize = rt2x00pci_initialize,
|
||||||
.uninitialize = rt2x00pci_uninitialize,
|
.uninitialize = rt2x00pci_uninitialize,
|
||||||
.init_rxentry = rt2400pci_init_rxentry,
|
.get_entry_state = rt2400pci_get_entry_state,
|
||||||
.init_txentry = rt2400pci_init_txentry,
|
.clear_entry = rt2400pci_clear_entry,
|
||||||
.set_device_state = rt2400pci_set_device_state,
|
.set_device_state = rt2400pci_set_device_state,
|
||||||
.rfkill_poll = rt2400pci_rfkill_poll,
|
.rfkill_poll = rt2400pci_rfkill_poll,
|
||||||
.link_stats = rt2400pci_link_stats,
|
.link_stats = rt2400pci_link_stats,
|
||||||
|
|
|
@ -69,14 +69,14 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
*/
|
*/
|
||||||
reg = rt2500pci_bbp_check(rt2x00dev);
|
reg = rt2500pci_bbp_check(rt2x00dev);
|
||||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||||
ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
|
goto exit_fail;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the data into the BBP.
|
* Write the data into the BBP.
|
||||||
|
@ -88,6 +88,15 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||||
rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1);
|
rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1);
|
||||||
|
|
||||||
rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
|
rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
exit_fail:
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
|
@ -95,14 +104,14 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
*/
|
*/
|
||||||
reg = rt2500pci_bbp_check(rt2x00dev);
|
reg = rt2500pci_bbp_check(rt2x00dev);
|
||||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||||
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
|
goto exit_fail;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the request into the BBP.
|
* Write the request into the BBP.
|
||||||
|
@ -118,13 +127,20 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
*/
|
*/
|
||||||
reg = rt2500pci_bbp_check(rt2x00dev);
|
reg = rt2500pci_bbp_check(rt2x00dev);
|
||||||
if (rt2x00_get_field32(reg, BBPCSR_BUSY)) {
|
if (rt2x00_get_field32(reg, BBPCSR_BUSY))
|
||||||
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
|
goto exit_fail;
|
||||||
*value = 0xff;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*value = rt2x00_get_field32(reg, BBPCSR_VALUE);
|
*value = rt2x00_get_field32(reg, BBPCSR_VALUE);
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
exit_fail:
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
|
||||||
|
*value = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
|
@ -136,6 +152,8 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
if (!word)
|
if (!word)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||||
rt2x00pci_register_read(rt2x00dev, RFCSR, ®);
|
rt2x00pci_register_read(rt2x00dev, RFCSR, ®);
|
||||||
if (!rt2x00_get_field32(reg, RFCSR_BUSY))
|
if (!rt2x00_get_field32(reg, RFCSR_BUSY))
|
||||||
|
@ -143,6 +161,7 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
udelay(REGISTER_BUSY_DELAY);
|
udelay(REGISTER_BUSY_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
|
ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -155,6 +174,8 @@ rf_write:
|
||||||
|
|
||||||
rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
|
rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
|
||||||
rt2x00_rf_write(rt2x00dev, word, value);
|
rt2x00_rf_write(rt2x00dev, word, value);
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
|
static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
|
||||||
|
@ -327,7 +348,7 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
|
||||||
/*
|
/*
|
||||||
* Enable beacon config
|
* Enable beacon config
|
||||||
*/
|
*/
|
||||||
bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20);
|
bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
|
||||||
rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®);
|
rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®);
|
||||||
rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload);
|
rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload);
|
||||||
rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min);
|
rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min);
|
||||||
|
@ -373,25 +394,25 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
|
||||||
rt2x00pci_register_read(rt2x00dev, ARCSR2, ®);
|
rt2x00pci_register_read(rt2x00dev, ARCSR2, ®);
|
||||||
rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00);
|
rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00);
|
||||||
rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04);
|
rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04);
|
||||||
rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10));
|
rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
|
||||||
rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
|
rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
|
||||||
|
|
||||||
rt2x00pci_register_read(rt2x00dev, ARCSR3, ®);
|
rt2x00pci_register_read(rt2x00dev, ARCSR3, ®);
|
||||||
rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask);
|
rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask);
|
||||||
rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04);
|
rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04);
|
||||||
rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20));
|
rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
|
||||||
rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
|
rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
|
||||||
|
|
||||||
rt2x00pci_register_read(rt2x00dev, ARCSR4, ®);
|
rt2x00pci_register_read(rt2x00dev, ARCSR4, ®);
|
||||||
rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask);
|
rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask);
|
||||||
rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04);
|
rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04);
|
||||||
rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55));
|
rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
|
||||||
rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
|
rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
|
||||||
|
|
||||||
rt2x00pci_register_read(rt2x00dev, ARCSR5, ®);
|
rt2x00pci_register_read(rt2x00dev, ARCSR5, ®);
|
||||||
rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask);
|
rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask);
|
||||||
rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84);
|
rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84);
|
||||||
rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
|
rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110));
|
||||||
rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
|
rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
|
||||||
|
|
||||||
rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
|
rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
|
||||||
|
@ -722,32 +743,43 @@ dynamic_cca_tune:
|
||||||
/*
|
/*
|
||||||
* Initialization functions.
|
* Initialization functions.
|
||||||
*/
|
*/
|
||||||
static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
|
static bool rt2500pci_get_entry_state(struct queue_entry *entry)
|
||||||
struct queue_entry *entry)
|
{
|
||||||
|
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
||||||
|
u32 word;
|
||||||
|
|
||||||
|
if (entry->queue->qid == QID_RX) {
|
||||||
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
|
|
||||||
|
return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
|
||||||
|
} else {
|
||||||
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
|
|
||||||
|
return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
|
||||||
|
rt2x00_get_field32(word, TXD_W0_VALID));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rt2500pci_clear_entry(struct queue_entry *entry)
|
||||||
{
|
{
|
||||||
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
||||||
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||||
u32 word;
|
u32 word;
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 1, &word);
|
if (entry->queue->qid == QID_RX) {
|
||||||
rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
|
rt2x00_desc_read(entry_priv->desc, 1, &word);
|
||||||
rt2x00_desc_write(entry_priv->desc, 1, word);
|
rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
|
||||||
|
rt2x00_desc_write(entry_priv->desc, 1, word);
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
||||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||||
}
|
} else {
|
||||||
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev,
|
rt2x00_set_field32(&word, TXD_W0_VALID, 0);
|
||||||
struct queue_entry *entry)
|
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
|
||||||
{
|
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||||
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
}
|
||||||
u32 word;
|
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
|
||||||
rt2x00_set_field32(&word, TXD_W0_VALID, 0);
|
|
||||||
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
|
|
||||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
|
static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
|
||||||
|
@ -1871,8 +1903,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
|
||||||
.probe_hw = rt2500pci_probe_hw,
|
.probe_hw = rt2500pci_probe_hw,
|
||||||
.initialize = rt2x00pci_initialize,
|
.initialize = rt2x00pci_initialize,
|
||||||
.uninitialize = rt2x00pci_uninitialize,
|
.uninitialize = rt2x00pci_uninitialize,
|
||||||
.init_rxentry = rt2500pci_init_rxentry,
|
.get_entry_state = rt2500pci_get_entry_state,
|
||||||
.init_txentry = rt2500pci_init_txentry,
|
.clear_entry = rt2500pci_clear_entry,
|
||||||
.set_device_state = rt2500pci_set_device_state,
|
.set_device_state = rt2500pci_set_device_state,
|
||||||
.rfkill_poll = rt2500pci_rfkill_poll,
|
.rfkill_poll = rt2500pci_rfkill_poll,
|
||||||
.link_stats = rt2500pci_link_stats,
|
.link_stats = rt2500pci_link_stats,
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
* between each attampt. When the busy bit is still set at that time,
|
* between each attampt. When the busy bit is still set at that time,
|
||||||
* the access attempt is considered to have failed,
|
* the access attempt is considered to have failed,
|
||||||
* and we will print an error.
|
* and we will print an error.
|
||||||
* If the usb_cache_mutex is already held then the _lock variants must
|
* If the csr_mutex is already held then the _lock variants must
|
||||||
* be used instead.
|
* be used instead.
|
||||||
*/
|
*/
|
||||||
static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
|
static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
|
||||||
|
@ -132,7 +132,7 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u16 reg;
|
u16 reg;
|
||||||
|
|
||||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
|
@ -151,12 +151,12 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||||
|
|
||||||
rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
|
rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
|
||||||
|
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
exit_fail:
|
exit_fail:
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
|
ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u16 reg;
|
u16 reg;
|
||||||
|
|
||||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
|
@ -194,12 +194,12 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®);
|
rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®);
|
||||||
*value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
|
*value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
|
||||||
|
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
exit_fail:
|
exit_fail:
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
|
ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
|
||||||
*value = 0xff;
|
*value = 0xff;
|
||||||
|
@ -214,7 +214,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
if (!word)
|
if (!word)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||||
rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, ®);
|
rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, ®);
|
||||||
|
@ -223,7 +223,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
udelay(REGISTER_BUSY_DELAY);
|
udelay(REGISTER_BUSY_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
|
ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ rf_write:
|
||||||
rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
|
rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
|
||||||
rt2x00_rf_write(rt2x00dev, word, value);
|
rt2x00_rf_write(rt2x00dev, word, value);
|
||||||
|
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
|
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
|
||||||
|
@ -385,7 +385,7 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
|
||||||
/*
|
/*
|
||||||
* Enable beacon config
|
* Enable beacon config
|
||||||
*/
|
*/
|
||||||
bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20);
|
bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
|
||||||
rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®);
|
rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®);
|
||||||
rt2x00_set_field16(®, TXRX_CSR20_OFFSET, bcn_preload >> 6);
|
rt2x00_set_field16(®, TXRX_CSR20_OFFSET, bcn_preload >> 6);
|
||||||
rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW,
|
rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW,
|
||||||
|
@ -1777,8 +1777,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
|
||||||
.probe_hw = rt2500usb_probe_hw,
|
.probe_hw = rt2500usb_probe_hw,
|
||||||
.initialize = rt2x00usb_initialize,
|
.initialize = rt2x00usb_initialize,
|
||||||
.uninitialize = rt2x00usb_uninitialize,
|
.uninitialize = rt2x00usb_uninitialize,
|
||||||
.init_rxentry = rt2x00usb_init_rxentry,
|
.clear_entry = rt2x00usb_clear_entry,
|
||||||
.init_txentry = rt2x00usb_init_txentry,
|
|
||||||
.set_device_state = rt2500usb_set_device_state,
|
.set_device_state = rt2500usb_set_device_state,
|
||||||
.link_stats = rt2500usb_link_stats,
|
.link_stats = rt2500usb_link_stats,
|
||||||
.reset_tuner = rt2500usb_reset_tuner,
|
.reset_tuner = rt2500usb_reset_tuner,
|
||||||
|
|
|
@ -91,6 +91,16 @@
|
||||||
#define EEPROM(__dev, __msg, __args...) \
|
#define EEPROM(__dev, __msg, __args...) \
|
||||||
DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args)
|
DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Duration calculations
|
||||||
|
* The rate variable passed is: 100kbs.
|
||||||
|
* To convert from bytes to bits we multiply size with 8,
|
||||||
|
* then the size is multiplied with 10 to make the
|
||||||
|
* real rate -> rate argument correction.
|
||||||
|
*/
|
||||||
|
#define GET_DURATION(__size, __rate) (((__size) * 8 * 10) / (__rate))
|
||||||
|
#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Standard timing and size defines.
|
* Standard timing and size defines.
|
||||||
* These values should follow the ieee80211 specifications.
|
* These values should follow the ieee80211 specifications.
|
||||||
|
@ -109,9 +119,9 @@
|
||||||
#define DIFS ( PIFS + SLOT_TIME )
|
#define DIFS ( PIFS + SLOT_TIME )
|
||||||
#define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME )
|
#define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME )
|
||||||
#define EIFS ( SIFS + DIFS + \
|
#define EIFS ( SIFS + DIFS + \
|
||||||
(8 * (IEEE80211_HEADER + ACK_SIZE)) )
|
GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
|
||||||
#define SHORT_EIFS ( SIFS + SHORT_DIFS + \
|
#define SHORT_EIFS ( SIFS + SHORT_DIFS + \
|
||||||
(8 * (IEEE80211_HEADER + ACK_SIZE)) )
|
GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Chipset identification
|
* Chipset identification
|
||||||
|
@ -523,10 +533,8 @@ struct rt2x00lib_ops {
|
||||||
/*
|
/*
|
||||||
* queue initialization handlers
|
* queue initialization handlers
|
||||||
*/
|
*/
|
||||||
void (*init_rxentry) (struct rt2x00_dev *rt2x00dev,
|
bool (*get_entry_state) (struct queue_entry *entry);
|
||||||
struct queue_entry *entry);
|
void (*clear_entry) (struct queue_entry *entry);
|
||||||
void (*init_txentry) (struct rt2x00_dev *rt2x00dev,
|
|
||||||
struct queue_entry *entry);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Radio control handlers.
|
* Radio control handlers.
|
||||||
|
@ -723,8 +731,7 @@ struct rt2x00_dev {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the default TX/RX antenna setup as indicated
|
* This is the default TX/RX antenna setup as indicated
|
||||||
* by the device's EEPROM. When mac80211 sets its
|
* by the device's EEPROM.
|
||||||
* antenna value to 0 we should be using these values.
|
|
||||||
*/
|
*/
|
||||||
struct antenna_setup default_ant;
|
struct antenna_setup default_ant;
|
||||||
|
|
||||||
|
@ -739,16 +746,15 @@ struct rt2x00_dev {
|
||||||
} csr;
|
} csr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mutex to protect register accesses on USB devices.
|
* Mutex to protect register accesses.
|
||||||
* There are 2 reasons this is needed, one is to ensure
|
* For PCI and USB devices it protects against concurrent indirect
|
||||||
* use of the csr_cache (for USB devices) by one thread
|
* register access (BBP, RF, MCU) since accessing those
|
||||||
* isn't corrupted by another thread trying to access it.
|
* registers require multiple calls to the CSR registers.
|
||||||
* The other is that access to BBP and RF registers
|
* For USB devices it also protects the csr_cache since that
|
||||||
* require multiple BUS transactions and if another thread
|
* field is used for normal CSR access and it cannot support
|
||||||
* attempted to access one of those registers at the same
|
* multiple callers simultaneously.
|
||||||
* time one of the writes could silently fail.
|
|
||||||
*/
|
*/
|
||||||
struct mutex usb_cache_mutex;
|
struct mutex csr_mutex;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Current packet filter configuration for the device.
|
* Current packet filter configuration for the device.
|
||||||
|
@ -923,23 +929,6 @@ static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
|
||||||
!!(chipset->rev & 0x0000f));
|
!!(chipset->rev & 0x0000f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Duration calculations
|
|
||||||
* The rate variable passed is: 100kbs.
|
|
||||||
* To convert from bytes to bits we multiply size with 8,
|
|
||||||
* then the size is multiplied with 10 to make the
|
|
||||||
* real rate -> rate argument correction.
|
|
||||||
*/
|
|
||||||
static inline u16 get_duration(const unsigned int size, const u8 rate)
|
|
||||||
{
|
|
||||||
return ((size * 8 * 10) / rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u16 get_duration_res(const unsigned int size, const u8 rate)
|
|
||||||
{
|
|
||||||
return ((size * 8 * 10) % rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
|
* rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
|
||||||
* @rt2x00dev: Pointer to &struct rt2x00_dev.
|
* @rt2x00dev: Pointer to &struct rt2x00_dev.
|
||||||
|
|
|
@ -92,8 +92,8 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
|
||||||
erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS;
|
erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS;
|
||||||
erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS;
|
erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS;
|
||||||
|
|
||||||
erp.ack_timeout = PLCP + erp.difs + get_duration(ACK_SIZE, 10);
|
erp.ack_timeout = PLCP + erp.difs + GET_DURATION(ACK_SIZE, 10);
|
||||||
erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10);
|
erp.ack_consume_time = SIFS + PLCP + GET_DURATION(ACK_SIZE, 10);
|
||||||
|
|
||||||
if (bss_conf->use_short_preamble) {
|
if (bss_conf->use_short_preamble) {
|
||||||
erp.ack_timeout += SHORT_PREAMBLE;
|
erp.ack_timeout += SHORT_PREAMBLE;
|
||||||
|
@ -109,15 +109,32 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
|
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
|
||||||
enum antenna rx, enum antenna tx)
|
struct antenna_setup *ant)
|
||||||
{
|
{
|
||||||
struct antenna_setup ant;
|
/*
|
||||||
|
* Failsafe: Make sure we are not sending the
|
||||||
|
* ANTENNA_SW_DIVERSITY state to the driver.
|
||||||
|
* If that happes fallback to hardware default,
|
||||||
|
* or our own default.
|
||||||
|
*/
|
||||||
|
if (ant->rx == ANTENNA_SW_DIVERSITY) {
|
||||||
|
if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
|
||||||
|
ant->rx = ANTENNA_B;
|
||||||
|
else
|
||||||
|
ant->rx = rt2x00dev->default_ant.rx;
|
||||||
|
}
|
||||||
|
if (ant->tx == ANTENNA_SW_DIVERSITY) {
|
||||||
|
if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
|
||||||
|
ant->tx = ANTENNA_B;
|
||||||
|
else
|
||||||
|
ant->tx = rt2x00dev->default_ant.tx;
|
||||||
|
}
|
||||||
|
|
||||||
ant.rx = rx;
|
/*
|
||||||
ant.tx = tx;
|
* Only reconfigure when something has changed.
|
||||||
|
*/
|
||||||
if (rx == rt2x00dev->link.ant.active.rx &&
|
if (ant->rx == rt2x00dev->link.ant.active.rx &&
|
||||||
tx == rt2x00dev->link.ant.active.tx)
|
ant->tx == rt2x00dev->link.ant.active.tx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -132,12 +149,12 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
|
||||||
* The latter is required since we need to recalibrate the
|
* The latter is required since we need to recalibrate the
|
||||||
* noise-sensitivity ratio for the new setup.
|
* noise-sensitivity ratio for the new setup.
|
||||||
*/
|
*/
|
||||||
rt2x00dev->ops->lib->config_ant(rt2x00dev, &ant);
|
rt2x00dev->ops->lib->config_ant(rt2x00dev, ant);
|
||||||
|
|
||||||
rt2x00lib_reset_link_tuner(rt2x00dev);
|
rt2x00lib_reset_link_tuner(rt2x00dev);
|
||||||
rt2x00_reset_link_ant_rssi(&rt2x00dev->link);
|
rt2x00_reset_link_ant_rssi(&rt2x00dev->link);
|
||||||
|
|
||||||
memcpy(&rt2x00dev->link.ant.active, &ant, sizeof(ant));
|
memcpy(&rt2x00dev->link.ant.active, ant, sizeof(*ant));
|
||||||
|
|
||||||
if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
|
if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
|
||||||
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
|
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
|
||||||
|
|
|
@ -101,8 +101,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
|
||||||
/*
|
/*
|
||||||
* Initialize all data queues.
|
* Initialize all data queues.
|
||||||
*/
|
*/
|
||||||
rt2x00queue_init_rx(rt2x00dev);
|
rt2x00queue_init_queues(rt2x00dev);
|
||||||
rt2x00queue_init_tx(rt2x00dev);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable radio.
|
* Enable radio.
|
||||||
|
@ -176,13 +175,14 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
|
||||||
|
|
||||||
static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
|
static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
|
||||||
{
|
{
|
||||||
enum antenna rx = rt2x00dev->link.ant.active.rx;
|
struct antenna_setup ant;
|
||||||
enum antenna tx = rt2x00dev->link.ant.active.tx;
|
|
||||||
int sample_a =
|
int sample_a =
|
||||||
rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A);
|
rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A);
|
||||||
int sample_b =
|
int sample_b =
|
||||||
rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B);
|
rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B);
|
||||||
|
|
||||||
|
memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We are done sampling. Now we should evaluate the results.
|
* We are done sampling. Now we should evaluate the results.
|
||||||
*/
|
*/
|
||||||
|
@ -200,21 +200,22 @@ static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
|
if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
|
||||||
rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
|
ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
|
||||||
|
|
||||||
if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
|
if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
|
||||||
tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
|
ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
|
||||||
|
|
||||||
rt2x00lib_config_antenna(rt2x00dev, rx, tx);
|
rt2x00lib_config_antenna(rt2x00dev, &ant);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
|
static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
|
||||||
{
|
{
|
||||||
enum antenna rx = rt2x00dev->link.ant.active.rx;
|
struct antenna_setup ant;
|
||||||
enum antenna tx = rt2x00dev->link.ant.active.tx;
|
|
||||||
int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link);
|
int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link);
|
||||||
int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr);
|
int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr);
|
||||||
|
|
||||||
|
memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Legacy driver indicates that we should swap antenna's
|
* Legacy driver indicates that we should swap antenna's
|
||||||
* when the difference in RSSI is greater that 5. This
|
* when the difference in RSSI is greater that 5. This
|
||||||
|
@ -230,12 +231,12 @@ static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
|
||||||
rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
|
rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
|
||||||
|
|
||||||
if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
|
if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
|
||||||
rx = (rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
|
ant.rx = (ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
|
||||||
|
|
||||||
if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
|
if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
|
||||||
tx = (tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
|
ant.tx = (ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
|
||||||
|
|
||||||
rt2x00lib_config_antenna(rt2x00dev, rx, tx);
|
rt2x00lib_config_antenna(rt2x00dev, &ant);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
|
static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
|
||||||
|
@ -574,7 +575,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
|
||||||
entry->skb = NULL;
|
entry->skb = NULL;
|
||||||
entry->flags = 0;
|
entry->flags = 0;
|
||||||
|
|
||||||
rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry);
|
rt2x00dev->ops->lib->clear_entry(entry);
|
||||||
|
|
||||||
clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
||||||
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
|
rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
|
||||||
|
@ -706,7 +707,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
|
||||||
entry->skb = skb;
|
entry->skb = skb;
|
||||||
entry->flags = 0;
|
entry->flags = 0;
|
||||||
|
|
||||||
rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry);
|
rt2x00dev->ops->lib->clear_entry(entry);
|
||||||
|
|
||||||
rt2x00queue_index_inc(entry->queue, Q_INDEX);
|
rt2x00queue_index_inc(entry->queue, Q_INDEX);
|
||||||
}
|
}
|
||||||
|
@ -717,31 +718,31 @@ EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
|
||||||
*/
|
*/
|
||||||
const struct rt2x00_rate rt2x00_supported_rates[12] = {
|
const struct rt2x00_rate rt2x00_supported_rates[12] = {
|
||||||
{
|
{
|
||||||
.flags = DEV_RATE_CCK | DEV_RATE_BASIC,
|
.flags = DEV_RATE_CCK,
|
||||||
.bitrate = 10,
|
.bitrate = 10,
|
||||||
.ratemask = BIT(0),
|
.ratemask = BIT(0),
|
||||||
.plcp = 0x00,
|
.plcp = 0x00,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
|
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
|
||||||
.bitrate = 20,
|
.bitrate = 20,
|
||||||
.ratemask = BIT(1),
|
.ratemask = BIT(1),
|
||||||
.plcp = 0x01,
|
.plcp = 0x01,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
|
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
|
||||||
.bitrate = 55,
|
.bitrate = 55,
|
||||||
.ratemask = BIT(2),
|
.ratemask = BIT(2),
|
||||||
.plcp = 0x02,
|
.plcp = 0x02,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC,
|
.flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
|
||||||
.bitrate = 110,
|
.bitrate = 110,
|
||||||
.ratemask = BIT(3),
|
.ratemask = BIT(3),
|
||||||
.plcp = 0x03,
|
.plcp = 0x03,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
|
.flags = DEV_RATE_OFDM,
|
||||||
.bitrate = 60,
|
.bitrate = 60,
|
||||||
.ratemask = BIT(4),
|
.ratemask = BIT(4),
|
||||||
.plcp = 0x0b,
|
.plcp = 0x0b,
|
||||||
|
@ -753,7 +754,7 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
|
||||||
.plcp = 0x0f,
|
.plcp = 0x0f,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
|
.flags = DEV_RATE_OFDM,
|
||||||
.bitrate = 120,
|
.bitrate = 120,
|
||||||
.ratemask = BIT(6),
|
.ratemask = BIT(6),
|
||||||
.plcp = 0x0a,
|
.plcp = 0x0a,
|
||||||
|
@ -765,7 +766,7 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
|
||||||
.plcp = 0x0e,
|
.plcp = 0x0e,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.flags = DEV_RATE_OFDM | DEV_RATE_BASIC,
|
.flags = DEV_RATE_OFDM,
|
||||||
.bitrate = 240,
|
.bitrate = 240,
|
||||||
.ratemask = BIT(8),
|
.ratemask = BIT(8),
|
||||||
.plcp = 0x09,
|
.plcp = 0x09,
|
||||||
|
@ -1050,6 +1051,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
|
||||||
{
|
{
|
||||||
int retval = -ENOMEM;
|
int retval = -ENOMEM;
|
||||||
|
|
||||||
|
mutex_init(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make room for rt2x00_intf inside the per-interface
|
* Make room for rt2x00_intf inside the per-interface
|
||||||
* structure ieee80211_vif.
|
* structure ieee80211_vif.
|
||||||
|
|
|
@ -72,49 +72,33 @@ void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled)
|
static void rt2x00led_led_simple(struct rt2x00_led *led, bool enabled)
|
||||||
{
|
{
|
||||||
struct rt2x00_led *led = &rt2x00dev->led_qual;
|
unsigned int brightness = enabled ? LED_FULL : LED_OFF;
|
||||||
unsigned int brightness;
|
|
||||||
|
|
||||||
if ((led->type != LED_TYPE_ACTIVITY) || !(led->flags & LED_REGISTERED))
|
if (!(led->flags & LED_REGISTERED))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
brightness = enabled ? LED_FULL : LED_OFF;
|
led->led_dev.brightness_set(&led->led_dev, brightness);
|
||||||
if (brightness != led->led_dev.brightness) {
|
led->led_dev.brightness = brightness;
|
||||||
led->led_dev.brightness_set(&led->led_dev, brightness);
|
}
|
||||||
led->led_dev.brightness = brightness;
|
|
||||||
}
|
void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled)
|
||||||
|
{
|
||||||
|
if (rt2x00dev->led_qual.type == LED_TYPE_ACTIVITY)
|
||||||
|
rt2x00led_led_simple(&rt2x00dev->led_qual, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled)
|
void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled)
|
||||||
{
|
{
|
||||||
struct rt2x00_led *led = &rt2x00dev->led_assoc;
|
if (rt2x00dev->led_assoc.type == LED_TYPE_ASSOC)
|
||||||
unsigned int brightness;
|
rt2x00led_led_simple(&rt2x00dev->led_assoc, enabled);
|
||||||
|
|
||||||
if ((led->type != LED_TYPE_ASSOC) || !(led->flags & LED_REGISTERED))
|
|
||||||
return;
|
|
||||||
|
|
||||||
brightness = enabled ? LED_FULL : LED_OFF;
|
|
||||||
if (brightness != led->led_dev.brightness) {
|
|
||||||
led->led_dev.brightness_set(&led->led_dev, brightness);
|
|
||||||
led->led_dev.brightness = brightness;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled)
|
void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled)
|
||||||
{
|
{
|
||||||
struct rt2x00_led *led = &rt2x00dev->led_radio;
|
if (rt2x00dev->led_radio.type == LED_TYPE_ASSOC)
|
||||||
unsigned int brightness;
|
rt2x00led_led_simple(&rt2x00dev->led_radio, enabled);
|
||||||
|
|
||||||
if ((led->type != LED_TYPE_RADIO) || !(led->flags & LED_REGISTERED))
|
|
||||||
return;
|
|
||||||
|
|
||||||
brightness = enabled ? LED_FULL : LED_OFF;
|
|
||||||
if (brightness != led->led_dev.brightness) {
|
|
||||||
led->led_dev.brightness_set(&led->led_dev, brightness);
|
|
||||||
led->led_dev.brightness = brightness;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
|
static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
|
||||||
|
@ -125,6 +109,13 @@ static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
led->led_dev.name = name;
|
led->led_dev.name = name;
|
||||||
|
led->led_dev.brightness = LED_OFF;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure the LED is off, it might have been enabled
|
||||||
|
* by the hardware when the device was powered on.
|
||||||
|
*/
|
||||||
|
led->led_dev.brightness_set(&led->led_dev, LED_OFF);
|
||||||
|
|
||||||
retval = led_classdev_register(device, &led->led_dev);
|
retval = led_classdev_register(device, &led->led_dev);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
|
@ -199,7 +190,16 @@ exit_fail:
|
||||||
static void rt2x00leds_unregister_led(struct rt2x00_led *led)
|
static void rt2x00leds_unregister_led(struct rt2x00_led *led)
|
||||||
{
|
{
|
||||||
led_classdev_unregister(&led->led_dev);
|
led_classdev_unregister(&led->led_dev);
|
||||||
led->led_dev.brightness_set(&led->led_dev, LED_OFF);
|
|
||||||
|
/*
|
||||||
|
* This might look weird, but when we are unregistering while
|
||||||
|
* suspended the led is already off, and since we haven't
|
||||||
|
* fully resumed yet, access to the device might not be
|
||||||
|
* possible yet.
|
||||||
|
*/
|
||||||
|
if (!(led->led_dev.flags & LED_SUSPENDED))
|
||||||
|
led->led_dev.brightness_set(&led->led_dev, LED_OFF);
|
||||||
|
|
||||||
led->flags &= ~LED_REGISTERED;
|
led->flags &= ~LED_REGISTERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,22 +213,40 @@ void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev)
|
||||||
rt2x00leds_unregister_led(&rt2x00dev->led_radio);
|
rt2x00leds_unregister_led(&rt2x00dev->led_radio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void rt2x00leds_suspend_led(struct rt2x00_led *led)
|
||||||
|
{
|
||||||
|
led_classdev_suspend(&led->led_dev);
|
||||||
|
|
||||||
|
/* This shouldn't be needed, but just to be safe */
|
||||||
|
led->led_dev.brightness_set(&led->led_dev, LED_OFF);
|
||||||
|
led->led_dev.brightness = LED_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev)
|
void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev)
|
||||||
{
|
{
|
||||||
if (rt2x00dev->led_qual.flags & LED_REGISTERED)
|
if (rt2x00dev->led_qual.flags & LED_REGISTERED)
|
||||||
led_classdev_suspend(&rt2x00dev->led_qual.led_dev);
|
rt2x00leds_suspend_led(&rt2x00dev->led_qual);
|
||||||
if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
|
if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
|
||||||
led_classdev_suspend(&rt2x00dev->led_assoc.led_dev);
|
rt2x00leds_suspend_led(&rt2x00dev->led_assoc);
|
||||||
if (rt2x00dev->led_radio.flags & LED_REGISTERED)
|
if (rt2x00dev->led_radio.flags & LED_REGISTERED)
|
||||||
led_classdev_suspend(&rt2x00dev->led_radio.led_dev);
|
rt2x00leds_suspend_led(&rt2x00dev->led_radio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void rt2x00leds_resume_led(struct rt2x00_led *led)
|
||||||
|
{
|
||||||
|
led_classdev_resume(&led->led_dev);
|
||||||
|
|
||||||
|
/* Device might have enabled the LEDS during resume */
|
||||||
|
led->led_dev.brightness_set(&led->led_dev, LED_OFF);
|
||||||
|
led->led_dev.brightness = LED_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev)
|
void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev)
|
||||||
{
|
{
|
||||||
if (rt2x00dev->led_radio.flags & LED_REGISTERED)
|
if (rt2x00dev->led_radio.flags & LED_REGISTERED)
|
||||||
led_classdev_resume(&rt2x00dev->led_radio.led_dev);
|
rt2x00leds_resume_led(&rt2x00dev->led_radio);
|
||||||
if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
|
if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
|
||||||
led_classdev_resume(&rt2x00dev->led_assoc.led_dev);
|
rt2x00leds_resume_led(&rt2x00dev->led_assoc);
|
||||||
if (rt2x00dev->led_qual.flags & LED_REGISTERED)
|
if (rt2x00dev->led_qual.flags & LED_REGISTERED)
|
||||||
led_classdev_resume(&rt2x00dev->led_qual.led_dev);
|
rt2x00leds_resume_led(&rt2x00dev->led_qual);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ struct rt2x00_rate {
|
||||||
#define DEV_RATE_CCK 0x0001
|
#define DEV_RATE_CCK 0x0001
|
||||||
#define DEV_RATE_OFDM 0x0002
|
#define DEV_RATE_OFDM 0x0002
|
||||||
#define DEV_RATE_SHORT_PREAMBLE 0x0004
|
#define DEV_RATE_SHORT_PREAMBLE 0x0004
|
||||||
#define DEV_RATE_BASIC 0x0008
|
|
||||||
|
|
||||||
unsigned short bitrate; /* In 100kbit/s */
|
unsigned short bitrate; /* In 100kbit/s */
|
||||||
unsigned short ratemask;
|
unsigned short ratemask;
|
||||||
|
@ -94,7 +93,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
|
||||||
struct rt2x00_intf *intf,
|
struct rt2x00_intf *intf,
|
||||||
struct ieee80211_bss_conf *conf);
|
struct ieee80211_bss_conf *conf);
|
||||||
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
|
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
|
||||||
enum antenna rx, enum antenna tx);
|
struct antenna_setup *ant);
|
||||||
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
|
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
|
||||||
struct ieee80211_conf *conf,
|
struct ieee80211_conf *conf,
|
||||||
const unsigned int changed_flags);
|
const unsigned int changed_flags);
|
||||||
|
@ -151,8 +150,16 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
|
||||||
*/
|
*/
|
||||||
void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
|
void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
|
||||||
|
|
||||||
void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev);
|
/**
|
||||||
void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev);
|
* rt2x00queue_init_queues - Initialize all data queues
|
||||||
|
* @rt2x00dev: Pointer to &struct rt2x00_dev.
|
||||||
|
*
|
||||||
|
* This function will loop through all available queues to clear all
|
||||||
|
* index numbers and set the queue entry to the correct initialization
|
||||||
|
* state.
|
||||||
|
*/
|
||||||
|
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev);
|
||||||
|
|
||||||
int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
|
int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
|
||||||
void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev);
|
void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev);
|
||||||
int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev);
|
int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev);
|
||||||
|
|
|
@ -339,7 +339,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
|
||||||
{
|
{
|
||||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||||
struct ieee80211_conf *conf = &hw->conf;
|
struct ieee80211_conf *conf = &hw->conf;
|
||||||
int radio_on;
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -356,7 +355,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
|
||||||
* some configuration parameters (e.g. channel and antenna values) can
|
* some configuration parameters (e.g. channel and antenna values) can
|
||||||
* only be set when the radio is enabled.
|
* only be set when the radio is enabled.
|
||||||
*/
|
*/
|
||||||
radio_on = test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
|
|
||||||
if (conf->radio_enabled) {
|
if (conf->radio_enabled) {
|
||||||
/* For programming the values, we have to turn RX off */
|
/* For programming the values, we have to turn RX off */
|
||||||
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
|
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
|
||||||
|
@ -372,6 +370,17 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
|
||||||
*/
|
*/
|
||||||
rt2x00lib_config(rt2x00dev, conf, changed);
|
rt2x00lib_config(rt2x00dev, conf, changed);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The radio was enabled, configure the antenna to the
|
||||||
|
* default settings, the link tuner will later start
|
||||||
|
* continue configuring the antenna based on the software
|
||||||
|
* diversity. But for non-diversity configurations, we need
|
||||||
|
* to have configured the correct state now.
|
||||||
|
*/
|
||||||
|
if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED)
|
||||||
|
rt2x00lib_config_antenna(rt2x00dev,
|
||||||
|
&rt2x00dev->default_ant);
|
||||||
|
|
||||||
/* Turn RX back on */
|
/* Turn RX back on */
|
||||||
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
|
rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
|
||||||
} else {
|
} else {
|
||||||
|
@ -486,7 +495,9 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||||
struct ieee80211_key_conf *key);
|
struct ieee80211_key_conf *key);
|
||||||
struct rt2x00lib_crypto crypto;
|
struct rt2x00lib_crypto crypto;
|
||||||
|
|
||||||
if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
|
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
|
||||||
|
return 0;
|
||||||
|
else if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
else if (key->keylen > 32)
|
else if (key->keylen > 32)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
|
@ -36,20 +36,17 @@
|
||||||
*/
|
*/
|
||||||
int rt2x00pci_write_tx_data(struct queue_entry *entry)
|
int rt2x00pci_write_tx_data(struct queue_entry *entry)
|
||||||
{
|
{
|
||||||
|
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||||
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
||||||
struct skb_frame_desc *skbdesc;
|
struct skb_frame_desc *skbdesc;
|
||||||
u32 word;
|
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This should not happen, we already checked the entry
|
* This should not happen, we already checked the entry
|
||||||
* was ours. When the hardware disagrees there has been
|
* was ours. When the hardware disagrees there has been
|
||||||
* a queue corruption!
|
* a queue corruption!
|
||||||
*/
|
*/
|
||||||
if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) ||
|
if (unlikely(rt2x00dev->ops->lib->get_entry_state(entry))) {
|
||||||
rt2x00_get_field32(word, TXD_ENTRY_VALID))) {
|
ERROR(rt2x00dev,
|
||||||
ERROR(entry->queue->rt2x00dev,
|
|
||||||
"Corrupt queue %d, accessing entry which is not ours.\n"
|
"Corrupt queue %d, accessing entry which is not ours.\n"
|
||||||
"Please file bug report to %s.\n",
|
"Please file bug report to %s.\n",
|
||||||
entry->queue->qid, DRV_PROJECT);
|
entry->queue->qid, DRV_PROJECT);
|
||||||
|
@ -76,14 +73,12 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
|
||||||
struct queue_entry *entry;
|
struct queue_entry *entry;
|
||||||
struct queue_entry_priv_pci *entry_priv;
|
struct queue_entry_priv_pci *entry_priv;
|
||||||
struct skb_frame_desc *skbdesc;
|
struct skb_frame_desc *skbdesc;
|
||||||
u32 word;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
entry = rt2x00queue_get_entry(queue, Q_INDEX);
|
entry = rt2x00queue_get_entry(queue, Q_INDEX);
|
||||||
entry_priv = entry->priv_data;
|
entry_priv = entry->priv_data;
|
||||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
|
||||||
|
|
||||||
if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC))
|
if (rt2x00dev->ops->lib->get_entry_state(entry))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -43,17 +43,6 @@
|
||||||
#define REGISTER_BUSY_COUNT 5
|
#define REGISTER_BUSY_COUNT 5
|
||||||
#define REGISTER_BUSY_DELAY 100
|
#define REGISTER_BUSY_DELAY 100
|
||||||
|
|
||||||
/*
|
|
||||||
* Descriptor availability flags.
|
|
||||||
* All PCI device descriptors have these 2 flags
|
|
||||||
* with the exact same definition.
|
|
||||||
* By storing them here we can use them inside rt2x00pci
|
|
||||||
* for some simple entry availability checking.
|
|
||||||
*/
|
|
||||||
#define TXD_ENTRY_OWNER_NIC FIELD32(0x00000001)
|
|
||||||
#define TXD_ENTRY_VALID FIELD32(0x00000002)
|
|
||||||
#define RXD_ENTRY_OWNER_NIC FIELD32(0x00000001)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register access.
|
* Register access.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -319,8 +319,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
|
||||||
/*
|
/*
|
||||||
* Convert length to microseconds.
|
* Convert length to microseconds.
|
||||||
*/
|
*/
|
||||||
residual = get_duration_res(data_length, hwrate->bitrate);
|
residual = GET_DURATION_RES(data_length, hwrate->bitrate);
|
||||||
duration = get_duration(data_length, hwrate->bitrate);
|
duration = GET_DURATION(data_length, hwrate->bitrate);
|
||||||
|
|
||||||
if (residual != 0) {
|
if (residual != 0) {
|
||||||
duration++;
|
duration++;
|
||||||
|
@ -589,40 +589,18 @@ static void rt2x00queue_reset(struct data_queue *queue)
|
||||||
spin_unlock_irqrestore(&queue->lock, irqflags);
|
spin_unlock_irqrestore(&queue->lock, irqflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev)
|
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
|
||||||
{
|
|
||||||
struct data_queue *queue = rt2x00dev->rx;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
rt2x00queue_reset(queue);
|
|
||||||
|
|
||||||
if (!rt2x00dev->ops->lib->init_rxentry)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < queue->limit; i++) {
|
|
||||||
queue->entries[i].flags = 0;
|
|
||||||
|
|
||||||
rt2x00dev->ops->lib->init_rxentry(rt2x00dev,
|
|
||||||
&queue->entries[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev)
|
|
||||||
{
|
{
|
||||||
struct data_queue *queue;
|
struct data_queue *queue;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
txall_queue_for_each(rt2x00dev, queue) {
|
queue_for_each(rt2x00dev, queue) {
|
||||||
rt2x00queue_reset(queue);
|
rt2x00queue_reset(queue);
|
||||||
|
|
||||||
if (!rt2x00dev->ops->lib->init_txentry)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (i = 0; i < queue->limit; i++) {
|
for (i = 0; i < queue->limit; i++) {
|
||||||
queue->entries[i].flags = 0;
|
queue->entries[i].flags = 0;
|
||||||
|
|
||||||
rt2x00dev->ops->lib->init_txentry(rt2x00dev,
|
rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
|
||||||
&queue->entries[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex));
|
BUG_ON(!mutex_is_locked(&rt2x00dev->csr_mutex));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for Cache availability.
|
* Check for Cache availability.
|
||||||
|
@ -110,13 +110,13 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
|
status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
|
||||||
requesttype, offset, buffer,
|
requesttype, offset, buffer,
|
||||||
buffer_length, timeout);
|
buffer_length, timeout);
|
||||||
|
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
|
||||||
unsigned char *tb;
|
unsigned char *tb;
|
||||||
u16 off, len, bsize;
|
u16 off, len, bsize;
|
||||||
|
|
||||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
tb = (char *)buffer;
|
tb = (char *)buffer;
|
||||||
off = offset;
|
off = offset;
|
||||||
|
@ -148,7 +148,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
|
||||||
off += bsize;
|
off += bsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -351,28 +351,25 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
|
||||||
/*
|
/*
|
||||||
* Device initialization handlers.
|
* Device initialization handlers.
|
||||||
*/
|
*/
|
||||||
void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
|
void rt2x00usb_clear_entry(struct queue_entry *entry)
|
||||||
struct queue_entry *entry)
|
|
||||||
{
|
{
|
||||||
struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
|
struct usb_device *usb_dev =
|
||||||
|
to_usb_device_intf(entry->queue->rt2x00dev->dev);
|
||||||
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
|
struct queue_entry_priv_usb *entry_priv = entry->priv_data;
|
||||||
|
|
||||||
usb_fill_bulk_urb(entry_priv->urb, usb_dev,
|
if (entry->queue->qid == QID_RX) {
|
||||||
usb_rcvbulkpipe(usb_dev, 1),
|
usb_fill_bulk_urb(entry_priv->urb, usb_dev,
|
||||||
entry->skb->data, entry->skb->len,
|
usb_rcvbulkpipe(usb_dev, 1),
|
||||||
rt2x00usb_interrupt_rxdone, entry);
|
entry->skb->data, entry->skb->len,
|
||||||
|
rt2x00usb_interrupt_rxdone, entry);
|
||||||
|
|
||||||
set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
|
||||||
usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
|
usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
|
||||||
|
} else {
|
||||||
|
entry->flags = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry);
|
EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
|
||||||
|
|
||||||
void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
|
|
||||||
struct queue_entry *entry)
|
|
||||||
{
|
|
||||||
entry->flags = 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry);
|
|
||||||
|
|
||||||
static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
|
static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
|
||||||
struct data_queue *queue)
|
struct data_queue *queue)
|
||||||
|
@ -534,7 +531,6 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
|
||||||
rt2x00dev->dev = &usb_intf->dev;
|
rt2x00dev->dev = &usb_intf->dev;
|
||||||
rt2x00dev->ops = ops;
|
rt2x00dev->ops = ops;
|
||||||
rt2x00dev->hw = hw;
|
rt2x00dev->hw = hw;
|
||||||
mutex_init(&rt2x00dev->usb_cache_mutex);
|
|
||||||
|
|
||||||
rt2x00dev->usb_maxpacket =
|
rt2x00dev->usb_maxpacket =
|
||||||
usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1);
|
usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1);
|
||||||
|
|
|
@ -286,10 +286,7 @@ void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
|
||||||
/*
|
/*
|
||||||
* Device initialization handlers.
|
* Device initialization handlers.
|
||||||
*/
|
*/
|
||||||
void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
|
void rt2x00usb_clear_entry(struct queue_entry *entry);
|
||||||
struct queue_entry *entry);
|
|
||||||
void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
|
|
||||||
struct queue_entry *entry);
|
|
||||||
int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev);
|
int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev);
|
||||||
void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev);
|
void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev);
|
||||||
|
|
||||||
|
|
|
@ -75,14 +75,14 @@ static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
*/
|
*/
|
||||||
reg = rt61pci_bbp_check(rt2x00dev);
|
reg = rt61pci_bbp_check(rt2x00dev);
|
||||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
|
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
|
||||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
|
goto exit_fail;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the data into the BBP.
|
* Write the data into the BBP.
|
||||||
|
@ -94,6 +94,14 @@ static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||||
rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0);
|
rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0);
|
||||||
|
|
||||||
rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
|
rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
exit_fail:
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
|
@ -101,14 +109,14 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
*/
|
*/
|
||||||
reg = rt61pci_bbp_check(rt2x00dev);
|
reg = rt61pci_bbp_check(rt2x00dev);
|
||||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
|
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
|
||||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
goto exit_fail;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the request into the BBP.
|
* Write the request into the BBP.
|
||||||
|
@ -124,13 +132,19 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
*/
|
*/
|
||||||
reg = rt61pci_bbp_check(rt2x00dev);
|
reg = rt61pci_bbp_check(rt2x00dev);
|
||||||
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
|
if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
|
||||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
goto exit_fail;
|
||||||
*value = 0xff;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
|
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
exit_fail:
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
||||||
|
*value = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
|
@ -142,6 +156,8 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
if (!word)
|
if (!word)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||||
rt2x00pci_register_read(rt2x00dev, PHY_CSR4, ®);
|
rt2x00pci_register_read(rt2x00dev, PHY_CSR4, ®);
|
||||||
if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY))
|
if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY))
|
||||||
|
@ -149,6 +165,7 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
udelay(REGISTER_BUSY_DELAY);
|
udelay(REGISTER_BUSY_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
|
ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -161,6 +178,8 @@ rf_write:
|
||||||
|
|
||||||
rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg);
|
rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg);
|
||||||
rt2x00_rf_write(rt2x00dev, word, value);
|
rt2x00_rf_write(rt2x00dev, word, value);
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_RT2X00_LIB_LEDS
|
#ifdef CONFIG_RT2X00_LIB_LEDS
|
||||||
|
@ -175,14 +194,12 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, ®);
|
rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, ®);
|
||||||
|
|
||||||
if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER)) {
|
if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER))
|
||||||
ERROR(rt2x00dev, "mcu request error. "
|
goto exit_fail;
|
||||||
"Request 0x%02x failed for token 0x%02x.\n",
|
|
||||||
command, token);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1);
|
rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1);
|
||||||
rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token);
|
rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token);
|
||||||
|
@ -194,6 +211,17 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
|
||||||
rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command);
|
rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command);
|
||||||
rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1);
|
rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1);
|
||||||
rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg);
|
rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg);
|
||||||
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
exit_fail:
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
|
ERROR(rt2x00dev,
|
||||||
|
"mcu request error. Request 0x%02x failed for token 0x%02x.\n",
|
||||||
|
command, token);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_RT2X00_LIB_LEDS */
|
#endif /* CONFIG_RT2X00_LIB_LEDS */
|
||||||
|
|
||||||
|
@ -1261,33 +1289,44 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
|
||||||
/*
|
/*
|
||||||
* Initialization functions.
|
* Initialization functions.
|
||||||
*/
|
*/
|
||||||
static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
|
static bool rt61pci_get_entry_state(struct queue_entry *entry)
|
||||||
struct queue_entry *entry)
|
{
|
||||||
|
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
||||||
|
u32 word;
|
||||||
|
|
||||||
|
if (entry->queue->qid == QID_RX) {
|
||||||
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
|
|
||||||
|
return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
|
||||||
|
} else {
|
||||||
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
|
|
||||||
|
return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
|
||||||
|
rt2x00_get_field32(word, TXD_W0_VALID));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rt61pci_clear_entry(struct queue_entry *entry)
|
||||||
{
|
{
|
||||||
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
||||||
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||||
u32 word;
|
u32 word;
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 5, &word);
|
if (entry->queue->qid == QID_RX) {
|
||||||
rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
|
rt2x00_desc_read(entry_priv->desc, 5, &word);
|
||||||
skbdesc->skb_dma);
|
rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
|
||||||
rt2x00_desc_write(entry_priv->desc, 5, word);
|
skbdesc->skb_dma);
|
||||||
|
rt2x00_desc_write(entry_priv->desc, 5, word);
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
|
||||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||||
}
|
} else {
|
||||||
|
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
||||||
static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev,
|
rt2x00_set_field32(&word, TXD_W0_VALID, 0);
|
||||||
struct queue_entry *entry)
|
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
|
||||||
{
|
rt2x00_desc_write(entry_priv->desc, 0, word);
|
||||||
struct queue_entry_priv_pci *entry_priv = entry->priv_data;
|
}
|
||||||
u32 word;
|
|
||||||
|
|
||||||
rt2x00_desc_read(entry_priv->desc, 0, &word);
|
|
||||||
rt2x00_set_field32(&word, TXD_W0_VALID, 0);
|
|
||||||
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
|
|
||||||
rt2x00_desc_write(entry_priv->desc, 0, word);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev)
|
static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev)
|
||||||
|
@ -2722,8 +2761,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
|
||||||
.load_firmware = rt61pci_load_firmware,
|
.load_firmware = rt61pci_load_firmware,
|
||||||
.initialize = rt2x00pci_initialize,
|
.initialize = rt2x00pci_initialize,
|
||||||
.uninitialize = rt2x00pci_uninitialize,
|
.uninitialize = rt2x00pci_uninitialize,
|
||||||
.init_rxentry = rt61pci_init_rxentry,
|
.get_entry_state = rt61pci_get_entry_state,
|
||||||
.init_txentry = rt61pci_init_txentry,
|
.clear_entry = rt61pci_clear_entry,
|
||||||
.set_device_state = rt61pci_set_device_state,
|
.set_device_state = rt61pci_set_device_state,
|
||||||
.rfkill_poll = rt61pci_rfkill_poll,
|
.rfkill_poll = rt61pci_rfkill_poll,
|
||||||
.link_stats = rt61pci_link_stats,
|
.link_stats = rt61pci_link_stats,
|
||||||
|
|
|
@ -55,7 +55,7 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
|
||||||
* between each attampt. When the busy bit is still set at that time,
|
* between each attampt. When the busy bit is still set at that time,
|
||||||
* the access attempt is considered to have failed,
|
* the access attempt is considered to have failed,
|
||||||
* and we will print an error.
|
* and we will print an error.
|
||||||
* The _lock versions must be used if you already hold the usb_cache_mutex
|
* The _lock versions must be used if you already hold the csr_mutex
|
||||||
*/
|
*/
|
||||||
static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev,
|
static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev,
|
||||||
const unsigned int offset, u32 *value)
|
const unsigned int offset, u32 *value)
|
||||||
|
@ -135,7 +135,7 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
|
@ -154,12 +154,12 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
|
||||||
rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0);
|
rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0);
|
||||||
|
|
||||||
rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
|
rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
exit_fail:
|
exit_fail:
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
|
ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until the BBP becomes ready.
|
* Wait until the BBP becomes ready.
|
||||||
|
@ -196,12 +196,12 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
|
||||||
goto exit_fail;
|
goto exit_fail;
|
||||||
|
|
||||||
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
|
*value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
exit_fail:
|
exit_fail:
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
|
||||||
*value = 0xff;
|
*value = 0xff;
|
||||||
|
@ -216,7 +216,7 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
if (!word)
|
if (!word)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
mutex_lock(&rt2x00dev->csr_mutex);
|
||||||
|
|
||||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||||
rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, ®);
|
rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, ®);
|
||||||
|
@ -225,7 +225,7 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
|
||||||
udelay(REGISTER_BUSY_DELAY);
|
udelay(REGISTER_BUSY_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
|
ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -245,7 +245,8 @@ rf_write:
|
||||||
|
|
||||||
rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg);
|
rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg);
|
||||||
rt2x00_rf_write(rt2x00dev, word, value);
|
rt2x00_rf_write(rt2x00dev, word, value);
|
||||||
mutex_unlock(&rt2x00dev->usb_cache_mutex);
|
|
||||||
|
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
|
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
|
||||||
|
@ -2313,8 +2314,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
|
||||||
.load_firmware = rt73usb_load_firmware,
|
.load_firmware = rt73usb_load_firmware,
|
||||||
.initialize = rt2x00usb_initialize,
|
.initialize = rt2x00usb_initialize,
|
||||||
.uninitialize = rt2x00usb_uninitialize,
|
.uninitialize = rt2x00usb_uninitialize,
|
||||||
.init_rxentry = rt2x00usb_init_rxentry,
|
.clear_entry = rt2x00usb_clear_entry,
|
||||||
.init_txentry = rt2x00usb_init_txentry,
|
|
||||||
.set_device_state = rt73usb_set_device_state,
|
.set_device_state = rt73usb_set_device_state,
|
||||||
.link_stats = rt73usb_link_stats,
|
.link_stats = rt73usb_link_stats,
|
||||||
.reset_tuner = rt73usb_reset_tuner,
|
.reset_tuner = rt73usb_reset_tuner,
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
|
||||||
|
rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_RTL8180) += rtl8180.o
|
||||||
|
obj-$(CONFIG_RTL8187) += rtl8187.o
|
||||||
|
|
||||||
|
|
|
@ -720,6 +720,17 @@ static int rtl8180_config_interface(struct ieee80211_hw *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
|
||||||
|
struct ieee80211_vif *vif,
|
||||||
|
struct ieee80211_bss_conf *info,
|
||||||
|
u32 changed)
|
||||||
|
{
|
||||||
|
struct rtl8180_priv *priv = dev->priv;
|
||||||
|
|
||||||
|
if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
|
||||||
|
priv->rf->conf_erp(dev, info);
|
||||||
|
}
|
||||||
|
|
||||||
static void rtl8180_configure_filter(struct ieee80211_hw *dev,
|
static void rtl8180_configure_filter(struct ieee80211_hw *dev,
|
||||||
unsigned int changed_flags,
|
unsigned int changed_flags,
|
||||||
unsigned int *total_flags,
|
unsigned int *total_flags,
|
||||||
|
@ -760,6 +771,7 @@ static const struct ieee80211_ops rtl8180_ops = {
|
||||||
.remove_interface = rtl8180_remove_interface,
|
.remove_interface = rtl8180_remove_interface,
|
||||||
.config = rtl8180_config,
|
.config = rtl8180_config,
|
||||||
.config_interface = rtl8180_config_interface,
|
.config_interface = rtl8180_config_interface,
|
||||||
|
.bss_info_changed = rtl8180_bss_info_changed,
|
||||||
.configure_filter = rtl8180_configure_filter,
|
.configure_filter = rtl8180_configure_filter,
|
||||||
};
|
};
|
||||||
|
|
|
@ -725,8 +725,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
|
||||||
|
|
||||||
rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
|
rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
|
||||||
msleep(10);
|
msleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
|
static void rtl8225_rf_conf_erp(struct ieee80211_hw *dev,
|
||||||
|
struct ieee80211_bss_conf *info)
|
||||||
|
{
|
||||||
|
struct rtl8180_priv *priv = dev->priv;
|
||||||
|
|
||||||
|
if (info->use_short_slot) {
|
||||||
rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
|
rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
|
||||||
rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
|
rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
|
||||||
rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
|
rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
|
||||||
|
@ -745,14 +751,16 @@ static const struct rtl818x_rf_ops rtl8225_ops = {
|
||||||
.name = "rtl8225",
|
.name = "rtl8225",
|
||||||
.init = rtl8225_rf_init,
|
.init = rtl8225_rf_init,
|
||||||
.stop = rtl8225_rf_stop,
|
.stop = rtl8225_rf_stop,
|
||||||
.set_chan = rtl8225_rf_set_channel
|
.set_chan = rtl8225_rf_set_channel,
|
||||||
|
.conf_erp = rtl8225_rf_conf_erp,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct rtl818x_rf_ops rtl8225z2_ops = {
|
static const struct rtl818x_rf_ops rtl8225z2_ops = {
|
||||||
.name = "rtl8225z2",
|
.name = "rtl8225z2",
|
||||||
.init = rtl8225z2_rf_init,
|
.init = rtl8225z2_rf_init,
|
||||||
.stop = rtl8225_rf_stop,
|
.stop = rtl8225_rf_stop,
|
||||||
.set_chan = rtl8225_rf_set_channel
|
.set_chan = rtl8225_rf_set_channel,
|
||||||
|
.conf_erp = rtl8225_rf_conf_erp,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
|
const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
|
|
@ -7,6 +7,11 @@
|
||||||
* Based on the r8187 driver, which is:
|
* Based on the r8187 driver, which is:
|
||||||
* Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
|
* Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
|
||||||
*
|
*
|
||||||
|
* The driver was extended to the RTL8187B in 2008 by:
|
||||||
|
* Herton Ronaldo Krzesinski <herton@mandriva.com.br>
|
||||||
|
* Hin-Tak Leung <htl10@users.sourceforge.net>
|
||||||
|
* Larry Finger <Larry.Finger@lwfinger.net>
|
||||||
|
*
|
||||||
* Magic delays and register offsets below are taken from the original
|
* Magic delays and register offsets below are taken from the original
|
||||||
* r8187 driver sources. Thanks to Realtek for their support!
|
* r8187 driver sources. Thanks to Realtek for their support!
|
||||||
*
|
*
|
||||||
|
@ -27,6 +32,9 @@
|
||||||
|
|
||||||
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
|
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
|
||||||
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
|
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
|
||||||
|
MODULE_AUTHOR("Herton Ronaldo Krzesinski <herton@mandriva.com.br>");
|
||||||
|
MODULE_AUTHOR("Hin-Tak Leung <htl10@users.sourceforge.net>");
|
||||||
|
MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
|
||||||
MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
|
MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -191,6 +191,7 @@ struct rtl818x_rf_ops {
|
||||||
void (*init)(struct ieee80211_hw *);
|
void (*init)(struct ieee80211_hw *);
|
||||||
void (*stop)(struct ieee80211_hw *);
|
void (*stop)(struct ieee80211_hw *);
|
||||||
void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
|
void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
|
||||||
|
void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Tx/Rx flags are common between RTL818X chips */
|
/* Tx/Rx flags are common between RTL818X chips */
|
|
@ -743,7 +743,7 @@ static int zd1201_join(struct zd1201 *zd, char *essid, int essidlen)
|
||||||
|
|
||||||
static int zd1201_net_open(struct net_device *dev)
|
static int zd1201_net_open(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
|
|
||||||
/* Start MAC with wildcard if no essid set */
|
/* Start MAC with wildcard if no essid set */
|
||||||
if (!zd->mac_enabled)
|
if (!zd->mac_enabled)
|
||||||
|
@ -781,7 +781,7 @@ static int zd1201_net_stop(struct net_device *dev)
|
||||||
*/
|
*/
|
||||||
static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
unsigned char *txbuf = zd->txdata;
|
unsigned char *txbuf = zd->txdata;
|
||||||
int txbuflen, pad = 0, err;
|
int txbuflen, pad = 0, err;
|
||||||
struct urb *urb = zd->tx_urb;
|
struct urb *urb = zd->tx_urb;
|
||||||
|
@ -831,7 +831,7 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
static void zd1201_tx_timeout(struct net_device *dev)
|
static void zd1201_tx_timeout(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
|
|
||||||
if (!zd)
|
if (!zd)
|
||||||
return;
|
return;
|
||||||
|
@ -846,7 +846,7 @@ static void zd1201_tx_timeout(struct net_device *dev)
|
||||||
static int zd1201_set_mac_address(struct net_device *dev, void *p)
|
static int zd1201_set_mac_address(struct net_device *dev, void *p)
|
||||||
{
|
{
|
||||||
struct sockaddr *addr = p;
|
struct sockaddr *addr = p;
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!zd)
|
if (!zd)
|
||||||
|
@ -863,21 +863,21 @@ static int zd1201_set_mac_address(struct net_device *dev, void *p)
|
||||||
|
|
||||||
static struct net_device_stats *zd1201_get_stats(struct net_device *dev)
|
static struct net_device_stats *zd1201_get_stats(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
|
|
||||||
return &zd->stats;
|
return &zd->stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev)
|
static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
|
|
||||||
return &zd->iwstats;
|
return &zd->iwstats;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zd1201_set_multicast(struct net_device *dev)
|
static void zd1201_set_multicast(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
struct dev_mc_list *mc = dev->mc_list;
|
struct dev_mc_list *mc = dev->mc_list;
|
||||||
unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI];
|
unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI];
|
||||||
int i;
|
int i;
|
||||||
|
@ -897,7 +897,7 @@ static void zd1201_set_multicast(struct net_device *dev)
|
||||||
static int zd1201_config_commit(struct net_device *dev,
|
static int zd1201_config_commit(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_point *data, char *essid)
|
struct iw_request_info *info, struct iw_point *data, char *essid)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
|
|
||||||
return zd1201_mac_reset(zd);
|
return zd1201_mac_reset(zd);
|
||||||
}
|
}
|
||||||
|
@ -912,7 +912,7 @@ static int zd1201_get_name(struct net_device *dev,
|
||||||
static int zd1201_set_freq(struct net_device *dev,
|
static int zd1201_set_freq(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_freq *freq, char *extra)
|
struct iw_request_info *info, struct iw_freq *freq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short channel = 0;
|
short channel = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -937,7 +937,7 @@ static int zd1201_set_freq(struct net_device *dev,
|
||||||
static int zd1201_get_freq(struct net_device *dev,
|
static int zd1201_get_freq(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_freq *freq, char *extra)
|
struct iw_request_info *info, struct iw_freq *freq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short channel;
|
short channel;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -953,7 +953,7 @@ static int zd1201_get_freq(struct net_device *dev,
|
||||||
static int zd1201_set_mode(struct net_device *dev,
|
static int zd1201_set_mode(struct net_device *dev,
|
||||||
struct iw_request_info *info, __u32 *mode, char *extra)
|
struct iw_request_info *info, __u32 *mode, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short porttype, monitor = 0;
|
short porttype, monitor = 0;
|
||||||
unsigned char buffer[IW_ESSID_MAX_SIZE+2];
|
unsigned char buffer[IW_ESSID_MAX_SIZE+2];
|
||||||
int err;
|
int err;
|
||||||
|
@ -1015,7 +1015,7 @@ static int zd1201_set_mode(struct net_device *dev,
|
||||||
static int zd1201_get_mode(struct net_device *dev,
|
static int zd1201_get_mode(struct net_device *dev,
|
||||||
struct iw_request_info *info, __u32 *mode, char *extra)
|
struct iw_request_info *info, __u32 *mode, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short porttype;
|
short porttype;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1091,7 +1091,7 @@ static int zd1201_get_range(struct net_device *dev,
|
||||||
static int zd1201_get_wap(struct net_device *dev,
|
static int zd1201_get_wap(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct sockaddr *ap_addr, char *extra)
|
struct iw_request_info *info, struct sockaddr *ap_addr, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
unsigned char buffer[6];
|
unsigned char buffer[6];
|
||||||
|
|
||||||
if (!zd1201_getconfig(zd, ZD1201_RID_COMMSQUALITY, buffer, 6)) {
|
if (!zd1201_getconfig(zd, ZD1201_RID_COMMSQUALITY, buffer, 6)) {
|
||||||
|
@ -1119,7 +1119,7 @@ static int zd1201_set_scan(struct net_device *dev,
|
||||||
static int zd1201_get_scan(struct net_device *dev,
|
static int zd1201_get_scan(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_point *srq, char *extra)
|
struct iw_request_info *info, struct iw_point *srq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
int err, i, j, enabled_save;
|
int err, i, j, enabled_save;
|
||||||
struct iw_event iwe;
|
struct iw_event iwe;
|
||||||
char *cev = extra;
|
char *cev = extra;
|
||||||
|
@ -1211,7 +1211,7 @@ static int zd1201_get_scan(struct net_device *dev,
|
||||||
static int zd1201_set_essid(struct net_device *dev,
|
static int zd1201_set_essid(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_point *data, char *essid)
|
struct iw_request_info *info, struct iw_point *data, char *essid)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
|
|
||||||
if (data->length > IW_ESSID_MAX_SIZE)
|
if (data->length > IW_ESSID_MAX_SIZE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1226,7 +1226,7 @@ static int zd1201_set_essid(struct net_device *dev,
|
||||||
static int zd1201_get_essid(struct net_device *dev,
|
static int zd1201_get_essid(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_point *data, char *essid)
|
struct iw_request_info *info, struct iw_point *data, char *essid)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
|
|
||||||
memcpy(essid, zd->essid, zd->essidlen);
|
memcpy(essid, zd->essid, zd->essidlen);
|
||||||
data->flags = 1;
|
data->flags = 1;
|
||||||
|
@ -1247,7 +1247,7 @@ static int zd1201_get_nick(struct net_device *dev, struct iw_request_info *info,
|
||||||
static int zd1201_set_rate(struct net_device *dev,
|
static int zd1201_set_rate(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short rate;
|
short rate;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1280,7 +1280,7 @@ static int zd1201_set_rate(struct net_device *dev,
|
||||||
static int zd1201_get_rate(struct net_device *dev,
|
static int zd1201_get_rate(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short rate;
|
short rate;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1313,7 +1313,7 @@ static int zd1201_get_rate(struct net_device *dev,
|
||||||
static int zd1201_set_rts(struct net_device *dev, struct iw_request_info *info,
|
static int zd1201_set_rts(struct net_device *dev, struct iw_request_info *info,
|
||||||
struct iw_param *rts, char *extra)
|
struct iw_param *rts, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
int err;
|
int err;
|
||||||
short val = rts->value;
|
short val = rts->value;
|
||||||
|
|
||||||
|
@ -1333,7 +1333,7 @@ static int zd1201_set_rts(struct net_device *dev, struct iw_request_info *info,
|
||||||
static int zd1201_get_rts(struct net_device *dev, struct iw_request_info *info,
|
static int zd1201_get_rts(struct net_device *dev, struct iw_request_info *info,
|
||||||
struct iw_param *rts, char *extra)
|
struct iw_param *rts, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short rtst;
|
short rtst;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1350,7 +1350,7 @@ static int zd1201_get_rts(struct net_device *dev, struct iw_request_info *info,
|
||||||
static int zd1201_set_frag(struct net_device *dev, struct iw_request_info *info,
|
static int zd1201_set_frag(struct net_device *dev, struct iw_request_info *info,
|
||||||
struct iw_param *frag, char *extra)
|
struct iw_param *frag, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
int err;
|
int err;
|
||||||
short val = frag->value;
|
short val = frag->value;
|
||||||
|
|
||||||
|
@ -1371,7 +1371,7 @@ static int zd1201_set_frag(struct net_device *dev, struct iw_request_info *info,
|
||||||
static int zd1201_get_frag(struct net_device *dev, struct iw_request_info *info,
|
static int zd1201_get_frag(struct net_device *dev, struct iw_request_info *info,
|
||||||
struct iw_param *frag, char *extra)
|
struct iw_param *frag, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short fragt;
|
short fragt;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1400,7 +1400,7 @@ static int zd1201_get_retry(struct net_device *dev,
|
||||||
static int zd1201_set_encode(struct net_device *dev,
|
static int zd1201_set_encode(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_point *erq, char *key)
|
struct iw_request_info *info, struct iw_point *erq, char *key)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short i;
|
short i;
|
||||||
int err, rid;
|
int err, rid;
|
||||||
|
|
||||||
|
@ -1457,7 +1457,7 @@ static int zd1201_set_encode(struct net_device *dev,
|
||||||
static int zd1201_get_encode(struct net_device *dev,
|
static int zd1201_get_encode(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_point *erq, char *key)
|
struct iw_request_info *info, struct iw_point *erq, char *key)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short i;
|
short i;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1490,7 +1490,7 @@ static int zd1201_get_encode(struct net_device *dev,
|
||||||
static int zd1201_set_power(struct net_device *dev,
|
static int zd1201_set_power(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_param *vwrq, char *extra)
|
struct iw_request_info *info, struct iw_param *vwrq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short enabled, duration, level;
|
short enabled, duration, level;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1529,7 +1529,7 @@ out:
|
||||||
static int zd1201_get_power(struct net_device *dev,
|
static int zd1201_get_power(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_param *vwrq, char *extra)
|
struct iw_request_info *info, struct iw_param *vwrq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short enabled, level, duration;
|
short enabled, level, duration;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1616,7 +1616,7 @@ static const iw_handler zd1201_iw_handler[] =
|
||||||
static int zd1201_set_hostauth(struct net_device *dev,
|
static int zd1201_set_hostauth(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
|
|
||||||
if (!zd->ap)
|
if (!zd->ap)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
@ -1627,7 +1627,7 @@ static int zd1201_set_hostauth(struct net_device *dev,
|
||||||
static int zd1201_get_hostauth(struct net_device *dev,
|
static int zd1201_get_hostauth(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short hostauth;
|
short hostauth;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1646,7 +1646,7 @@ static int zd1201_get_hostauth(struct net_device *dev,
|
||||||
static int zd1201_auth_sta(struct net_device *dev,
|
static int zd1201_auth_sta(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct sockaddr *sta, char *extra)
|
struct iw_request_info *info, struct sockaddr *sta, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
unsigned char buffer[10];
|
unsigned char buffer[10];
|
||||||
|
|
||||||
if (!zd->ap)
|
if (!zd->ap)
|
||||||
|
@ -1662,7 +1662,7 @@ static int zd1201_auth_sta(struct net_device *dev,
|
||||||
static int zd1201_set_maxassoc(struct net_device *dev,
|
static int zd1201_set_maxassoc(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!zd->ap)
|
if (!zd->ap)
|
||||||
|
@ -1677,7 +1677,7 @@ static int zd1201_set_maxassoc(struct net_device *dev,
|
||||||
static int zd1201_get_maxassoc(struct net_device *dev,
|
static int zd1201_get_maxassoc(struct net_device *dev,
|
||||||
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = netdev_priv(dev);
|
||||||
short maxassoc;
|
short maxassoc;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1729,6 +1729,7 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd;
|
struct zd1201 *zd;
|
||||||
|
struct net_device *dev;
|
||||||
struct usb_device *usb;
|
struct usb_device *usb;
|
||||||
int err;
|
int err;
|
||||||
short porttype;
|
short porttype;
|
||||||
|
@ -1736,9 +1737,12 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||||
|
|
||||||
usb = interface_to_usbdev(interface);
|
usb = interface_to_usbdev(interface);
|
||||||
|
|
||||||
zd = kzalloc(sizeof(struct zd1201), GFP_KERNEL);
|
dev = alloc_etherdev(sizeof(*zd));
|
||||||
if (!zd)
|
if (!dev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
zd = netdev_priv(dev);
|
||||||
|
zd->dev = dev;
|
||||||
|
|
||||||
zd->ap = ap;
|
zd->ap = ap;
|
||||||
zd->usb = usb;
|
zd->usb = usb;
|
||||||
zd->removed = 0;
|
zd->removed = 0;
|
||||||
|
@ -1773,34 +1777,29 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||||
if (err)
|
if (err)
|
||||||
goto err_start;
|
goto err_start;
|
||||||
|
|
||||||
zd->dev = alloc_etherdev(0);
|
dev->open = zd1201_net_open;
|
||||||
if (!zd->dev)
|
dev->stop = zd1201_net_stop;
|
||||||
goto err_start;
|
dev->get_stats = zd1201_get_stats;
|
||||||
|
dev->wireless_handlers =
|
||||||
zd->dev->priv = zd;
|
|
||||||
zd->dev->open = zd1201_net_open;
|
|
||||||
zd->dev->stop = zd1201_net_stop;
|
|
||||||
zd->dev->get_stats = zd1201_get_stats;
|
|
||||||
zd->dev->wireless_handlers =
|
|
||||||
(struct iw_handler_def *)&zd1201_iw_handlers;
|
(struct iw_handler_def *)&zd1201_iw_handlers;
|
||||||
zd->dev->hard_start_xmit = zd1201_hard_start_xmit;
|
dev->hard_start_xmit = zd1201_hard_start_xmit;
|
||||||
zd->dev->watchdog_timeo = ZD1201_TX_TIMEOUT;
|
dev->watchdog_timeo = ZD1201_TX_TIMEOUT;
|
||||||
zd->dev->tx_timeout = zd1201_tx_timeout;
|
dev->tx_timeout = zd1201_tx_timeout;
|
||||||
zd->dev->set_multicast_list = zd1201_set_multicast;
|
dev->set_multicast_list = zd1201_set_multicast;
|
||||||
zd->dev->set_mac_address = zd1201_set_mac_address;
|
dev->set_mac_address = zd1201_set_mac_address;
|
||||||
strcpy(zd->dev->name, "wlan%d");
|
strcpy(dev->name, "wlan%d");
|
||||||
|
|
||||||
err = zd1201_getconfig(zd, ZD1201_RID_CNFOWNMACADDR,
|
err = zd1201_getconfig(zd, ZD1201_RID_CNFOWNMACADDR,
|
||||||
zd->dev->dev_addr, zd->dev->addr_len);
|
dev->dev_addr, dev->addr_len);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_net;
|
goto err_start;
|
||||||
|
|
||||||
/* Set wildcard essid to match zd->essid */
|
/* Set wildcard essid to match zd->essid */
|
||||||
*(__le16 *)buf = cpu_to_le16(0);
|
*(__le16 *)buf = cpu_to_le16(0);
|
||||||
err = zd1201_setconfig(zd, ZD1201_RID_CNFDESIREDSSID, buf,
|
err = zd1201_setconfig(zd, ZD1201_RID_CNFDESIREDSSID, buf,
|
||||||
IW_ESSID_MAX_SIZE+2, 1);
|
IW_ESSID_MAX_SIZE+2, 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_net;
|
goto err_start;
|
||||||
|
|
||||||
if (zd->ap)
|
if (zd->ap)
|
||||||
porttype = ZD1201_PORTTYPE_AP;
|
porttype = ZD1201_PORTTYPE_AP;
|
||||||
|
@ -1808,30 +1807,28 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||||
porttype = ZD1201_PORTTYPE_BSS;
|
porttype = ZD1201_PORTTYPE_BSS;
|
||||||
err = zd1201_setconfig16(zd, ZD1201_RID_CNFPORTTYPE, porttype);
|
err = zd1201_setconfig16(zd, ZD1201_RID_CNFPORTTYPE, porttype);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_net;
|
goto err_start;
|
||||||
|
|
||||||
SET_NETDEV_DEV(zd->dev, &usb->dev);
|
SET_NETDEV_DEV(dev, &usb->dev);
|
||||||
|
|
||||||
err = register_netdev(zd->dev);
|
err = register_netdev(dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_net;
|
goto err_start;
|
||||||
dev_info(&usb->dev, "%s: ZD1201 USB Wireless interface\n",
|
dev_info(&usb->dev, "%s: ZD1201 USB Wireless interface\n",
|
||||||
zd->dev->name);
|
dev->name);
|
||||||
|
|
||||||
usb_set_intfdata(interface, zd);
|
usb_set_intfdata(interface, zd);
|
||||||
zd1201_enable(zd); /* zd1201 likes to startup enabled, */
|
zd1201_enable(zd); /* zd1201 likes to startup enabled, */
|
||||||
zd1201_disable(zd); /* interfering with all the wifis in range */
|
zd1201_disable(zd); /* interfering with all the wifis in range */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_net:
|
|
||||||
free_netdev(zd->dev);
|
|
||||||
err_start:
|
err_start:
|
||||||
/* Leave the device in reset state */
|
/* Leave the device in reset state */
|
||||||
zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
|
zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
|
||||||
err_zd:
|
err_zd:
|
||||||
usb_free_urb(zd->tx_urb);
|
usb_free_urb(zd->tx_urb);
|
||||||
usb_free_urb(zd->rx_urb);
|
usb_free_urb(zd->rx_urb);
|
||||||
kfree(zd);
|
free_netdev(dev);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,7 @@ int ssb_devices_freeze(struct ssb_bus *bus)
|
||||||
err = drv->suspend(dev, state);
|
err = drv->suspend(dev, state);
|
||||||
if (err) {
|
if (err) {
|
||||||
ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n",
|
ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n",
|
||||||
dev->dev->bus_id);
|
dev_name(dev->dev));
|
||||||
goto err_unwind;
|
goto err_unwind;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ int ssb_devices_thaw(struct ssb_bus *bus)
|
||||||
err = drv->resume(dev);
|
err = drv->resume(dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n",
|
ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n",
|
||||||
dev->dev->bus_id);
|
dev_name(dev->dev));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,8 +454,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
|
||||||
|
|
||||||
dev->release = ssb_release_dev;
|
dev->release = ssb_release_dev;
|
||||||
dev->bus = &ssb_bustype;
|
dev->bus = &ssb_bustype;
|
||||||
snprintf(dev->bus_id, sizeof(dev->bus_id),
|
dev_set_name(dev, "ssb%u:%d", bus->busnumber, dev_idx);
|
||||||
"ssb%u:%d", bus->busnumber, dev_idx);
|
|
||||||
|
|
||||||
switch (bus->bustype) {
|
switch (bus->bustype) {
|
||||||
case SSB_BUSTYPE_PCI:
|
case SSB_BUSTYPE_PCI:
|
||||||
|
@ -480,7 +479,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
|
||||||
if (err) {
|
if (err) {
|
||||||
ssb_printk(KERN_ERR PFX
|
ssb_printk(KERN_ERR PFX
|
||||||
"Could not register %s\n",
|
"Could not register %s\n",
|
||||||
dev->bus_id);
|
dev_name(dev));
|
||||||
/* Set dev to NULL to not unregister
|
/* Set dev to NULL to not unregister
|
||||||
* dev on error unwinding. */
|
* dev on error unwinding. */
|
||||||
sdev->dev = NULL;
|
sdev->dev = NULL;
|
||||||
|
@ -796,7 +795,7 @@ int ssb_bus_pcibus_register(struct ssb_bus *bus,
|
||||||
err = ssb_bus_register(bus, ssb_pci_get_invariants, 0);
|
err = ssb_bus_register(bus, ssb_pci_get_invariants, 0);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
|
ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
|
||||||
"PCI device %s\n", host_pci->dev.bus_id);
|
"PCI device %s\n", dev_name(&host_pci->dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -65,7 +65,7 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
|
||||||
err = pci_enable_device(dev);
|
err = pci_enable_device(dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_kfree_ssb;
|
goto err_kfree_ssb;
|
||||||
name = dev->dev.bus_id;
|
name = dev_name(&dev->dev);
|
||||||
if (dev->driver && dev->driver->name)
|
if (dev->driver && dev->driver->name)
|
||||||
name = dev->driver->name;
|
name = dev->driver->name;
|
||||||
err = pci_request_regions(dev, name);
|
err = pci_request_regions(dev, name);
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
#include <linux/wireless.h>
|
#include <linux/wireless.h>
|
||||||
#include <linux/ieee80211.h>
|
#include <linux/ieee80211.h>
|
||||||
|
|
||||||
|
#include <net/lib80211.h>
|
||||||
|
|
||||||
#define IEEE80211_VERSION "git-1.1.13"
|
#define IEEE80211_VERSION "git-1.1.13"
|
||||||
|
|
||||||
#define IEEE80211_DATA_LEN 2304
|
#define IEEE80211_DATA_LEN 2304
|
||||||
|
@ -355,8 +357,6 @@ struct ieee80211_stats {
|
||||||
|
|
||||||
struct ieee80211_device;
|
struct ieee80211_device;
|
||||||
|
|
||||||
#include "ieee80211_crypt.h"
|
|
||||||
|
|
||||||
#define SEC_KEY_1 (1<<0)
|
#define SEC_KEY_1 (1<<0)
|
||||||
#define SEC_KEY_2 (1<<1)
|
#define SEC_KEY_2 (1<<1)
|
||||||
#define SEC_KEY_3 (1<<2)
|
#define SEC_KEY_3 (1<<2)
|
||||||
|
@ -937,11 +937,7 @@ struct ieee80211_device {
|
||||||
size_t wpa_ie_len;
|
size_t wpa_ie_len;
|
||||||
u8 *wpa_ie;
|
u8 *wpa_ie;
|
||||||
|
|
||||||
struct list_head crypt_deinit_list;
|
struct lib80211_crypt_info crypt_info;
|
||||||
struct ieee80211_crypt_data *crypt[WEP_KEYS];
|
|
||||||
int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
|
|
||||||
struct timer_list crypt_deinit_timer;
|
|
||||||
int crypt_quiesced;
|
|
||||||
|
|
||||||
int bcrx_sta_key; /* use individual keys to override default keys even
|
int bcrx_sta_key; /* use individual keys to override default keys even
|
||||||
* with RX of broad/multicast frames */
|
* with RX of broad/multicast frames */
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue